#define V_COMMIT_HASH "b876644e82044741b88cf56645abc2ac3ee2676f" #ifndef V_COMMIT_HASH #define V_COMMIT_HASH "cd94cff219b025837c31233560c388aaeca87a94" #endif #define V_USE_SIGNAL_H // V comptime_definitions: // V compile time defines by -d or -define flags: // All custom defines : no_backtrace,cross,linux // Turned ON custom defines: no_backtrace,cross,linux #define CUSTOM_DEFINE_no_backtrace #define CUSTOM_DEFINE_cross #define CUSTOM_DEFINE_linux #define __VTHREADS__ (1) // V typedefs: typedef struct IError IError; typedef struct rand__PRNG rand__PRNG; typedef struct hash__Hash hash__Hash; typedef struct hash__Hash32er hash__Hash32er; typedef struct hash__Hash64er hash__Hash64er; typedef struct v__type_resolver__IResolverType v__type_resolver__IResolverType; typedef struct v__ast__walker__Visitor v__ast__walker__Visitor; typedef struct none none; typedef struct v__ast__TypeDecl v__ast__TypeDecl; typedef struct v__ast__Expr v__ast__Expr; typedef struct v__ast__Stmt v__ast__Stmt; typedef struct v__ast__ScopeObject v__ast__ScopeObject; typedef struct v__ast__Node v__ast__Node; typedef struct v__ast__ComptTimeConstValue v__ast__ComptTimeConstValue; typedef struct v__ast__IdentInfo v__ast__IdentInfo; typedef struct v__ast__AsmArg v__ast__AsmArg; typedef struct v__ast__TypeInfo v__ast__TypeInfo; typedef struct v__checker__ORMExpr v__checker__ORMExpr; // BEGIN_array_fixed_return_typedefs typedef struct _v_Array_fixed_bool_256 _v_Array_fixed_bool_256; // END_array_fixed_return_typedefs // BEGIN_multi_return_typedefs typedef struct multi_return_u32_u32 multi_return_u32_u32; typedef struct multi_return_string_string multi_return_string_string; typedef struct multi_return_int_int multi_return_int_int; typedef struct multi_return_u32_u32_u32 multi_return_u32_u32_u32; typedef struct multi_return_strconv__ParserState_strconv__PrepNumber multi_return_strconv__ParserState_strconv__PrepNumber; typedef struct multi_return_u64_int multi_return_u64_int; typedef struct multi_return_strconv__Dec32_bool multi_return_strconv__Dec32_bool; typedef struct multi_return_strconv__Dec64_bool multi_return_strconv__Dec64_bool; typedef struct multi_return_string_int multi_return_string_int; typedef struct multi_return_int_bool multi_return_int_bool; typedef struct multi_return_ref_v__pref__Preferences_string multi_return_ref_v__pref__Preferences_string; typedef struct multi_return_u64_u64 multi_return_u64_u64; typedef struct multi_return_int_int_int multi_return_int_int_int; typedef struct multi_return_int_int_int_int_int_i64_bool multi_return_int_int_int_int_int_i64_bool; typedef struct multi_return_f64_f64 multi_return_f64_f64; typedef struct multi_return_Array_string_v__vmod__ModFileAndFolder multi_return_Array_string_v__vmod__ModFileAndFolder; typedef struct multi_return_string_bool multi_return_string_bool; typedef struct multi_return_v__ast__Fn_Array_v__ast__Type multi_return_v__ast__Fn_Array_v__ast__Type; typedef struct multi_return_v__ast__StructField_Array_v__ast__Type multi_return_v__ast__StructField_Array_v__ast__Type; typedef struct multi_return_ref_v__ast__TypeSymbol_int multi_return_ref_v__ast__TypeSymbol_int; typedef struct multi_return_v__ast__Type_string multi_return_v__ast__Type_string; typedef struct multi_return_int_v__ast__Type multi_return_int_v__ast__Type; typedef struct multi_return_bool_bool_int multi_return_bool_bool_int; typedef struct multi_return_string_v__token__Pos multi_return_string_v__token__Pos; typedef struct multi_return_bool_int_int multi_return_bool_int_int; typedef struct multi_return_v__ast__Type_ref_v__ast__TypeSymbol multi_return_v__ast__Type_ref_v__ast__TypeSymbol; typedef struct multi_return_Array_v__ast__Param_bool_bool_bool multi_return_Array_v__ast__Param_bool_bool_bool; typedef struct multi_return_Array_v__ast__Stmt_v__token__Pos multi_return_Array_v__ast__Stmt_v__token__Pos; typedef struct multi_return_Array_v__ast__Type_Array_string multi_return_Array_v__ast__Type_Array_string; typedef struct multi_return_Map_string_v__ast__FnDecl_Map_string_v__ast__ConstField_Map_string_v__ast__GlobalField_Map_string_v__ast__TypeDecl_Map_string_v__ast__StructDecl multi_return_Map_string_v__ast__FnDecl_Map_string_v__ast__ConstField_Map_string_v__ast__GlobalField_Map_string_v__ast__TypeDecl_Map_string_v__ast__StructDecl; typedef struct multi_return_bool_Array_string multi_return_bool_Array_string; typedef struct multi_return_bool_string_int_Array_string multi_return_bool_string_int_Array_string; typedef struct multi_return_Array_string_Array_string_Array_string multi_return_Array_string_Array_string_Array_string; typedef struct multi_return_string_string_string_string multi_return_string_string_string_string; typedef struct multi_return_int_string_string_string multi_return_int_string_string_string; typedef struct multi_return_bool_bool multi_return_bool_bool; typedef struct multi_return_Array_string_Array_string_Array_bool multi_return_Array_string_Array_string_Array_bool; typedef struct multi_return_u64_string multi_return_u64_string; typedef struct multi_return_v__ast__StructField_string multi_return_v__ast__StructField_string; typedef struct multi_return_bool_Array_v__ast__Type multi_return_bool_Array_v__ast__Type; typedef struct multi_return_int_string multi_return_int_string; // END_multi_return_typedefs typedef struct builtin__closure__Closure builtin__closure__Closure; typedef struct builtin__closure__ClosureMutex builtin__closure__ClosureMutex; typedef struct strconv__AtoF64Param strconv__AtoF64Param; typedef struct strconv__BF_param strconv__BF_param; typedef struct strconv__PrepNumber strconv__PrepNumber; typedef struct strconv__Dec32 strconv__Dec32; typedef struct strconv__Dec64 strconv__Dec64; typedef struct strconv__Uint128 strconv__Uint128; typedef union strconv__Uf32 strconv__Uf32; typedef union strconv__Uf64 strconv__Uf64; typedef union strconv__Float64u strconv__Float64u; typedef union strconv__Float32u strconv__Float32u; typedef struct array array; typedef struct VCastTypeIndexName VCastTypeIndexName; typedef struct EnumData EnumData; typedef struct DenseArray DenseArray; typedef struct map map; typedef struct _option _option; typedef struct None__ None__; typedef struct VMemoryBlock VMemoryBlock; typedef struct _result _result; typedef struct Error Error; typedef struct MessageError MessageError; typedef struct mapnode mapnode; typedef struct string string; typedef struct RepIndex RepIndex; typedef struct WrapConfig WrapConfig; typedef struct RunesIterator RunesIterator; typedef union StrIntpMem StrIntpMem; typedef struct StrIntpData StrIntpData; typedef struct strings__textscanner__TextScanner strings__textscanner__TextScanner; typedef struct time__TimeParseError time__TimeParseError; typedef struct time__StopWatchOptions time__StopWatchOptions; typedef struct time__StopWatch time__StopWatch; typedef struct time__Time time__Time; typedef struct v__token__KeywordsMatcherTrie v__token__KeywordsMatcherTrie; typedef struct v__token__TrieNode v__token__TrieNode; typedef struct v__token__Pos v__token__Pos; typedef struct v__token__Token v__token__Token; typedef struct v__dotgraph__DotGraph v__dotgraph__DotGraph; typedef struct v__dotgraph__NewNodeConfig v__dotgraph__NewNodeConfig; typedef struct v__dotgraph__NewEdgeConfig v__dotgraph__NewEdgeConfig; typedef struct encoding__utf8__validate__Utf8State encoding__utf8__validate__Utf8State; typedef struct rand__buffer__PRNGBuffer rand__buffer__PRNGBuffer; typedef struct flag__Flag flag__Flag; typedef struct flag__UnknownFlagError flag__UnknownFlagError; typedef struct flag__ArgsCountError flag__ArgsCountError; typedef struct flag__FlagParser flag__FlagParser; typedef struct flag__FlagConfig flag__FlagConfig; typedef struct semver__RawVersion semver__RawVersion; typedef struct semver__InvalidComparatorFormatError semver__InvalidComparatorFormatError; typedef struct semver__Version semver__Version; typedef struct semver__EmptyInputError semver__EmptyInputError; typedef struct semver__InvalidVersionFormatError semver__InvalidVersionFormatError; typedef struct os__Eof os__Eof; typedef struct os__NotExpected os__NotExpected; typedef struct os__File os__File; typedef struct os__FileNotOpenedError os__FileNotOpenedError; typedef struct os__SizeOfTypeIs0Error os__SizeOfTypeIs0Error; typedef struct os__SystemError os__SystemError; typedef struct os__Result os__Result; typedef struct os__MvParams os__MvParams; typedef struct os__ExecutableNotFoundError os__ExecutableNotFoundError; typedef struct os__WalkParams os__WalkParams; typedef struct os__MkdirParams os__MkdirParams; typedef struct os__Uname os__Uname; typedef struct os__Stat os__Stat; typedef struct os__Process os__Process; typedef struct v__errors__CompilerMessage v__errors__CompilerMessage; typedef struct v__errors__Error v__errors__Error; typedef struct v__errors__Warning v__errors__Warning; typedef struct v__errors__Notice v__errors__Notice; typedef struct os__filelock__FileLock os__filelock__FileLock; typedef struct v__depgraph__DepGraphNode v__depgraph__DepGraphNode; typedef struct v__depgraph__DepGraph v__depgraph__DepGraph; typedef struct v__depgraph__OrderedDepMap v__depgraph__OrderedDepMap; typedef struct v__depgraph__NodeNames v__depgraph__NodeNames; typedef struct v__help__ExitOptions v__help__ExitOptions; typedef struct v__vcache__CacheManager v__vcache__CacheManager; typedef struct v__vmod__ModFileAndFolder v__vmod__ModFileAndFolder; typedef struct v__vmod__ModFileCacher v__vmod__ModFileCacher; typedef struct v__cflag__CFlag v__cflag__CFlag; typedef struct rand__config__PRNGConfigStruct rand__config__PRNGConfigStruct; typedef struct rand__config__NormalConfigStruct rand__config__NormalConfigStruct; typedef struct rand__config__ShuffleConfigStruct rand__config__ShuffleConfigStruct; typedef struct rand__wyrand__WyRandRNG rand__wyrand__WyRandRNG; typedef struct v__pkgconfig__Main v__pkgconfig__Main; typedef struct v__pkgconfig__MainOptions v__pkgconfig__MainOptions; typedef struct v__pkgconfig__Options v__pkgconfig__Options; typedef struct v__pkgconfig__PkgConfig v__pkgconfig__PkgConfig; typedef struct v__pref__Preferences v__pref__Preferences; typedef struct v__pref__LineInfo v__pref__LineInfo; typedef struct sync__Subscription sync__Subscription; typedef struct sync__Channel sync__Channel; typedef struct sync__SpinLock sync__SpinLock; typedef struct sync__WaitGroup sync__WaitGroup; typedef struct sync__Mutex sync__Mutex; typedef struct sync__RwMutex sync__RwMutex; typedef struct sync__RwMutexAttr sync__RwMutexAttr; typedef struct sync__Semaphore sync__Semaphore; typedef struct v__util__EManager v__util__EManager; typedef struct v__util__LinesCache v__util__LinesCache; typedef struct v__util__Possibility v__util__Possibility; typedef struct v__util__Suggestion v__util__Suggestion; typedef struct v__util__SuggestionParams v__util__SuggestionParams; typedef struct v__util__Surrounder v__util__Surrounder; typedef struct v__util__Timers v__util__Timers; typedef struct v__util__TimerParams v__util__TimerParams; typedef struct v__util__SourceCache v__util__SourceCache; typedef struct sync__pool__PoolProcessor sync__pool__PoolProcessor; typedef struct sync__pool__PoolProcessorConfig sync__pool__PoolProcessorConfig; typedef struct v__ast__EmptyScopeObject v__ast__EmptyScopeObject; typedef struct v__ast__TypeNode v__ast__TypeNode; typedef struct v__ast__ComptimeType v__ast__ComptimeType; typedef struct v__ast__EmptyStmt v__ast__EmptyStmt; typedef struct v__ast__EmptyNode v__ast__EmptyNode; typedef struct v__ast__Block v__ast__Block; typedef struct v__ast__ExprStmt v__ast__ExprStmt; typedef struct v__ast__IntegerLiteral v__ast__IntegerLiteral; typedef struct v__ast__FloatLiteral v__ast__FloatLiteral; typedef struct v__ast__StringLiteral v__ast__StringLiteral; typedef struct v__ast__StringInterLiteral v__ast__StringInterLiteral; typedef struct v__ast__CharLiteral v__ast__CharLiteral; typedef struct v__ast__BoolLiteral v__ast__BoolLiteral; typedef struct v__ast__Nil v__ast__Nil; typedef struct v__ast__SelectorExpr v__ast__SelectorExpr; typedef struct v__ast__Module v__ast__Module; typedef struct v__ast__SemicolonStmt v__ast__SemicolonStmt; typedef struct v__ast__StructField v__ast__StructField; typedef struct v__ast__ConstField v__ast__ConstField; typedef struct v__ast__ConstDecl v__ast__ConstDecl; typedef struct v__ast__StructDecl v__ast__StructDecl; typedef struct v__ast__Embed v__ast__Embed; typedef struct v__ast__InterfaceEmbedding v__ast__InterfaceEmbedding; typedef struct v__ast__InterfaceDecl v__ast__InterfaceDecl; typedef struct v__ast__StructInitField v__ast__StructInitField; typedef struct v__ast__StructInit v__ast__StructInit; typedef struct v__ast__Import v__ast__Import; typedef struct v__ast__ImportSymbol v__ast__ImportSymbol; typedef struct v__ast__AnonFn v__ast__AnonFn; typedef struct v__ast__FnDecl v__ast__FnDecl; typedef struct v__ast__FnTrace v__ast__FnTrace; typedef struct v__ast__Fn v__ast__Fn; typedef struct v__ast__Param v__ast__Param; typedef struct v__ast__BranchStmt v__ast__BranchStmt; typedef struct v__ast__CallExpr v__ast__CallExpr; typedef struct v__ast__CallArg v__ast__CallArg; typedef struct v__ast__Return v__ast__Return; typedef struct v__ast__Var v__ast__Var; typedef struct v__ast__ScopeStructField v__ast__ScopeStructField; typedef struct v__ast__GlobalField v__ast__GlobalField; typedef struct v__ast__GlobalDecl v__ast__GlobalDecl; typedef struct v__ast__EmbeddedFile v__ast__EmbeddedFile; typedef struct v__ast__File v__ast__File; typedef struct v__ast__IdentFn v__ast__IdentFn; typedef struct v__ast__IdentVar v__ast__IdentVar; typedef struct v__ast__Ident v__ast__Ident; typedef struct v__ast__InfixExpr v__ast__InfixExpr; typedef struct v__ast__PostfixExpr v__ast__PostfixExpr; typedef struct v__ast__PrefixExpr v__ast__PrefixExpr; typedef struct v__ast__IndexExpr v__ast__IndexExpr; typedef struct v__ast__IfExpr v__ast__IfExpr; typedef struct v__ast__IfBranch v__ast__IfBranch; typedef struct v__ast__UnsafeExpr v__ast__UnsafeExpr; typedef struct v__ast__LockExpr v__ast__LockExpr; typedef struct v__ast__MatchExpr v__ast__MatchExpr; typedef struct v__ast__MatchBranch v__ast__MatchBranch; typedef struct v__ast__SelectExpr v__ast__SelectExpr; typedef struct v__ast__SelectBranch v__ast__SelectBranch; typedef struct v__ast__ComptimeFor v__ast__ComptimeFor; typedef struct v__ast__ForStmt v__ast__ForStmt; typedef struct v__ast__ForInStmt v__ast__ForInStmt; typedef struct v__ast__ForCStmt v__ast__ForCStmt; typedef struct v__ast__HashStmt v__ast__HashStmt; typedef struct v__ast__AssignStmt v__ast__AssignStmt; typedef struct v__ast__AsCast v__ast__AsCast; typedef struct v__ast__EnumVal v__ast__EnumVal; typedef struct v__ast__EnumField v__ast__EnumField; typedef struct v__ast__EnumDecl v__ast__EnumDecl; typedef struct v__ast__AliasTypeDecl v__ast__AliasTypeDecl; typedef struct v__ast__SumTypeDecl v__ast__SumTypeDecl; typedef struct v__ast__FnTypeDecl v__ast__FnTypeDecl; typedef struct v__ast__DeferStmt v__ast__DeferStmt; typedef struct v__ast__ParExpr v__ast__ParExpr; typedef struct v__ast__GoExpr v__ast__GoExpr; typedef struct v__ast__SpawnExpr v__ast__SpawnExpr; typedef struct v__ast__GotoLabel v__ast__GotoLabel; typedef struct v__ast__GotoStmt v__ast__GotoStmt; typedef struct v__ast__ArrayInit v__ast__ArrayInit; typedef struct v__ast__ArrayDecompose v__ast__ArrayDecompose; typedef struct v__ast__ChanInit v__ast__ChanInit; typedef struct v__ast__MapInit v__ast__MapInit; typedef struct v__ast__RangeExpr v__ast__RangeExpr; typedef struct v__ast__CastExpr v__ast__CastExpr; typedef struct v__ast__AsmStmt v__ast__AsmStmt; typedef struct v__ast__AsmTemplate v__ast__AsmTemplate; typedef struct v__ast__AsmRegister v__ast__AsmRegister; typedef struct v__ast__AsmDisp v__ast__AsmDisp; typedef struct v__ast__AsmAlias v__ast__AsmAlias; typedef struct v__ast__AsmAddressing v__ast__AsmAddressing; typedef struct v__ast__AsmClobbered v__ast__AsmClobbered; typedef struct v__ast__AsmIO v__ast__AsmIO; typedef struct v__ast__DebuggerStmt v__ast__DebuggerStmt; typedef struct v__ast__AssertStmt v__ast__AssertStmt; typedef struct v__ast__IfGuardVar v__ast__IfGuardVar; typedef struct v__ast__IfGuardExpr v__ast__IfGuardExpr; typedef struct v__ast__OrExpr v__ast__OrExpr; typedef struct v__ast__Assoc v__ast__Assoc; typedef struct v__ast__SizeOf v__ast__SizeOf; typedef struct v__ast__IsRefType v__ast__IsRefType; typedef struct v__ast__OffsetOf v__ast__OffsetOf; typedef struct v__ast__LambdaExpr v__ast__LambdaExpr; typedef struct v__ast__Likely v__ast__Likely; typedef struct v__ast__TypeOf v__ast__TypeOf; typedef struct v__ast__DumpExpr v__ast__DumpExpr; typedef struct v__ast__Comment v__ast__Comment; typedef struct v__ast__ConcatExpr v__ast__ConcatExpr; typedef struct v__ast__AtExpr v__ast__AtExpr; typedef struct v__ast__ComptimeSelector v__ast__ComptimeSelector; typedef struct v__ast__ComptimeCall v__ast__ComptimeCall; typedef struct v__ast__None v__ast__None; typedef struct v__ast__SqlStmt v__ast__SqlStmt; typedef struct v__ast__SqlStmtLine v__ast__SqlStmtLine; typedef struct v__ast__SqlExpr v__ast__SqlExpr; typedef struct v__ast__NodeError v__ast__NodeError; typedef struct v__ast__CTempVar v__ast__CTempVar; typedef struct v__ast__Attr v__ast__Attr; typedef struct v__ast__Scope v__ast__Scope; typedef struct v__ast__StringifyModReplacement v__ast__StringifyModReplacement; typedef struct v__ast__UsedFeatures v__ast__UsedFeatures; typedef struct v__ast__Table v__ast__Table; typedef struct v__ast__GetEmbedsOptions v__ast__GetEmbedsOptions; typedef struct v__ast__UnknownTypeInfo v__ast__UnknownTypeInfo; typedef struct v__ast__TypeSymbol v__ast__TypeSymbol; typedef struct v__ast__MultiReturn v__ast__MultiReturn; typedef struct v__ast__FnType v__ast__FnType; typedef struct v__ast__Struct v__ast__Struct; typedef struct v__ast__GenericInst v__ast__GenericInst; typedef struct v__ast__Interface v__ast__Interface; typedef struct v__ast__Enum v__ast__Enum; typedef struct v__ast__Alias v__ast__Alias; typedef struct v__ast__Aggregate v__ast__Aggregate; typedef struct v__ast__Array v__ast__Array; typedef struct v__ast__ArrayFixed v__ast__ArrayFixed; typedef struct v__ast__Chan v__ast__Chan; typedef struct v__ast__Thread v__ast__Thread; typedef struct v__ast__Map v__ast__Map; typedef struct v__ast__SumType v__ast__SumType; typedef struct v__ast__FnSignatureOpts v__ast__FnSignatureOpts; typedef struct v__transformer__KeyVal v__transformer__KeyVal; typedef struct v__transformer__IndexState v__transformer__IndexState; typedef struct v__transformer__Transformer v__transformer__Transformer; typedef struct v__markused__Walker v__markused__Walker; typedef struct v__type_resolver__ResolverInfo v__type_resolver__ResolverInfo; typedef struct v__type_resolver__DummyResolver v__type_resolver__DummyResolver; typedef struct v__type_resolver__TypeResolver v__type_resolver__TypeResolver; typedef struct v__scanner__Scanner v__scanner__Scanner; typedef struct v__ast__walker__Inspector v__ast__walker__Inspector; typedef struct v__checker__ACFieldMethod v__checker__ACFieldMethod; typedef struct v__checker__Checker v__checker__Checker; typedef struct v__checker__HaveWantParams v__checker__HaveWantParams; typedef struct v__checker__LoHiLimit v__checker__LoHiLimit; typedef struct v__parser__ReceiverParsingInfo v__parser__ReceiverParsingInfo; typedef struct v__parser__ParamsForUnexpected v__parser__ParamsForUnexpected; typedef struct v__parser__Parser v__parser__Parser; typedef struct v__parser__EatCommentsConfig v__parser__EatCommentsConfig; typedef struct v__parser__DependencyCache v__parser__DependencyCache; typedef struct v__parser__IncludeError v__parser__IncludeError; typedef struct v__callgraph__Mapper v__callgraph__Mapper; typedef struct v__gen__c__UnsupportedAssertCtempTransform v__gen__c__UnsupportedAssertCtempTransform; typedef struct v__gen__c__StrType v__gen__c__StrType; typedef struct v__gen__c__Gen v__gen__c__Gen; typedef struct v__gen__c__GenOutput v__gen__c__GenOutput; typedef struct v__gen__c__SumtypeCastingFn v__gen__c__SumtypeCastingFn; typedef struct v__gen__c__GlobalConstDef v__gen__c__GlobalConstDef; typedef struct v__gen__c__CoverageInfo v__gen__c__CoverageInfo; typedef struct v__gen__c__VSafeArithmeticOp v__gen__c__VSafeArithmeticOp; typedef struct v__gen__c__GenSafeIntegerCfg v__gen__c__GenSafeIntegerCfg; typedef struct v__gen__c__PastTmpVar v__gen__c__PastTmpVar; typedef struct v__gen__c__ProfileCounterMeta v__gen__c__ProfileCounterMeta; typedef struct v__gen__c__Type v__gen__c__Type; typedef struct v__builder__Builder v__builder__Builder; typedef struct v__builder__FunctionRedefinition v__builder__FunctionRedefinition; typedef struct v__builder__CcompilerOptions v__builder__CcompilerOptions; typedef struct v__builder__MsvcResult v__builder__MsvcResult; typedef struct v__builder__WindowsKit v__builder__WindowsKit; typedef struct v__builder__VsInstallation v__builder__VsInstallation; typedef struct v__builder__MsvcStringFlags v__builder__MsvcStringFlags; typedef struct __shared__Map_string_time__StopWatch __shared__Map_string_time__StopWatch; typedef struct __shared__Map_u64_string __shared__Map_u64_string; typedef struct __shared__Map_int_Array_v__ast__Type __shared__Map_int_Array_v__ast__Type; typedef struct __shared__Array_voidptr __shared__Array_voidptr; typedef struct __shared__Array_string __shared__Array_string; typedef struct __shared__Map_string_bool __shared__Map_string_bool; typedef struct _result_f64 _result_f64; typedef struct _result_u64 _result_u64; typedef struct _result_i64 _result_i64; typedef struct _result_void _result_void; typedef struct _result_string _result_string; typedef struct _result_time__Time _result_time__Time; typedef struct _result_multi_return_int_int_int _result_multi_return_int_int_int; typedef struct _result_multi_return_int_int_int_int_int_i64_bool _result_multi_return_int_int_int_int_int_i64_bool; typedef struct _result_bool _result_bool; typedef struct _result_semver__Version _result_semver__Version; typedef struct _result_os__File _result_os__File; typedef struct _result_FILE_ptr _result_FILE_ptr; typedef struct _result_int _result_int; typedef struct _result_Array_u8 _result_Array_u8; typedef struct _result_strings__Builder _result_strings__Builder; typedef struct _result_os__Stat _result_os__Stat; typedef struct _result_Array_string _result_Array_string; typedef struct _result_os__Result _result_os__Result; typedef struct _result_anon_fn_os__signal _result_anon_fn_os__signal; typedef struct _result_v__pkgconfig__PkgConfig_ptr _result_v__pkgconfig__PkgConfig_ptr; typedef struct _result_v__pkgconfig__Main_ptr _result_v__pkgconfig__Main_ptr; typedef struct _result_u32 _result_u32; typedef struct _result_v__pref__Arch _result_v__pref__Arch; typedef struct _result_v__pref__OS _result_v__pref__OS; typedef struct _result_v__pref__Subsystem _result_v__pref__Subsystem; typedef struct _result_v__pref__Backend _result_v__pref__Backend; typedef struct _result_v__ast__Fn _result_v__ast__Fn; typedef struct _result_multi_return_v__ast__Fn_Array_v__ast__Type _result_multi_return_v__ast__Fn_Array_v__ast__Type; typedef struct _result_v__ast__StructField _result_v__ast__StructField; typedef struct _result_multi_return_v__ast__StructField_Array_v__ast__Type _result_multi_return_v__ast__StructField_Array_v__ast__Type; typedef struct _result_v__scanner__Scanner_ptr _result_v__scanner__Scanner_ptr; typedef struct _result_v__ast__Expr _result_v__ast__Expr; typedef struct _result_v__builder__MsvcResult _result_v__builder__MsvcResult; typedef struct _result_v__builder__WindowsKit _result_v__builder__WindowsKit; typedef struct _result_v__builder__VsInstallation _result_v__builder__VsInstallation; typedef struct _option_multi_return_string_string _option_multi_return_string_string; typedef struct _option_int _option_int; typedef struct _option_rune _option_rune; typedef struct _option_u8 _option_u8; typedef struct _option_semver__Version _option_semver__Version; typedef struct _option_string _option_string; typedef struct _option_Array_string _option_Array_string; typedef struct _option_bool _option_bool; typedef struct _option_time__StopWatch _option_time__StopWatch; typedef struct _option_v__ast__Ident _option_v__ast__Ident; typedef struct _option_v__ast__CallArg _option_v__ast__CallArg; typedef struct _option_v__ast__Attr _option_v__ast__Attr; typedef struct _option_i8 _option_i8; typedef struct _option_i64 _option_i64; typedef struct _option_i16 _option_i16; typedef struct _option_i32 _option_i32; typedef struct _option_voidptr _option_voidptr; typedef struct _option_u64 _option_u64; typedef struct _option_u16 _option_u16; typedef struct _option_u32 _option_u32; typedef struct _option_f32 _option_f32; typedef struct _option_f64 _option_f64; typedef struct _option_v__ast__ComptTimeConstValue _option_v__ast__ComptTimeConstValue; typedef struct _option_v__ast__ScopeObject _option_v__ast__ScopeObject; typedef struct _option_v__ast__ScopeStructField _option_v__ast__ScopeStructField; typedef struct _option_v__ast__Var_ptr _option_v__ast__Var_ptr; typedef struct _option_v__ast__GlobalField_ptr _option_v__ast__GlobalField_ptr; typedef struct _option_v__ast__ConstField_ptr _option_v__ast__ConstField_ptr; typedef struct _option_v__ast__Fn _option_v__ast__Fn; typedef struct _option_v__ast__StructField _option_v__ast__StructField; typedef struct _option_v__ast__TypeSymbol_ptr _option_v__ast__TypeSymbol_ptr; typedef struct _option_Array_Array_v__ast__Type _option_Array_Array_v__ast__Type; typedef struct _option_v__ast__Type _option_v__ast__Type; typedef struct _option_Array_v__ast__Type _option_Array_v__ast__Type; typedef struct _option_v__ast__FnDecl _option_v__ast__FnDecl; typedef struct _option_v__ast__ConstField _option_v__ast__ConstField; typedef struct _option_v__ast__GlobalField _option_v__ast__GlobalField; typedef struct _option_v__ast__EnumDecl _option_v__ast__EnumDecl; typedef struct _option_v__ast__StructDecl _option_v__ast__StructDecl; typedef struct _option_v__ast__InterfaceDecl _option_v__ast__InterfaceDecl; typedef struct _option_v__ast__Expr _option_v__ast__Expr; typedef struct _option_v__ast__Param _option_v__ast__Param; typedef struct _option_Array_v__ast__StructField _option_Array_v__ast__StructField; typedef struct _option_v__checker__LoHiLimit _option_v__checker__LoHiLimit; typedef struct _option_v__ast__LambdaExpr _option_v__ast__LambdaExpr; typedef struct _option_v__gen__c__GlobalConstDef _option_v__gen__c__GlobalConstDef; typedef struct _option_v__ast__Stmt_ptr _option_v__ast__Stmt_ptr; typedef struct _option_v__ast__FnTrace _option_v__ast__FnTrace; // V preincludes: #if defined(__TINYC__) && defined(__has_include) // tcc does not support has_include properly yet, turn it off completely #undef __has_include #endif // V cheaders: // Generated by the V compiler #if defined __GNUC__ && __GNUC__ >= 14 #pragma GCC diagnostic warning "-Wimplicit-function-declaration" #pragma GCC diagnostic warning "-Wincompatible-pointer-types" #pragma GCC diagnostic warning "-Wint-conversion" #pragma GCC diagnostic warning "-Wreturn-mismatch" #endif #define _GNU_SOURCE #if defined(__TINYC__) && defined(__has_include) // tcc does not support has_include properly yet, turn it off completely #undef __has_include #endif #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE The C compiler can not find . Please install the package `build-essential`. #endif #else #include #endif #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE The C compiler can not find . Please install the package `build-essential`. #endif #else #include #endif //================================== builtin types ================================*/ #if defined(__x86_64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || (defined(__riscv_xlen) && __riscv_xlen == 64) || defined(__s390x__) || (defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)) || defined(__loongarch64) typedef int64_t vint_t; #else typedef int32_t vint_t; #endif typedef int64_t i64; typedef int16_t i16; typedef int8_t i8; typedef uint64_t u64; typedef uint32_t u32; typedef uint8_t u8; typedef uint16_t u16; typedef u8 byte; typedef int32_t i32; typedef uint32_t rune; typedef size_t usize; typedef ptrdiff_t isize; #ifndef VNOFLOAT typedef float f32; typedef double f64; #else typedef int32_t f32; typedef int64_t f64; #endif typedef int64_t int_literal; #ifndef VNOFLOAT typedef double float_literal; #else typedef int64_t float_literal; #endif typedef unsigned char* byteptr; typedef void* voidptr; typedef char* charptr; typedef u8 array_fixed_byte_300 [300]; typedef struct sync__Channel* chan; #ifndef CUSTOM_DEFINE_no_bool #ifndef __cplusplus #ifndef bool #ifdef CUSTOM_DEFINE_4bytebool typedef int bool; #else typedef u8 bool; #endif #define true 1 #define false 0 #endif #endif #endif typedef u64 (*MapHashFn)(voidptr); typedef bool (*MapEqFn)(voidptr, voidptr); typedef void (*MapCloneFn)(voidptr, voidptr); typedef void (*MapFreeFn)(voidptr); //============================== HELPER C MACROS =============================*/ // _SLIT0 is used as NULL string for literal arguments // `"" s` is used to enforce a string literal argument #define _SLIT0 (string){.str=(byteptr)(""), .len=0, .is_lit=1} #define _S(s) ((string){.str=(byteptr)("" s), .len=(sizeof(s)-1), .is_lit=1}) #define _SLEN(s, n) ((string){.str=(byteptr)("" s), .len=n, .is_lit=1}) // optimized way to compare literal strings #define _SLIT_EQ(sptr, slen, lit) (slen == sizeof("" lit)-1 && !vmemcmp(sptr, "" lit, slen)) #define _SLIT_NE(sptr, slen, lit) (slen != sizeof("" lit)-1 || vmemcmp(sptr, "" lit, slen)) // take the address of an rvalue #define ADDR(type, expr) (&((type[]){expr}[0])) // copy something to the heap #define HEAP(type, expr) ((type*)memdup((void*)&((type[]){expr}[0]), sizeof(type))) #define HEAP_noscan(type, expr) ((type*)memdup_noscan((void*)&((type[]){expr}[0]), sizeof(type))) #define HEAP_align(type, expr, align) ((type*)memdup_align((void*)&((type[]){expr}[0]), sizeof(type), align)) #define _PUSH_MANY(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array_push_many(arr, tmp.data, tmp.len);} #define _PUSH_MANY_noscan(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array_push_many_noscan(arr, tmp.data, tmp.len);} // unsigned/signed comparisons static inline bool _us32_gt(uint32_t a, int32_t b) { return a > INT32_MAX || (int32_t)a > b; } static inline bool _us32_ge(uint32_t a, int32_t b) { return a >= INT32_MAX || (int32_t)a >= b; } static inline bool _us32_eq(uint32_t a, int32_t b) { return a <= INT32_MAX && (int32_t)a == b; } static inline bool _us32_ne(uint32_t a, int32_t b) { return a > INT32_MAX || (int32_t)a != b; } static inline bool _us32_le(uint32_t a, int32_t b) { return a <= INT32_MAX && (int32_t)a <= b; } static inline bool _us32_lt(uint32_t a, int32_t b) { return a < INT32_MAX && (int32_t)a < b; } static inline bool _us64_gt(uint64_t a, int64_t b) { return a > INT64_MAX || (int64_t)a > b; } static inline bool _us64_ge(uint64_t a, int64_t b) { return a >= INT64_MAX || (int64_t)a >= b; } static inline bool _us64_eq(uint64_t a, int64_t b) { return a <= INT64_MAX && (int64_t)a == b; } static inline bool _us64_ne(uint64_t a, int64_t b) { return a > INT64_MAX || (int64_t)a != b; } static inline bool _us64_le(uint64_t a, int64_t b) { return a <= INT64_MAX && (int64_t)a <= b; } static inline bool _us64_lt(uint64_t a, int64_t b) { return a < INT64_MAX && (int64_t)a < b; } #define EMPTY_VARG_INITIALIZATION 0 #define EMPTY_STRUCT_DECLARATION #define E_STRUCT // Due to a tcc bug, the length of an array needs to be specified, but GCC crashes if it is... #define EMPTY_ARRAY_OF_ELEMS(x,n) (x[]) #define TCCSKIP(x) x #define __NOINLINE __attribute__((noinline)) #define __IRQHANDLER __attribute__((interrupt)) #define __V_architecture 0 #if defined(__x86_64__) || defined(_M_AMD64) #define __V_amd64 1 #undef __V_architecture #define __V_architecture 1 #endif #if defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) #define __V_arm64 1 #undef __V_architecture #define __V_architecture 2 #endif #if defined(__arm__) || defined(_M_ARM) #define __V_arm32 1 #undef __V_architecture #define __V_architecture 3 #endif #if defined(__riscv) && __riscv_xlen == 64 #define __V_rv64 1 #undef __V_architecture #define __V_architecture 4 #endif #if defined(__riscv) && __riscv_xlen == 32 #define __V_rv32 1 #undef __V_architecture #define __V_architecture 5 #endif #if defined(__i386__) || defined(_M_IX86) #define __V_x86 1 #undef __V_architecture #define __V_architecture 6 #endif #if defined(__s390x__) #define __V_s390x 1 #undef __V_architecture #define __V_architecture 7 #endif #if defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) #define __V_ppc64le 1 #undef __V_architecture #define __V_architecture 8 #endif #if defined(__loongarch64) #define __V_loongarch64 1 #undef __V_architecture #define __V_architecture 9 #endif // Using just __GNUC__ for detecting gcc, is not reliable because other compilers define it too: #ifdef __GNUC__ #define __V_GCC__ #endif #ifdef __TINYC__ #undef __V_GCC__ #endif #ifdef __cplusplus #undef __V_GCC__ #endif #ifdef __clang__ #undef __V_GCC__ #endif #ifdef _MSC_VER #undef __V_GCC__ #undef EMPTY_STRUCT_DECLARATION #undef E_STRUCT #define EMPTY_STRUCT_DECLARATION unsigned char _dummy_pad #define E_STRUCT 0 #endif #ifndef _WIN32 #if defined __has_include #if __has_include () #include #else // On linux: int backtrace(void **__array, int __size); // On BSD: size_t backtrace(void **, size_t); #endif #endif #endif #ifdef __TINYC__ #define _Atomic volatile #undef EMPTY_STRUCT_DECLARATION #undef E_STRUCT #define EMPTY_STRUCT_DECLARATION unsigned char _dummy_pad #define E_STRUCT 0 #undef EMPTY_ARRAY_OF_ELEMS #define EMPTY_ARRAY_OF_ELEMS(x,n) (x[n]) #undef __NOINLINE #undef __IRQHANDLER // tcc does not support inlining at all #define __NOINLINE #define __IRQHANDLER #undef TCCSKIP #define TCCSKIP(x) // #include int tcc_backtrace(const char *fmt, ...); #endif // Use __offsetof_ptr instead of __offset_of, when you *do* have a valid pointer, to avoid UB: #ifndef __offsetof_ptr #define __offsetof_ptr(ptr,PTYPE,FIELDNAME) ((size_t)((byte *)&((PTYPE *)ptr)->FIELDNAME - (byte *)ptr)) #endif // for __offset_of #ifndef __offsetof #if defined(__TINYC__) || defined(_MSC_VER) #define __offsetof(PTYPE,FIELDNAME) ((size_t)(&((PTYPE *)0)->FIELDNAME)) #else #define __offsetof(st, m) __builtin_offsetof(st, m) #endif #endif #define OPTION_CAST(x) (x) #if defined(_WIN32) || defined(__CYGWIN__) #define VV_EXP extern __declspec(dllexport) #define VV_LOC static #else // 4 < gcc < 5 is used by some older Ubuntu LTS and Centos versions, // and does not support __has_attribute(visibility) ... #ifndef __has_attribute #define __has_attribute(x) 0 // Compatibility with non-clang compilers. #endif #if (defined(__GNUC__) && (__GNUC__ >= 4)) || (defined(__clang__) && __has_attribute(visibility)) #ifdef ARM #define VV_EXP extern __attribute__((externally_visible,visibility("default"))) #else #define VV_EXP extern __attribute__((visibility("default"))) #endif #if defined(__clang__) && (defined(_VUSECACHE) || defined(_VBUILDMODULE)) #define VV_LOC static #else #define VV_LOC __attribute__ ((visibility ("hidden"))) #endif #else #define VV_EXP extern #define VV_LOC static #endif #endif #ifdef __cplusplus #include #define _MOV std::move #else #define _MOV #endif // tcc does not support has_include properly yet, turn it off completely #if defined(__TINYC__) && defined(__has_include) #undef __has_include #endif #if !defined(VWEAK) #define VWEAK __attribute__((weak)) #ifdef _MSC_VER #undef VWEAK #define VWEAK #endif #if defined(__MINGW32__) || defined(__MINGW64__) #undef VWEAK #define VWEAK #endif #endif #if !defined(VHIDDEN) #define VHIDDEN __attribute__((visibility("hidden"))) #ifdef _MSC_VER #undef VHIDDEN #define VHIDDEN #endif #if defined(__MINGW32__) || defined(__MINGW64__) #undef VHIDDEN #define VHIDDEN #endif #endif #if !defined(VNORETURN) #if defined(__TINYC__) #include #define VNORETURN noreturn #endif # if !defined(__TINYC__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L # define VNORETURN _Noreturn # elif !defined(VNORETURN) && defined(__GNUC__) && __GNUC__ >= 2 # define VNORETURN __attribute__((noreturn)) # endif #ifndef VNORETURN #define VNORETURN #endif #endif #if !defined(VUNREACHABLE) #if defined(__GNUC__) && !defined(__clang__) #define V_GCC_VERSION (__GNUC__ * 10000L + __GNUC_MINOR__ * 100L + __GNUC_PATCHLEVEL__) #if (V_GCC_VERSION >= 40500L) && !defined(__TINYC__) #define VUNREACHABLE() do { __builtin_unreachable(); } while (0) #endif #endif #if defined(__clang__) && defined(__has_builtin) && !defined(__TINYC__) #if __has_builtin(__builtin_unreachable) #define VUNREACHABLE() do { __builtin_unreachable(); } while (0) #endif #endif #ifndef VUNREACHABLE #define VUNREACHABLE() do { } while (0) #endif #endif //likely and unlikely macros #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) #define _likely_(x) __builtin_expect(x,1) #define _unlikely_(x) __builtin_expect(x,0) #else #define _likely_(x) (x) #define _unlikely_(x) (x) #endif // c_headers typedef int (*qsort_callback_func)(const void*, const void*); #include // TODO: remove all these includes, define all function signatures and types manually #include #include #include // for va_list //================================== GLOBALS =================================*/ int load_so(byteptr); void _vinit(int ___argc, voidptr ___argv); void _vcleanup(void); #ifdef _WIN32 // workaround for windows, export _vinit_caller/_vcleanup_caller, let dl.open()/dl.close() call it // NOTE: This is hardcoded in vlib/dl/dl_windows.c.v! VV_EXP void _vinit_caller(); VV_EXP void _vcleanup_caller(); #endif #define sigaction_size sizeof(sigaction); #define _ARR_LEN(a) ( (sizeof(a)) / (sizeof(a[0])) ) void v_free(voidptr ptr); #if INTPTR_MAX == INT32_MAX #define TARGET_IS_32BIT 1 #elif INTPTR_MAX == INT64_MAX #define TARGET_IS_64BIT 1 #else #error "The environment is not 32 or 64-bit." #endif #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) #define TARGET_ORDER_IS_BIG 1 #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || defined(_M_AMD64) || defined(_M_ARM64) || defined(_M_X64) || defined(_M_IX86) #define TARGET_ORDER_IS_LITTLE 1 #else #error "Unknown architecture endianness" #endif #ifndef _WIN32 #include #include // tolower #include #include // sleep extern char **environ; #endif #if defined(__CYGWIN__) && !defined(_WIN32) #error Cygwin is not supported, please use MinGW or Visual Studio. #endif #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__vinix__) || defined(__serenity__) || defined(__sun) || defined(__plan9__) #include #include // os__wait uses wait on nix #endif #ifdef __OpenBSD__ #include #include #include // os__wait uses wait on nix #endif #ifdef __FreeBSD__ #include #include #endif #ifdef __NetBSD__ #include // os__wait uses wait on nix #endif #ifdef _WIN32 #define WINVER 0x0600 #ifdef _WIN32_WINNT #undef _WIN32_WINNT #endif #define _WIN32_WINNT 0x0600 #ifndef WIN32_FULL #define WIN32_LEAN_AND_MEAN #endif #ifndef _UNICODE #define _UNICODE #endif #ifndef UNICODE #define UNICODE #endif #include #include // _waccess #include // _wgetcwd #ifdef V_USE_SIGNAL_H #include // signal and SIGSEGV for segmentation fault handler #endif #ifdef _MSC_VER // On MSVC these are the same (as long as /volatile:ms is passed) #define _Atomic volatile // MSVC cannot parse some things properly #undef OPTION_CAST #define OPTION_CAST(x) #undef __NOINLINE #undef __IRQHANDLER #define __NOINLINE __declspec(noinline) #define __IRQHANDLER __declspec(naked) #include #pragma comment(lib, "Dbghelp") #endif #else #include #ifndef PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP // musl does not have that #define pthread_rwlockattr_setkind_np(a, b) #endif #endif // g_live_info is used by live.info() static void* g_live_info = NULL; #if defined(__MINGW32__) || defined(__MINGW64__) || (defined(_WIN32) && defined(__TINYC__)) #undef PRId64 #undef PRIi64 #undef PRIo64 #undef PRIu64 #undef PRIx64 #undef PRIX64 #define PRId64 "lld" #define PRIi64 "lli" #define PRIo64 "llo" #define PRIu64 "llu" #define PRIx64 "llx" #define PRIX64 "llX" #endif #ifdef _VFREESTANDING #undef _VFREESTANDING #endif // ============== wyhash ============== #ifndef wyhash_final_version_3 #define wyhash_final_version_3 #ifndef WYHASH_CONDOM // protections that produce different results: // 1: normal valid behavior // 2: extra protection against entropy loss (probability=2^-63), aka. "blind multiplication" #define WYHASH_CONDOM 1 #endif #ifndef WYHASH_32BIT_MUM // 0: normal version, slow on 32 bit systems // 1: faster on 32 bit systems but produces different results, incompatible with wy2u0k function #define WYHASH_32BIT_MUM 0 #endif // includes #include #if defined(_MSC_VER) && defined(_M_X64) #include #pragma intrinsic(_umul128) #endif // 128bit multiply function static inline uint64_t _wyrot(uint64_t x) { return (x>>32)|(x<<32); } static inline void _wymum(uint64_t *A, uint64_t *B){ #if(WYHASH_32BIT_MUM) uint64_t hh=(*A>>32)*(*B>>32), hl=(*A>>32)*(uint32_t)*B, lh=(uint32_t)*A*(*B>>32), ll=(uint64_t)(uint32_t)*A*(uint32_t)*B; #if(WYHASH_CONDOM>1) *A^=_wyrot(hl)^hh; *B^=_wyrot(lh)^ll; #else *A=_wyrot(hl)^hh; *B=_wyrot(lh)^ll; #endif #elif defined(__SIZEOF_INT128__) && !defined(VWASM) __uint128_t r=*A; r*=*B; #if(WYHASH_CONDOM>1) *A^=(uint64_t)r; *B^=(uint64_t)(r>>64); #else *A=(uint64_t)r; *B=(uint64_t)(r>>64); #endif #elif defined(_MSC_VER) && defined(_M_X64) #if(WYHASH_CONDOM>1) uint64_t a, b; a=_umul128(*A,*B,&b); *A^=a; *B^=b; #else *A=_umul128(*A,*B,B); #endif #else uint64_t ha=*A>>32, hb=*B>>32, la=(uint32_t)*A, lb=(uint32_t)*B, hi, lo; uint64_t rh=ha*hb, rm0=ha*lb, rm1=hb*la, rl=la*lb, t=rl+(rm0<<32), c=t>32)+(rm1>>32)+c; #if(WYHASH_CONDOM>1) *A^=lo; *B^=hi; #else *A=lo; *B=hi; #endif #endif } // multiply and xor mix function, aka MUM static inline uint64_t _wymix(uint64_t A, uint64_t B){ _wymum(&A,&B); return A^B; } // endian macros #ifndef WYHASH_LITTLE_ENDIAN #ifdef TARGET_ORDER_IS_LITTLE #define WYHASH_LITTLE_ENDIAN 1 #else #define WYHASH_LITTLE_ENDIAN 0 #endif #endif // read functions #if (WYHASH_LITTLE_ENDIAN) static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return v;} static inline uint64_t _wyr4(const uint8_t *p) { uint32_t v; memcpy(&v, p, 4); return v;} #elif !defined(__TINYC__) && (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)) static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return __builtin_bswap64(v);} static inline uint64_t _wyr4(const uint8_t *p) { uint32_t v; memcpy(&v, p, 4); return __builtin_bswap32(v);} #elif defined(_MSC_VER) static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return _byteswap_uint64(v);} static inline uint64_t _wyr4(const uint8_t *p) { uint32_t v; memcpy(&v, p, 4); return _byteswap_ulong(v);} #else static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return (((v >> 56) & 0xff)| ((v >> 40) & 0xff00)| ((v >> 24) & 0xff0000)| ((v >> 8) & 0xff000000)| ((v << 8) & 0xff00000000)| ((v << 24) & 0xff0000000000)| ((v << 40) & 0xff000000000000)| ((v << 56) & 0xff00000000000000)); } static inline uint64_t _wyr4(const uint8_t *p) { uint32_t v; memcpy(&v, p, 4); return (((v >> 24) & 0xff)| ((v >> 8) & 0xff00)| ((v << 8) & 0xff0000)| ((v << 24) & 0xff000000)); } #endif static inline uint64_t _wyr3(const uint8_t *p, size_t k) { return (((uint64_t)p[0])<<16)|(((uint64_t)p[k>>1])<<8)|p[k-1];} // wyhash main function static inline uint64_t wyhash(const void *key, size_t len, uint64_t seed, const uint64_t *secret){ const uint8_t *p=(const uint8_t *)key; seed^=*secret; uint64_t a, b; if (_likely_(len<=16)) { if (_likely_(len>=4)) { a=(_wyr4(p)<<32)|_wyr4(p+((len>>3)<<2)); b=(_wyr4(p+len-4)<<32)|_wyr4(p+len-4-((len>>3)<<2)); } else if (_likely_(len>0)) { a=_wyr3(p,len); b=0; } else a=b=0; } else { size_t i=len; if (_unlikely_(i>48)) { uint64_t see1=seed, see2=seed; do { seed=_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed); see1=_wymix(_wyr8(p+16)^secret[2],_wyr8(p+24)^see1); see2=_wymix(_wyr8(p+32)^secret[3],_wyr8(p+40)^see2); p+=48; i-=48; } while(_likely_(i>48)); seed^=see1^see2; } while(_unlikely_(i>16)) { seed=_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed); i-=16; p+=16; } a=_wyr8(p+i-16); b=_wyr8(p+i-8); } return _wymix(secret[1]^len,_wymix(a^secret[1],b^seed)); } // the default secret parameters static const uint64_t _wyp[4] = {0xa0761d6478bd642f, 0xe7037ed1a0b428db, 0x8ebc6af09c88c6e3, 0x589965cc75374cc3}; // a useful 64bit-64bit mix function to produce deterministic pseudo random numbers that can pass BigCrush and PractRand static inline uint64_t wyhash64(uint64_t A, uint64_t B){ A^=0xa0761d6478bd642f; B^=0xe7037ed1a0b428db; _wymum(&A,&B); return _wymix(A^0xa0761d6478bd642f,B^0xe7037ed1a0b428db);} // the wyrand PRNG that pass BigCrush and PractRand static inline uint64_t wyrand(uint64_t *seed){ *seed+=0xa0761d6478bd642f; return _wymix(*seed,*seed^0xe7037ed1a0b428db);} #ifndef __vinix__ // convert any 64 bit pseudo random numbers to uniform distribution [0,1). It can be combined with wyrand, wyhash64 or wyhash. static inline double wy2u01(uint64_t r){ const double _wynorm=1.0/(1ull<<52); return (r>>12)*_wynorm;} // convert any 64 bit pseudo random numbers to APPROXIMATE Gaussian distribution. It can be combined with wyrand, wyhash64 or wyhash. static inline double wy2gau(uint64_t r){ const double _wynorm=1.0/(1ull<<20); return ((r&0x1fffff)+((r>>21)&0x1fffff)+((r>>42)&0x1fffff))*_wynorm-3.0;} #endif #if(!WYHASH_32BIT_MUM) // fast range integer random number generation on [0,k) credit to Daniel Lemire. May not work when WYHASH_32BIT_MUM=1. It can be combined with wyrand, wyhash64 or wyhash. static inline uint64_t wy2u0k(uint64_t r, uint64_t k){ _wymum(&r,&k); return k; } #endif #endif #define _IN_MAP(val, m) map_exists(m, val) #if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30 #include #define gettid() syscall(SYS_gettid) #endif // V includes: #if defined(__TINYC__) && defined(__has_include) // tcc does not support has_include properly yet, turn it off completely #undef __has_include #endif #if !defined(_VFREESTANDING) && !defined(__vinix__) // added by module `builtin.closure`, file: closure_nix.c.v:4: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `builtin.closure` was not found. Please install the corresponding development headers. #endif #else #include #endif #endif // $if !defined(_VFREESTANDING) && !defined(__vinix__) #if !defined(_VNATIVE) // added by module `builtin`, file: float.c.v:10: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `builtin` was not found. Please install the corresponding development headers. #endif #else #include #endif #endif // $if !defined(_VNATIVE) // added by module `term.termios`, file: termios_linux.c.v:10: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `term.termios` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `term.termios`, file: termios_linux.c.v:11: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `term.termios` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `time`, file: time.c.v:6: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `time` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `time`, file: time_nix.c.v:7: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `time` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `time`, file: time_nix.c.v:8: #include #if defined(_WIN32) // inserted by module `sync.stdatomic`, file: 1.declarations.c.v:8: /* * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef COMPAT_ATOMICS_WIN32_STDATOMIC_H #define COMPAT_ATOMICS_WIN32_STDATOMIC_H #define WIN32_LEAN_AND_MEAN #include #include #include #ifdef _MSC_VER #define cpu_relax() _mm_pause() #else #define cpu_relax() __asm__ __volatile__ ("pause") #endif #define ATOMIC_FLAG_INIT 0 #define ATOMIC_VAR_INIT(value) (value) #define atomic_init(obj, value) \ do \ { \ *(obj) = (value); \ } while (0) #define kill_dependency(y) ((void)0) // memory order policies - we use "sequentially consistent" by default #define memory_order_relaxed 0 #define memory_order_consume 1 #define memory_order_acquire 2 #define memory_order_release 3 #define memory_order_acq_rel 4 #define memory_order_seq_cst 5 #ifdef _MSC_VER #define atomic_thread_fence(order) \ do { \ switch (order) { \ case memory_order_release: \ _WriteBarrier(); \ _ReadWriteBarrier(); \ break; \ case memory_order_acquire: \ _ReadBarrier(); \ _ReadWriteBarrier(); \ break; \ case memory_order_acq_rel: \ _ReadBarrier(); \ _WriteBarrier(); \ _ReadWriteBarrier(); \ break; \ case memory_order_seq_cst: \ MemoryBarrier(); \ break; \ default: /* relaxed, consume */ \ break; \ } \ } while (0) #else #define atomic_thread_fence(order) do { \ switch (order) { \ case memory_order_relaxed: \ break; \ case memory_order_acquire: \ case memory_order_consume: \ case memory_order_release: \ case memory_order_acq_rel: \ __asm__ __volatile__ ("" : : : "memory"); \ break; \ case memory_order_seq_cst: \ __asm__ __volatile__ ("mfence" : : : "memory"); \ break; \ default: \ __asm__ __volatile__ ("mfence" : : : "memory"); \ break; \ } \ } while (0) #endif #define atomic_signal_fence(order) \ ((void)0) #define atomic_is_lock_free(obj) 0 typedef intptr_t atomic_flag; typedef _Atomic bool atomic_bool; typedef _Atomic char atomic_char; typedef _Atomic signed char atomic_schar; typedef _Atomic unsigned char atomic_uchar; typedef _Atomic short atomic_short; typedef _Atomic unsigned short atomic_ushort; typedef _Atomic int atomic_int; typedef _Atomic unsigned int atomic_uint; typedef _Atomic long atomic_long; typedef _Atomic unsigned long atomic_ulong; typedef _Atomic long long atomic_llong; typedef _Atomic unsigned long long atomic_ullong; typedef intptr_t atomic_wchar_t; typedef intptr_t atomic_int_least8_t; typedef intptr_t atomic_uint_least8_t; typedef intptr_t atomic_int_least16_t; typedef intptr_t atomic_uint_least16_t; typedef intptr_t atomic_int_least32_t; typedef intptr_t atomic_uint_least32_t; typedef intptr_t atomic_int_least64_t; typedef intptr_t atomic_uint_least64_t; typedef intptr_t atomic_int_fast8_t; typedef intptr_t atomic_uint_fast8_t; typedef intptr_t atomic_int_fast16_t; typedef intptr_t atomic_uint_fast16_t; typedef intptr_t atomic_int_fast32_t; typedef intptr_t atomic_uint_fast32_t; typedef intptr_t atomic_int_fast64_t; typedef intptr_t atomic_uint_fast64_t; typedef _Atomic intptr_t atomic_intptr_t; typedef _Atomic uintptr_t atomic_uintptr_t; typedef _Atomic size_t atomic_size_t; typedef intptr_t atomic_ptrdiff_t; typedef intptr_t atomic_intmax_t; typedef intptr_t atomic_uintmax_t; #ifdef __TINYC__ /* For TCC it is missing the x64 version of _InterlockedExchangeAdd64 so we fake it (works the same) with InterlockedCompareExchange64 until it succeeds */ __CRT_INLINE LONGLONG _InterlockedExchangeAdd64(LONGLONG volatile *Addend, LONGLONG Value) { LONGLONG Old; do { Old = *Addend; } while (InterlockedCompareExchange64(Addend, Old + Value, Old) != Old); return Old; } __CRT_INLINE LONG _InterlockedExchangeAdd(LONG volatile *Addend, LONG Value) { LONG Old; do { Old = *Addend; } while (InterlockedCompareExchange(Addend, Old + Value, Old) != Old); return Old; } #define InterlockedIncrement64 _InterlockedExchangeAdd64 #endif #define atomic_store(object, desired) \ do \ { \ MemoryBarrier(); \ *(object) = (desired); \ MemoryBarrier(); \ } while (0) #define atomic_store_explicit(object, desired, order) \ atomic_store(object, desired) #define atomic_load(object) \ (MemoryBarrier(), *(object)) #define atomic_load_explicit(object, order) \ atomic_load(object) #define atomic_exchange(object, desired) \ InterlockedExchangePointer(object, desired) #define atomic_exchange_explicit(object, desired, order) \ atomic_exchange(object, desired) static inline int atomic_compare_exchange_strong(intptr_t volatile *object, intptr_t volatile *expected, intptr_t desired) { intptr_t old = *expected; *expected = (intptr_t)InterlockedCompareExchangePointer( (PVOID *)object, (PVOID)desired, (PVOID)old); return *expected == old; } #define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ atomic_compare_exchange_strong(object, expected, desired) #define atomic_compare_exchange_weak(object, expected, desired) \ atomic_compare_exchange_strong(object, expected, desired) #define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ atomic_compare_exchange_weak(object, expected, desired) #ifdef _WIN64 #define atomic_fetch_add(object, operand) \ InterlockedExchangeAdd64(object, operand) #define atomic_fetch_sub(object, operand) \ InterlockedExchangeAdd64(object, -(operand)) #define atomic_fetch_or(object, operand) \ InterlockedOr64(object, operand) #define atomic_fetch_xor(object, operand) \ InterlockedXor64(object, operand) #define atomic_fetch_and(object, operand) \ InterlockedAnd64(object, operand) #else #define atomic_fetch_add(object, operand) \ InterlockedExchangeAdd(object, operand) #define atomic_fetch_sub(object, operand) \ InterlockedExchangeAdd(object, -(operand)) #define atomic_fetch_or(object, operand) \ InterlockedOr(object, operand) #define atomic_fetch_xor(object, operand) \ InterlockedXor(object, operand) #define atomic_fetch_and(object, operand) \ InterlockedAnd(object, operand) #endif /* _WIN64 */ /* specialized versions with explicit object size */ #define atomic_load_ptr atomic_load #define atomic_store_ptr atomic_store #define atomic_compare_exchange_weak_ptr atomic_compare_exchange_weak #define atomic_compare_exchange_strong_ptr atomic_compare_exchange_strong #define atomic_exchange_ptr atomic_exchange #define atomic_fetch_add_ptr atomic_fetch_add #define atomic_fetch_sub_ptr atomic_fetch_sub #define atomic_fetch_and_ptr atomic_fetch_and #define atomic_fetch_or_ptr atomic_fetch_or #define atomic_fetch_xor_ptr atomic_fetch_xor static inline void atomic_store_u64(unsigned long long volatile * object, unsigned long long desired) { do { MemoryBarrier(); *(object) = (desired); MemoryBarrier(); } while (0); } static inline unsigned long long atomic_load_u64(unsigned long long volatile * object) { return (MemoryBarrier(), *(object)); } #define atomic_exchange_u64(object, desired) \ InterlockedExchange64(object, desired) static inline int atomic_compare_exchange_strong_u64(unsigned long long volatile * object, unsigned long long volatile * expected, unsigned long long desired) { unsigned long long old = *expected; *expected = InterlockedCompareExchange64(object, desired, old); return *expected == old; } #define atomic_compare_exchange_weak_u64(object, expected, desired) \ atomic_compare_exchange_strong_u64(object, expected, desired) #define atomic_fetch_add_u64(object, operand) \ InterlockedExchangeAdd64(object, operand) #define atomic_fetch_sub_u64(object, operand) \ InterlockedExchangeAdd64(object, -(operand)) #define atomic_fetch_or_u64(object, operand) \ InterlockedOr64(object, operand) #define atomic_fetch_xor_u64(object, operand) \ InterlockedXor64(object, operand) #define atomic_fetch_and_u64(object, operand) \ InterlockedAnd64(object, operand) static inline void atomic_store_u32(unsigned volatile * object, unsigned desired) { do { MemoryBarrier(); *(object) = (desired); MemoryBarrier(); } while (0); } static inline unsigned atomic_load_u32(unsigned volatile * object) { return (MemoryBarrier(), *(object)); } #define atomic_exchange_u32(object, desired) \ InterlockedExchange(object, desired) static inline int atomic_compare_exchange_strong_u32(unsigned volatile * object, unsigned volatile * expected, unsigned desired) { unsigned old = *expected; *expected = InterlockedCompareExchange((void *)object, desired, old); return *expected == old; } #define atomic_compare_exchange_weak_u32(object, expected, desired) \ atomic_compare_exchange_strong_u32(object, expected, desired) #define atomic_fetch_add_u32(object, operand) \ InterlockedExchangeAdd(object, operand) #define atomic_fetch_sub_u32(object, operand) \ InterlockedExchangeAdd(object, -(operand)) #define atomic_fetch_or_u32(object, operand) \ InterlockedOr(object, operand) #define atomic_fetch_xor_u32(object, operand) \ InterlockedXor(object, operand) #define atomic_fetch_and_u32(object, operand) \ InterlockedAnd(object, operand) #ifdef _MSC_VER #define InterlockedExchangeAdd16 _InterlockedExchangeAdd16 #else #define InterlockedExchange16 ManualInterlockedExchange16 #define InterlockedExchangeAdd16 ManualInterlockedExchangeAdd16 static inline uint16_t ManualInterlockedExchange16(volatile uint16_t* object, uint16_t desired) { __asm__ __volatile__ ( "xchgw %0, %1" : "+r" (desired), "+m" (*object) : : "memory" ); return desired; } static inline unsigned short ManualInterlockedExchangeAdd16(unsigned short volatile* Addend, unsigned short Value) { __asm__ __volatile__ ( "lock xaddw %w[value], %[mem]" : [mem] "+m" (*Addend), [value] "+r" (Value) : : "memory" ); return Value; } #endif static inline void atomic_store_u16(unsigned short volatile * object, unsigned short desired) { do { MemoryBarrier(); *(object) = (desired); MemoryBarrier(); } while (0); } static inline unsigned short atomic_load_u16(unsigned short volatile * object) { return (MemoryBarrier(), *(object)); } #define atomic_exchange_u16(object, desired) \ InterlockedExchange16(object, desired) static inline int atomic_compare_exchange_strong_u16(unsigned short volatile * object, unsigned short volatile * expected, unsigned short desired) { unsigned short old = *expected; *expected = InterlockedCompareExchange16(object, desired, old); return *expected == old; } #define atomic_compare_exchange_weak_u16(object, expected, desired) \ atomic_compare_exchange_strong_u16((void*)object, expected, desired) #define atomic_fetch_add_u16(object, operand) \ InterlockedExchangeAdd16(object, operand) #define atomic_fetch_sub_u16(object, operand) \ InterlockedExchangeAdd16(object, -(operand)) #define atomic_fetch_or_u16(object, operand) \ InterlockedOr16(object, operand) #define atomic_fetch_xor_u16(object, operand) \ InterlockedXor16(object, operand) #define atomic_fetch_and_u16(object, operand) \ InterlockedAnd16(object, operand) #define atomic_fetch_add_explicit(object, operand, order) \ atomic_fetch_add(object, operand) #define atomic_fetch_sub_explicit(object, operand, order) \ atomic_fetch_sub(object, operand) #define atomic_fetch_or_explicit(object, operand, order) \ atomic_fetch_or(object, operand) #define atomic_fetch_xor_explicit(object, operand, order) \ atomic_fetch_xor(object, operand) #define atomic_fetch_and_explicit(object, operand, order) \ atomic_fetch_and(object, operand) #define atomic_flag_test_and_set(object) \ atomic_exchange(object, 1) #define atomic_flag_test_and_set_explicit(object, order) \ atomic_flag_test_and_set(object) #define atomic_flag_clear(object) \ atomic_store(object, 0) #define atomic_flag_clear_explicit(object, order) \ atomic_flag_clear(object) #ifdef _MSC_VER #define InterlockedCompareExchange8 _InterlockedCompareExchange8 #define InterlockedExchangeAdd8 _InterlockedExchangeAdd8 #define InterlockedOr8 _InterlockedOr8 #define InterlockedXor8 _InterlockedXor8 #define InterlockedAnd8 _InterlockedAnd8 #else #define InterlockedExchange8 ManualInterlockedExchange8 #define InterlockedCompareExchange8 ManualInterlockedCompareExchange8 #define InterlockedExchangeAdd8 ManualInterlockedExchangeAdd8 #define InterlockedOr8 ManualInterlockedOr8 #define InterlockedXor8 ManualInterlockedXor8 #define InterlockedAnd8 ManualInterlockedAnd8 static inline char ManualInterlockedExchange8(char volatile* object, char desired) { __asm__ __volatile__ ( "xchgb %0, %1" : "+q" (desired), "+m" (*object) : : "memory" ); return desired; } static inline unsigned char ManualInterlockedCompareExchange8(unsigned char volatile * dest, unsigned char exchange, unsigned char comparand) { unsigned char result; __asm__ volatile ( "lock cmpxchgb %[exchange], %[dest]" : "=a" (result), [dest] "+m" (*dest) : [exchange] "q" (exchange), "a" (comparand) : "memory" ); return result; } static inline unsigned char ManualInterlockedExchangeAdd8(unsigned char volatile * dest, unsigned char value) { unsigned char oldValue; unsigned char newValue; do { oldValue = *dest; } while (ManualInterlockedCompareExchange8(dest, oldValue + value, oldValue) != oldValue); return oldValue; } static inline unsigned char ManualInterlockedOr8(unsigned char volatile * dest, unsigned char value) { unsigned char oldValue; do { oldValue = *dest; } while (ManualInterlockedCompareExchange8(dest, oldValue | value, oldValue) != oldValue); return oldValue; } static inline unsigned char ManualInterlockedXor8(unsigned char volatile * dest, unsigned char value) { unsigned char oldValue; do { oldValue = *dest; } while (ManualInterlockedCompareExchange8(dest, oldValue ^ value, oldValue) != oldValue); return oldValue; } static inline unsigned char ManualInterlockedAnd8(unsigned char volatile * dest, unsigned char value) { unsigned char oldValue; do { oldValue = *dest; } while (ManualInterlockedCompareExchange8(dest, oldValue & value, oldValue) != oldValue); return oldValue; } #endif static inline void atomic_store_byte(unsigned char volatile * object, unsigned char desired) { do { MemoryBarrier(); *(object) = (desired); MemoryBarrier(); } while (0); } static inline unsigned char atomic_load_byte(unsigned char volatile * object) { return (MemoryBarrier(), *(object)); } #define atomic_exchange_byte(object, desired) \ InterlockedExchange8(object, desired) static inline int atomic_compare_exchange_strong_byte(unsigned char volatile * object, unsigned char volatile * expected, unsigned char desired) { unsigned char old = *expected; *expected = InterlockedCompareExchange8(object, desired, old); return *expected == old; } #define atomic_compare_exchange_weak_byte(object, expected, desired) \ atomic_compare_exchange_strong_byte(object, expected, desired) #define atomic_fetch_add_byte(object, operand) \ InterlockedExchangeAdd8(object, operand) #define atomic_fetch_sub_byte(object, operand) \ InterlockedExchangeAdd8(object, -(operand)) #define atomic_fetch_or_byte(object, operand) \ InterlockedOr8(object, operand) #define atomic_fetch_xor_byte(object, operand) \ InterlockedXor8(object, operand) #define atomic_fetch_and_byte(object, operand) \ InterlockedAnd8(object, operand) #endif /* COMPAT_ATOMICS_WIN32_STDATOMIC_H */ #endif // $if defined(_WIN32) #if 1 // inserted by module `sync.stdatomic`, file: 1.declarations.c.v:11: /* Compatibility header for stdatomic.h that works for all compilers supported by V. For TCC, we use libatomic from the OS. */ #ifndef __ATOMIC_H #define __ATOMIC_H #ifndef __cplusplus // If C just use stdatomic.h #ifndef __TINYC__ #include #endif #else // CPP wrapper for atomic operations that are compatible with C #include "atomic_cpp.h" #endif #if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) /* x86 architecture: uses PAUSE instruction for efficient spinning */ #define cpu_relax() __asm__ __volatile__ ("pause") #elif defined(__aarch64__) || defined(_M_ARM64) || defined(__arm__) || defined(_M_ARM) #if defined(__TINYC__) /* TCC compiler limitation: assembly not supported on ARM */ #define cpu_relax() #else /* ARM architecture: uses YIELD instruction for power-efficient spinning */ #define cpu_relax() __asm__ __volatile__ ("yield" ::: "memory") #endif #elif defined(__riscv) && __riscv_xlen == 64 /* RISC-V 64-bit: no dedicated pause instruction, using alternative sequence */ #define cpu_relax() __asm__ __volatile__ ( \ "fence rw, rw\n\t" /* Full memory barrier (read-write ordering) */ \ "andi a0, a0, 0\n\t" /* Dummy arithmetic instruction (always sets a0 = 0) */ \ ::: "memory", "a0") /* Clobbers memory and a0 register to prevent optimizations */ #elif defined(__powerpc64__) || defined(__ppc64__) /* PowerPC 64-bit: use OR instruction for synchronization */ #define cpu_relax() __asm__ __volatile__ ("or 1,1,1\n\t" ::: "memory") #elif defined(__mips64) /* MIPS 64-bit: use series of super-scalar NOPs */ #define cpu_relax() __asm__ __volatile__ ("ssnop\n\tssnop\n\tssnop\n\t" ::: "memory") #else /* Fallback implementation for unsupported architectures */ #define cpu_relax() __asm__ __volatile__ ( \ "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" /* Series of no-operation instructions */ \ ::: "memory") /* Memory clobber to prevent instruction reordering */ #endif #ifdef __TINYC__ typedef volatile long long atomic_llong; typedef volatile unsigned long long atomic_ullong; typedef volatile uintptr_t atomic_uintptr_t; extern void atomic_thread_fence (int memory_order); extern void __atomic_thread_fence (int memory_order); #define atomic_thread_fence(order) __atomic_thread_fence (order) // use functions for 64, 32 and 8 bit from libatomic directly // since tcc is not capible to use "generic" C functions // there is no header file for libatomic so we provide function declarations here extern unsigned long long __atomic_load_8(unsigned long long* x, int mo); extern void __atomic_store_8(unsigned long long* x, unsigned long long y, int mo); extern _Bool __atomic_compare_exchange_8(unsigned long long* x, unsigned long long* expected, unsigned long long y, int mo, int mo2); extern unsigned long long __atomic_exchange_8(unsigned long long* x, unsigned long long y, int mo); extern unsigned long long __atomic_fetch_add_8(unsigned long long* x, unsigned long long y, int mo); extern unsigned long long __atomic_fetch_sub_8(unsigned long long* x, unsigned long long y, int mo); extern unsigned long long __atomic_fetch_and_8(unsigned long long* x, unsigned long long y, int mo); extern unsigned long long __atomic_fetch_or_8(unsigned long long* x, unsigned long long y, int mo); extern unsigned long long __atomic_fetch_xor_8(unsigned long long* x, unsigned long long y, int mo); extern unsigned int __atomic_load_4(unsigned int* x, int mo); extern void __atomic_store_4(unsigned int* x, unsigned int y, int mo); extern _Bool __atomic_compare_exchange_4(unsigned int* x, unsigned int* expected, unsigned int y, int mo, int mo2); extern unsigned int __atomic_exchange_4(unsigned int* x, unsigned int y, int mo); extern unsigned int __atomic_fetch_add_4(unsigned int* x, unsigned int y, int mo); extern unsigned int __atomic_fetch_sub_4(unsigned int* x, unsigned int y, int mo); extern unsigned int __atomic_fetch_and_4(unsigned int* x, unsigned int y, int mo); extern unsigned int __atomic_fetch_or_4(unsigned int* x, unsigned int y, int mo); extern unsigned int __atomic_fetch_xor_4(unsigned int* x, unsigned int y, int mo); extern unsigned short __atomic_load_2(unsigned short* x, int mo); extern void __atomic_store_2(unsigned short* x, unsigned short y, int mo); extern _Bool __atomic_compare_exchange_2(unsigned short* x, unsigned short* expected, unsigned short y, int mo, int mo2); extern unsigned short __atomic_exchange_2(unsigned short* x, unsigned short y, int mo); extern unsigned short __atomic_fetch_add_2(unsigned short* x, unsigned short y, int mo); extern unsigned short __atomic_fetch_sub_2(unsigned short* x, unsigned short y, int mo); extern unsigned short __atomic_fetch_and_2(unsigned short* x, unsigned short y, int mo); extern unsigned short __atomic_fetch_or_2(unsigned short* x, unsigned short y, int mo); extern unsigned short __atomic_fetch_xor_2(unsigned short* x, unsigned short y, int mo); extern unsigned char __atomic_load_1(unsigned char* x, int mo); extern void __atomic_store_1(unsigned char* x, unsigned char y, int mo); extern _Bool __atomic_compare_exchange_1(unsigned char* x, unsigned char* expected, unsigned char y, int mo, int mo2); extern unsigned char __atomic_exchange_1(unsigned char* x, unsigned char y, int mo); extern unsigned char __atomic_fetch_add_1(unsigned char* x, unsigned char y, int mo); extern unsigned char __atomic_fetch_sub_1(unsigned char* x, unsigned char y, int mo); extern unsigned char __atomic_fetch_and_1(unsigned char* x, unsigned char y, int mo); extern unsigned char __atomic_fetch_or_1(unsigned char* x, unsigned char y, int mo); extern unsigned char __atomic_fetch_xor_1(unsigned char* x, unsigned char y, int mo); // The default functions should work with pointers so we have to decide based on pointer size #if UINTPTR_MAX == 0xFFFFFFFF #define atomic_load_explicit __atomic_load_4 #define atomic_store_explicit __atomic_store_4 #define atomic_compare_exchange_weak_explicit __atomic_compare_exchange_4 #define atomic_compare_exchange_strong_explicit __atomic_compare_exchange_4 #define atomic_exchange_explicit __atomic_exchange_4 #define atomic_fetch_add_explicit __atomic_fetch_add_4 #define atomic_fetch_sub_explicit __atomic_sub_fetch_4 #else #define atomic_load_explicit __atomic_load_8 #define atomic_store_explicit __atomic_store_8 #define atomic_compare_exchange_weak_explicit __atomic_compare_exchange_8 #define atomic_compare_exchange_strong_explicit __atomic_compare_exchange_8 #define atomic_exchange_explicit __atomic_exchange_8 #define atomic_fetch_add_explicit __atomic_fetch_add_8 #define atomic_fetch_sub_explicit __atomic_sub_fetch_8 #endif // memory order policies - we use "sequentially consistent" by default #define memory_order_relaxed 0 #define memory_order_consume 1 #define memory_order_acquire 2 #define memory_order_release 3 #define memory_order_acq_rel 4 #define memory_order_seq_cst 5 static inline void** atomic_load(void** x) { return (void**)atomic_load_explicit((unsigned long long*)x, memory_order_seq_cst); } static inline void atomic_store(void** x, void* y) { atomic_store_explicit((unsigned long long*)x, (uintptr_t)y, memory_order_seq_cst); } static inline int atomic_compare_exchange_weak(void** x, void** expected, intptr_t y) { return (int)atomic_compare_exchange_weak_explicit((unsigned long long*)x, (unsigned long long*)expected, (uintptr_t)y, memory_order_seq_cst, memory_order_seq_cst); } static inline int atomic_compare_exchange_strong(void** x, void** expected, intptr_t y) { return (int)atomic_compare_exchange_strong_explicit((unsigned long long*)x, (unsigned long long*)expected, (uintptr_t)y, memory_order_seq_cst, memory_order_seq_cst); } static inline uintptr_t atomic_exchange(void** x, void* y) { return atomic_exchange_explicit((unsigned long long*)x, (uintptr_t)y, memory_order_seq_cst); } static inline uintptr_t atomic_fetch_add(uintptr_t* x, uintptr_t y) { return atomic_fetch_add_explicit(x, y, memory_order_seq_cst); } static inline uintptr_t atomic_fetch_sub(uintptr_t* x, uintptr_t y) { return atomic_fetch_sub_explicit(x, y, memory_order_seq_cst); } static inline uintptr_t atomic_fetch_and(uintptr_t* x, uintptr_t y) { return atomic_fetch_and_explicit(x, y, memory_order_seq_cst); } static inline uintptr_t atomic_fetch_or(uintptr_t* x, uintptr_t y) { return atomic_fetch_or_explicit(x, y, memory_order_seq_cst); } static inline uintptr_t atomic_fetch_xor(uintptr_t* x, uintptr_t y) { return atomic_fetch_xor_explicit(x, y, memory_order_seq_cst); } #define atomic_load_ptr atomic_load #define atomic_store_ptr atomic_store #define atomic_compare_exchange_weak_ptr atomic_compare_exchange_weak #define atomic_compare_exchange_strong_ptr atomic_compare_exchange_strong #define atomic_exchange_ptr atomic_exchange #define atomic_fetch_add_ptr atomic_fetch_add #define atomic_fetch_sub_ptr atomic_fetch_sub #define atomic_fetch_and_ptr atomic_fetch_and #define atomic_fetch_or_ptr atomic_fetch_or #define atomic_fetch_xor_ptr atomic_fetch_xor // specialized versions for 64 bit static inline unsigned long long atomic_load_u64(unsigned long long* x) { return __atomic_load_8(x, memory_order_seq_cst); } static inline void atomic_store_u64(unsigned long long* x, unsigned long long y) { __atomic_store_8(x, y, memory_order_seq_cst); } static inline int atomic_compare_exchange_weak_u64(unsigned long long* x, unsigned long long* expected, unsigned long long y) { return (int)__atomic_compare_exchange_8(x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline int atomic_compare_exchange_strong_u64(unsigned long long* x, unsigned long long* expected, unsigned long long y) { return (int)__atomic_compare_exchange_8(x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline unsigned long long atomic_exchange_u64(unsigned long long* x, unsigned long long y) { return __atomic_exchange_8(x, y, memory_order_seq_cst); } static inline unsigned long long atomic_fetch_add_u64(unsigned long long* x, unsigned long long y) { return __atomic_fetch_add_8(x, y, memory_order_seq_cst); } static inline unsigned long long atomic_fetch_sub_u64(unsigned long long* x, unsigned long long y) { return __atomic_fetch_sub_8(x, y, memory_order_seq_cst); } static inline unsigned long long atomic_fetch_and_u64(unsigned long long* x, unsigned long long y) { return __atomic_fetch_and_8(x, y, memory_order_seq_cst); } static inline unsigned long long atomic_fetch_or_u64(unsigned long long* x, unsigned long long y) { return __atomic_fetch_or_8(x, y, memory_order_seq_cst); } static inline unsigned long long atomic_fetch_xor_u64(unsigned long long* x, unsigned long long y) { return __atomic_fetch_xor_8(x, y, memory_order_seq_cst); } static inline unsigned atomic_load_u32(unsigned* x) { return __atomic_load_4(x, memory_order_seq_cst); } static inline void atomic_store_u32(unsigned* x, unsigned y) { __atomic_store_4(x, y, memory_order_seq_cst); } static inline int atomic_compare_exchange_weak_u32(unsigned* x, unsigned* expected, unsigned y) { return (int)__atomic_compare_exchange_4(x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline int atomic_compare_exchange_strong_u32(unsigned* x, unsigned* expected, unsigned y) { return (int)__atomic_compare_exchange_4(x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline unsigned atomic_exchange_u32(unsigned* x, unsigned y) { return __atomic_exchange_4(x, y, memory_order_seq_cst); } static inline unsigned atomic_fetch_add_u32(unsigned* x, unsigned y) { return __atomic_fetch_add_4(x, y, memory_order_seq_cst); } static inline unsigned atomic_fetch_sub_u32(unsigned* x, unsigned y) { return __atomic_fetch_sub_4(x, y, memory_order_seq_cst); } static inline unsigned atomic_fetch_and_u32(unsigned* x, unsigned y) { return __atomic_fetch_and_4(x, y, memory_order_seq_cst); } static inline unsigned atomic_fetch_or_u32(unsigned* x, unsigned y) { return __atomic_fetch_or_4(x, y, memory_order_seq_cst); } static inline unsigned atomic_fetch_xor_u32(unsigned* x, unsigned y) { return __atomic_fetch_xor_4(x, y, memory_order_seq_cst); } static inline unsigned short atomic_load_u16(unsigned short* x) { return __atomic_load_2(x, memory_order_seq_cst); } static inline void atomic_store_u16(void* x, unsigned short y) { __atomic_store_2(x, y, memory_order_seq_cst); } static inline int atomic_compare_exchange_weak_u16(void* x, unsigned short* expected, unsigned short y) { return (int)__atomic_compare_exchange_2(x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline int atomic_compare_exchange_strong_u16(unsigned short* x, unsigned short* expected, unsigned short y) { return (int)__atomic_compare_exchange_2(x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline unsigned short atomic_exchange_u16(unsigned short* x, unsigned short y) { return __atomic_exchange_2(x, y, memory_order_seq_cst); } static inline unsigned short atomic_fetch_add_u16(unsigned short* x, unsigned short y) { return __atomic_fetch_add_2(x, y, memory_order_seq_cst); } static inline unsigned short atomic_fetch_sub_u16(unsigned short* x, unsigned short y) { return __atomic_fetch_sub_2(x, y, memory_order_seq_cst); } static inline unsigned short atomic_fetch_and_u16(unsigned short* x, unsigned short y) { return __atomic_fetch_and_2(x, y, memory_order_seq_cst); } static inline unsigned short atomic_fetch_or_u16(unsigned short* x, unsigned short y) { return __atomic_fetch_or_2(x, y, memory_order_seq_cst); } static inline unsigned short atomic_fetch_xor_u16(unsigned short* x, unsigned short y) { return __atomic_fetch_xor_2(x, y, memory_order_seq_cst); } static inline unsigned char atomic_load_byte(unsigned char* x) { return __atomic_load_1(x, memory_order_seq_cst); } static inline void atomic_store_byte(unsigned char* x, unsigned char y) { __atomic_store_1(x, y, memory_order_seq_cst); } static inline int atomic_compare_exchange_weak_byte(unsigned char* x, unsigned char* expected, unsigned char y) { return __atomic_compare_exchange_1(x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline int atomic_compare_exchange_strong_byte(unsigned char* x, unsigned char* expected, unsigned char y) { return __atomic_compare_exchange_1(x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline unsigned char atomic_exchange_byte(unsigned char* x, unsigned char y) { return __atomic_exchange_1(x, y, memory_order_seq_cst); } static inline unsigned char atomic_fetch_add_byte(unsigned char* x, unsigned char y) { return __atomic_fetch_add_1(x, y, memory_order_seq_cst); } static inline unsigned char atomic_fetch_sub_byte(unsigned char* x, unsigned char y) { return __atomic_fetch_sub_1(x, y, memory_order_seq_cst); } static inline unsigned char atomic_fetch_and_byte(unsigned char* x, unsigned char y) { return __atomic_fetch_and_1(x, y, memory_order_seq_cst); } static inline unsigned char atomic_fetch_or_byte(unsigned char* x, unsigned char y) { return __atomic_fetch_or_1(x, y, memory_order_seq_cst); } static inline unsigned char atomic_fetch_xor_byte(unsigned char* x, unsigned char y) { return __atomic_fetch_xor_1(x, y, memory_order_seq_cst); } #ifdef __aarch64__ // must has an `extern` to link with libatomic.a // acq_rel version extern inline _Bool __aarch64_cas1_acq_rel(unsigned char*ptr, unsigned char*expected, unsigned char desired) { return __atomic_compare_exchange_1( ptr, expected, desired, memory_order_acq_rel, memory_order_acquire ); } extern inline _Bool __aarch64_cas2_acq_rel(unsigned short*ptr, unsigned short*expected, unsigned short desired) { return __atomic_compare_exchange_2( ptr, expected, desired, memory_order_acq_rel, memory_order_acquire ); } extern inline _Bool __aarch64_cas4_acq_rel(unsigned int*ptr, unsigned int*expected, unsigned int desired) { return __atomic_compare_exchange_4( ptr, expected, desired, memory_order_acq_rel, memory_order_acquire ); } extern inline _Bool __aarch64_cas8_acq_rel(unsigned long long*ptr, unsigned long long*expected, unsigned long long desired) { return __atomic_compare_exchange_8( ptr, expected, desired, memory_order_acq_rel, memory_order_acquire ); } extern inline char __aarch64_ldadd1_acq_rel(char*ptr, char value) { return __atomic_fetch_add_1( (unsigned char*)ptr, (unsigned char)value, memory_order_acq_rel ); } extern inline short __aarch64_ldadd2_acq_rel(short*ptr, short value) { return __atomic_fetch_add_2( (unsigned short*)ptr, (unsigned short)value, memory_order_acq_rel ); } extern inline int __aarch64_ldadd4_acq_rel(int*ptr, int value) { return __atomic_fetch_add_4( (unsigned int*)ptr, (unsigned int)value, memory_order_acq_rel ); } extern inline long long __aarch64_ldadd8_acq_rel(long long*ptr, long long value) { return __atomic_fetch_add_8( (unsigned long long*)ptr, (unsigned long long)value, memory_order_acq_rel ); } extern inline unsigned char __aarch64_swp1_acq_rel(unsigned char*ptr, unsigned char newval) { return __atomic_exchange_1( ptr, newval, memory_order_acq_rel ); } extern inline unsigned short __aarch64_swp2_acq_rel(unsigned short*ptr, unsigned short newval) { return __atomic_exchange_2( ptr, newval, memory_order_acq_rel ); } extern inline unsigned int __aarch64_swp4_acq_rel(unsigned int*ptr, unsigned int newval) { return __atomic_exchange_4( ptr, newval, memory_order_acq_rel ); } extern inline unsigned long long __aarch64_swp8_acq_rel(unsigned long long*ptr, unsigned long long newval) { return __atomic_exchange_8( ptr, newval, memory_order_acq_rel ); } extern inline unsigned char __aarch64_ldclr1_acq_rel(unsigned char*ptr, unsigned char mask) { return __atomic_fetch_and_1( ptr, ~mask, memory_order_acq_rel ); } extern inline unsigned short __aarch64_ldclr2_acq_rel(unsigned short*ptr, unsigned short mask) { return __atomic_fetch_and_2( ptr, ~mask, memory_order_acq_rel ); } extern inline unsigned int __aarch64_ldclr4_acq_rel(unsigned int*ptr, unsigned int mask) { return __atomic_fetch_and_4( ptr, ~mask, memory_order_acq_rel ); } extern inline unsigned long long __aarch64_ldclr8_acq_rel(unsigned long long*ptr, unsigned long long mask) { return __atomic_fetch_and_8( ptr, ~mask, memory_order_acq_rel ); } extern inline unsigned char __aarch64_ldset1_acq_rel(unsigned char*ptr, unsigned char mask) { return __atomic_fetch_or_1( ptr, mask, memory_order_acq_rel ); } extern inline unsigned short __aarch64_ldset2_acq_rel(unsigned short*ptr, unsigned short mask) { return __atomic_fetch_or_2( ptr, mask, memory_order_acq_rel ); } extern inline unsigned int __aarch64_ldset4_acq_rel(unsigned int*ptr, unsigned int mask) { return __atomic_fetch_or_4( ptr, mask, memory_order_acq_rel ); } extern inline unsigned long long __aarch64_ldset8_acq_rel(unsigned long long*ptr, unsigned long long mask) { return __atomic_fetch_or_8( ptr, mask, memory_order_acq_rel ); } extern inline unsigned char __aarch64_ldeor1_acq_rel(unsigned char*ptr, unsigned char mask) { return __atomic_fetch_xor_1( ptr, mask, memory_order_acq_rel ); } extern inline unsigned short __aarch64_ldeor2_acq_rel(unsigned short*ptr, unsigned short mask) { return __atomic_fetch_xor_2( ptr, mask, memory_order_acq_rel ); } extern inline unsigned int __aarch64_ldeor4_acq_rel(unsigned int*ptr, unsigned int mask) { return __atomic_fetch_xor_4( ptr, mask, memory_order_acq_rel ); } extern inline unsigned long long __aarch64_ldeor8_acq_rel(unsigned long long*ptr, unsigned long long mask) { return __atomic_fetch_xor_8( ptr, mask, memory_order_acq_rel ); } #define aarch64_cas_acq_rel(ptr, expected, desired) \ _Generic((ptr), \ char*: __aarch64_cas1_acq_rel, \ short*: __aarch64_cas2_acq_rel, \ int*: __aarch64_cas4_acq_rel, \ long long*: __aarch64_cas8_acq_rel \ )(ptr, expected, desired) // relax version extern inline _Bool __aarch64_cas1_relax(unsigned char*ptr, unsigned char*expected, unsigned char desired) { return __atomic_compare_exchange_1( ptr, expected, desired, memory_order_relaxed, memory_order_relaxed ); } extern inline _Bool __aarch64_cas2_relax(unsigned short*ptr, unsigned short*expected, unsigned short desired) { return __atomic_compare_exchange_2( ptr, expected, desired, memory_order_relaxed, memory_order_relaxed ); } extern inline _Bool __aarch64_cas4_relax(unsigned int*ptr, unsigned int*expected, unsigned int desired) { return __atomic_compare_exchange_4( ptr, expected, desired, memory_order_relaxed, memory_order_relaxed ); } extern inline _Bool __aarch64_cas8_relax(unsigned long long*ptr, unsigned long long*expected, unsigned long long desired) { return __atomic_compare_exchange_8( ptr, expected, desired, memory_order_relaxed, memory_order_relaxed ); } extern inline char __aarch64_ldadd1_relax(char*ptr, char value) { return __atomic_fetch_add_1( (unsigned char*)ptr, (unsigned char)value, memory_order_relaxed ); } extern inline short __aarch64_ldadd2_relax(short*ptr, short value) { return __atomic_fetch_add_2( (unsigned short*)ptr, (unsigned short)value, memory_order_relaxed ); } extern inline int __aarch64_ldadd4_relax(int*ptr, int value) { return __atomic_fetch_add_4( (unsigned int*)ptr, (unsigned int)value, memory_order_relaxed ); } extern inline long long __aarch64_ldadd8_relax(long long*ptr, long long value) { return __atomic_fetch_add_8( (unsigned long long*)ptr, (unsigned long long)value, memory_order_relaxed ); } extern inline unsigned char __aarch64_swp1_relax(unsigned char*ptr, unsigned char newval) { return __atomic_exchange_1( ptr, newval, memory_order_relaxed ); } extern inline unsigned short __aarch64_swp2_relax(unsigned short*ptr, unsigned short newval) { return __atomic_exchange_2( ptr, newval, memory_order_relaxed ); } extern inline unsigned int __aarch64_swp4_relax(unsigned int*ptr, unsigned int newval) { return __atomic_exchange_4( ptr, newval, memory_order_relaxed ); } extern inline unsigned long long __aarch64_swp8_relax(unsigned long long*ptr, unsigned long long newval) { return __atomic_exchange_8( ptr, newval, memory_order_relaxed ); } extern inline unsigned char __aarch64_ldclr1_relax(unsigned char*ptr, unsigned char mask) { return __atomic_fetch_and_1( ptr, ~mask, memory_order_relaxed ); } extern inline unsigned short __aarch64_ldclr2_relax(unsigned short*ptr, unsigned short mask) { return __atomic_fetch_and_2( ptr, ~mask, memory_order_relaxed ); } extern inline unsigned int __aarch64_ldclr4_relax(unsigned int*ptr, unsigned int mask) { return __atomic_fetch_and_4( ptr, ~mask, memory_order_relaxed ); } extern inline unsigned long long __aarch64_ldclr8_relax(unsigned long long*ptr, unsigned long long mask) { return __atomic_fetch_and_8( ptr, ~mask, memory_order_relaxed ); } extern inline unsigned char __aarch64_ldset1_relax(unsigned char*ptr, unsigned char mask) { return __atomic_fetch_or_1( ptr, mask, memory_order_relaxed ); } extern inline unsigned short __aarch64_ldset2_relax(unsigned short*ptr, unsigned short mask) { return __atomic_fetch_or_2( ptr, mask, memory_order_relaxed ); } extern inline unsigned int __aarch64_ldset4_relax(unsigned int*ptr, unsigned int mask) { return __atomic_fetch_or_4( ptr, mask, memory_order_relaxed ); } extern inline unsigned long long __aarch64_ldset8_relax(unsigned long long*ptr, unsigned long long mask) { return __atomic_fetch_or_8( ptr, mask, memory_order_relaxed ); } extern inline unsigned char __aarch64_ldeor1_relax(unsigned char*ptr, unsigned char mask) { return __atomic_fetch_xor_1( ptr, mask, memory_order_relaxed ); } extern inline unsigned short __aarch64_ldeor2_relax(unsigned short*ptr, unsigned short mask) { return __atomic_fetch_xor_2( ptr, mask, memory_order_relaxed ); } extern inline unsigned int __aarch64_ldeor4_relax(unsigned int*ptr, unsigned int mask) { return __atomic_fetch_xor_4( ptr, mask, memory_order_relaxed ); } extern inline unsigned long long __aarch64_ldeor8_relax(unsigned long long*ptr, unsigned long long mask) { return __atomic_fetch_xor_8( ptr, mask, memory_order_relaxed ); } #define aarch64_cas_relax(ptr, expected, desired) \ _Generic((ptr), \ char*: __aarch64_cas1_relax, \ short*: __aarch64_cas2_relax, \ int*: __aarch64_cas4_relax, \ long long*: __aarch64_cas8_relax \ )(ptr, expected, desired) #endif // __aarch64__ #else // Since V might be confused with "generic" C functions either we provide special versions // for gcc/clang, too static inline unsigned long long atomic_load_u64(uint64_t* x) { return atomic_load_explicit((_Atomic (uint64_t)*)x, memory_order_seq_cst); } static inline void atomic_store_u64(uint64_t* x, uint64_t y) { atomic_store_explicit((_Atomic(uint64_t)*)x, y, memory_order_seq_cst); } static inline int atomic_compare_exchange_weak_u64(uint64_t* x, uint64_t* expected, uint64_t y) { return (int)atomic_compare_exchange_weak_explicit((_Atomic(uint64_t)*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline int atomic_compare_exchange_strong_u64(uint64_t* x, uint64_t* expected, uint64_t y) { return (int)atomic_compare_exchange_strong_explicit((_Atomic(uint64_t)*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline unsigned long long atomic_exchange_u64(uint64_t* x, uint64_t y) { return atomic_exchange_explicit((_Atomic(uint64_t)*)x, y, memory_order_seq_cst); } static inline unsigned long long atomic_fetch_add_u64(uint64_t* x, uint64_t y) { return atomic_fetch_add_explicit((_Atomic(uint64_t)*)x, y, memory_order_seq_cst); } static inline unsigned long long atomic_fetch_sub_u64(uint64_t* x, uint64_t y) { return atomic_fetch_sub_explicit((_Atomic(uint64_t)*)x, y, memory_order_seq_cst); } static inline unsigned long long atomic_fetch_and_u64(uint64_t* x, uint64_t y) { return atomic_fetch_and_explicit((_Atomic(uint64_t)*)x, y, memory_order_seq_cst); } static inline unsigned long long atomic_fetch_or_u64(uint64_t* x, uint64_t y) { return atomic_fetch_or_explicit((_Atomic(uint64_t)*)x, y, memory_order_seq_cst); } static inline unsigned long long atomic_fetch_xor_u64(uint64_t* x, uint64_t y) { return atomic_fetch_xor_explicit((_Atomic(uint64_t)*)x, y, memory_order_seq_cst); } static inline void* atomic_load_ptr(void** x) { return (void*)atomic_load_explicit((_Atomic(uintptr_t)*)x, memory_order_seq_cst); } static inline void atomic_store_ptr(void** x, void* y) { atomic_store_explicit((_Atomic(uintptr_t)*)x, (uintptr_t)y, memory_order_seq_cst); } static inline int atomic_compare_exchange_weak_ptr(void** x, void** expected, intptr_t y) { return (int)atomic_compare_exchange_weak_explicit((_Atomic(uintptr_t)*)x, (unsigned long *)expected, (uintptr_t)y, memory_order_seq_cst, memory_order_seq_cst); } static inline int atomic_compare_exchange_strong_ptr(void** x, void** expected, intptr_t y) { return (int)atomic_compare_exchange_strong_explicit((_Atomic(uintptr_t)*)x, (unsigned long *)expected, (uintptr_t)y, memory_order_seq_cst, memory_order_seq_cst); } static inline void* atomic_exchange_ptr(void** x, void* y) { return (void*)atomic_exchange_explicit((_Atomic(uintptr_t)*)x, (uintptr_t)y, memory_order_seq_cst); } static inline void* atomic_fetch_add_ptr(void** x, void* y) { return (void*)atomic_fetch_add_explicit((_Atomic(uintptr_t)*)x, (uintptr_t)y, memory_order_seq_cst); } static inline void* atomic_fetch_sub_ptr(void** x, void* y) { return (void*)atomic_fetch_sub_explicit((_Atomic(uintptr_t)*)x, (uintptr_t)y, memory_order_seq_cst); } static inline void* atomic_fetch_and_ptr(void** x, void* y) { return (void*)atomic_fetch_and_explicit((_Atomic(uintptr_t)*)x, (uintptr_t)y, memory_order_seq_cst); } static inline void* atomic_fetch_or_ptr(void** x, void* y) { return (void*)atomic_fetch_or_explicit((_Atomic(uintptr_t)*)x, (uintptr_t)y, memory_order_seq_cst); } static inline void* atomic_fetch_xor_ptr(void** x, void* y) { return (void*)atomic_fetch_xor_explicit((_Atomic(uintptr_t)*)x, (uintptr_t)y, memory_order_seq_cst); } static inline unsigned atomic_load_u32(unsigned* x) { return atomic_load_explicit((_Atomic(unsigned)*)x, memory_order_seq_cst); } static inline void atomic_store_u32(unsigned* x, unsigned y) { atomic_store_explicit((_Atomic(unsigned)*)x, y, memory_order_seq_cst); } static inline int atomic_compare_exchange_weak_u32(unsigned* x, unsigned* expected, unsigned y) { return (int)atomic_compare_exchange_weak_explicit((_Atomic(unsigned)*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline int atomic_compare_exchange_strong_u32(unsigned* x, unsigned* expected, unsigned y) { return (int)atomic_compare_exchange_strong_explicit((_Atomic(unsigned)*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline unsigned atomic_exchange_u32(unsigned* x, unsigned y) { return atomic_exchange_explicit((_Atomic(unsigned)*)x, y, memory_order_seq_cst); } static inline unsigned atomic_fetch_add_u32(unsigned* x, unsigned y) { return atomic_fetch_add_explicit((_Atomic(unsigned)*)x, y, memory_order_seq_cst); } static inline unsigned atomic_fetch_sub_u32(unsigned* x, unsigned y) { return atomic_fetch_sub_explicit((_Atomic(unsigned)*)x, y, memory_order_seq_cst); } static inline unsigned atomic_fetch_and_u32(unsigned* x, unsigned y) { return atomic_fetch_and_explicit((_Atomic(unsigned)*)x, y, memory_order_seq_cst); } static inline unsigned atomic_fetch_or_u32(unsigned* x, unsigned y) { return atomic_fetch_or_explicit((_Atomic(unsigned)*)x, y, memory_order_seq_cst); } static inline unsigned atomic_fetch_xor_u32(unsigned* x, unsigned y) { return atomic_fetch_xor_explicit((_Atomic(unsigned)*)x, y, memory_order_seq_cst); } static inline unsigned short atomic_load_u16(unsigned short* x) { return atomic_load_explicit((_Atomic(unsigned short)*)x, memory_order_seq_cst); } static inline void atomic_store_u16(void* x, unsigned short y) { atomic_store_explicit((_Atomic(unsigned short)*)x, y, memory_order_seq_cst); } static inline int atomic_compare_exchange_weak_u16(void* x, unsigned short* expected, unsigned short y) { return (int)atomic_compare_exchange_weak_explicit((_Atomic(unsigned short)*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline int atomic_compare_exchange_strong_u16(unsigned short* x, unsigned short* expected, unsigned short y) { return (int)atomic_compare_exchange_strong_explicit((_Atomic(unsigned short)*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline unsigned short atomic_exchange_u16(unsigned short* x, unsigned short y) { return atomic_exchange_explicit((_Atomic(unsigned short)*)x, y, memory_order_seq_cst); } static inline unsigned short atomic_fetch_add_u16(unsigned short* x, unsigned short y) { return atomic_fetch_add_explicit((_Atomic(unsigned short)*)x, y, memory_order_seq_cst); } static inline unsigned short atomic_fetch_sub_u16(unsigned short* x, unsigned short y) { return atomic_fetch_sub_explicit((_Atomic(unsigned short)*)x, y, memory_order_seq_cst); } static inline unsigned short atomic_fetch_and_u16(unsigned short* x, unsigned short y) { return atomic_fetch_and_explicit((_Atomic(unsigned short)*)x, y, memory_order_seq_cst); } static inline unsigned short atomic_fetch_or_u16(unsigned short* x, unsigned short y) { return atomic_fetch_or_explicit((_Atomic(unsigned short)*)x, y, memory_order_seq_cst); } static inline unsigned short atomic_fetch_xor_u16(unsigned short* x, unsigned short y) { return atomic_fetch_xor_explicit((_Atomic(unsigned short)*)x, y, memory_order_seq_cst); } static inline unsigned char atomic_load_byte(unsigned char* x) { return atomic_load_explicit((_Atomic(unsigned char)*)x, memory_order_seq_cst); } static inline void atomic_store_byte(unsigned char* x, unsigned char y) { atomic_store_explicit((_Atomic(unsigned char)*)x, y, memory_order_seq_cst); } static inline int atomic_compare_exchange_weak_byte(unsigned char* x, unsigned char* expected, unsigned char y) { return (int)atomic_compare_exchange_weak_explicit((_Atomic(unsigned char)*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline int atomic_compare_exchange_strong_byte(unsigned char* x, unsigned char* expected, unsigned char y) { return (int)atomic_compare_exchange_strong_explicit((_Atomic(unsigned char)*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst); } static inline unsigned char atomic_exchange_byte(unsigned char* x, unsigned char y) { return atomic_exchange_explicit((_Atomic(unsigned char)*)x, y, memory_order_seq_cst); } static inline unsigned char atomic_fetch_add_byte(unsigned char* x, unsigned char y) { return atomic_fetch_add_explicit((_Atomic(unsigned char)*)x, y, memory_order_seq_cst); } static inline unsigned char atomic_fetch_sub_byte(unsigned char* x, unsigned char y) { return atomic_fetch_sub_explicit((_Atomic(unsigned char)*)x, y, memory_order_seq_cst); } static inline unsigned char atomic_fetch_and_byte(unsigned char* x, unsigned char y) { return atomic_fetch_and_explicit((_Atomic(unsigned char)*)x, y, memory_order_seq_cst); } static inline unsigned char atomic_fetch_or_byte(unsigned char* x, unsigned char y) { return atomic_fetch_or_explicit((_Atomic(unsigned char)*)x, y, memory_order_seq_cst); } static inline unsigned char atomic_fetch_xor_byte(unsigned char* x, unsigned char y) { return atomic_fetch_xor_explicit((_Atomic(unsigned char)*)x, y, memory_order_seq_cst); } #endif #endif #endif // $if 1 #if defined(CUSTOM_DEFINE_valgrind) // added by module `sync.stdatomic`, file: 1.declarations.c.v:120: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `sync.stdatomic` was not found. Please install the corresponding development headers. #endif #else #include #endif #endif // $if defined(CUSTOM_DEFINE_valgrind) // added by module `os`, file: debugger_linux.c.v:3: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif #if !defined(_WIN32) // added by module `os`, file: fd.c.v:6: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif #endif // $if !defined(_WIN32) #if defined(_WIN32) // added by module `os`, file: fd.c.v:10: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif #endif // $if defined(_WIN32) // added by module `os`, file: os.c.v:5: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `os`, file: os.c.v:6: #include #if defined(__FreeBSD__) || defined(__OpenBSD__) // added by module `os`, file: os.c.v:9: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif #endif // $if defined(__FreeBSD__) || defined(__OpenBSD__) // added by module `os`, file: os_nix.c.v:5: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `os`, file: os_nix.c.v:6: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `os`, file: os_nix.c.v:7: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `os`, file: os_nix.c.v:8: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `os`, file: os_nix.c.v:9: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `os`, file: os_nix.c.v:10: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `os`, file: os_nix.c.v:11: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `os`, file: signal.c.v:3: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `os`, file: signal_linux.c.v:5: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `os.filelock`, file: lib_nix.c.v:3: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `os.filelock` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `term`, file: term_nix.c.v:7: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `term` was not found. Please install the corresponding development headers. #endif #else #include #endif // added by module `sync`, file: sync_default.c.v:14: #if defined(__has_include) #if __has_include() #include #else #error VERROR_MESSAGE Header file , needed for module `sync` was not found. Please install the corresponding development headers. #endif #else #include #endif // V global/const #define ... : #define _const_builtin__closure__assumed_page_size 16384 #define _const_strconv__c_plus '+' #define _const_strconv__c_minus '-' #define _const_strconv__c_zero '0' #define _const_strconv__int_size 32 #define _const_strconv__max_size_f64_char 512 #define _const_max_int 2147483647 #define _const_hashbits 24 #define _const_max_cached_hashbits 16 #define _const_init_log_capicity 5 #define _const_init_capicity 32 #define _const_init_even_index 30 #define _const_extra_metas_inc 4 #define _const_prealloc_block_size 16777216 #define _const_rune_maps_columns_in_row 4 #define _const_rune_maps_ul -3 #define _const_rune_maps_utl -2 #define _const_degree 6 #define _const_max_len 11 #define _const_replace_stack_buffer_size 10 #define _const_kmp_stack_buffer_size 20 #define _const_cp_acp 0 #define _const_cp_utf8 65001 #define _const_time__seconds_per_minute 60 #define _const_time__seconds_per_hour 3600 #define _const_time__seconds_per_day 86400 #define _const_flag__max_args_number 4048 #define _const_semver__ver_major 0 #define _const_semver__ver_minor 1 #define _const_semver__ver_patch 2 #define _const_os__max_path_buffer_size 4096 #define _const_os__fslash '/' #define _const_os__bslash '\\' #define _const_os__dot '.' #define _const_os__buf_size 4096 #define _const_os__error_code_not_set -1 #define _const_os__max_path_len 4096 #define _const_os__f_ok 0 #define _const_os__x_ok 1 #define _const_os__r_ok 4 #define _const_os__s_ixusr 64 #define _const_os__s_ixgrp 8 #define _const_os__s_ixoth 1 #define _const_sync__spinloops 750 #define _const_sync__spinloops_sem 4000 #define _const_v__util__backslash 92 #define _const_v__util__double_quote 34 #define _const_v__ast__invalid_type_idx -1 #define _const_v__ast__no_type_idx 0 #define _const_v__ast__void_type_idx 1 #define _const_v__ast__voidptr_type_idx 2 #define _const_v__ast__byteptr_type_idx 3 #define _const_v__ast__charptr_type_idx 4 #define _const_v__ast__i8_type_idx 5 #define _const_v__ast__i16_type_idx 6 #define _const_v__ast__i32_type_idx 7 #define _const_v__ast__int_type_idx 8 #define _const_v__ast__i64_type_idx 9 #define _const_v__ast__isize_type_idx 10 #define _const_v__ast__u8_type_idx 11 #define _const_v__ast__u16_type_idx 12 #define _const_v__ast__u32_type_idx 13 #define _const_v__ast__u64_type_idx 14 #define _const_v__ast__usize_type_idx 15 #define _const_v__ast__f32_type_idx 16 #define _const_v__ast__f64_type_idx 17 #define _const_v__ast__char_type_idx 18 #define _const_v__ast__bool_type_idx 19 #define _const_v__ast__none_type_idx 20 #define _const_v__ast__string_type_idx 21 #define _const_v__ast__rune_type_idx 22 #define _const_v__ast__array_type_idx 23 #define _const_v__ast__map_type_idx 24 #define _const_v__ast__chan_type_idx 25 #define _const_v__ast__any_type_idx 26 #define _const_v__ast__float_literal_type_idx 27 #define _const_v__ast__int_literal_type_idx 28 #define _const_v__ast__thread_type_idx 29 #define _const_v__ast__error_type_idx 30 #define _const_v__ast__nil_type_idx 31 #define _const_v__scanner__single_quote '\'' #define _const_v__scanner__double_quote '"' #define _const_v__scanner__num_sep '_' #define _const_v__scanner__backslash '\\' #define _const_v__checker__generic_fn_cutoff_limit_per_fn 10000 #define _const_v__parser__max_expr_level 100 #define _const_v__builder__key_query_value 1 #define _const_v__builder__key_wow64_32key 512 #define _const_v__builder__key_enumerate_sub_keys 8 #define _const_v__builder__thirdparty_obj_build_max_retries 5 // Enum definitions: typedef enum { builtin__closure__MemoryProtectAtrr__read_exec, // builtin__closure__MemoryProtectAtrr__read_write, // +1 } builtin__closure__MemoryProtectAtrr; typedef enum { strconv__ParserState__ok, // strconv__ParserState__pzero, // +1 strconv__ParserState__mzero, // +2 strconv__ParserState__pinf, // +3 strconv__ParserState__minf, // +4 strconv__ParserState__invalid_number, // +5 strconv__ParserState__extra_char, // +6 } strconv__ParserState; typedef enum { strconv__Align_text__right = 0, // 0 strconv__Align_text__left, // 0+1 strconv__Align_text__center, // 0+2 } strconv__Align_text; typedef enum { strconv__Char_parse_state__start, // strconv__Char_parse_state__norm_char, // +1 strconv__Char_parse_state__field_char, // +2 strconv__Char_parse_state__pad_ch, // +3 strconv__Char_parse_state__len_set_start, // +4 strconv__Char_parse_state__len_set_in, // +5 strconv__Char_parse_state__check_type, // +6 strconv__Char_parse_state__check_float, // +7 strconv__Char_parse_state__check_float_in, // +8 strconv__Char_parse_state__reset_params, // +9 } strconv__Char_parse_state; typedef enum { ArrayFlags__noslices = 1U, // u64(1) << 0 ArrayFlags__noshrink = 2U, // u64(1) << 1 ArrayFlags__nogrow = 4U, // u64(1) << 2 ArrayFlags__nofree = 8U, // u64(1) << 3 } ArrayFlags; typedef enum { AttributeKind__plain, // AttributeKind__string, // +1 AttributeKind__number, // +2 AttributeKind__bool, // +3 AttributeKind__comptime_define, // +4 } AttributeKind; typedef enum { ChanState__success, // ChanState__not_ready, // +1 ChanState__closed, // +2 } ChanState; typedef enum { MapMode__to_upper, // MapMode__to_lower, // +1 MapMode__to_title, // +2 } MapMode; typedef enum { TrimMode__trim_left, // TrimMode__trim_right, // +1 TrimMode__trim_both, // +2 } TrimMode; typedef enum { StrIntpType__si_no_str = 0, // 0 StrIntpType__si_c, // 0+1 StrIntpType__si_u8, // 0+2 StrIntpType__si_i8, // 0+3 StrIntpType__si_u16, // 0+4 StrIntpType__si_i16, // 0+5 StrIntpType__si_u32, // 0+6 StrIntpType__si_i32, // 0+7 StrIntpType__si_u64, // 0+8 StrIntpType__si_i64, // 0+9 StrIntpType__si_e32, // 0+10 StrIntpType__si_e64, // 0+11 StrIntpType__si_f32, // 0+12 StrIntpType__si_f64, // 0+13 StrIntpType__si_g32, // 0+14 StrIntpType__si_g64, // 0+15 StrIntpType__si_s, // 0+16 StrIntpType__si_p, // 0+17 StrIntpType__si_r, // 0+18 StrIntpType__si_vp, // 0+19 } StrIntpType; typedef enum { time__FormatTime__hhmm12, // time__FormatTime__hhmm24, // +1 time__FormatTime__hhmmss12, // +2 time__FormatTime__hhmmss24, // +3 time__FormatTime__hhmmss24_milli, // +4 time__FormatTime__hhmmss24_micro, // +5 time__FormatTime__hhmmss24_nano, // +6 time__FormatTime__no_time, // +7 } time__FormatTime; typedef enum { time__FormatDate__ddmmyy, // time__FormatDate__ddmmyyyy, // +1 time__FormatDate__mmddyy, // +2 time__FormatDate__mmddyyyy, // +3 time__FormatDate__mmmd, // +4 time__FormatDate__mmmdd, // +5 time__FormatDate__mmmddyy, // +6 time__FormatDate__mmmddyyyy, // +7 time__FormatDate__no_date, // +8 time__FormatDate__yyyymmdd, // +9 time__FormatDate__yymmdd, // +10 } time__FormatDate; typedef enum { time__FormatDelimiter__dot, // time__FormatDelimiter__hyphen, // +1 time__FormatDelimiter__slash, // +2 time__FormatDelimiter__space, // +3 time__FormatDelimiter__no_delimiter, // +4 } time__FormatDelimiter; typedef enum { v__token__Kind__unknown, // v__token__Kind__eof, // +1 v__token__Kind__name, // +2 v__token__Kind__number, // +3 v__token__Kind__string, // +4 v__token__Kind__str_inter, // +5 v__token__Kind__chartoken, // +6 v__token__Kind__plus, // +7 v__token__Kind__minus, // +8 v__token__Kind__mul, // +9 v__token__Kind__div, // +10 v__token__Kind__mod, // +11 v__token__Kind__xor, // +12 v__token__Kind__pipe, // +13 v__token__Kind__inc, // +14 v__token__Kind__dec, // +15 v__token__Kind__and, // +16 v__token__Kind__logical_or, // +17 v__token__Kind__not, // +18 v__token__Kind__bit_not, // +19 v__token__Kind__question, // +20 v__token__Kind__comma, // +21 v__token__Kind__semicolon, // +22 v__token__Kind__colon, // +23 v__token__Kind__arrow, // +24 v__token__Kind__amp, // +25 v__token__Kind__hash, // +26 v__token__Kind__dollar, // +27 v__token__Kind__at, // +28 v__token__Kind__str_dollar, // +29 v__token__Kind__left_shift, // +30 v__token__Kind__right_shift, // +31 v__token__Kind__unsigned_right_shift, // +32 v__token__Kind__not_in, // +33 v__token__Kind__not_is, // +34 v__token__Kind__assign, // +35 v__token__Kind__decl_assign, // +36 v__token__Kind__plus_assign, // +37 v__token__Kind__minus_assign, // +38 v__token__Kind__div_assign, // +39 v__token__Kind__mult_assign, // +40 v__token__Kind__xor_assign, // +41 v__token__Kind__mod_assign, // +42 v__token__Kind__or_assign, // +43 v__token__Kind__and_assign, // +44 v__token__Kind__right_shift_assign, // +45 v__token__Kind__left_shift_assign, // +46 v__token__Kind__unsigned_right_shift_assign, // +47 v__token__Kind__boolean_and_assign, // +48 v__token__Kind__boolean_or_assign, // +49 v__token__Kind__lcbr, // +50 v__token__Kind__rcbr, // +51 v__token__Kind__lpar, // +52 v__token__Kind__rpar, // +53 v__token__Kind__lsbr, // +54 v__token__Kind__nilsbr, // +55 v__token__Kind__rsbr, // +56 v__token__Kind__eq, // +57 v__token__Kind__ne, // +58 v__token__Kind__gt, // +59 v__token__Kind__lt, // +60 v__token__Kind__ge, // +61 v__token__Kind__le, // +62 v__token__Kind__comment, // +63 v__token__Kind__nl, // +64 v__token__Kind__dot, // +65 v__token__Kind__dotdot, // +66 v__token__Kind__ellipsis, // +67 v__token__Kind__keyword_beg, // +68 v__token__Kind__key_as, // +69 v__token__Kind__key_asm, // +70 v__token__Kind__key_assert, // +71 v__token__Kind__key_atomic, // +72 v__token__Kind__key_break, // +73 v__token__Kind__key_const, // +74 v__token__Kind__key_continue, // +75 v__token__Kind__key_defer, // +76 v__token__Kind__key_else, // +77 v__token__Kind__key_enum, // +78 v__token__Kind__key_false, // +79 v__token__Kind__key_for, // +80 v__token__Kind__key_fn, // +81 v__token__Kind__key_global, // +82 v__token__Kind__key_go, // +83 v__token__Kind__key_goto, // +84 v__token__Kind__key_if, // +85 v__token__Kind__key_import, // +86 v__token__Kind__key_in, // +87 v__token__Kind__key_interface, // +88 v__token__Kind__key_is, // +89 v__token__Kind__key_match, // +90 v__token__Kind__key_module, // +91 v__token__Kind__key_mut, // +92 v__token__Kind__key_nil, // +93 v__token__Kind__key_shared, // +94 v__token__Kind__key_lock, // +95 v__token__Kind__key_rlock, // +96 v__token__Kind__key_none, // +97 v__token__Kind__key_return, // +98 v__token__Kind__key_select, // +99 v__token__Kind__key_like, // +100 v__token__Kind__key_ilike, // +101 v__token__Kind__key_sizeof, // +102 v__token__Kind__key_isreftype, // +103 v__token__Kind__key_likely, // +104 v__token__Kind__key_unlikely, // +105 v__token__Kind__key_offsetof, // +106 v__token__Kind__key_struct, // +107 v__token__Kind__key_true, // +108 v__token__Kind__key_type, // +109 v__token__Kind__key_typeof, // +110 v__token__Kind__key_dump, // +111 v__token__Kind__key_orelse, // +112 v__token__Kind__key_union, // +113 v__token__Kind__key_pub, // +114 v__token__Kind__key_static, // +115 v__token__Kind__key_volatile, // +116 v__token__Kind__key_unsafe, // +117 v__token__Kind__key_spawn, // +118 v__token__Kind__key_implements, // +119 v__token__Kind__keyword_end, // +120 v__token__Kind___end_, // +121 } v__token__Kind; typedef enum { v__token__AtKind__unknown, // v__token__AtKind__fn_name, // +1 v__token__AtKind__method_name, // +2 v__token__AtKind__mod_name, // +3 v__token__AtKind__struct_name, // +4 v__token__AtKind__vexe_path, // +5 v__token__AtKind__file_path, // +6 v__token__AtKind__file_dir, // +7 v__token__AtKind__line_nr, // +8 v__token__AtKind__column_nr, // +9 v__token__AtKind__vhash, // +10 v__token__AtKind__v_current_hash, // +11 v__token__AtKind__vmod_file, // +12 v__token__AtKind__vmodroot_path, // +13 v__token__AtKind__vmod_hash, // +14 v__token__AtKind__vroot_path, // +15 v__token__AtKind__vexeroot_path, // +16 v__token__AtKind__file_path_line_nr, // +17 v__token__AtKind__location, // +18 v__token__AtKind__build_date, // +19 v__token__AtKind__build_time, // +20 v__token__AtKind__build_timestamp, // +21 } v__token__AtKind; typedef enum { v__token__Precedence__lowest, // v__token__Precedence__cond, // +1 v__token__Precedence__in_as, // +2 v__token__Precedence__assign, // +3 v__token__Precedence__eq, // +4 v__token__Precedence__sum, // +5 v__token__Precedence__product, // +6 v__token__Precedence__prefix, // +7 v__token__Precedence__postfix, // +8 v__token__Precedence__call, // +9 v__token__Precedence__index, // +10 v__token__Precedence__highest, // +11 } v__token__Precedence; typedef enum { flag__ParseMode__strict, // flag__ParseMode__relaxed, // +1 } flag__ParseMode; typedef enum { flag__Style__short, // flag__Style__long, // +1 flag__Style__short_long, // +2 flag__Style__v, // +3 flag__Style__v_flag_parser, // +4 flag__Style__go_flag, // +5 flag__Style__cmd_exe, // +6 } flag__Style; typedef enum { flag__FieldHints__is_bool = 1U, // u64(1) << 0 flag__FieldHints__is_array = 2U, // u64(1) << 1 flag__FieldHints__is_ignore = 4U, // u64(1) << 2 flag__FieldHints__is_int_type = 8U, // u64(1) << 3 flag__FieldHints__has_tail = 16U, // u64(1) << 4 flag__FieldHints__short_only = 32U, // u64(1) << 5 flag__FieldHints__can_repeat = 64U, // u64(1) << 6 } flag__FieldHints; typedef enum { flag__Show__name = 1U, // u64(1) << 0 flag__Show__version = 2U, // u64(1) << 1 flag__Show__flags = 4U, // u64(1) << 2 flag__Show__flag_type = 8U, // u64(1) << 3 flag__Show__flag_hint = 16U, // u64(1) << 4 flag__Show__description = 32U, // u64(1) << 5 flag__Show__flags_header = 64U, // u64(1) << 6 flag__Show__footer = 128U, // u64(1) << 7 } flag__Show; typedef enum { semver__Operator__gt, // semver__Operator__lt, // +1 semver__Operator__ge, // +2 semver__Operator__le, // +3 semver__Operator__eq, // +4 } semver__Operator; typedef enum { semver__Increment__major, // semver__Increment__minor, // +1 semver__Increment__patch, // +2 } semver__Increment; typedef enum { os__SeekMode__start, // os__SeekMode__current, // +1 os__SeekMode__end, // +2 } os__SeekMode; typedef enum { os__FileBufferMode__fully_buffered = _IOFBF, // _IOFBF os__FileBufferMode__line_buffered = _IOLBF, // _IOLBF os__FileBufferMode__not_buffered = _IONBF, // _IONBF } os__FileBufferMode; typedef enum { os__FileType__unknown, // os__FileType__regular, // +1 os__FileType__directory, // +2 os__FileType__character_device, // +3 os__FileType__block_device, // +4 os__FileType__fifo, // +5 os__FileType__symbolic_link, // +6 os__FileType__socket, // +7 } os__FileType; typedef enum { os__GlobMatch__exact, // os__GlobMatch__ends_with, // +1 os__GlobMatch__starts_with, // +2 os__GlobMatch__start_and_ends_with, // +3 os__GlobMatch__contains, // +4 os__GlobMatch__any, // +5 } os__GlobMatch; typedef enum { os__ChildProcessPipeKind__stdin, // os__ChildProcessPipeKind__stdout, // +1 os__ChildProcessPipeKind__stderr, // +2 } os__ChildProcessPipeKind; typedef enum { os__ProcessState__not_started, // os__ProcessState__running, // +1 os__ProcessState__stopped, // +2 os__ProcessState__exited, // +3 os__ProcessState__aborted, // +4 os__ProcessState__closed, // +5 } os__ProcessState; typedef enum { os__Signal__hup = 1, // 1 os__Signal__int = 2, // 2 os__Signal__quit = 3, // 3 os__Signal__ill = 4, // 4 os__Signal__trap = 5, // 5 os__Signal__abrt = 6, // 6 os__Signal__bus = 7, // 7 os__Signal__fpe = 8, // 8 os__Signal__kill = 9, // 9 os__Signal__usr1 = 10, // 10 os__Signal__segv = 11, // 11 os__Signal__usr2 = 12, // 12 os__Signal__pipe = 13, // 13 os__Signal__alrm = 14, // 14 os__Signal__term = 15, // 15 os__Signal__stkflt = 16, // 16 os__Signal__chld = 17, // 17 os__Signal__cont = 18, // 18 os__Signal__stop = 19, // 19 os__Signal__tstp = 20, // 20 os__Signal__ttin = 21, // 21 os__Signal__ttou = 22, // 22 os__Signal__urg = 23, // 23 os__Signal__xcpu = 24, // 24 os__Signal__xfsz = 25, // 25 os__Signal__vtalrm = 26, // 26 os__Signal__prof = 27, // 27 os__Signal__winch = 28, // 28 os__Signal__poll = 29, // 29 os__Signal__pwr = 30, // 30 os__Signal__sys = 31, // 31 } os__Signal; typedef enum { v__errors__Reporter__scanner, // v__errors__Reporter__parser, // +1 v__errors__Reporter__checker, // +2 v__errors__Reporter__builder, // +3 v__errors__Reporter__gen, // +4 } v__errors__Reporter; typedef enum { term__TextStyle__bold = 1, // 1 term__TextStyle__dim = 2, // 2 term__TextStyle__italic = 3, // 3 term__TextStyle__underline = 4, // 4 term__TextStyle__blink = 5, // 5 term__TextStyle__reverse = 7, // 7 } term__TextStyle; typedef enum { term__FgColor__black = 30, // 30 term__FgColor__red = 31, // 31 term__FgColor__green = 32, // 32 term__FgColor__yellow = 33, // 33 term__FgColor__blue = 34, // 34 term__FgColor__magenta = 35, // 35 term__FgColor__cyan = 36, // 36 term__FgColor__white = 37, // 37 } term__FgColor; typedef enum { term__BgColor__black = 40, // 40 term__BgColor__red = 41, // 41 term__BgColor__green = 42, // 42 term__BgColor__yellow = 43, // 43 term__BgColor__blue = 44, // 44 term__BgColor__magenta = 45, // 45 term__BgColor__cyan = 46, // 46 term__BgColor__white = 47, // 47 } term__BgColor; typedef enum { v__vmod__TokenKind__module_keyword, // v__vmod__TokenKind__field_key, // +1 v__vmod__TokenKind__lcbr, // +2 v__vmod__TokenKind__rcbr, // +3 v__vmod__TokenKind__labr, // +4 v__vmod__TokenKind__rabr, // +5 v__vmod__TokenKind__comma, // +6 v__vmod__TokenKind__colon, // +7 v__vmod__TokenKind__eof, // +8 v__vmod__TokenKind__str, // +9 v__vmod__TokenKind__ident, // +10 v__vmod__TokenKind__unknown, // +11 } v__vmod__TokenKind; typedef enum { v__pref__Arch___auto, // v__pref__Arch__amd64, // +1 v__pref__Arch__arm64, // +2 v__pref__Arch__arm32, // +3 v__pref__Arch__rv64, // +4 v__pref__Arch__rv32, // +5 v__pref__Arch__i386, // +6 v__pref__Arch__s390x, // +7 v__pref__Arch__ppc64le, // +8 v__pref__Arch__loongarch64, // +9 v__pref__Arch__js_node, // +10 v__pref__Arch__js_browser, // +11 v__pref__Arch__js_freestanding, // +12 v__pref__Arch__wasm32, // +13 v__pref__Arch___max, // +14 } v__pref__Arch; typedef enum { v__pref__OS___auto, // v__pref__OS__ios, // +1 v__pref__OS__macos, // +2 v__pref__OS__linux, // +3 v__pref__OS__windows, // +4 v__pref__OS__freebsd, // +5 v__pref__OS__openbsd, // +6 v__pref__OS__netbsd, // +7 v__pref__OS__dragonfly, // +8 v__pref__OS__js_node, // +9 v__pref__OS__js_browser, // +10 v__pref__OS__js_freestanding, // +11 v__pref__OS__android, // +12 v__pref__OS__termux, // +13 v__pref__OS__solaris, // +14 v__pref__OS__qnx, // +15 v__pref__OS__serenity, // +16 v__pref__OS__plan9, // +17 v__pref__OS__vinix, // +18 v__pref__OS__haiku, // +19 v__pref__OS__wasm32, // +20 v__pref__OS__wasm32_emscripten, // +21 v__pref__OS__wasm32_wasi, // +22 v__pref__OS__browser, // +23 v__pref__OS__wasi, // +24 v__pref__OS__raw, // +25 v__pref__OS__all, // +26 } v__pref__OS; typedef enum { v__pref__BuildMode__default_mode, // v__pref__BuildMode__build_module, // +1 } v__pref__BuildMode; typedef enum { v__pref__AssertFailureMode__default, // v__pref__AssertFailureMode__aborts, // +1 v__pref__AssertFailureMode__backtraces, // +2 v__pref__AssertFailureMode__continues, // +3 } v__pref__AssertFailureMode; typedef enum { v__pref__GarbageCollectionMode__unknown, // v__pref__GarbageCollectionMode__no_gc, // +1 v__pref__GarbageCollectionMode__boehm_full, // +2 v__pref__GarbageCollectionMode__boehm_incr, // +3 v__pref__GarbageCollectionMode__boehm_full_opt, // +4 v__pref__GarbageCollectionMode__boehm_incr_opt, // +5 v__pref__GarbageCollectionMode__boehm_leak, // +6 } v__pref__GarbageCollectionMode; typedef enum { v__pref__OutputMode__stdout, // v__pref__OutputMode__silent, // +1 } v__pref__OutputMode; typedef enum { v__pref__ColorOutput__auto, // v__pref__ColorOutput__always, // +1 v__pref__ColorOutput__never, // +2 } v__pref__ColorOutput; typedef enum { v__pref__Subsystem__auto, // v__pref__Subsystem__console, // +1 v__pref__Subsystem__windows, // +2 } v__pref__Subsystem; typedef enum { v__pref__Backend__c, // v__pref__Backend__golang, // +1 v__pref__Backend__interpret, // +2 v__pref__Backend__js_node, // +3 v__pref__Backend__js_browser, // +4 v__pref__Backend__js_freestanding, // +5 v__pref__Backend__native, // +6 v__pref__Backend__wasm, // +7 } v__pref__Backend; typedef enum { v__pref__CompilerType__gcc, // v__pref__CompilerType__tinyc, // +1 v__pref__CompilerType__clang, // +2 v__pref__CompilerType__emcc, // +3 v__pref__CompilerType__mingw, // +4 v__pref__CompilerType__msvc, // +5 v__pref__CompilerType__cplusplus, // +6 } v__pref__CompilerType; typedef enum { sync__BufferElemStat__unused = 0, // 0 sync__BufferElemStat__writing, // 0+1 sync__BufferElemStat__written, // 0+2 sync__BufferElemStat__reading, // 0+3 } sync__BufferElemStat; typedef enum { sync__Direction__pop, // sync__Direction__push, // +1 } sync__Direction; typedef enum { v__ast__ComptimeTypeKind__unknown, // v__ast__ComptimeTypeKind__map, // +1 v__ast__ComptimeTypeKind__int, // +2 v__ast__ComptimeTypeKind__float, // +3 v__ast__ComptimeTypeKind__struct, // +4 v__ast__ComptimeTypeKind__iface, // +5 v__ast__ComptimeTypeKind__array, // +6 v__ast__ComptimeTypeKind__array_fixed, // +7 v__ast__ComptimeTypeKind__array_dynamic, // +8 v__ast__ComptimeTypeKind__sum_type, // +9 v__ast__ComptimeTypeKind__enum, // +10 v__ast__ComptimeTypeKind__alias, // +11 v__ast__ComptimeTypeKind__function, // +12 v__ast__ComptimeTypeKind__option, // +13 v__ast__ComptimeTypeKind__string, // +14 v__ast__ComptimeTypeKind__pointer, // +15 v__ast__ComptimeTypeKind__voidptr, // +16 } v__ast__ComptimeTypeKind; typedef enum { v__ast__GenericKindField__unknown, // v__ast__GenericKindField__name, // +1 v__ast__GenericKindField__typ, // +2 v__ast__GenericKindField__unaliased_typ, // +3 v__ast__GenericKindField__indirections, // +4 } v__ast__GenericKindField; typedef enum { v__ast__StructInitKind__normal, // v__ast__StructInitKind__short_syntax, // +1 v__ast__StructInitKind__anon, // +2 } v__ast__StructInitKind; typedef enum { v__ast__ComptimeVarKind__no_comptime, // v__ast__ComptimeVarKind__key_var, // +1 v__ast__ComptimeVarKind__value_var, // +2 v__ast__ComptimeVarKind__field_var, // +3 v__ast__ComptimeVarKind__generic_param, // +4 v__ast__ComptimeVarKind__generic_var, // +5 v__ast__ComptimeVarKind__smartcast, // +6 v__ast__ComptimeVarKind__aggregate, // +7 } v__ast__ComptimeVarKind; typedef enum { v__ast__IdentKind__unresolved, // v__ast__IdentKind__blank_ident, // +1 v__ast__IdentKind__variable, // +2 v__ast__IdentKind__constant, // +3 v__ast__IdentKind__global, // +4 v__ast__IdentKind__function, // +5 } v__ast__IdentKind; typedef enum { v__ast__ComptimeForKind__methods, // v__ast__ComptimeForKind__fields, // +1 v__ast__ComptimeForKind__attributes, // +2 v__ast__ComptimeForKind__values, // +3 v__ast__ComptimeForKind__variants, // +4 v__ast__ComptimeForKind__params, // +5 } v__ast__ComptimeForKind; typedef enum { v__ast__AddressingMode__invalid, // v__ast__AddressingMode__displacement, // +1 v__ast__AddressingMode__base, // +2 v__ast__AddressingMode__base_plus_displacement, // +3 v__ast__AddressingMode__index_times_scale_plus_displacement, // +4 v__ast__AddressingMode__base_plus_index_plus_displacement, // +5 v__ast__AddressingMode__base_plus_index_times_scale_plus_displacement, // +6 v__ast__AddressingMode__rip_plus_displacement, // +7 } v__ast__AddressingMode; typedef enum { v__ast__OrKind__absent, // v__ast__OrKind__block, // +1 v__ast__OrKind__propagate_option, // +2 v__ast__OrKind__propagate_result, // +3 } v__ast__OrKind; typedef enum { v__ast__ComptimeCallKind__unknown, // v__ast__ComptimeCallKind__d, // +1 v__ast__ComptimeCallKind__env, // +2 v__ast__ComptimeCallKind__res, // +3 v__ast__ComptimeCallKind__html, // +4 v__ast__ComptimeCallKind__tmpl, // +5 v__ast__ComptimeCallKind__method, // +6 v__ast__ComptimeCallKind__pkgconfig, // +7 v__ast__ComptimeCallKind__embed_file, // +8 v__ast__ComptimeCallKind__compile_warn, // +9 v__ast__ComptimeCallKind__compile_error, // +10 } v__ast__ComptimeCallKind; typedef enum { v__ast__SqlStmtKind__insert, // v__ast__SqlStmtKind__update, // +1 v__ast__SqlStmtKind__delete, // +2 v__ast__SqlStmtKind__create, // +3 v__ast__SqlStmtKind__drop, // +4 } v__ast__SqlStmtKind; typedef enum { v__ast__SqlExprKind__insert, // v__ast__SqlExprKind__select_, // +1 } v__ast__SqlExprKind; typedef enum { v__ast__AttrKind__plain, // v__ast__AttrKind__string, // +1 v__ast__AttrKind__number, // +2 v__ast__AttrKind__bool, // +3 v__ast__AttrKind__comptime_define, // +4 } v__ast__AttrKind; typedef enum { v__ast__Language__v, // v__ast__Language__c, // +1 v__ast__Language__js, // +2 v__ast__Language__wasm, // +3 v__ast__Language__amd64, // +4 v__ast__Language__i386, // +5 v__ast__Language__arm64, // +6 v__ast__Language__arm32, // +7 v__ast__Language__rv64, // +8 v__ast__Language__rv32, // +9 v__ast__Language__s390x, // +10 v__ast__Language__ppc64le, // +11 v__ast__Language__loongarch64, // +12 v__ast__Language__wasm32, // +13 } v__ast__Language; #pragma pack(push, 1) typedef enum { v__ast__TypeFlag__option = 16777216, // 16777216 v__ast__TypeFlag__result = 33554432, // 33554432 v__ast__TypeFlag__variadic = 67108864, // 67108864 v__ast__TypeFlag__generic = 134217728, // 134217728 v__ast__TypeFlag__shared_f = 268435456, // 268435456 v__ast__TypeFlag__atomic_f = 536870912, // 536870912 v__ast__TypeFlag__option_mut_param_t = 1073741824, // 1073741824 } __attribute__((packed)) v__ast__TypeFlag; #pragma pack(pop) typedef enum { v__ast__ShareType__mut_t, // v__ast__ShareType__shared_t, // +1 v__ast__ShareType__atomic_t, // +2 } v__ast__ShareType; typedef enum { v__ast__Kind__placeholder, // v__ast__Kind__void, // +1 v__ast__Kind__voidptr, // +2 v__ast__Kind__byteptr, // +3 v__ast__Kind__charptr, // +4 v__ast__Kind__i8, // +5 v__ast__Kind__i16, // +6 v__ast__Kind__i32, // +7 v__ast__Kind__int, // +8 v__ast__Kind__i64, // +9 v__ast__Kind__isize, // +10 v__ast__Kind__u8, // +11 v__ast__Kind__u16, // +12 v__ast__Kind__u32, // +13 v__ast__Kind__u64, // +14 v__ast__Kind__usize, // +15 v__ast__Kind__f32, // +16 v__ast__Kind__f64, // +17 v__ast__Kind__char, // +18 v__ast__Kind__rune, // +19 v__ast__Kind__bool, // +20 v__ast__Kind__none, // +21 v__ast__Kind__string, // +22 v__ast__Kind__array, // +23 v__ast__Kind__array_fixed, // +24 v__ast__Kind__map, // +25 v__ast__Kind__chan, // +26 v__ast__Kind__any, // +27 v__ast__Kind__struct, // +28 v__ast__Kind__generic_inst, // +29 v__ast__Kind__multi_return, // +30 v__ast__Kind__sum_type, // +31 v__ast__Kind__alias, // +32 v__ast__Kind__enum, // +33 v__ast__Kind__function, // +34 v__ast__Kind__interface, // +35 v__ast__Kind__float_literal, // +36 v__ast__Kind__int_literal, // +37 v__ast__Kind__aggregate, // +38 v__ast__Kind__thread, // +39 } v__ast__Kind; typedef enum { v__scanner__CommentsMode__skip_comments, // v__scanner__CommentsMode__parse_comments, // +1 v__scanner__CommentsMode__toplevel_comments, // +2 } v__scanner__CommentsMode; typedef enum { v__checker__ComptimeBranchSkipState__eval, // v__checker__ComptimeBranchSkipState__skip, // +1 v__checker__ComptimeBranchSkipState__unknown, // +2 } v__checker__ComptimeBranchSkipState; typedef enum { v__parser__OrBlockErrVarMode__no_err_var, // v__parser__OrBlockErrVarMode__with_err_var, // +1 } v__parser__OrBlockErrVarMode; typedef enum { v__parser__State__simple, // v__parser__State__html, // +1 v__parser__State__css, // +2 v__parser__State__js, // +3 } v__parser__State; typedef enum { v__gen__c__AssertMetainfoKind__pass, // v__gen__c__AssertMetainfoKind__fail, // +1 v__gen__c__AssertMetainfoKind__panic, // +2 } v__gen__c__AssertMetainfoKind; typedef enum { v__gen__c__SqlExprSide__left, // v__gen__c__SqlExprSide__right, // +1 } v__gen__c__SqlExprSide; typedef enum { v__gen__c__SpawnGoMode__spawn_, // v__gen__c__SpawnGoMode__go_, // +1 } v__gen__c__SpawnGoMode; typedef enum { v__builder__CC__tcc, // v__builder__CC__gcc, // +1 v__builder__CC__icc, // +2 v__builder__CC__msvc, // +3 v__builder__CC__clang, // +4 v__builder__CC__emcc, // +5 v__builder__CC__unknown, // +6 } v__builder__CC; // V type definitions: struct IError { union { void* _object; None__* _None__; voidptr* _voidptr; Error* _Error; MessageError* _MessageError; time__TimeParseError* _time__TimeParseError; flag__UnknownFlagError* _flag__UnknownFlagError; flag__ArgsCountError* _flag__ArgsCountError; semver__InvalidComparatorFormatError* _semver__InvalidComparatorFormatError; semver__EmptyInputError* _semver__EmptyInputError; semver__InvalidVersionFormatError* _semver__InvalidVersionFormatError; os__Eof* _os__Eof; os__NotExpected* _os__NotExpected; os__FileNotOpenedError* _os__FileNotOpenedError; os__SizeOfTypeIs0Error* _os__SizeOfTypeIs0Error; os__ExecutableNotFoundError* _os__ExecutableNotFoundError; v__parser__IncludeError* _v__parser__IncludeError; v__gen__c__UnsupportedAssertCtempTransform* _v__gen__c__UnsupportedAssertCtempTransform; }; int _typ; }; struct string { u8* str; int len; int is_lit; }; struct array { voidptr data; int offset; int len; int cap; ArrayFlags flags; int element_size; }; struct DenseArray { int key_bytes; int value_bytes; int cap; int len; u32 deletes; u8* all_deleted; u8* keys; u8* values; }; struct map { int key_bytes; int value_bytes; u32 even_index; u8 cached_hashbits; u8 shift; DenseArray key_values; u32* metas; u32 extra_metas; bool has_string_keys; MapHashFn hash_fn; MapEqFn key_eq_fn; MapCloneFn clone_fn; MapFreeFn free_fn; int len; }; struct Error { EMPTY_STRUCT_DECLARATION; }; struct _option { u8 state; IError err; }; struct _result { bool is_error; IError err; }; typedef array Array_string; typedef array Array_u8; typedef array Array_voidptr; typedef array Array_VCastTypeIndexName; typedef array Array_int; typedef array Array_rune; typedef string Array_fixed_string_11 [11]; typedef voidptr Array_fixed_voidptr_11 [11]; typedef array Array_RepIndex; typedef map Map_string_int; typedef array Array_bool; typedef map Map_string_string; typedef array Array_char_ptr; typedef int Array_fixed_int_3 [3]; typedef char Array_fixed_char_256 [256]; typedef int Array_fixed_int_10 [10]; typedef map Map_string_bool; typedef map Map_string_Array_string; typedef array Array_v__util__Possibility; typedef map Map_string_time__StopWatch; typedef array Array_v__ast__File_ptr; typedef array Array_v__builder__FunctionRedefinition; typedef array Array_v__cflag__CFlag; typedef array Array_os__File; typedef array Array_u32; typedef array Array_v__token__TrieNode_ptr; typedef map Map_string_T; typedef map Map_string_v__token__Kind; typedef array Array_v__token__Precedence; typedef u8 Array_fixed_u8_63 [63]; typedef map Map_string_v__vmod__ModFileAndFolder; typedef array Array_v__ast__Comment; typedef array Array_v__ast__Stmt; typedef array Array_v__token__Pos; typedef array Array_v__ast__Expr; typedef array Array_v__ast__Type; typedef array Array_Array_v__ast__Type; typedef array Array_v__ast__Attr; typedef array Array_v__ast__ConstField; typedef array Array_v__ast__Embed; typedef array Array_v__ast__TypeNode; typedef array Array_v__ast__StructField; typedef array Array_v__ast__FnDecl; typedef array Array_v__ast__InterfaceEmbedding; typedef array Array_v__ast__StructInitField; typedef array Array_v__ast__ImportSymbol; typedef array Array_v__ast__Param; typedef array Array_v__ast__DeferStmt; typedef map Map_string_v__ast__FnTrace; typedef array Array_v__ast__CallArg; typedef array Array_v__ast__GlobalField; typedef array Array_v__ast__Import; typedef array Array_v__ast__EmbeddedFile; typedef array Array_v__errors__Error; typedef array Array_v__errors__Warning; typedef array Array_v__errors__Notice; typedef array Array_v__ast__FnDecl_ptr; typedef array Array_v__ast__IfBranch; typedef array Array_v__ast__MatchBranch; typedef array Array_Array_v__ast__Comment; typedef array Array_v__ast__SelectBranch; typedef array Array_v__ast__EnumField; typedef array Array_v__ast__Ident; typedef array Array_v__ast__AsmClobbered; typedef array Array_v__ast__AsmTemplate; typedef array Array_v__ast__AsmIO; typedef array Array_v__ast__AsmArg; typedef array Array_v__ast__IfGuardVar; typedef array Array_v__ast__SqlStmtLine; typedef map Map_int_v__ast__SqlStmtLine; typedef map Map_int_v__ast__SqlExpr; typedef array Array_v__ast__Node; typedef map Map_string_v__ast__ScopeObject; typedef map Map_string_v__ast__ScopeStructField; typedef array Array_v__ast__Scope_ptr; typedef array Array_v__ast__ScopeObject; typedef array Array_v__ast__StringifyModReplacement; typedef map Map_int_bool; typedef map Map_v__ast__Type_bool; typedef array Array_v__ast__TypeSymbol_ptr; typedef map Map_string_v__ast__Fn; typedef map Map_string_Array_v__ast__Type; typedef map Map_int_string; typedef map Map_string_Array_Array_v__ast__Type; typedef map Map_int_v__ast__InterfaceDecl; typedef map Map_int_v__ast__SumTypeDecl; typedef map Map_string_v__ast__EnumDecl; typedef map Map_string_Array_v__ast__Attr; typedef map Map_u64_string; typedef array Array_v__ast__Fn; typedef array Array_i64; typedef map Map_string_v__ast__StructField; typedef map Map_int_Array_v__ast__Type; typedef array Array_v__ast__TypeFlag; typedef array Array_v__ast__Kind; typedef array Array_v__checker__ACFieldMethod; typedef array Array_v__ast__Stmt_ptr; typedef map Map_string_v__checker__ComptimeBranchSkipState; typedef map Map_string_v__ast__GotoLabel; typedef map Map_string_Array_v__ast__StructField; typedef map Map_int_v__ast__InterfaceEmbedding; typedef array Array_u64; typedef array Array_v__transformer__KeyVal; typedef array Array_Array_v__transformer__KeyVal; typedef map Map_string_v__ast__FnDecl; typedef map Map_string_v__ast__ConstField; typedef map Map_string_v__ast__GlobalField; typedef map Map_string_v__ast__TypeDecl; typedef map Map_string_v__ast__StructDecl; typedef array Array_v__depgraph__DepGraphNode; typedef map Map_string_i64; typedef map Map_string_strings__Builder; typedef map Map_string_v__gen__c__GlobalConstDef; typedef map Map_string_v__gen__c__VSafeArithmeticOp; typedef map Map_v__ast__Type_string; typedef map Map_string_v__ast__Stmt_ptr; typedef map Map_u64_v__gen__c__CoverageInfo_ptr; typedef array Array_v__gen__c__StrType; typedef array Array_v__gen__c__SumtypeCastingFn; typedef array Array_v__gen__c__ProfileCounterMeta; typedef array Array_v__ast__InfixExpr; typedef array Array_v__ast__TypeSymbol; typedef array Array_Array_int; typedef map Map_int_v__ast__Type; typedef map Map_string_v__ast__Type; typedef array Array_v__type_resolver__ResolverInfo; typedef array Array_v__token__Token; typedef array Array_flag__Flag; typedef u8 Array_fixed_u8_5 [5]; typedef u8 Array_fixed_u8_25 [25]; typedef u8 Array_fixed_u8_32 [32]; typedef u8 Array_fixed_u8_64 [64]; typedef u8 Array_fixed_u8_256 [256]; typedef u32 Array_fixed_u32_10 [10]; typedef u64 Array_fixed_u64_20 [20]; typedef u64 Array_fixed_u64_584 [584]; typedef u64 Array_fixed_u64_652 [652]; typedef f64 Array_fixed_f64_36 [36]; typedef u8 Array_fixed_u8_26 [26]; typedef u8 Array_fixed_u8_512 [512]; typedef u64 Array_fixed_u64_47 [47]; typedef u64 Array_fixed_u64_31 [31]; typedef voidptr Array_fixed_voidptr_100 [100]; typedef u8 Array_fixed_u8_1000 [1000]; typedef u8 Array_fixed_u8_17 [17]; typedef i32 Array_fixed_i32_1264 [1264]; typedef array Array_MapMode; typedef int Array_fixed_int_20 [20]; typedef array Array_TrimMode; typedef array Array_StrIntpType; typedef char Array_fixed_char_1024 [1024]; typedef array Array_v__token__Kind; typedef u8 Array_fixed_u8_4096 [4096]; typedef u8 Array_fixed_u8_1024 [1024]; typedef array Array_u8_ptr; typedef int Array_fixed_int_4 [4]; typedef array Array_os__ProcessState; typedef int Array_fixed_int_6 [6]; typedef u8 Array_fixed_u8_50 [50]; typedef array Array_v__pref__Backend; typedef array Array_v__pref__OS; typedef bool Array_fixed_bool_256 [256]; typedef string Array_fixed_string_8 [8]; typedef map Map_int_Array_string; typedef map Map_int_Map_string_int; typedef array Array_v__ast__IdentKind; typedef array Array_v__pref__GarbageCollectionMode; typedef array Array_v__ast__ComptimeVarKind; typedef array Array_v__ast__OrKind; typedef array Array_v__ast__CallExpr; typedef array Array_v__ast__IfExpr; typedef array Array_v__ast__BoolLiteral; typedef array Array_v__ast__IntegerLiteral; typedef array Array_v__ast__ComptimeType; typedef array Array_v__ast__Var; typedef array Array_v__ast__Language; typedef array Array_v__ast__Return; typedef map Map_rune_v__checker__LoHiLimit; typedef array Array_v__pref__Arch; typedef array Array_v__ast__IndexExpr; typedef array Array_v__ast__SelectorExpr; typedef array Array_v__ast__MatchExpr; typedef array Array_v__gen__c__Gen_ptr; typedef array Array_v__ast__StructInit; typedef array Array_v__ast__Struct; typedef array Array_v__ast__ArrayInit; typedef array Array_v__ast__StringLiteral; typedef array Array_v__builder__CC; typedef array Array_os__Result; #define C__intptr_t intptr_t typedef Array_u8 strings__Builder; typedef voidptr v__builder__RegKey; typedef i64 time__Duration; #define C__time_t time_t typedef u8 v__ast__EmptyExpr; typedef u32 v__ast__Type; typedef int (*anon_fn_voidptr_voidptr__int)(voidptr,voidptr); typedef void (*FnExitCb)(); typedef void (*FnGC_WarnCB)(char*,usize); typedef int (*FnSortCB)(voidptr,voidptr); typedef voidptr (*anon_fn___voidptr)(); typedef void (*os__SignalHandler)(os__Signal); typedef string (*anon_fn_string__string)(string); typedef f32 (*v__util__CalculateSuggestionSimilarityFN)(string,string); typedef void (*v__builder__FnBackend)(v__builder__Builder*); typedef void (*v__ast__FnPanicHandler)(v__ast__Table*,string); typedef string (*v__dotgraph__FnLabel2NodeName)(string,voidptr); typedef voidptr (*sync__pool__ThreadCB)(sync__pool__PoolProcessor*,int,int); typedef bool (*v__ast__walker__InspectorFn)(v__ast__Node*,voidptr); struct rand__PRNG { union { void* _object; rand__wyrand__WyRandRNG* _rand__wyrand__WyRandRNG; voidptr* _voidptr; }; int _typ; }; struct v__type_resolver__IResolverType { union { void* _object; v__type_resolver__DummyResolver* _v__type_resolver__DummyResolver; voidptr* _voidptr; v__checker__Checker* _v__checker__Checker; v__gen__c__Gen* _v__gen__c__Gen; }; int _typ; v__ast__File** file; }; struct v__ast__walker__Visitor { union { void* _object; v__ast__walker__Inspector* _v__ast__walker__Inspector; voidptr* _voidptr; v__callgraph__Mapper* _v__callgraph__Mapper; }; int _typ; }; // #start sorted_symbols struct none { EMPTY_STRUCT_DECLARATION; }; struct None__ { Error Error; }; struct os__Eof { Error Error; }; struct os__FileNotOpenedError { Error Error; }; struct os__SizeOfTypeIs0Error { Error Error; }; struct os__ExecutableNotFoundError { Error Error; }; struct os__Uname { string sysname; string nodename; string release; string version; string machine; }; struct v__cflag__CFlag { string mod; string os; string name; string value; string cached; }; struct v__builder__WindowsKit { string um_lib_path; string ucrt_lib_path; string um_include_path; string ucrt_include_path; string shared_include_path; }; struct v__builder__VsInstallation { string include_path; string lib_path; string exe_path; }; typedef v__token__TrieNode* Array_fixed_v__token__TrieNode_ptr1_123 [123]; struct sync__Subscription { sync__Semaphore* sem; sync__Subscription** prev; sync__Subscription* nxt; }; struct v__vmod__ModFileAndFolder { string vmod_file; string vmod_folder; }; // Union sum type v__ast__TypeDecl = // | 331 = v__ast__AliasTypeDecl // | 332 = v__ast__FnTypeDecl // | 333 = v__ast__SumTypeDecl struct v__ast__TypeDecl { union { v__ast__AliasTypeDecl* _v__ast__AliasTypeDecl; v__ast__FnTypeDecl* _v__ast__FnTypeDecl; v__ast__SumTypeDecl* _v__ast__SumTypeDecl; }; int _typ; string* name; bool* is_pub; v__ast__Type* typ; v__token__Pos* pos; Array_v__ast__Attr* attrs; bool* is_markused; }; // Union sum type v__ast__Expr = // | 335 = v__ast__NodeError // | 336 = v__ast__AnonFn // | 337 = v__ast__ArrayDecompose // | 338 = v__ast__ArrayInit // | 339 = v__ast__AsCast // | 340 = v__ast__Assoc // | 341 = v__ast__AtExpr // | 342 = v__ast__BoolLiteral // | 343 = v__ast__CTempVar // | 344 = v__ast__CallExpr // | 345 = v__ast__CastExpr // | 346 = v__ast__ChanInit // | 347 = v__ast__CharLiteral // | 348 = v__ast__Comment // | 349 = v__ast__ComptimeCall // | 350 = v__ast__ComptimeSelector // | 351 = v__ast__ComptimeType // | 352 = v__ast__ConcatExpr // | 353 = v__ast__DumpExpr // | 354 = v__ast__EmptyExpr // | 355 = v__ast__EnumVal // | 356 = v__ast__FloatLiteral // | 357 = v__ast__GoExpr // | 358 = v__ast__Ident // | 359 = v__ast__IfExpr // | 360 = v__ast__IfGuardExpr // | 361 = v__ast__IndexExpr // | 362 = v__ast__InfixExpr // | 363 = v__ast__IntegerLiteral // | 364 = v__ast__IsRefType // | 365 = v__ast__LambdaExpr // | 366 = v__ast__Likely // | 367 = v__ast__LockExpr // | 368 = v__ast__MapInit // | 369 = v__ast__MatchExpr // | 370 = v__ast__Nil // | 371 = v__ast__None // | 372 = v__ast__OffsetOf // | 373 = v__ast__OrExpr // | 374 = v__ast__ParExpr // | 375 = v__ast__PostfixExpr // | 376 = v__ast__PrefixExpr // | 377 = v__ast__RangeExpr // | 378 = v__ast__SelectExpr // | 379 = v__ast__SelectorExpr // | 380 = v__ast__SizeOf // | 381 = v__ast__SpawnExpr // | 382 = v__ast__SqlExpr // | 383 = v__ast__StringInterLiteral // | 384 = v__ast__StringLiteral // | 385 = v__ast__StructInit // | 386 = v__ast__TypeNode // | 387 = v__ast__TypeOf // | 388 = v__ast__UnsafeExpr struct v__ast__Expr { union { v__ast__NodeError* _v__ast__NodeError; v__ast__AnonFn* _v__ast__AnonFn; v__ast__ArrayDecompose* _v__ast__ArrayDecompose; v__ast__ArrayInit* _v__ast__ArrayInit; v__ast__AsCast* _v__ast__AsCast; v__ast__Assoc* _v__ast__Assoc; v__ast__AtExpr* _v__ast__AtExpr; v__ast__BoolLiteral* _v__ast__BoolLiteral; v__ast__CTempVar* _v__ast__CTempVar; v__ast__CallExpr* _v__ast__CallExpr; v__ast__CastExpr* _v__ast__CastExpr; v__ast__ChanInit* _v__ast__ChanInit; v__ast__CharLiteral* _v__ast__CharLiteral; v__ast__Comment* _v__ast__Comment; v__ast__ComptimeCall* _v__ast__ComptimeCall; v__ast__ComptimeSelector* _v__ast__ComptimeSelector; v__ast__ComptimeType* _v__ast__ComptimeType; v__ast__ConcatExpr* _v__ast__ConcatExpr; v__ast__DumpExpr* _v__ast__DumpExpr; v__ast__EmptyExpr* _v__ast__EmptyExpr; v__ast__EnumVal* _v__ast__EnumVal; v__ast__FloatLiteral* _v__ast__FloatLiteral; v__ast__GoExpr* _v__ast__GoExpr; v__ast__Ident* _v__ast__Ident; v__ast__IfExpr* _v__ast__IfExpr; v__ast__IfGuardExpr* _v__ast__IfGuardExpr; v__ast__IndexExpr* _v__ast__IndexExpr; v__ast__InfixExpr* _v__ast__InfixExpr; v__ast__IntegerLiteral* _v__ast__IntegerLiteral; v__ast__IsRefType* _v__ast__IsRefType; v__ast__LambdaExpr* _v__ast__LambdaExpr; v__ast__Likely* _v__ast__Likely; v__ast__LockExpr* _v__ast__LockExpr; v__ast__MapInit* _v__ast__MapInit; v__ast__MatchExpr* _v__ast__MatchExpr; v__ast__Nil* _v__ast__Nil; v__ast__None* _v__ast__None; v__ast__OffsetOf* _v__ast__OffsetOf; v__ast__OrExpr* _v__ast__OrExpr; v__ast__ParExpr* _v__ast__ParExpr; v__ast__PostfixExpr* _v__ast__PostfixExpr; v__ast__PrefixExpr* _v__ast__PrefixExpr; v__ast__RangeExpr* _v__ast__RangeExpr; v__ast__SelectExpr* _v__ast__SelectExpr; v__ast__SelectorExpr* _v__ast__SelectorExpr; v__ast__SizeOf* _v__ast__SizeOf; v__ast__SpawnExpr* _v__ast__SpawnExpr; v__ast__SqlExpr* _v__ast__SqlExpr; v__ast__StringInterLiteral* _v__ast__StringInterLiteral; v__ast__StringLiteral* _v__ast__StringLiteral; v__ast__StructInit* _v__ast__StructInit; v__ast__TypeNode* _v__ast__TypeNode; v__ast__TypeOf* _v__ast__TypeOf; v__ast__UnsafeExpr* _v__ast__UnsafeExpr; }; int _typ; }; // Union sum type v__ast__Stmt = // | 390 = v__ast__AsmStmt // | 391 = v__ast__AssertStmt // | 392 = v__ast__AssignStmt // | 393 = v__ast__Block // | 394 = v__ast__BranchStmt // | 395 = v__ast__ComptimeFor // | 396 = v__ast__ConstDecl // | 397 = v__ast__DebuggerStmt // | 398 = v__ast__DeferStmt // | 399 = v__ast__EmptyStmt // | 400 = v__ast__EnumDecl // | 401 = v__ast__ExprStmt // | 237 = v__ast__FnDecl // | 402 = v__ast__ForCStmt // | 403 = v__ast__ForInStmt // | 404 = v__ast__ForStmt // | 405 = v__ast__GlobalDecl // | 406 = v__ast__GotoLabel // | 407 = v__ast__GotoStmt // | 408 = v__ast__HashStmt // | 409 = v__ast__Import // | 410 = v__ast__InterfaceDecl // | 411 = v__ast__Module // | 335 = v__ast__NodeError // | 412 = v__ast__Return // | 413 = v__ast__SemicolonStmt // | 414 = v__ast__SqlStmt // | 415 = v__ast__StructDecl // | 334 = v__ast__TypeDecl struct v__ast__Stmt { union { v__ast__AsmStmt* _v__ast__AsmStmt; v__ast__AssertStmt* _v__ast__AssertStmt; v__ast__AssignStmt* _v__ast__AssignStmt; v__ast__Block* _v__ast__Block; v__ast__BranchStmt* _v__ast__BranchStmt; v__ast__ComptimeFor* _v__ast__ComptimeFor; v__ast__ConstDecl* _v__ast__ConstDecl; v__ast__DebuggerStmt* _v__ast__DebuggerStmt; v__ast__DeferStmt* _v__ast__DeferStmt; v__ast__EmptyStmt* _v__ast__EmptyStmt; v__ast__EnumDecl* _v__ast__EnumDecl; v__ast__ExprStmt* _v__ast__ExprStmt; v__ast__FnDecl* _v__ast__FnDecl; v__ast__ForCStmt* _v__ast__ForCStmt; v__ast__ForInStmt* _v__ast__ForInStmt; v__ast__ForStmt* _v__ast__ForStmt; v__ast__GlobalDecl* _v__ast__GlobalDecl; v__ast__GotoLabel* _v__ast__GotoLabel; v__ast__GotoStmt* _v__ast__GotoStmt; v__ast__HashStmt* _v__ast__HashStmt; v__ast__Import* _v__ast__Import; v__ast__InterfaceDecl* _v__ast__InterfaceDecl; v__ast__Module* _v__ast__Module; v__ast__NodeError* _v__ast__NodeError; v__ast__Return* _v__ast__Return; v__ast__SemicolonStmt* _v__ast__SemicolonStmt; v__ast__SqlStmt* _v__ast__SqlStmt; v__ast__StructDecl* _v__ast__StructDecl; v__ast__TypeDecl* _v__ast__TypeDecl; }; int _typ; v__token__Pos* pos; }; // Union sum type v__ast__ScopeObject = // | 418 = v__ast__EmptyScopeObject // | 419 = v__ast__AsmRegister // | 420 = v__ast__ConstField // | 421 = v__ast__GlobalField // | 422 = v__ast__Var struct v__ast__ScopeObject { union { v__ast__EmptyScopeObject* _v__ast__EmptyScopeObject; v__ast__AsmRegister* _v__ast__AsmRegister; v__ast__ConstField* _v__ast__ConstField; v__ast__GlobalField* _v__ast__GlobalField; v__ast__Var* _v__ast__Var; }; int _typ; string* name; v__ast__Type* typ; }; // Union sum type v__ast__Node = // | 424 = v__ast__CallArg // | 420 = v__ast__ConstField // | 425 = v__ast__EmptyNode // | 426 = v__ast__EnumField // | 389 = v__ast__Expr // | 228 = v__ast__File // | 421 = v__ast__GlobalField // | 427 = v__ast__IfBranch // | 428 = v__ast__MatchBranch // | 335 = v__ast__NodeError // | 429 = v__ast__Param // | 423 = v__ast__ScopeObject // | 430 = v__ast__SelectBranch // | 416 = v__ast__Stmt // | 431 = v__ast__StructField // | 432 = v__ast__StructInitField struct v__ast__Node { union { v__ast__CallArg* _v__ast__CallArg; v__ast__ConstField* _v__ast__ConstField; v__ast__EmptyNode* _v__ast__EmptyNode; v__ast__EnumField* _v__ast__EnumField; v__ast__Expr* _v__ast__Expr; v__ast__File* _v__ast__File; v__ast__GlobalField* _v__ast__GlobalField; v__ast__IfBranch* _v__ast__IfBranch; v__ast__MatchBranch* _v__ast__MatchBranch; v__ast__NodeError* _v__ast__NodeError; v__ast__Param* _v__ast__Param; v__ast__ScopeObject* _v__ast__ScopeObject; v__ast__SelectBranch* _v__ast__SelectBranch; v__ast__Stmt* _v__ast__Stmt; v__ast__StructField* _v__ast__StructField; v__ast__StructInitField* _v__ast__StructInitField; }; int _typ; }; // Union sum type v__ast__ComptTimeConstValue = // | 354 = v__ast__EmptyExpr // | 16 = f32 // | 17 = f64 // | 6 = i16 // | 7 = i32 // | 9 = i64 // | 5 = i8 // | 22 = rune // | 21 = string // | 12 = u16 // | 13 = u32 // | 14 = u64 // | 11 = u8 // | 2 = voidptr struct v__ast__ComptTimeConstValue { union { v__ast__EmptyExpr* _v__ast__EmptyExpr; f32* _f32; f64* _f64; i16* _i16; i32* _i32; i64* _i64; i8* _i8; rune* _rune; string* _string; u16* _u16; u32* _u32; u64* _u64; u8* _u8; voidptr* _voidptr; }; int _typ; }; // Union sum type v__ast__IdentInfo = // | 476 = v__ast__IdentFn // | 477 = v__ast__IdentVar struct v__ast__IdentInfo { union { v__ast__IdentFn* _v__ast__IdentFn; v__ast__IdentVar* _v__ast__IdentVar; }; int _typ; v__ast__Type* typ; }; // Union sum type v__ast__AsmArg = // | 496 = v__ast__AsmAddressing // | 497 = v__ast__AsmAlias // | 498 = v__ast__AsmDisp // | 419 = v__ast__AsmRegister // | 342 = v__ast__BoolLiteral // | 347 = v__ast__CharLiteral // | 356 = v__ast__FloatLiteral // | 363 = v__ast__IntegerLiteral // | 21 = string struct v__ast__AsmArg { union { v__ast__AsmAddressing* _v__ast__AsmAddressing; v__ast__AsmAlias* _v__ast__AsmAlias; v__ast__AsmDisp* _v__ast__AsmDisp; v__ast__AsmRegister* _v__ast__AsmRegister; v__ast__BoolLiteral* _v__ast__BoolLiteral; v__ast__CharLiteral* _v__ast__CharLiteral; v__ast__FloatLiteral* _v__ast__FloatLiteral; v__ast__IntegerLiteral* _v__ast__IntegerLiteral; string* _string; }; int _typ; }; struct v__ast__UnknownTypeInfo { EMPTY_STRUCT_DECLARATION; }; // Union sum type v__ast__TypeInfo = // | 557 = v__ast__UnknownTypeInfo // | 537 = v__ast__Aggregate // | 539 = v__ast__Alias // | 513 = v__ast__Array // | 549 = v__ast__ArrayFixed // | 550 = v__ast__Chan // | 548 = v__ast__Enum // | 553 = v__ast__FnType // | 555 = v__ast__GenericInst // | 542 = v__ast__Interface // | 514 = v__ast__Map // | 552 = v__ast__MultiReturn // | 518 = v__ast__Struct // | 544 = v__ast__SumType // | 551 = v__ast__Thread struct v__ast__TypeInfo { union { v__ast__UnknownTypeInfo* _v__ast__UnknownTypeInfo; v__ast__Aggregate* _v__ast__Aggregate; v__ast__Alias* _v__ast__Alias; v__ast__Array* _v__ast__Array; v__ast__ArrayFixed* _v__ast__ArrayFixed; v__ast__Chan* _v__ast__Chan; v__ast__Enum* _v__ast__Enum; v__ast__FnType* _v__ast__FnType; v__ast__GenericInst* _v__ast__GenericInst; v__ast__Interface* _v__ast__Interface; v__ast__Map* _v__ast__Map; v__ast__MultiReturn* _v__ast__MultiReturn; v__ast__Struct* _v__ast__Struct; v__ast__SumType* _v__ast__SumType; v__ast__Thread* _v__ast__Thread; }; int _typ; }; struct v__checker__ACFieldMethod { string name; string typ; }; // Union sum type v__checker__ORMExpr = // | 382 = v__ast__SqlExpr // | 414 = v__ast__SqlStmt struct v__checker__ORMExpr { union { v__ast__SqlExpr* _v__ast__SqlExpr; v__ast__SqlStmt* _v__ast__SqlStmt; }; int _typ; v__token__Pos* pos; v__ast__Expr* db_expr; v__ast__OrExpr* or_expr; }; struct v__checker__LoHiLimit { string lower; string higher; }; struct v__parser__ParamsForUnexpected { string got; string expecting; string prepend_msg; string additional_msg; }; struct v__gen__c__UnsupportedAssertCtempTransform { Error Error; }; struct v__gen__c__ProfileCounterMeta { string fn_name; string vpc_name; string vpc_calls; }; struct v__type_resolver__DummyResolver { v__ast__File* file; }; struct flag__UnknownFlagError { Error Error; string flag; }; struct flag__FlagConfig { string val_desc; }; struct semver__EmptyInputError { Error Error; }; struct semver__InvalidVersionFormatError { Error Error; string input; }; struct VCastTypeIndexName { int tindex; string tname; }; struct EnumData { string name; i64 value; Array_string attrs; }; union strconv__Float64u { f64 f; u64 u; }; union strconv__Float32u { f32 f; u32 u; }; struct VMemoryBlock { u8* current; u8* stop; u8* start; VMemoryBlock* previous; VMemoryBlock* next; int id; int mallocs; }; struct MessageError { string msg; int code; }; struct RepIndex { int idx; int val_idx; }; struct WrapConfig { int width; string end; }; struct RunesIterator { string s; int i; }; union StrIntpMem { u32 d_c; u8 d_u8; i8 d_i8; u16 d_u16; i16 d_i16; u32 d_u32; int d_i32; u64 d_u64; i64 d_i64; f32 d_f32; f64 d_f64; string d_s; string d_r; voidptr d_p; voidptr d_vp; }; struct strconv__BF_param { u8 pad_ch; int len0; int len1; bool positive; bool sign_flag; strconv__Align_text align; bool rm_tail_zero; }; struct v__util__Timers { string label; __shared__Map_string_time__StopWatch* swatches; bool should_print; Array_string already_shown; }; struct builtin__closure__ClosureMutex { pthread_mutex_t closure_mtx; }; struct strconv__PrepNumber { bool negative; int exponent; u64 mantissa; }; struct strconv__AtoF64Param { bool allow_extra_chars; }; struct strconv__Dec32 { u32 m; int e; }; union strconv__Uf32 { f32 f; u32 u; }; struct strconv__Dec64 { u64 m; int e; }; struct strconv__Uint128 { u64 lo; u64 hi; }; union strconv__Uf64 { f64 f; u64 u; }; struct os__NotExpected { string cause; int code; }; struct os__File { voidptr cfile; int fd; bool is_opened; }; struct os__Stat { u64 dev; u64 inode; u32 mode; u64 nlink; u32 uid; u32 gid; u64 rdev; u64 size; i64 atime; i64 mtime; i64 ctime; }; struct os__SystemError { string msg; int code; }; struct os__Result { int exit_code; string output; }; struct os__MvParams { bool overwrite; }; struct os__WalkParams { bool hidden; }; struct os__MkdirParams { u32 mode; }; struct v__help__ExitOptions { int exit_code; }; struct v__pref__LineInfo { int line_nr; string path; string expr; bool is_running; Map_string_bool vars_printed; }; struct v__vcache__CacheManager { string basepath; string original_vopts; string vopts; Map_string_string k2cpath; }; struct v__util__EManager { bool support_color; }; struct v__token__Pos { int len; int line_nr; int pos; int col; int last_line; }; struct v__util__LinesCache { Map_string_Array_string lines; }; struct v__util__Possibility { string value; string svalue; f32 similarity; }; struct v__util__Suggestion { Array_v__util__Possibility known; string wanted; string swanted; f32 similarity_threshold; v__util__CalculateSuggestionSimilarityFN similarity_fn; }; struct v__util__SuggestionParams { f32 similarity_threshold; v__util__CalculateSuggestionSimilarityFN similarity_fn; }; struct v__util__Surrounder { Array_string befores; Array_string afters; }; struct time__StopWatch { u64 elapsed; u64 start; u64 end; }; struct v__util__TimerParams { bool should_print; string label; }; struct time__Time { i64 __v_unix; int year; int month; int day; int hour; int minute; int second; int nanosecond; bool is_local; }; struct v__util__SourceCache { Map_string_string sources; }; struct v__transformer__Transformer { v__pref__Preferences* pref; v__transformer__IndexState* index; v__ast__Table* table; v__ast__File* file; bool is_assert; bool inside_dump; v__ast__Type strings_builder_type; }; struct v__builder__MsvcResult { string full_cl_exe_path; string exe_path; string um_lib_path; string ucrt_lib_path; string vs_lib_path; string um_include_path; string ucrt_include_path; string vs_include_path; string shared_include_path; bool valid; }; struct v__ast__Table { string parsing_type; Array_v__ast__TypeSymbol_ptr type_symbols; Map_string_int type_idxs; Map_string_v__ast__Fn fns; Map_string_Array_v__ast__Type iface_types; Map_int_string dumps; Array_string imports; Array_string modules; v__ast__Scope* global_scope; Array_v__cflag__CFlag cflags; Array_string redefined_fns; Map_string_Array_Array_v__ast__Type fn_generic_types; Map_int_v__ast__InterfaceDecl interfaces; Map_int_v__ast__SumTypeDecl sumtypes; string cmod_prefix; bool is_fmt; v__ast__UsedFeatures* used_features; int veb_res_idx_cache; int veb_ctx_idx_cache; v__ast__FnPanicHandler panic_handler; voidptr panic_userdata; int panic_npanics; v__ast__FnDecl* cur_fn; v__ast__LambdaExpr* cur_lambda; Array_v__ast__Type cur_concrete_types; int gostmts; Map_string_v__ast__EnumDecl enum_decls; Map_string_bool module_deprecated; Map_string_Array_v__ast__Attr module_attrs; Map_string_bool builtin_pub_fns; int pointer_size; __shared__Map_u64_string* cached_type_to_str; Map_string_int anon_struct_names; int anon_struct_counter; Map_string_int anon_union_names; int anon_union_counter; }; struct v__builder__CcompilerOptions { string guessed_compiler; string shared_postfix; bool debug_mode; v__builder__CC cc; string env_cflags; string env_ldflags; Array_string args; Array_string wargs; Array_string pre_args; Array_string o_args; Array_string source_args; Array_string post_args; Array_string linker_flags; Array_string ldflags; }; struct v__depgraph__DepGraph { bool acyclic; Array_v__depgraph__DepGraphNode nodes; Map_string_i64 values; }; struct v__builder__MsvcStringFlags { Array_string real_libs; Array_string inc_paths; Array_string lib_paths; Array_string defines; Array_string other_flags; }; struct v__gen__c__GenOutput { string header; strings__Builder res_builder; string out_str; string out0_str; string extern_str; Array_int out_fn_start_pos; }; struct strings__textscanner__TextScanner { string input; int ilen; int pos; }; struct time__TimeParseError { Error Error; int code; string message; }; struct time__StopWatchOptions { bool auto_start; }; struct rand__config__NormalConfigStruct { f64 mu; f64 sigma; }; struct rand__config__ShuffleConfigStruct { int start; int end; }; struct rand__config__PRNGConfigStruct { Array_u32 seed_; }; struct v__token__TrieNode { Array_fixed_v__token__TrieNode_ptr1_123 children; int value; }; struct v__token__KeywordsMatcherTrie { Array_v__token__TrieNode_ptr nodes; int min_len; int max_len; }; struct v__token__Token { v__token__Kind kind; string lit; int line_nr; int col; int pos; int len; int tidx; }; struct sync__Semaphore { sem_t sem; }; struct sync__Mutex { pthread_mutex_t mutex; }; struct sync__RwMutex { pthread_rwlock_t mutex; }; struct sync__RwMutexAttr { pthread_rwlockattr_t attr; }; struct os__filelock__FileLock { string name; i64 fd; }; struct v__vmod__ModFileCacher { Map_string_v__vmod__ModFileAndFolder cache; Map_string_Array_string folder_files; int hits; int misses; int get_files_hits; int get_files_misses; }; struct v__ast__CTempVar { string name; v__ast__Type typ; bool is_ptr; v__ast__Expr orig; bool is_fixed_ret; }; struct v__ast__IfGuardExpr { Array_v__ast__IfGuardVar vars; v__ast__Expr expr; v__ast__Type expr_type; }; struct v__ast__EmptyScopeObject { string name; v__ast__Type typ; }; struct v__ast__AsmRegister { string name; v__ast__Type typ; int size; }; struct v__ast__Scope { Map_string_v__ast__ScopeObject objects; Map_string_v__ast__ScopeStructField struct_fields; v__ast__Scope* parent; bool detached_from_parent; Array_v__ast__Scope_ptr children; int start_pos; int end_pos; }; struct v__ast__FnTrace { string name; string file; i64 line; v__ast__Type return_type; v__ast__Fn* func; bool is_fn_var; }; struct v__ast__EmbeddedFile { string compression_type; string rpath; string apath; bool is_compressed; Array_u8 bytes; int len; }; struct v__ast__IdentFn { v__ast__Type typ; }; struct v__ast__IdentVar { v__ast__Type typ; bool is_mut; bool is_static; bool is_volatile; bool is_option; v__ast__ShareType share; }; struct v__ast__Array { int nr_dims; v__ast__Type elem_type; }; struct v__ast__Map { v__ast__Type key_type; v__ast__Type value_type; }; struct v__ast__Struct { Array_v__ast__Attr attrs; string scoped_name; Array_v__ast__Type embeds; Array_v__ast__StructField fields; bool is_typedef; bool is_union; bool is_heap; bool is_minify; bool is_anon; bool is_generic; bool is_shared; bool is_markused; bool has_option; Array_v__ast__Type generic_types; Array_v__ast__Type concrete_types; v__ast__Type parent_type; }; struct v__ast__StringifyModReplacement { string mod; string alias; int weight; }; struct v__ast__UsedFeatures { bool dump; bool index; bool range_index; bool cast_ptr; bool anon_fn; bool auto_str; bool auto_str_ptr; bool arr_prepend; bool arr_insert; bool arr_first; bool arr_last; bool arr_pop; bool arr_delete; bool arr_reverse; bool arr_map; bool type_name; bool print_options; Map_int_bool print_types; Map_string_bool used_fns; Map_string_bool used_consts; Map_string_bool used_globals; Map_int_bool used_syms; Array_v__ast__Type used_veb_types; int used_maps; int used_none; Map_string_bool comptime_calls; Map_v__ast__Type_bool comptime_syms; }; struct v__ast__TypeSymbol { int parent_idx; v__ast__TypeInfo info; v__ast__Kind kind; string name; string cname; string rname; Array_v__ast__Fn methods; Array_v__ast__Type generic_types; string mod; bool is_pub; bool is_builtin; v__ast__Language language; int idx; int size; int align; }; struct v__ast__Aggregate { Array_v__ast__StructField fields; v__ast__Type sum_type; Array_v__ast__Type types; }; struct v__ast__GetEmbedsOptions { Array_v__ast__Type preceding; }; struct v__ast__Alias { v__ast__Type parent_type; v__ast__Language language; bool is_import; }; struct v__ast__Interface { Array_v__ast__Type types; Array_v__ast__StructField fields; Array_v__ast__Fn methods; Array_v__ast__Type embeds; __shared__Map_int_Array_v__ast__Type* conversions; bool is_generic; bool is_markused; Array_v__ast__Type generic_types; Array_v__ast__Type concrete_types; v__ast__Type parent_type; }; struct v__ast__SumType { Array_v__ast__StructField fields; bool found_fields; bool is_anon; bool is_generic; Array_v__ast__Type variants; Array_v__ast__Type generic_types; Array_v__ast__Type concrete_types; v__ast__Type parent_type; }; struct v__ast__Enum { Array_string vals; bool is_flag; bool is_multi_allowed; bool uses_exprs; v__ast__Type typ; Map_string_Array_v__ast__Attr attrs; }; struct v__ast__ArrayFixed { int size; v__ast__Expr size_expr; v__ast__Type elem_type; bool is_fn_ret; }; struct v__ast__Chan { v__ast__Type elem_type; bool is_mut; }; struct v__ast__Thread { v__ast__Type return_type; }; struct v__ast__MultiReturn { Array_v__ast__Type types; }; struct v__ast__GenericInst { int parent_idx; Array_v__ast__Type concrete_types; }; struct v__ast__FnSignatureOpts { bool skip_receiver; bool type_only; }; struct v__transformer__KeyVal { string key; int value; }; struct v__transformer__IndexState { Map_string_int max_index; Array_bool saved_disabled; Array_Array_v__transformer__KeyVal saved_key_vals; bool disabled; int level; }; struct v__scanner__Scanner { string file_path; string file_base; string text; int pos; int line_nr; int last_nl_pos; bool is_crlf; bool is_inside_string; bool is_nested_string; bool is_inter_start; bool is_inter_end; bool is_enclosed_inter; bool is_nested_enclosed_inter; int string_count; Array_bool str_dollar_needs_rcbr; string line_comment; int last_lt; bool is_print_line_on_error; bool is_print_colored_error; bool is_print_rel_paths_on_error; u8 quote; u8 inter_quote; bool just_closed_inter; int nr_lines; bool is_vh; bool is_fmt; v__scanner__CommentsMode comments_mode; bool is_inside_toplvl_statement; Array_v__token__Token all_tokens; int tidx; int eofs; int max_eofs; int inter_cbr_count; v__pref__Preferences* pref; Array_string error_details; Array_v__errors__Error errors; Array_v__errors__Warning warnings; Array_v__errors__Notice notices; bool should_abort; Array_int all_pos; Array_int u16_escapes_pos; Array_int u32_escapes_pos; Array_int h_escapes_pos; Array_string str_segments; }; struct v__parser__EatCommentsConfig { bool same_line; bool follow_up; }; struct v__parser__DependencyCache { Map_string_Array_string dependencies; Map_string_Array_string cache; }; struct v__parser__IncludeError { Error Error; string calling_file; int line_nr; int position; int col; string message; }; struct v__markused__Walker { v__ast__Table* table; v__ast__UsedFeatures* features; Map_string_bool used_fns; bool trace_enabled; Map_string_bool used_consts; Map_string_bool used_globals; Map_string_bool used_fields; Map_int_bool used_syms; int used_none; int used_option; int used_result; int used_panic; v__pref__Preferences* pref; Map_string_v__ast__FnDecl all_fns; Map_string_v__ast__ConstField all_consts; Map_string_v__ast__GlobalField all_globals; Map_string_v__ast__StructField all_fields; Map_string_v__ast__TypeDecl all_decltypes; Map_string_v__ast__StructDecl all_structs; int level; bool is_builtin_mod; bool uses_atomic; bool uses_array; bool uses_channel; bool uses_lock; bool uses_ct_fields; bool uses_ct_methods; bool uses_ct_params; bool uses_ct_values; bool uses_ct_variants; bool uses_ct_attribute; bool uses_external_type; bool uses_err; bool uses_asserts; bool uses_map_update; bool uses_debugger; bool uses_mem_align; bool uses_eq; bool uses_interp; bool uses_guard; bool uses_orm; Map_v__ast__Type_bool uses_str; Map_v__ast__Type_bool uses_free; bool uses_spawn; bool uses_dump; bool uses_memdup; bool uses_arr_void; }; struct v__depgraph__DepGraphNode { string name; i64 value; Array_string deps; }; struct v__depgraph__OrderedDepMap { Array_string keys; Map_string_Array_string data; }; struct v__depgraph__NodeNames { Map_string_bool is_cycle; Map_string_Array_string names; }; struct v__dotgraph__DotGraph { strings__Builder sb; }; struct v__dotgraph__NewNodeConfig { string node_name; bool should_highlight; string tooltip; voidptr ctx; v__dotgraph__FnLabel2NodeName name2node_fn; }; struct v__dotgraph__NewEdgeConfig { bool should_highlight; voidptr ctx; v__dotgraph__FnLabel2NodeName name2node_fn; }; struct v__gen__c__Type { v__ast__Type typ; v__ast__TypeSymbol* sym; v__ast__Type unaliased; v__ast__TypeSymbol* unaliased_sym; }; struct v__gen__c__StrType { string styp; v__ast__Type typ; }; struct v__gen__c__GlobalConstDef { string mod; string def; string init; Array_string dep_names; int order; bool is_precomputed; }; struct v__gen__c__VSafeArithmeticOp { v__ast__Type typ; v__token__Kind op; }; struct v__gen__c__CoverageInfo { int idx; Array_u64 points; v__ast__File* file; string fhash; string build_options; }; struct v__gen__c__SumtypeCastingFn { string fn_name; v__ast__Type got; v__ast__Type exp; }; struct v__gen__c__GenSafeIntegerCfg { v__token__Kind op; bool reverse; v__ast__Type unsigned_type; v__ast__Expr unsigned_expr; v__ast__Type signed_type; v__ast__Expr signed_expr; }; struct v__gen__c__PastTmpVar { string var_name; string tmp_var; string s; bool s_ends_with_ln; }; struct sync__pool__PoolProcessorConfig { int maxjobs; sync__pool__ThreadCB callback; }; struct rand__buffer__PRNGBuffer { int bytes_left; u64 buffer; }; struct v__pkgconfig__MainOptions { bool modversion; bool description; bool help; bool debug; bool listall; bool exists; bool variables; bool __v_requires; string atleast; string atleastpc; string exactversion; bool version; bool cflags; bool cflags_only_path; bool cflags_only_other; bool stat1c; bool libs; bool libs_only_link; bool libs_only_path; bool libs_only_other; Array_string args; }; struct v__pkgconfig__Main { v__pkgconfig__MainOptions* opt; string res; bool has_actions; }; struct v__pkgconfig__Options { string path; bool debug; bool norecurse; bool only_description; bool use_default_paths; }; struct flag__FlagParser { Array_string original_args; int idx_dashdash; Array_string all_after_dashdash; Array_string usage_examples; string default_help_label; string default_version_label; Array_string args; int max_free_args; Array_flag__Flag flags; string application_name; string application_version; string application_description; int min_free_args; string args_description; bool allow_unknown_args; Array_string footers; }; struct encoding__utf8__validate__Utf8State { int index; int subindex; bool failed; }; struct v__ast__walker__Inspector { v__ast__walker__InspectorFn inspector_callback; voidptr data; }; struct flag__Flag { string name; u8 abbr; string usage; string val_desc; }; struct flag__ArgsCountError { Error Error; int got; int want; }; struct semver__Version { int major; int minor; int patch; string prerelease; string metadata; }; struct semver__RawVersion { string prerelease; string metadata; Array_string raw_ints; }; struct mapnode { voidptr* children; int len; Array_fixed_string_11 keys; Array_fixed_voidptr_11 values; }; struct StrIntpData { string str; u32 fmt; StrIntpMem d; }; struct v__pref__Preferences { v__pref__OS os; v__pref__Backend backend; bool backend_set_by_flag; v__pref__BuildMode build_mode; v__pref__Arch arch; v__pref__OutputMode output_mode; bool is_verbose; bool is_glibc; bool is_musl; bool is_test; bool is_script; bool is_vsh; string raw_vsh_tmp_prefix; bool is_livemain; bool is_liveshared; bool is_shared; bool is_o; bool is_prof; bool is_prod; bool no_prod_options; bool is_repl; bool is_eval_argument; bool is_run; bool is_crun; bool is_debug; bool is_vlines; bool is_stats; bool show_asserts; bool show_timings; bool is_fmt; bool is_vet; bool is_vweb; bool is_ios_simulator; bool is_apk; bool is_help; bool is_quiet; bool is_cstrict; bool is_callstack; bool is_trace; bool is_coverage; bool is_check_return; string eval_argument; string test_runner; string profile_file; string coverage_dir; bool profile_no_inline; Array_string profile_fns; bool translated; bool translated_go; bool obfuscate_removed; bool hide_auto_str; bool sanitize; bool sourcemap; bool sourcemap_inline; bool sourcemap_src_included; bool show_cc; bool show_c_output; bool show_callgraph; bool show_depgraph; bool show_unused_params; string dump_c_flags; string dump_modules; string dump_files; string dump_defines; bool use_cache; bool retry_compilation; bool use_os_system_to_run; string macosx_version_min; string cflags; string ldflags; bool m64; string ccompiler; v__pref__CompilerType ccompiler_type; string cppcompiler; string third_party_option; bool building_v; bool no_bounds_checking; bool force_bounds_checking; bool autofree; bool print_autofree_vars; string print_autofree_vars_in_fn; bool trace_calls; Array_string trace_fns; bool compress; bool no_builtin; bool enable_globals; bool is_bare; string bare_builtin_dir; bool no_preludes; string custom_prelude; string cmain; Array_string lookup_path; bool output_cross_c; bool output_es5; bool prealloc; string vroot; string vlib; Array_string vmodules_paths; string out_name_c; string out_name; string path; string line_info; v__pref__LineInfo linfo; Array_string run_only; Array_string exclude; Array_string compile_defines; Array_string compile_defines_all; Map_string_string compile_values; Array_string run_args; Array_string printfn_list; bool print_v_files; bool print_watched_files; bool skip_running; bool skip_warnings; bool skip_notes; bool warn_impure_v; bool warns_are_errors; bool notes_are_errors; bool fatal_errors; bool reuse_tmpc; bool no_rsp; bool no_std; bool no_parallel; bool parallel_cc; bool only_check_syntax; bool check_only; bool experimental; bool skip_unused; v__pref__ColorOutput use_color; Array_string cleanup_files; Array_string build_options; v__vcache__CacheManager cache_manager; v__pref__GarbageCollectionMode gc_mode; v__pref__AssertFailureMode assert_failure_mode; int message_limit; bool nofloat; bool use_coroutines; bool fast_math; int checker_match_exhaustive_cutoff_limit; int thread_stack_size; int wasm_stack_top; bool wasm_validate; bool warn_about_allocs; bool div_by_zero_is_zero; bool relaxed_gcc14; v__pref__Subsystem subsystem; bool is_vls; }; struct builtin__closure__Closure { builtin__closure__ClosureMutex ClosureMutex; voidptr closure_ptr; anon_fn___voidptr closure_get_data; int closure_cap; int v_page_size; }; struct os__Process { string filename; int pid; int code; os__ProcessState status; string err; Array_string args; string work_folder; bool env_is_custom; Array_string env; bool use_stdio_ctl; bool use_pgroup; Array_fixed_int_3 stdio_fd; voidptr wdata; bool create_no_window; }; struct v__errors__CompilerMessage { string message; string details; string file_path; v__token__Pos pos; v__errors__Reporter reporter; }; struct v__builder__Builder { string compiled_dir; string module_path; v__checker__Checker* checker; v__transformer__Transformer* transformer; string out_name_c; string out_name_js; int stats_lines; int stats_bytes; int nr_errors; int nr_warnings; int nr_notices; v__pref__Preferences* pref; Array_string module_search_paths; Array_v__ast__File_ptr parsed_files; v__builder__MsvcResult cached_msvc; v__ast__Table* table; v__builder__CcompilerOptions ccoptions; Map_string_Array_string mod_invalidates_paths; Map_string_Array_string mod_invalidates_mods; Map_string_Array_string path_invalidates_mods; Array_string crun_cache_keys; bool executable_exists; string str_args; }; struct rand__wyrand__WyRandRNG { rand__buffer__PRNGBuffer PRNGBuffer; u64 state; int bytes_left; u64 buffer; }; struct sync__SpinLock { u8 locked; Array_fixed_u8_63 padding; }; struct sync__Channel { u8* ringbuf; u8* statusbuf; u32 objsize; sync__Semaphore writesem; sync__Semaphore readsem; sync__Semaphore writesem_im; sync__Semaphore readsem_im; atomic_uintptr_t write_adr; atomic_uintptr_t read_adr; atomic_uintptr_t adr_read; atomic_uintptr_t adr_written; u32 write_free; u32 read_avail; u32 buf_elem_write_idx; u32 buf_elem_read_idx; sync__Subscription* write_subscriber; sync__Subscription* read_subscriber; sync__SpinLock* write_sub_mtx; sync__SpinLock* read_sub_mtx; u16 closed; u32 cap; }; struct sync__WaitGroup { u32 task_count; u32 wait_count; sync__Semaphore sem; }; struct v__ast__AliasTypeDecl { string name; bool is_pub; v__ast__Type typ; v__token__Pos pos; v__token__Pos type_pos; Array_v__ast__Comment comments; Array_v__ast__Attr attrs; v__ast__Type parent_type; bool is_markused; }; struct v__ast__FnTypeDecl { string name; bool is_pub; v__ast__Type typ; v__token__Pos pos; v__token__Pos type_pos; Array_v__ast__Comment comments; Array_v__ast__Type generic_types; Array_v__ast__Attr attrs; bool is_markused; }; struct v__ast__SumTypeDecl { string name; bool is_pub; v__token__Pos pos; v__token__Pos name_pos; v__ast__Type typ; Array_v__ast__Type generic_types; Array_v__ast__Attr attrs; Array_v__ast__TypeNode variants; bool is_markused; }; struct v__ast__NodeError { int idx; v__token__Pos pos; }; struct v__ast__ArrayDecompose { v__token__Pos pos; v__ast__Expr expr; v__ast__Type expr_type; v__ast__Type arg_type; }; struct v__ast__ArrayInit { v__token__Pos pos; v__token__Pos elem_type_pos; Array_Array_v__ast__Comment ecmnts; Array_v__ast__Comment pre_cmnts; bool is_fixed; bool is_option; bool has_val; string mod; bool has_len; bool has_cap; bool has_init; bool has_index; Array_v__ast__Expr exprs; v__ast__Expr len_expr; v__ast__Expr cap_expr; v__ast__Expr init_expr; Array_v__ast__Type expr_types; v__ast__Type elem_type; v__ast__Type init_type; v__ast__Type typ; v__ast__Type alias_type; bool has_callexpr; }; struct v__ast__AsCast { v__ast__Type typ; v__token__Pos pos; v__ast__Expr expr; v__ast__Type expr_type; }; struct v__ast__Assoc { string var_name; Array_string fields; v__token__Pos pos; Array_v__ast__Expr exprs; v__ast__Type typ; v__ast__Scope* scope; }; struct v__ast__AtExpr { string name; v__token__Pos pos; v__token__AtKind kind; string val; }; struct v__ast__BoolLiteral { bool val; v__token__Pos pos; }; struct v__ast__CastExpr { v__ast__Expr arg; v__ast__Type typ; v__ast__Expr expr; string typname; v__ast__Type expr_type; bool has_arg; v__token__Pos pos; }; struct v__ast__ChanInit { v__token__Pos pos; v__token__Pos elem_type_pos; bool has_cap; v__ast__Expr cap_expr; v__ast__Type typ; v__ast__Type elem_type; }; struct v__ast__CharLiteral { string val; v__token__Pos pos; }; struct v__ast__Comment { string text; bool is_multi; v__token__Pos pos; }; struct v__ast__ComptimeType { v__ast__ComptimeTypeKind kind; v__token__Pos pos; }; struct v__ast__ConcatExpr { Array_v__ast__Expr vals; v__token__Pos pos; v__ast__Type return_type; }; struct v__ast__DumpExpr { v__token__Pos pos; v__ast__Expr expr; v__ast__Type expr_type; string cname; }; struct v__ast__EnumVal { string enum_name; string val; string mod; v__token__Pos pos; v__ast__Type typ; }; struct v__ast__FloatLiteral { string val; v__token__Pos pos; }; struct v__ast__IfExpr { bool is_comptime; v__token__Kind tok_kind; v__token__Pos pos; Array_v__ast__Comment post_comments; v__ast__Expr left; Array_v__ast__IfBranch branches; bool is_expr; v__ast__Type typ; bool has_else; }; struct v__ast__IntegerLiteral { string val; v__token__Pos pos; }; struct v__ast__IsRefType { bool guessed_type; bool is_type; v__token__Pos pos; v__ast__Expr expr; v__ast__Type typ; }; struct v__ast__LambdaExpr { v__token__Pos pos; Array_v__ast__Ident params; v__token__Pos pos_expr; v__ast__Expr expr; v__token__Pos pos_end; v__ast__Scope* scope; v__ast__AnonFn* func; bool is_checked; v__ast__Type typ; v__ast__CallExpr* call_ctx; }; struct v__ast__Likely { v__token__Pos pos; bool is_likely; v__ast__Expr expr; }; struct v__ast__LockExpr { Array_bool is_rlock; v__token__Pos pos; Array_v__ast__Stmt stmts; Array_v__ast__Expr lockeds; Array_v__ast__Comment comments; bool is_expr; v__ast__Type typ; v__ast__Scope* scope; }; struct v__ast__MapInit { v__token__Pos pos; Array_Array_v__ast__Comment comments; Array_v__ast__Comment pre_cmnts; Array_v__ast__Expr keys; Array_v__ast__Expr vals; Array_v__ast__Type val_types; v__ast__Type typ; v__ast__Type key_type; v__ast__Type value_type; bool has_update_expr; v__ast__Expr update_expr; v__token__Pos update_expr_pos; Array_v__ast__Comment update_expr_comments; }; struct v__ast__MatchExpr { v__token__Kind tok_kind; v__token__Pos pos; Array_v__ast__Comment comments; v__ast__Expr cond; Array_v__ast__MatchBranch branches; bool is_expr; v__ast__Type return_type; v__ast__Type cond_type; v__ast__Type expected_type; bool is_sum_type; }; struct v__ast__Nil { v__token__Pos pos; }; struct v__ast__None { v__token__Pos pos; }; struct v__ast__OffsetOf { v__ast__Type struct_type; string field; v__token__Pos pos; }; struct v__ast__OrExpr { v__ast__OrKind kind; v__token__Pos pos; Array_v__ast__Stmt stmts; }; struct v__ast__ParExpr { v__token__Pos pos; v__ast__Expr expr; Array_v__ast__Comment comments; }; struct v__ast__PostfixExpr { v__token__Kind op; v__token__Pos pos; bool is_c2v_prefix; v__ast__Expr expr; v__ast__Type typ; string auto_locked; }; struct v__ast__RangeExpr { bool has_high; bool has_low; v__token__Pos pos; bool is_gated; v__ast__Expr low; v__ast__Expr high; v__ast__Type typ; }; struct v__ast__SelectExpr { Array_v__ast__SelectBranch branches; v__token__Pos pos; bool has_exception; bool is_expr; v__ast__Type expected_type; }; struct v__ast__SizeOf { bool guessed_type; bool is_type; v__token__Pos pos; v__ast__Expr expr; v__ast__Type typ; }; struct v__ast__StringInterLiteral { Array_string vals; Array_int fwidths; Array_int precisions; Array_bool pluss; Array_bool fills; Array_v__token__Pos fmt_poss; v__token__Pos pos; Array_v__ast__Expr exprs; Array_v__ast__Type expr_types; Array_u8 fmts; Array_bool need_fmts; }; struct v__ast__StringLiteral { string val; bool is_raw; v__ast__Language language; v__token__Pos pos; }; struct v__ast__StructInit { v__token__Pos pos; v__token__Pos name_pos; bool no_keys; bool is_short_syntax; bool is_anon; bool unresolved; Array_v__ast__Comment pre_comments; string typ_str; v__ast__Type typ; v__ast__Expr update_expr; v__ast__Type update_expr_type; v__token__Pos update_expr_pos; Array_v__ast__Comment update_expr_comments; bool is_update_embed; bool has_update_expr; Array_v__ast__StructInitField init_fields; Array_v__ast__Type generic_types; v__ast__Language language; }; struct v__ast__TypeNode { v__token__Pos pos; v__ast__Type typ; v__ast__Stmt stmt; Array_v__ast__Comment end_comments; }; struct v__ast__TypeOf { bool is_type; v__token__Pos pos; v__ast__Expr expr; v__ast__Type typ; }; struct v__ast__UnsafeExpr { v__token__Pos pos; v__ast__Expr expr; }; struct v__ast__AsmStmt { v__pref__Arch arch; bool is_basic; bool is_volatile; bool is_goto; Array_v__ast__AsmClobbered clobbered; v__token__Pos pos; Array_v__ast__AsmTemplate templates; v__ast__Scope* scope; Array_v__ast__AsmIO output; Array_v__ast__AsmIO input; Array_string global_labels; Array_string local_labels; }; struct v__ast__AssertStmt { v__token__Pos pos; v__token__Pos extra_pos; v__ast__Expr expr; v__ast__Expr extra; bool is_used; }; struct v__ast__Block { bool is_unsafe; v__token__Pos pos; Array_v__ast__Stmt stmts; }; struct v__ast__BranchStmt { v__token__Kind kind; string label; v__token__Pos pos; }; struct v__ast__ComptimeFor { string val_var; v__ast__ComptimeForKind kind; v__token__Pos pos; v__token__Pos typ_pos; Array_v__ast__Stmt stmts; v__ast__Type typ; v__ast__Expr expr; }; struct v__ast__ConstDecl { bool is_pub; v__token__Pos pos; Array_v__ast__Attr attrs; Array_v__ast__ConstField fields; Array_v__ast__Comment end_comments; bool is_block; }; struct v__ast__DebuggerStmt { v__token__Pos pos; }; struct v__ast__DeferStmt { v__token__Pos pos; Array_v__ast__Stmt stmts; Array_v__ast__Ident defer_vars; string ifdef; int idx_in_fn; }; struct v__ast__EmptyStmt { v__token__Pos pos; }; struct v__ast__EnumDecl { string name; bool is_pub; bool is_flag; bool is_multi_allowed; Array_v__ast__Comment comments; Array_v__ast__EnumField fields; Array_v__ast__Attr attrs; v__ast__Type typ; v__token__Pos typ_pos; v__token__Pos pos; }; struct v__ast__ExprStmt { v__token__Pos pos; Array_v__ast__Comment comments; v__ast__Expr expr; bool is_expr; v__ast__Type typ; }; struct v__ast__ForCStmt { bool has_init; bool has_cond; bool has_inc; bool is_multi; v__token__Pos pos; Array_v__ast__Comment comments; v__ast__Stmt init; v__ast__Expr cond; v__ast__Stmt inc; Array_v__ast__Stmt stmts; string label; v__ast__Scope* scope; }; struct v__ast__ForInStmt { string key_var; string val_var; bool is_range; v__token__Pos pos; v__token__Pos kv_pos; v__token__Pos vv_pos; Array_v__ast__Comment comments; bool val_is_mut; bool val_is_ref; v__ast__Expr cond; v__ast__Type key_type; v__ast__Type val_type; v__ast__Type cond_type; v__ast__Expr high; v__ast__Type high_type; v__ast__Kind kind; string label; v__ast__Scope* scope; Array_v__ast__Stmt stmts; }; struct v__ast__ForStmt { bool is_inf; v__token__Pos pos; Array_v__ast__Comment comments; v__ast__Expr cond; Array_v__ast__Stmt stmts; string label; v__ast__Scope* scope; }; struct v__ast__GlobalDecl { string mod; v__token__Pos pos; bool is_block; Array_v__ast__Attr attrs; Array_v__ast__GlobalField fields; Array_v__ast__Comment end_comments; }; struct v__ast__GotoLabel { string name; v__token__Pos pos; bool is_used; }; struct v__ast__GotoStmt { string name; v__token__Pos pos; }; struct v__ast__HashStmt { string mod; v__token__Pos pos; string source_file; bool is_use_once; string val; string kind; string main; string msg; Array_v__ast__Expr ct_conds; Array_v__ast__Attr attrs; }; struct v__ast__Import { string source_name; string mod; string alias; v__token__Pos pos; v__token__Pos mod_pos; v__token__Pos alias_pos; v__token__Pos syms_pos; Array_v__ast__ImportSymbol syms; Array_v__ast__Comment comments; Array_v__ast__Comment next_comments; }; struct v__ast__InterfaceDecl { string name; v__ast__Type typ; v__token__Pos name_pos; v__ast__Language language; Array_string field_names; bool is_pub; int mut_pos; v__token__Pos pos; Array_v__ast__Comment pre_comments; Array_v__ast__Type generic_types; Array_v__ast__Attr attrs; Array_v__ast__FnDecl methods; Array_v__ast__StructField fields; Array_v__ast__InterfaceEmbedding embeds; bool are_embeds_expanded; }; struct v__ast__Module { string name; string short_name; Array_v__ast__Attr attrs; v__token__Pos pos; v__token__Pos name_pos; bool is_skipped; }; struct v__ast__Return { v__token__Pos pos; Array_v__ast__Comment comments; Array_v__ast__Expr exprs; Array_v__ast__Type types; }; struct v__ast__SemicolonStmt { v__token__Pos pos; }; struct v__ast__StructDecl { v__token__Pos pos; string name; string scoped_name; Array_v__ast__Type generic_types; bool is_pub; int mut_pos; int pub_pos; int pub_mut_pos; int global_pos; int module_pos; bool is_union; bool is_option; Array_v__ast__Attr attrs; Array_v__ast__Comment pre_comments; Array_v__ast__Comment end_comments; Array_v__ast__Embed embeds; bool is_implements; Array_v__ast__TypeNode implements_types; v__ast__Language language; Array_v__ast__StructField fields; int idx; }; struct v__ast__ConstField { string mod; string name; bool is_pub; bool is_markused; v__token__Pos pos; Array_v__ast__Attr attrs; bool is_virtual_c; v__ast__Expr expr; v__ast__Type typ; Array_v__ast__Comment comments; Array_v__ast__Comment end_comments; v__ast__ComptTimeConstValue comptime_expr_value; }; struct v__ast__GlobalField { string name; bool has_expr; v__token__Pos pos; v__token__Pos typ_pos; bool is_markused; bool is_volatile; bool is_exported; v__ast__Expr expr; v__ast__Type typ; Array_v__ast__Comment comments; }; struct v__ast__Var { string name; v__ast__ShareType share; bool is_mut; bool is_static; bool is_volatile; bool is_autofree_tmp; bool is_inherited; bool has_inherited; bool is_arg; bool is_auto_deref; bool is_unwrapped; bool is_index_var; v__ast__Expr expr; v__ast__Type typ; v__ast__Type orig_type; Array_v__ast__Type smartcasts; v__token__Pos pos; bool is_used; bool is_changed; v__ast__ComptimeVarKind ct_type_var; bool ct_type_unwrapped; bool is_or; bool is_tmp; bool is_auto_heap; bool is_stack_obj; }; struct v__ast__CallArg { bool is_mut; v__ast__ShareType share; Array_v__ast__Comment comments; v__ast__Expr expr; v__ast__Type typ; bool is_tmp_autofree; v__token__Pos pos; bool should_be_ptr; bool ct_expr; }; struct v__ast__EmptyNode { v__token__Pos pos; }; struct v__ast__EnumField { string name; string source_name; v__token__Pos pos; Array_v__ast__Comment pre_comments; Array_v__ast__Comment comments; Array_v__ast__Comment next_comments; bool has_expr; bool has_prev_newline; bool has_break_line; Array_v__ast__Attr attrs; v__ast__Expr expr; }; struct v__ast__IfBranch { v__token__Pos pos; v__token__Pos body_pos; Array_v__ast__Comment comments; v__ast__Expr cond; bool pkg_exist; Array_v__ast__Stmt stmts; v__ast__Scope* scope; }; struct v__ast__MatchBranch { Array_Array_v__ast__Comment ecmnts; v__token__Pos pos; bool is_else; Array_v__ast__Comment post_comments; v__token__Pos branch_pos; Array_v__ast__Stmt stmts; Array_v__ast__Expr exprs; v__ast__Scope* scope; }; struct v__ast__Param { v__token__Pos pos; string name; bool is_mut; bool is_shared; bool is_atomic; v__token__Pos type_pos; bool is_hidden; bool on_newline; v__ast__Type typ; }; struct v__ast__StructInitField { v__token__Pos pos; v__token__Pos name_pos; Array_v__ast__Comment pre_comments; Array_v__ast__Comment end_comments; Array_v__ast__Comment next_comments; bool has_prev_newline; bool has_break_line; bool is_embed; v__ast__Expr expr; string name; v__ast__Type typ; v__ast__Type expected_type; v__ast__Type parent_type; }; struct v__ast__Attr { string name; bool has_arg; string arg; v__ast__AttrKind kind; bool ct_opt; v__token__Pos pos; bool has_at; v__ast__Expr ct_expr; bool ct_evaled; bool ct_skip; }; struct v__ast__Embed { v__ast__Type typ; v__token__Pos pos; Array_v__ast__Comment comments; }; struct v__ast__InterfaceEmbedding { string name; v__ast__Type typ; v__token__Pos pos; Array_v__ast__Comment comments; }; struct v__ast__ImportSymbol { v__token__Pos pos; string name; }; struct v__ast__Fn { bool is_variadic; bool is_c_variadic; v__ast__Language language; bool is_pub; bool is_ctor_new; bool is_deprecated; bool is_noreturn; bool is_unsafe; bool is_must_use; bool is_placeholder; bool is_main; bool is_test; bool is_keep_alive; bool is_method; bool is_static_type_method; bool no_body; bool is_file_translated; string mod; string file; v__ast__Language file_mode; v__token__Pos pos; v__token__Pos name_pos; v__token__Pos return_type_pos; v__ast__Type return_type; v__ast__Type receiver_type; string name; Array_v__ast__Param params; voidptr source_fn; int usages; Array_string generic_names; Array_string dep_names; Array_v__ast__Attr attrs; bool is_conditional; int ctdefine_idx; v__ast__Type from_embedded_type; bool is_expand_simple_interpolation; }; struct v__ast__ScopeStructField { v__ast__Type struct_type; string name; v__token__Pos pos; v__ast__Type typ; v__ast__Type orig_type; Array_v__ast__Type smartcasts; }; struct v__ast__AsmClobbered { v__ast__AsmRegister reg; Array_v__ast__Comment comments; }; struct v__ast__AsmTemplate { string name; bool is_label; bool is_directive; Array_v__ast__AsmArg args; Array_v__ast__Comment comments; v__token__Pos pos; }; struct v__ast__AsmIO { string alias; string constraint; Array_v__ast__Comment comments; v__ast__Type typ; v__token__Pos pos; v__ast__Expr expr; }; struct v__ast__AsmAddressing { int scale; v__ast__AddressingMode mode; v__token__Pos pos; string segment; v__ast__AsmArg displacement; v__ast__AsmArg base; v__ast__AsmArg index; }; struct v__ast__AsmAlias { v__token__Pos pos; string name; }; struct v__ast__AsmDisp { string val; v__token__Pos pos; }; struct v__ast__IfGuardVar { string name; bool is_mut; v__token__Pos pos; }; struct v__checker__HaveWantParams { int nr_params; int nr_args; Array_v__ast__CallArg args; Array_v__ast__Param params; v__token__Pos pos; }; struct v__parser__ReceiverParsingInfo { string name; v__token__Pos pos; v__ast__Type typ; v__token__Pos type_pos; bool is_mut; v__ast__Language language; }; struct v__callgraph__Mapper { int pos; v__pref__Preferences* pref; v__ast__Table* table; v__ast__File* file; v__ast__Node* node; v__ast__FnDecl* fn_decl; string caller_name; string dot_caller_name; bool is_caller_used; v__dotgraph__DotGraph dg; }; struct v__pkgconfig__PkgConfig { string file_path; v__pkgconfig__Options options; string name; string modname; string url; string version; string description; Array_string libs; Array_string libs_private; Array_string cflags; Array_string paths; Map_string_string vars; Array_string __v_requires; Array_string requires_private; Array_string conflicts; Array_string loaded; }; struct semver__InvalidComparatorFormatError { MessageError MessageError; }; struct v__ast__File { int nr_lines; int nr_bytes; int nr_tokens; v__ast__Module mod; v__ast__Scope* global_scope; bool is_test; bool is_generated; bool is_translated; v__ast__Language language; int idx; string path; string path_base; v__ast__Scope* scope; Array_v__ast__Stmt stmts; Array_v__ast__Import imports; Array_string auto_imports; Array_v__ast__EmbeddedFile embedded_files; Map_string_string imported_symbols; Array_v__errors__Error errors; Array_v__errors__Warning warnings; Array_v__errors__Notice notices; Array_v__ast__FnDecl_ptr generic_fns; Array_string global_labels; Array_string template_paths; string unique_prefix; bool is_parse_text; bool is_template_text; }; struct v__errors__Error { v__errors__CompilerMessage CompilerMessage; }; struct sync__pool__PoolProcessor { voidptr thread_cb; int njobs; Array_voidptr items; __shared__Array_voidptr* results; u32 ntask; sync__WaitGroup waitgroup; voidptr shared_context; Array_voidptr thread_contexts; }; struct v__errors__Warning { v__errors__CompilerMessage CompilerMessage; }; struct v__errors__Notice { v__errors__CompilerMessage CompilerMessage; }; struct v__ast__CallExpr { v__token__Pos pos; v__token__Pos name_pos; string mod; string name; bool is_method; bool is_field; bool is_fn_var; bool is_fn_a_const; bool is_keep_alive; bool is_noreturn; bool is_ctor_new; bool is_file_translated; bool is_static_method; Array_v__ast__CallArg args; Array_v__ast__Type expected_arg_types; bool comptime_ret_val; v__ast__Language language; v__ast__OrExpr or_block; v__ast__Expr left; v__ast__Type left_type; v__ast__Type receiver_type; v__ast__Type receiver_concrete_type; v__ast__Type return_type; v__ast__Type return_type_generic; int nr_ret_values; v__ast__Type fn_var_type; string const_name; bool should_be_skipped; Array_v__ast__Type concrete_types; v__token__Pos concrete_list_pos; Array_v__ast__Type raw_concrete_types; bool free_receiver; v__ast__Scope* scope; Array_v__ast__Type from_embed_types; Array_v__ast__Comment comments; bool is_return_used; bool is_expand_simple_interpolation; bool is_unwrapped_fn_selector; }; struct v__ast__ComptimeSelector { bool has_parens; v__token__Pos pos; v__ast__OrExpr or_block; v__ast__Expr left; v__ast__Type left_type; v__ast__Expr field_expr; v__ast__Type typ; bool is_name; string typ_key; }; struct v__ast__Ident { v__ast__Language language; v__token__Kind tok_kind; v__token__Pos pos; v__token__Pos mut_pos; bool comptime; v__ast__Scope* scope; v__ast__ScopeObject obj; string mod; string name; string full_name; string cached_name; v__ast__IdentKind kind; v__ast__IdentInfo info; bool is_mut; v__ast__OrExpr or_expr; Array_v__ast__Type concrete_types; bool ct_expr; }; struct v__ast__IndexExpr { v__token__Pos pos; v__ast__Expr index; v__ast__OrExpr or_expr; v__ast__Expr left; v__ast__Type left_type; bool is_setter; bool is_map; bool is_array; bool is_farray; bool is_option; bool is_direct; bool is_gated; v__ast__Type typ; }; struct v__ast__InfixExpr { v__token__Kind op; v__token__Pos pos; bool is_stmt; v__ast__Expr left; v__ast__Expr right; v__ast__Type left_type; v__ast__Type right_type; v__ast__Type promoted_type; string auto_locked; v__ast__OrExpr or_block; bool ct_left_value_evaled; v__ast__ComptTimeConstValue ct_left_value; bool left_ct_expr; bool ct_right_value_evaled; v__ast__ComptTimeConstValue ct_right_value; bool right_ct_expr; Array_v__ast__Comment before_op_comments; Array_v__ast__Comment after_op_comments; }; struct v__ast__PrefixExpr { v__token__Kind op; v__token__Pos pos; v__ast__Type right_type; v__ast__Expr right; v__ast__OrExpr or_block; bool is_option; }; struct v__ast__SelectorExpr { v__token__Pos pos; string field_name; bool is_mut; v__token__Pos mut_pos; v__token__Kind next_token; v__ast__Expr expr; v__ast__Type expr_type; v__ast__Type typ; v__ast__Type name_type; v__ast__OrExpr or_block; v__ast__GenericKindField gkind_field; v__ast__Scope* scope; Array_v__ast__Type from_embed_types; Array_Array_v__ast__Type generic_from_embed_types; bool has_hidden_receiver; bool is_field_typ; }; struct v__ast__SqlExpr { bool is_count; bool is_insert; string inserted_var; bool has_where; bool has_order; bool has_limit; bool has_offset; bool has_desc; bool is_array; bool is_generated; v__token__Pos pos; v__ast__Type typ; v__ast__Expr db_expr; v__ast__Expr where_expr; v__ast__Expr order_expr; v__ast__Expr limit_expr; v__ast__Expr offset_expr; v__ast__TypeNode table_expr; Array_v__ast__StructField fields; Map_int_v__ast__SqlExpr sub_structs; v__ast__OrExpr or_expr; }; struct v__ast__AssignStmt { v__token__Kind op; v__token__Pos pos; Array_v__ast__Comment end_comments; Array_v__ast__Expr right; Array_v__ast__Expr left; Array_v__ast__Type left_types; Array_v__ast__Type right_types; bool is_static; bool is_volatile; bool is_simple; bool has_cross_var; v__ast__Attr attr; }; struct v__ast__SqlStmt { v__token__Pos pos; Array_v__ast__SqlStmtLine lines; v__ast__Expr db_expr; v__ast__OrExpr or_expr; v__ast__Type db_expr_type; }; struct v__ast__SelectBranch { v__token__Pos pos; v__ast__Comment comment; bool is_else; bool is_timeout; Array_v__ast__Comment post_comments; v__ast__Stmt stmt; Array_v__ast__Stmt stmts; }; struct v__ast__StructField { v__token__Pos pos; v__token__Pos type_pos; v__token__Pos option_pos; Array_v__ast__Comment pre_comments; Array_v__ast__Comment comments; int i; bool has_default_expr; bool has_prev_newline; bool has_break_line; Array_v__ast__Attr attrs; bool is_pub; string default_val; bool is_mut; bool is_global; bool is_volatile; bool is_deprecated; bool is_embed; Array_v__ast__Comment next_comments; bool is_recursive; bool is_part_of_union; v__ast__Type container_typ; v__ast__Expr default_expr; v__ast__Type default_expr_typ; string name; v__ast__Type typ; v__ast__Type unaliased_typ; v__ast__StructDecl anon_struct_decl; }; struct v__ast__SqlStmtLine { v__ast__SqlStmtKind kind; v__token__Pos pos; bool is_generated; v__ast__Scope* scope; string object_var; Array_string updated_columns; v__ast__TypeNode table_expr; Array_v__ast__StructField fields; Map_int_v__ast__SqlStmtLine sub_structs; v__ast__Expr where_expr; Array_v__ast__Expr update_exprs; Array_v__ast__Comment pre_comments; Array_v__ast__Comment end_comments; }; struct v__ast__FnType { bool is_anon; bool has_decl; v__ast__Fn func; }; struct v__parser__Parser { v__pref__Preferences* pref; string file_base; string file_path; string file_display_path; string unique_prefix; v__ast__Language file_backend_mode; v__token__Token tok; v__token__Token prev_tok; v__token__Token peek_tok; v__ast__Language language; v__ast__Language fn_language; int expr_level; bool inside_vlib_file; bool inside_test_file; bool inside_if; bool inside_comptime_if; bool inside_if_expr; bool inside_if_cond; bool inside_ct_if_expr; bool inside_or_expr; bool inside_for; bool inside_for_expr; bool inside_fn; bool inside_fn_return; bool inside_fn_concrete_type; bool inside_call_args; bool inside_unsafe_fn; bool inside_str_interp; bool inside_array_lit; bool inside_in_array; bool inside_infix; bool inside_assign_rhs; bool inside_match; bool inside_select; bool inside_match_case; bool inside_match_body; bool inside_unsafe; bool inside_sum_type; bool inside_asm_template; bool inside_asm; bool inside_defer; bool inside_generic_params; bool inside_receiver_param; bool inside_struct_field_decl; bool inside_struct_attr_decl; bool inside_map_init; bool inside_orm; bool inside_chan_decl; bool inside_attr_decl; int array_dim; int fixed_array_dim; bool or_is_handled; bool builtin_mod; string mod; bool is_manualfree; bool has_globals; bool is_generated; bool is_translated; Array_v__ast__Attr attrs; string expr_mod; string last_enum_name; string last_enum_mod; Map_string_string imports; Array_v__ast__Import ast_imports; Array_string used_imports; Array_string auto_imports; Map_string_string imported_symbols; bool is_amp; bool returns; bool is_stmt_ident; bool expecting_type; bool expecting_value; string cur_fn_name; v__ast__Scope* cur_fn_scope; Array_string label_names; bool name_error; int n_asm; Array_string global_labels; bool comptime_if_cond; Array_v__ast__Ident defer_vars; bool should_abort; string codegen_text; v__ast__StructDecl anon_struct_decl; Array_v__ast__Type init_generic_types; Array_v__ast__Comment if_cond_comments; Array_v__ast__Comment left_comments; bool script_mode; v__token__Token script_mode_start_token; int generic_type_level; bool main_already_defined; bool is_vls; v__scanner__Scanner* scanner; v__ast__Table* table; v__ast__Scope* scope; int opened_scopes; int max_opened_scopes; Array_v__errors__Error errors; Array_v__errors__Warning warnings; Array_v__errors__Notice notices; Array_string template_paths; }; struct v__ast__FnDecl { string name; string short_name; string mod; bool is_deprecated; bool is_pub; bool is_c_variadic; bool is_c_extern; bool is_variadic; bool is_anon; bool is_noreturn; bool is_manualfree; bool is_main; bool is_test; bool is_conditional; bool is_exported; bool is_keep_alive; bool is_unsafe; bool is_must_use; bool is_markused; bool is_file_translated; v__ast__StructField receiver; v__token__Pos receiver_pos; bool is_method; bool is_static_type_method; v__token__Pos static_type_pos; v__token__Pos method_type_pos; int method_idx; bool rec_mut; bool has_prev_newline; bool has_break_line; v__ast__ShareType rec_share; v__ast__Language language; v__ast__Language file_mode; bool no_body; bool is_builtin; v__token__Pos name_pos; v__token__Pos body_pos; string file; Array_string generic_names; bool is_direct_arr; Array_v__ast__Attr attrs; int ctdefine_idx; int idx; Array_v__ast__Param params; Array_v__ast__Stmt stmts; Array_v__ast__DeferStmt defer_stmts; Map_string_v__ast__FnTrace trace_fns; v__ast__Type return_type; v__token__Pos return_type_pos; bool has_return; bool should_be_skipped; int ninstances; bool has_await; Array_v__ast__Comment comments; Array_v__ast__Comment end_comments; Array_v__ast__Comment next_comments; v__ast__File* source_file; v__ast__Scope* scope; Array_string label_names; v__token__Pos pos; v__token__Pos end_pos; bool is_expand_simple_interpolation; }; struct v__ast__ComptimeCall { v__token__Pos pos; bool has_parens; string method_name; v__ast__ComptimeCallKind kind; v__token__Pos method_pos; v__ast__Scope* scope; bool is_vweb; bool is_veb; v__token__Pos env_pos; bool is_d_resolved; v__ast__File veb_tmpl; v__ast__Expr left; v__ast__Type left_type; v__ast__Type result_type; string env_value; string compile_value; string args_var; Array_v__ast__CallArg args; v__ast__EmbeddedFile embed_file; v__ast__OrExpr or_block; }; struct v__ast__GoExpr { v__token__Pos pos; v__ast__CallExpr call_expr; bool is_expr; }; struct v__ast__SpawnExpr { v__token__Pos pos; v__ast__CallExpr call_expr; bool is_expr; }; struct v__type_resolver__ResolverInfo { Map_string_v__ast__Type saved_type_map; int comptime_loop_id; bool inside_comptime_for; bool inside_comptime_if; bool has_different_types; string comptime_for_variant_var; string comptime_for_field_var; v__ast__Type comptime_for_field_type; v__ast__StructField comptime_for_field_value; string comptime_for_enum_var; string comptime_for_attr_var; string comptime_for_method_var; v__ast__Fn* comptime_for_method; v__ast__Type comptime_for_method_ret_type; string comptime_for_method_param_var; }; struct v__builder__FunctionRedefinition { string fpath; int fline; string fheader; v__ast__FnDecl f; }; struct v__ast__AnonFn { v__ast__FnDecl decl; Array_v__ast__Param inherited_vars; v__ast__Type typ; Map_string_bool has_gen; }; struct v__type_resolver__TypeResolver { v__type_resolver__IResolverType resolver; v__ast__Table* table; v__type_resolver__ResolverInfo info; Array_v__type_resolver__ResolverInfo info_stack; Map_string_v__ast__Type type_map; }; struct v__checker__Checker { v__pref__Preferences* pref; v__ast__Table* table; v__ast__File* file; int nr_errors; int nr_warnings; int nr_notices; Array_v__errors__Error errors; Array_v__errors__Warning warnings; Array_v__errors__Notice notices; Map_string_bool error_lines; Map_string_bool warning_lines; Map_string_bool notice_lines; Array_string error_details; bool should_abort; v__ast__Type expected_type; v__ast__Type expected_or_type; v__ast__Type expected_expr_type; string mod; v__ast__ConstField* const_var; Array_string const_deps; Array_string const_names; Array_string global_names; Array_string locked_names; Array_string rlocked_names; int in_for_count; bool returns; bool scope_returns; bool is_builtin_mod; bool is_just_builtin_mod; bool is_generated; Array_v__ast__Stmt_ptr unresolved_fixed_sizes; bool inside_recheck; bool inside_unsafe; bool inside_const; bool inside_anon_fn; bool inside_lambda; bool inside_ref_lit; bool inside_defer; bool inside_return; bool inside_fn_arg; bool inside_ct_attr; bool inside_x_is_type; bool inside_x_matches_type; bool anon_struct_should_be_mut; bool inside_generic_struct_init; bool inside_integer_literal_cast; Array_v__ast__Type cur_struct_generic_types; Array_v__ast__Type cur_struct_concrete_types; bool skip_flags; int fn_level; v__token__Pos smartcast_mut_pos; v__token__Pos smartcast_cond_pos; Array_v__ast__Expr ct_cond_stack; Map_string_v__checker__ComptimeBranchSkipState ct_user_defines; Map_string_v__checker__ComptimeBranchSkipState ct_system_defines; int stmt_level; int expr_level; int type_level; int ensure_generic_type_level; v__ast__TypeSymbol cur_orm_ts; v__ast__AnonFn* cur_anon_fn; string vmod_file_content; Array_string loop_labels; Array_v__ast__Type vweb_gen_types; v__util__Timers* timers; v__type_resolver__TypeResolver type_resolver; v__type_resolver__ResolverInfo* comptime; v__ast__Scope* fn_scope; v__ast__FnDecl main_fn_decl_node; int match_exhaustive_cutoff_limit; bool is_last_stmt; bool prevent_sum_type_unwrapping_once; bool using_new_err_struct; bool need_recheck_generic_fns; Map_string_bool generic_fns; bool inside_sql; bool inside_selector_expr; bool inside_or_block_value; bool inside_interface_deref; bool inside_decl_rhs; bool inside_if_guard; bool inside_assign; bool is_index_assign; int comptime_call_pos; Map_string_v__ast__GotoLabel goto_labels; v__ast__Type enum_data_type; v__ast__Type field_data_type; v__ast__Type variant_data_type; v__ast__Type fn_return_type; Map_string_Array_v__ast__StructField orm_table_fields; string v_current_commit_hash; string assign_stmt_attr; v__ast__Type js_string; }; struct v__gen__c__Gen { v__pref__Preferences* pref; v__ast__Type field_data_type; v__ast__Type enum_data_type; v__ast__Type variant_data_type; string module_built; bool timers_should_print; strings__Builder out; strings__Builder extern_out; strings__Builder cheaders; strings__Builder preincludes; strings__Builder postincludes; strings__Builder includes; strings__Builder typedefs; strings__Builder enum_typedefs; strings__Builder definitions; strings__Builder type_definitions; strings__Builder sort_fn_definitions; strings__Builder alias_definitions; strings__Builder hotcode_definitions; strings__Builder channel_definitions; strings__Builder thread_definitions; strings__Builder comptime_definitions; strings__Builder type_default_vars; strings__Builder cleanup; Map_string_strings__Builder cleanups; strings__Builder gowrappers; strings__Builder waiter_fn_definitions; strings__Builder auto_str_funcs; strings__Builder dump_funcs; strings__Builder pcs_declarations; strings__Builder cov_declarations; strings__Builder embedded_data; strings__Builder shared_types; strings__Builder shared_functions; strings__Builder out_options_forward; strings__Builder out_options; strings__Builder out_results_forward; strings__Builder out_results; strings__Builder json_forward_decls; strings__Builder sql_buf; Map_string_v__gen__c__GlobalConstDef global_const_defs; Map_string_v__gen__c__VSafeArithmeticOp vsafe_arithmetic_ops; Array_string sorted_global_const_names; v__ast__File* file; v__ast__Table* table; Map_v__ast__Type_string styp_cache; Map_v__ast__Type_bool no_eq_method_types; u64 unique_file_path_hash; v__ast__FnDecl* fn_decl; string last_fn_c_name; int tmp_count; int tmp_count_af; int tmp_count_declarations; int global_tmp_count; bool discard_or_result; bool is_direct_array_access; bool is_assign_lhs; bool is_void_expr_stmt; bool is_arraymap_set; bool is_amp; bool is_sql; bool is_shared; bool is_vlines_enabled; bool is_autofree; bool is_builtin_mod; bool is_json_fn; bool is_js_call; bool is_fn_index_call; bool is_cc_msvc; bool is_option_auto_heap; string vlines_path; int options_pos_forward; Array_string options_forward; Map_string_string options; Array_string results_forward; Map_string_string results; __shared__Array_string* done_options; __shared__Array_string* done_results; Map_string_string chan_pop_options; Map_string_string chan_push_options; string mtxs; Map_string_bool tmp_var_ptr; Map_string_v__ast__Stmt_ptr labeled_loops; Map_v__ast__Type_bool contains_ptr_cache; v__ast__Stmt* inner_loop; Array_int cur_indexexpr; Map_int_string shareds; Map_u64_v__gen__c__CoverageInfo_ptr coverage_files; bool inside_smartcast; int inside_ternary; bool inside_map_postfix; bool inside_map_infix; bool inside_assign; bool inside_map_index; bool inside_array_index; bool inside_array_fixed_struct; bool inside_opt_or_res; bool inside_opt_data; bool inside_if_option; bool inside_if_result; bool inside_match_option; bool inside_match_result; bool inside_vweb_tmpl; bool inside_return; bool inside_return_tmpl; bool inside_struct_init; bool inside_or_block; bool inside_call; bool inside_curry_call; bool inside_dump_fn; bool inside_c_extern; bool expected_fixed_arr; bool inside_for_c_stmt; int inside_cast_in_heap; bool inside_cast; bool inside_selector; bool inside_selector_deref; bool inside_memset; bool inside_const; bool inside_array_item; bool inside_const_opt_or_res; bool inside_lambda; bool inside_cinit; bool inside_global_decl; bool inside_interface_deref; Array_string last_tmp_call_var; v__ast__Type last_if_option_type; int loop_depth; Map_string_string ternary_names; Map_string_Array_string ternary_level_names; int arraymap_set_pos; Array_int stmt_path_pos; bool skip_stmt_pos; bool left_is_opt; bool right_is_opt; v__ast__Type assign_ct_type; int indent; bool empty_line; v__token__Kind assign_op; Array_v__ast__DeferStmt defer_stmts; string defer_ifdef; string defer_profile_code; Array_string defer_vars; Array_string closure_structs; Array_v__gen__c__StrType str_types; Array_v__gen__c__StrType generated_str_fns; __shared__Array_string* str_fn_names; __shared__Array_string* threaded_fns; __shared__Array_string* waiter_fns; Array_v__ast__Type needed_equality_fns; Array_v__ast__Type generated_eq_fns; __shared__Array_string* array_sort_fn; Array_v__ast__Type array_contains_types; Array_v__ast__Type array_index_types; Array_string auto_fn_definitions; Array_v__gen__c__SumtypeCastingFn sumtype_casting_fns; Array_string anon_fn_definitions; __shared__Array_string* anon_fns; Map_int_bool sumtype_definitions; Array_string trace_fn_definitions; Array_v__ast__Type json_types; Array_v__gen__c__ProfileCounterMeta pcs; Array_string hotcode_fn_names; Array_string hotcode_fpaths; Array_v__ast__EmbeddedFile embedded_files; int sql_i; string sql_stmt_name; string sql_bind_name; Array_string sql_idents; Array_v__ast__Type sql_idents_types; v__ast__Type sql_left_type; string sql_table_name; string sql_fkey; string sql_parent_id; v__gen__c__SqlExprSide sql_side; int sql_last_stmt_out_len; Array_string strs_to_free0; v__type_resolver__TypeResolver type_resolver; v__type_resolver__ResolverInfo* comptime; bool prevent_sum_type_unwrapping_once; int aggregate_type_idx; bool arg_no_auto_deref; int branch_parent_pos; string returned_var_name; string infix_left_var_name; Array_string curr_var_name; string called_fn_name; v__util__Timers* timers; bool force_main_console; Map_string_string as_cast_type_names; Map_string_string obf_table; __shared__Map_string_bool* referenced_fns; int nr_closures; v__ast__Type expected_cast_type; bool expected_arg_mut; v__ast__Type or_expr_return_type; bool anon_fn; bool tests_inited; bool has_main; v__ast__Module cur_mod; Array_v__ast__Type cur_concrete_types; v__ast__FnDecl* cur_fn; v__ast__LockExpr cur_lock; v__ast__Type cur_struct_init_typ; Map_v__ast__Type_string autofree_methods; Map_v__ast__Type_bool generated_free_methods; Array_string autofree_scope_stmts; bool use_segfault_handler; Array_string test_function_names; Array_int out_fn_start_pos; string static_modifier; string static_non_parallel; bool has_reflection; bool has_debugger; Map_string_int* reflection_strings; string defer_return_tmp_var; string vweb_filter_fn_name; Array_string export_funcs; int type_default_impl_level; }; // #end sorted_symbols // BEGIN_array_fixed_return_structs struct _v_Array_fixed_bool_256 { bool ret_arr[256]; }; // END_array_fixed_return_structs // BEGIN_multi_return_structs struct multi_return_u32_u32 { u32 arg0; u32 arg1; }; struct multi_return_string_string { string arg0; string arg1; }; struct multi_return_int_int { int arg0; int arg1; }; struct multi_return_u32_u32_u32 { u32 arg0; u32 arg1; u32 arg2; }; struct multi_return_strconv__ParserState_strconv__PrepNumber { strconv__ParserState arg0; strconv__PrepNumber arg1; }; struct multi_return_u64_int { u64 arg0; int arg1; }; struct multi_return_strconv__Dec32_bool { strconv__Dec32 arg0; bool arg1; }; struct multi_return_strconv__Dec64_bool { strconv__Dec64 arg0; bool arg1; }; struct multi_return_string_int { string arg0; int arg1; }; struct multi_return_int_bool { int arg0; bool arg1; }; struct multi_return_ref_v__pref__Preferences_string { v__pref__Preferences* arg0; string arg1; }; struct multi_return_u64_u64 { u64 arg0; u64 arg1; }; struct multi_return_int_int_int { int arg0; int arg1; int arg2; }; struct multi_return_int_int_int_int_int_i64_bool { int arg0; int arg1; int arg2; int arg3; int arg4; i64 arg5; bool arg6; }; struct multi_return_f64_f64 { f64 arg0; f64 arg1; }; struct multi_return_Array_string_v__vmod__ModFileAndFolder { Array_string arg0; v__vmod__ModFileAndFolder arg1; }; struct multi_return_string_bool { string arg0; bool arg1; }; struct multi_return_v__ast__Fn_Array_v__ast__Type { v__ast__Fn arg0; Array_v__ast__Type arg1; }; struct multi_return_v__ast__StructField_Array_v__ast__Type { v__ast__StructField arg0; Array_v__ast__Type arg1; }; struct multi_return_ref_v__ast__TypeSymbol_int { v__ast__TypeSymbol* arg0; int arg1; }; struct multi_return_v__ast__Type_string { v__ast__Type arg0; string arg1; }; struct multi_return_int_v__ast__Type { int arg0; v__ast__Type arg1; }; struct multi_return_bool_bool_int { bool arg0; bool arg1; int arg2; }; struct multi_return_string_v__token__Pos { string arg0; v__token__Pos arg1; }; struct multi_return_bool_int_int { bool arg0; int arg1; int arg2; }; struct multi_return_v__ast__Type_ref_v__ast__TypeSymbol { v__ast__Type arg0; v__ast__TypeSymbol* arg1; }; struct multi_return_Array_v__ast__Param_bool_bool_bool { Array_v__ast__Param arg0; bool arg1; bool arg2; bool arg3; }; struct multi_return_Array_v__ast__Stmt_v__token__Pos { Array_v__ast__Stmt arg0; v__token__Pos arg1; }; struct multi_return_Array_v__ast__Type_Array_string { Array_v__ast__Type arg0; Array_string arg1; }; struct multi_return_Map_string_v__ast__FnDecl_Map_string_v__ast__ConstField_Map_string_v__ast__GlobalField_Map_string_v__ast__TypeDecl_Map_string_v__ast__StructDecl { Map_string_v__ast__FnDecl arg0; Map_string_v__ast__ConstField arg1; Map_string_v__ast__GlobalField arg2; Map_string_v__ast__TypeDecl arg3; Map_string_v__ast__StructDecl arg4; }; struct multi_return_bool_Array_string { bool arg0; Array_string arg1; }; struct multi_return_bool_string_int_Array_string { bool arg0; string arg1; int arg2; Array_string arg3; }; struct multi_return_Array_string_Array_string_Array_string { Array_string arg0; Array_string arg1; Array_string arg2; }; struct multi_return_string_string_string_string { string arg0; string arg1; string arg2; string arg3; }; struct multi_return_int_string_string_string { int arg0; string arg1; string arg2; string arg3; }; struct multi_return_bool_bool { bool arg0; bool arg1; }; struct multi_return_Array_string_Array_string_Array_bool { Array_string arg0; Array_string arg1; Array_bool arg2; }; struct multi_return_u64_string { u64 arg0; string arg1; }; struct multi_return_v__ast__StructField_string { v__ast__StructField arg0; string arg1; }; struct multi_return_bool_Array_v__ast__Type { bool arg0; Array_v__ast__Type arg1; }; struct multi_return_int_string { int arg0; string arg1; }; // END_multi_return_structs typedef struct thread_arg_sync__pool__process_in_thread { void (*fn) (sync__pool__PoolProcessor*, int); sync__pool__PoolProcessor* arg1; int arg2; } thread_arg_sync__pool__process_in_thread; static bool Array_u8_contains(Array_u8 a, u8 v); static bool Array_string_contains(Array_string a, string v); static bool Array_v__token__Kind_contains(Array_v__token__Kind a, v__token__Kind v); static bool Array_fixed_string_8_contains(Array_fixed_string_8 a, string v); static bool Array_Array_v__ast__Type_contains(Array_Array_v__ast__Type a, Array_v__ast__Type v); static bool Array_v__ast__Type_contains(Array_v__ast__Type a, v__ast__Type v); static bool Array_v__ast__Kind_contains(Array_v__ast__Kind a, v__ast__Kind v); static bool Array_int_contains(Array_int a, int v); static bool Array_rune_contains(Array_rune a, rune v); static bool Array_i64_contains(Array_i64 a, i64 v); static bool Array_u64_contains(Array_u64 a, u64 v); static bool Array_v__gen__c__StrType_contains(Array_v__gen__c__StrType a, v__gen__c__StrType v); static bool Array_v__gen__c__SumtypeCastingFn_contains(Array_v__gen__c__SumtypeCastingFn a, v__gen__c__SumtypeCastingFn v); static bool Array_v__ast__EmbeddedFile_contains(Array_v__ast__EmbeddedFile a, v__ast__EmbeddedFile v); static bool Array_v__ast__TypeSymbol_ptr_contains(Array_v__ast__TypeSymbol_ptr a, v__ast__TypeSymbol* v); static int Array_string_index(Array_string a, string v); static int Array_v__ast__StructField_index(Array_v__ast__StructField a, v__ast__StructField v); static int Array_int_index(Array_int a, int v); // V shared types: struct __shared__Map_string_time__StopWatch { sync__RwMutex mtx; Map_string_time__StopWatch val; }; struct __shared__Map_u64_string { sync__RwMutex mtx; Map_u64_string val; }; struct __shared__Map_int_Array_v__ast__Type { sync__RwMutex mtx; Map_int_Array_v__ast__Type val; }; struct __shared__Array_voidptr { sync__RwMutex mtx; Array_voidptr val; }; struct __shared__Array_string { sync__RwMutex mtx; Array_string val; }; struct __shared__Map_string_bool { sync__RwMutex mtx; Map_string_bool val; }; // V Option_xxx definitions: struct _option_multi_return_string_string { byte state; IError err; byte data[sizeof(multi_return_string_string) > 1 ? sizeof(multi_return_string_string) : 1]; }; struct _option_int { byte state; IError err; byte data[sizeof(int) > 1 ? sizeof(int) : 1]; }; struct _option_rune { byte state; IError err; byte data[sizeof(rune) > 1 ? sizeof(rune) : 1]; }; struct _option_u8 { byte state; IError err; byte data[sizeof(u8) > 1 ? sizeof(u8) : 1]; }; struct _option_semver__Version { byte state; IError err; byte data[sizeof(semver__Version) > 1 ? sizeof(semver__Version) : 1]; }; struct _option_string { byte state; IError err; byte data[sizeof(string) > 1 ? sizeof(string) : 1]; }; struct _option_Array_string { byte state; IError err; byte data[sizeof(Array_string) > 1 ? sizeof(Array_string) : 1]; }; struct _option_bool { byte state; IError err; byte data[sizeof(bool) > 1 ? sizeof(bool) : 1]; }; struct _option_time__StopWatch { byte state; IError err; byte data[sizeof(time__StopWatch) > 1 ? sizeof(time__StopWatch) : 1]; }; struct _option_v__ast__Ident { byte state; IError err; byte data[sizeof(v__ast__Ident) > 1 ? sizeof(v__ast__Ident) : 1]; }; struct _option_v__ast__CallArg { byte state; IError err; byte data[sizeof(v__ast__CallArg) > 1 ? sizeof(v__ast__CallArg) : 1]; }; struct _option_v__ast__Attr { byte state; IError err; byte data[sizeof(v__ast__Attr) > 1 ? sizeof(v__ast__Attr) : 1]; }; struct _option_i8 { byte state; IError err; byte data[sizeof(i8) > 1 ? sizeof(i8) : 1]; }; struct _option_i64 { byte state; IError err; byte data[sizeof(i64) > 1 ? sizeof(i64) : 1]; }; struct _option_i16 { byte state; IError err; byte data[sizeof(i16) > 1 ? sizeof(i16) : 1]; }; struct _option_i32 { byte state; IError err; byte data[sizeof(i32) > 1 ? sizeof(i32) : 1]; }; struct _option_voidptr { byte state; IError err; byte data[sizeof(voidptr) > 1 ? sizeof(voidptr) : 1]; }; struct _option_u64 { byte state; IError err; byte data[sizeof(u64) > 1 ? sizeof(u64) : 1]; }; struct _option_u16 { byte state; IError err; byte data[sizeof(u16) > 1 ? sizeof(u16) : 1]; }; struct _option_u32 { byte state; IError err; byte data[sizeof(u32) > 1 ? sizeof(u32) : 1]; }; struct _option_f32 { byte state; IError err; byte data[sizeof(f32) > 1 ? sizeof(f32) : 1]; }; struct _option_f64 { byte state; IError err; byte data[sizeof(f64) > 1 ? sizeof(f64) : 1]; }; struct _option_v__ast__ComptTimeConstValue { byte state; IError err; byte data[sizeof(v__ast__ComptTimeConstValue) > 1 ? sizeof(v__ast__ComptTimeConstValue) : 1]; }; struct _option_v__ast__ScopeObject { byte state; IError err; byte data[sizeof(v__ast__ScopeObject) > 1 ? sizeof(v__ast__ScopeObject) : 1]; }; struct _option_v__ast__ScopeStructField { byte state; IError err; byte data[sizeof(v__ast__ScopeStructField) > 1 ? sizeof(v__ast__ScopeStructField) : 1]; }; struct _option_v__ast__Var_ptr { byte state; IError err; byte data[sizeof(v__ast__Var*) > 1 ? sizeof(v__ast__Var*) : 1]; }; struct _option_v__ast__GlobalField_ptr { byte state; IError err; byte data[sizeof(v__ast__GlobalField*) > 1 ? sizeof(v__ast__GlobalField*) : 1]; }; struct _option_v__ast__ConstField_ptr { byte state; IError err; byte data[sizeof(v__ast__ConstField*) > 1 ? sizeof(v__ast__ConstField*) : 1]; }; struct _option_v__ast__Fn { byte state; IError err; byte data[sizeof(v__ast__Fn) > 1 ? sizeof(v__ast__Fn) : 1]; }; struct _option_v__ast__StructField { byte state; IError err; byte data[sizeof(v__ast__StructField) > 1 ? sizeof(v__ast__StructField) : 1]; }; struct _option_v__ast__TypeSymbol_ptr { byte state; IError err; byte data[sizeof(v__ast__TypeSymbol*) > 1 ? sizeof(v__ast__TypeSymbol*) : 1]; }; struct _option_Array_Array_v__ast__Type { byte state; IError err; byte data[sizeof(Array_Array_v__ast__Type) > 1 ? sizeof(Array_Array_v__ast__Type) : 1]; }; struct _option_v__ast__Type { byte state; IError err; byte data[sizeof(v__ast__Type) > 1 ? sizeof(v__ast__Type) : 1]; }; struct _option_Array_v__ast__Type { byte state; IError err; byte data[sizeof(Array_v__ast__Type) > 1 ? sizeof(Array_v__ast__Type) : 1]; }; struct _option_v__ast__FnDecl { byte state; IError err; byte data[sizeof(v__ast__FnDecl) > 1 ? sizeof(v__ast__FnDecl) : 1]; }; struct _option_v__ast__ConstField { byte state; IError err; byte data[sizeof(v__ast__ConstField) > 1 ? sizeof(v__ast__ConstField) : 1]; }; struct _option_v__ast__GlobalField { byte state; IError err; byte data[sizeof(v__ast__GlobalField) > 1 ? sizeof(v__ast__GlobalField) : 1]; }; struct _option_v__ast__EnumDecl { byte state; IError err; byte data[sizeof(v__ast__EnumDecl) > 1 ? sizeof(v__ast__EnumDecl) : 1]; }; struct _option_v__ast__StructDecl { byte state; IError err; byte data[sizeof(v__ast__StructDecl) > 1 ? sizeof(v__ast__StructDecl) : 1]; }; struct _option_v__ast__InterfaceDecl { byte state; IError err; byte data[sizeof(v__ast__InterfaceDecl) > 1 ? sizeof(v__ast__InterfaceDecl) : 1]; }; struct _option_v__ast__Expr { byte state; IError err; byte data[sizeof(v__ast__Expr) > 1 ? sizeof(v__ast__Expr) : 1]; }; struct _option_v__ast__Param { byte state; IError err; byte data[sizeof(v__ast__Param) > 1 ? sizeof(v__ast__Param) : 1]; }; struct _option_Array_v__ast__StructField { byte state; IError err; byte data[sizeof(Array_v__ast__StructField) > 1 ? sizeof(Array_v__ast__StructField) : 1]; }; struct _option_v__checker__LoHiLimit { byte state; IError err; byte data[sizeof(v__checker__LoHiLimit) > 1 ? sizeof(v__checker__LoHiLimit) : 1]; }; struct _option_v__ast__LambdaExpr { byte state; IError err; byte data[sizeof(v__ast__LambdaExpr) > 1 ? sizeof(v__ast__LambdaExpr) : 1]; }; struct _option_v__gen__c__GlobalConstDef { byte state; IError err; byte data[sizeof(v__gen__c__GlobalConstDef) > 1 ? sizeof(v__gen__c__GlobalConstDef) : 1]; }; struct _option_v__ast__Stmt_ptr { byte state; IError err; byte data[sizeof(v__ast__Stmt*) > 1 ? sizeof(v__ast__Stmt*) : 1]; }; struct _option_v__ast__FnTrace { byte state; IError err; byte data[sizeof(v__ast__FnTrace) > 1 ? sizeof(v__ast__FnTrace) : 1]; }; // V result_xxx definitions: struct _result_f64 { bool is_error; IError err; byte data[sizeof(f64) > 1 ? sizeof(f64) : 1]; }; struct _result_u64 { bool is_error; IError err; byte data[sizeof(u64) > 1 ? sizeof(u64) : 1]; }; struct _result_i64 { bool is_error; IError err; byte data[sizeof(i64) > 1 ? sizeof(i64) : 1]; }; struct _result_void { bool is_error; IError err; byte data[sizeof(u8) > 1 ? sizeof(u8) : 1]; }; struct _result_string { bool is_error; IError err; byte data[sizeof(string) > 1 ? sizeof(string) : 1]; }; struct _result_time__Time { bool is_error; IError err; byte data[sizeof(time__Time) > 1 ? sizeof(time__Time) : 1]; }; struct _result_multi_return_int_int_int { bool is_error; IError err; byte data[sizeof(multi_return_int_int_int) > 1 ? sizeof(multi_return_int_int_int) : 1]; }; struct _result_multi_return_int_int_int_int_int_i64_bool { bool is_error; IError err; byte data[sizeof(multi_return_int_int_int_int_int_i64_bool) > 1 ? sizeof(multi_return_int_int_int_int_int_i64_bool) : 1]; }; struct _result_bool { bool is_error; IError err; byte data[sizeof(bool) > 1 ? sizeof(bool) : 1]; }; struct _result_semver__Version { bool is_error; IError err; byte data[sizeof(semver__Version) > 1 ? sizeof(semver__Version) : 1]; }; struct _result_os__File { bool is_error; IError err; byte data[sizeof(os__File) > 1 ? sizeof(os__File) : 1]; }; struct _result_FILE_ptr { bool is_error; IError err; byte data[sizeof(FILE*) > 1 ? sizeof(FILE*) : 1]; }; struct _result_int { bool is_error; IError err; byte data[sizeof(int) > 1 ? sizeof(int) : 1]; }; struct _result_Array_u8 { bool is_error; IError err; byte data[sizeof(Array_u8) > 1 ? sizeof(Array_u8) : 1]; }; struct _result_strings__Builder { bool is_error; IError err; byte data[sizeof(strings__Builder) > 1 ? sizeof(strings__Builder) : 1]; }; struct _result_os__Stat { bool is_error; IError err; byte data[sizeof(os__Stat) > 1 ? sizeof(os__Stat) : 1]; }; struct _result_Array_string { bool is_error; IError err; byte data[sizeof(Array_string) > 1 ? sizeof(Array_string) : 1]; }; struct _result_os__Result { bool is_error; IError err; byte data[sizeof(os__Result) > 1 ? sizeof(os__Result) : 1]; }; struct _result_anon_fn_os__signal { bool is_error; IError err; byte data[sizeof(void*) > 1 ? sizeof(void*) : 1]; }; struct _result_v__pkgconfig__PkgConfig_ptr { bool is_error; IError err; byte data[sizeof(v__pkgconfig__PkgConfig*) > 1 ? sizeof(v__pkgconfig__PkgConfig*) : 1]; }; struct _result_v__pkgconfig__Main_ptr { bool is_error; IError err; byte data[sizeof(v__pkgconfig__Main*) > 1 ? sizeof(v__pkgconfig__Main*) : 1]; }; struct _result_u32 { bool is_error; IError err; byte data[sizeof(u32) > 1 ? sizeof(u32) : 1]; }; struct _result_v__pref__Arch { bool is_error; IError err; byte data[sizeof(v__pref__Arch) > 1 ? sizeof(v__pref__Arch) : 1]; }; struct _result_v__pref__OS { bool is_error; IError err; byte data[sizeof(v__pref__OS) > 1 ? sizeof(v__pref__OS) : 1]; }; struct _result_v__pref__Subsystem { bool is_error; IError err; byte data[sizeof(v__pref__Subsystem) > 1 ? sizeof(v__pref__Subsystem) : 1]; }; struct _result_v__pref__Backend { bool is_error; IError err; byte data[sizeof(v__pref__Backend) > 1 ? sizeof(v__pref__Backend) : 1]; }; struct _result_v__ast__Fn { bool is_error; IError err; byte data[sizeof(v__ast__Fn) > 1 ? sizeof(v__ast__Fn) : 1]; }; struct _result_multi_return_v__ast__Fn_Array_v__ast__Type { bool is_error; IError err; byte data[sizeof(multi_return_v__ast__Fn_Array_v__ast__Type) > 1 ? sizeof(multi_return_v__ast__Fn_Array_v__ast__Type) : 1]; }; struct _result_v__ast__StructField { bool is_error; IError err; byte data[sizeof(v__ast__StructField) > 1 ? sizeof(v__ast__StructField) : 1]; }; struct _result_multi_return_v__ast__StructField_Array_v__ast__Type { bool is_error; IError err; byte data[sizeof(multi_return_v__ast__StructField_Array_v__ast__Type) > 1 ? sizeof(multi_return_v__ast__StructField_Array_v__ast__Type) : 1]; }; struct _result_v__scanner__Scanner_ptr { bool is_error; IError err; byte data[sizeof(v__scanner__Scanner*) > 1 ? sizeof(v__scanner__Scanner*) : 1]; }; struct _result_v__ast__Expr { bool is_error; IError err; byte data[sizeof(v__ast__Expr) > 1 ? sizeof(v__ast__Expr) : 1]; }; struct _result_v__builder__MsvcResult { bool is_error; IError err; byte data[sizeof(v__builder__MsvcResult) > 1 ? sizeof(v__builder__MsvcResult) : 1]; }; struct _result_v__builder__WindowsKit { bool is_error; IError err; byte data[sizeof(v__builder__WindowsKit) > 1 ? sizeof(v__builder__WindowsKit) : 1]; }; struct _result_v__builder__VsInstallation { bool is_error; IError err; byte data[sizeof(v__builder__VsInstallation) > 1 ? sizeof(v__builder__VsInstallation) : 1]; }; // V definitions: static char * v_typeof_interface_IError(int sidx); int v_typeof_interface_idx_IError(int sidx); static char * v_typeof_interface_rand__PRNG(int sidx); int v_typeof_interface_idx_rand__PRNG(int sidx); char * v_typeof_sumtype_v__ast__TypeDecl(int); char * v_typeof_sumtype_v__ast__Expr(int); char * v_typeof_sumtype_v__ast__Stmt(int); char * v_typeof_sumtype_v__ast__ScopeObject(int); char * v_typeof_sumtype_v__ast__Node(int); char * v_typeof_sumtype_v__ast__ComptTimeConstValue(int); char * v_typeof_sumtype_v__ast__IdentInfo(int); char * v_typeof_sumtype_v__ast__AsmArg(int); char * v_typeof_sumtype_v__ast__TypeInfo(int); char * v_typeof_sumtype_v__checker__ORMExpr(int); static char * v_typeof_interface_v__type_resolver__IResolverType(int sidx); int v_typeof_interface_idx_v__type_resolver__IResolverType(int sidx); static char * v_typeof_interface_v__ast__walker__Visitor(int sidx); int v_typeof_interface_idx_v__ast__walker__Visitor(int sidx); // end of definitions #endif strings__Builder strings__new_builder(int initial_size); Array_u8 strings__Builder_reuse_as_plain_u8_array(strings__Builder* b); void strings__Builder_write_ptr(strings__Builder* b, u8* ptr, int len); void strings__Builder_write_rune(strings__Builder* b, rune r); void strings__Builder_write_runes(strings__Builder* b, Array_rune runes); void strings__Builder_write_u8(strings__Builder* b, u8 data); void strings__Builder_write_decimal(strings__Builder* b, i64 n); void strings__Builder_drain_builder(strings__Builder* b, strings__Builder* other, int other_new_cap); void strings__Builder_write_string(strings__Builder* b, string s); void strings__Builder_write_string2(strings__Builder* b, string s1, string s2); void strings__Builder_go_back(strings__Builder* b, int n); string strings__Builder_spart(strings__Builder* b, int start_pos, int n); string strings__Builder_cut_last(strings__Builder* b, int n); string strings__Builder_cut_to(strings__Builder* b, int pos); void strings__Builder_go_back_to(strings__Builder* b, int pos); void strings__Builder_writeln(strings__Builder* b, string s); void strings__Builder_writeln2(strings__Builder* b, string s1, string s2); string strings__Builder_last_n(strings__Builder* b, int n); string strings__Builder_after(strings__Builder* b, int n); string strings__Builder_str(strings__Builder* b); void strings__Builder_free(strings__Builder* b); f32 strings__dice_coefficient(string s1, string s2); string strings__repeat(u8 c, int n); string strings__repeat_string(string s, int n); VV_LOC void builtin__closure__closure_alloc(void); VV_LOC void builtin__closure__closure_init(void); VV_LOC voidptr builtin__closure__closure_create(voidptr func, voidptr data); VV_LOC u8* builtin__closure__closure_alloc_platform(void); VV_LOC void builtin__closure__closure_memory_protect_platform(voidptr ptr, isize size, builtin__closure__MemoryProtectAtrr attr); VV_LOC int builtin__closure__get_page_size_platform(void); VV_LOC void builtin__closure__closure_mtx_lock_init_platform(void); VV_LOC void builtin__closure__closure_mtx_lock_platform(void); VV_LOC void builtin__closure__closure_mtx_unlock_platform(void); int math__bits__trailing_zeros_32(u32 x); int math__bits__trailing_zeros_64(u64 x); int math__bits__len_32(u32 x); multi_return_u64_u64 math__bits__mul_64(u64 x, u64 y); VV_LOC multi_return_u32_u32_u32 strconv__lsr96(u32 s2, u32 s1, u32 s0); VV_LOC multi_return_u32_u32_u32 strconv__lsl96(u32 s2, u32 s1, u32 s0); VV_LOC multi_return_u32_u32_u32 strconv__add96(u32 s2, u32 s1, u32 s0, u32 d2, u32 d1, u32 d0); VV_LOC multi_return_strconv__ParserState_strconv__PrepNumber strconv__parser(string s); VV_LOC u64 strconv__converter(strconv__PrepNumber* pn); _result_f64 strconv__atof64(string s, strconv__AtoF64Param param); _result_u64 strconv__common_parse_uint(string s, int _base, int _bit_size, bool error_on_non_digit, bool error_on_high_digit); multi_return_u64_int strconv__common_parse_uint2(string s, int _base, int _bit_size); _result_u64 strconv__parse_uint(string s, int _base, int _bit_size); _result_i64 strconv__common_parse_int(string _s, int base, int _bit_size, bool error_on_non_digit, bool error_on_high_digit); string strconv__Dec32_get_string_32(strconv__Dec32 d, bool neg, int i_n_digit, int i_pad_digit); VV_LOC multi_return_strconv__Dec32_bool strconv__f32_to_decimal_exact_int(u32 i_mant, u32 exp); VV_LOC strconv__Dec32 strconv__f32_to_decimal(u32 mant, u32 exp); string strconv__f32_to_str(f32 f, int n_digit); VV_LOC string strconv__Dec64_get_string_64(strconv__Dec64 d, bool neg, int i_n_digit, int i_pad_digit); VV_LOC multi_return_strconv__Dec64_bool strconv__f64_to_decimal_exact_int(u64 i_mant, u64 exp); VV_LOC strconv__Dec64 strconv__f64_to_decimal(u64 mant, u64 exp); string strconv__f64_to_str(f64 f, int n_digit); string strconv__f64_to_str_pad(f64 f, int n_digit); void strconv__format_str_sb(string s, strconv__BF_param p, strings__Builder* sb); void strconv__format_dec_sb(u64 d, strconv__BF_param p, strings__Builder* res); string strconv__f64_to_str_lnd1(f64 f, int dec_digit); string strconv__format_fl(f64 f, strconv__BF_param p); string strconv__format_es(f64 f, strconv__BF_param p); string strconv__remove_tail_zeros(string s); string strconv__ftoa_64(f64 f); string strconv__ftoa_32(f32 f); string strconv__format_int(i64 n, int radix); string strconv__format_uint(u64 n, int radix); string strconv__f32_to_str_l(f32 f); string strconv__f32_to_str_l_with_dot(f32 f); string strconv__f64_to_str_l(f64 f); string strconv__f64_to_str_l_with_dot(f64 f); string strconv__fxx_to_str_l_parse(string s); string strconv__fxx_to_str_l_parse_with_dot(string s); VV_LOC u32 strconv__bool_to_u32(bool b); VV_LOC u64 strconv__bool_to_u64(bool b); VV_LOC string strconv__get_string_special(bool neg, bool expZero, bool mantZero); VV_LOC u32 strconv__mul_shift_32(u32 m, u64 mul, int ishift); VV_LOC u32 strconv__mul_pow5_invdiv_pow2(u32 m, u32 q, int j); VV_LOC u32 strconv__mul_pow5_div_pow2(u32 m, u32 i, int j); VV_LOC u32 strconv__pow5_factor_32(u32 i_v); VV_LOC bool strconv__multiple_of_power_of_five_32(u32 v, u32 p); VV_LOC bool strconv__multiple_of_power_of_two_32(u32 v, u32 p); VV_LOC u32 strconv__log10_pow2(int e); VV_LOC u32 strconv__log10_pow5(int e); VV_LOC int strconv__pow5_bits(int e); VV_LOC u64 strconv__shift_right_128(strconv__Uint128 v, int shift); VV_LOC u64 strconv__mul_shift_64(u64 m, strconv__Uint128 mul, int shift); VV_LOC u32 strconv__pow5_factor_64(u64 v_i); VV_LOC bool strconv__multiple_of_power_of_five_64(u64 v, u32 p); VV_LOC bool strconv__multiple_of_power_of_two_64(u64 v, u32 p); int strconv__dec_digits(u64 n); VV_LOC array __new_array(int mylen, int cap, int elm_size); VV_LOC array __new_array_with_default(int mylen, int cap, int elm_size, voidptr val); VV_LOC array __new_array_with_multi_default(int mylen, int cap, int elm_size, voidptr val); VV_LOC array __new_array_with_array_default(int mylen, int cap, int elm_size, array val, int depth); VV_LOC array new_array_from_c_array(int len, int cap, int elm_size, voidptr c_array); void array_ensure_cap(array* a, int required); void array_insert(array* a, int i, voidptr val); VV_LOC void array_insert_many(array* a, int i, voidptr val, int size); void array_prepend(array* a, voidptr val); VV_LOC void array_prepend_many(array* a, voidptr val, int size); void array_delete(array* a, int i); void array_delete_many(array* a, int i, int size); void array_clear(array* a); void array_trim(array* a, int index); VV_LOC voidptr array_get_unsafe(array a, int i); VV_LOC voidptr array_get(array a, int i); VV_LOC voidptr array_get_with_check(array a, int i); voidptr array_first(array a); voidptr array_last(array a); voidptr array_pop(array* a); void array_delete_last(array* a); VV_LOC array array_slice(array a, int start, int _end); VV_LOC array array_slice_ni(array a, int _start, int _end); VV_LOC array array_clone_static_to_depth(array a, int depth); array array_clone(array* a); array array_clone_to_depth(array* a, int depth); VV_LOC void array_set_unsafe(array* a, int i, voidptr val); VV_LOC void array_set(array* a, int i, voidptr val); VV_LOC void array_push(array* a, voidptr val); void array_push_many(array* a, voidptr val, int size); array array_reverse(array a); void array_free(array* a); array array_filter(array a, bool (*predicate)(voidptr )); bool array_any(array a, bool (*predicate)(voidptr )); bool array_all(array a, bool (*predicate)(voidptr )); array array_map(array a, voidptr (*callback)(voidptr )); void array_sort(array* a, int (*callback)(voidptr , voidptr )); array array_sorted(array* a, int (*callback)(voidptr , voidptr )); void array_sort_with_compare(array* a, int (*callback)(voidptr , voidptr )); bool array_contains(array a, voidptr value); int array_index(array a, voidptr value); void Array_string_free(Array_string* a); string Array_string_str(Array_string a); int copy(Array_u8* dst, Array_u8 src); Array_voidptr array_pointers(array a); void u8_free(u8* data); VV_LOC void panic_on_negative_len(int len); VV_LOC void panic_on_negative_cap(int cap); VV_LOC array __new_array_noscan(int mylen, int cap, int elm_size); VV_LOC array __new_array_with_multi_default_noscan(int mylen, int cap, int elm_size, voidptr val); VV_LOC array __new_array_with_array_default_noscan(int mylen, int cap, int elm_size, array val, int depth); void print_backtrace(void); VV_LOC void eprint_space_padding(string output, int max_len); bool print_backtrace_skipping_top_frames(int xskipframes); VV_LOC bool print_backtrace_skipping_top_frames_bsd(int skipframes); VV_LOC bool print_backtrace_skipping_top_frames_linux(int skipframes); VV_LOC void v_segmentation_fault_handler(i32 signal_number); void _v_exit(int code); _result_void at_exit(void (*cb)()); void panic_option_not_set(string s); void panic_result_not_set(string s); string vcurrent_hash(void); void _v_panic(string s); string c_error_number_str(int errnum); void panic_n(string s, i64 number1); void panic_n2(string s, i64 number1, i64 number2); VV_LOC void panic_n3(string s, i64 number1, i64 number2, i64 number3); void panic_error_number(string basestr, int errnum); void eprintln(string s); void eprint(string s); void flush_stdout(void); void flush_stderr(void); void unbuffer_stdout(void); void print(string s); void println(string s); VV_LOC void _writeln_to_fd(int fd, string s); VV_LOC void _write_buf_to_fd(int fd, u8* buf, int buf_len); VV_LOC void _memory_panic(string fname, isize size); u8* _v_malloc(isize n); u8* malloc_noscan(isize n); VV_LOC u64 __at_least_one(u64 how_many); u8* malloc_uncollectable(isize n); u8* v_realloc(u8* b, isize n); u8* realloc_data(u8* old_data, int old_size, int new_size); u8* vcalloc(isize n); u8* vcalloc_noscan(isize n); void _v_free(voidptr ptr); voidptr memdup(voidptr src, isize sz); voidptr memdup_noscan(voidptr src, isize sz); voidptr memdup_uncollectable(voidptr src, isize sz); VV_LOC int v_fixed_index(int i, int len); Array_string arguments(void); bool isnil(voidptr v); VV_LOC voidptr __as_cast(voidptr obj, int obj_type, int expected_type); VV_LOC void builtin_init(void); VV_LOC void break_if_debugger_attached(void); void gc_set_warn_proc(void (*cb)(char* msg, usize arg)); VV_LOC void internal_gc_warn_proc_none(char* msg, usize arg); VV_LOC void print_libbacktrace(int frames_to_skip); VV_LOC void eprint_libbacktrace(int frames_to_skip); int proc_pidpath(int , voidptr , int ); int vstrlen(u8* s); int vstrlen_char(char* s); voidptr vmemcpy(voidptr dest, const voidptr const_src, isize n); voidptr vmemmove(voidptr dest, const voidptr const_src, isize n); int vmemcmp(const voidptr const_s1, const voidptr const_s2, isize n); voidptr vmemset(voidptr s, int c, isize n); VV_LOC void vqsort(voidptr base, usize nmemb, usize size, int (*sort_cb)(const voidptr const_a, const voidptr const_b)); string f64_str(f64 x); string f64_strg(f64 x); string f32_str(f32 x); string f32_strg(f32 x); f32 f32_abs(f32 a); f64 f64_abs(f64 a); string ptr_str(voidptr ptr); string isize_str(isize x); string usize_str(usize x); string char_str(char* cptr); VV_LOC string int_str_l(int nn, int max); string i8_str(i8 n); string i16_str(i16 n); string u16_str(u16 n); string i32_str(i32 n); string int_str(int n); string u32_str(u32 nn); string int_literal_str(int_literal n); string i64_str(i64 nn); VV_LOC string impl_i64_to_string(i64 nn); string u64_str(u64 nn); string bool_str(bool b); VV_LOC string u64_to_hex(u64 nn, u8 len); VV_LOC string u64_to_hex_no_leading_zeros(u64 nn, u8 len); string u8_hex(u8 nn); string u32_hex(u32 nn); string int_hex(int nn); string u64_hex(u64 nn); string voidptr_str(voidptr nn); string byteptr_str(byteptr nn); string charptr_str(charptr nn); string u64_hex_full(u64 nn); string u8_str(u8 b); string u8_ascii_str(u8 b); bool u8_is_capital(u8 c); string Array_u8_bytestr(Array_u8 b); int int_min(int a, int b); int int_max(int a, int b); VV_LOC bool fast_string_eq(string a, string b); VV_LOC u64 map_hash_string(voidptr pkey); VV_LOC u64 map_hash_int_1(voidptr pkey); VV_LOC u64 map_hash_int_2(voidptr pkey); VV_LOC u64 map_hash_int_4(voidptr pkey); VV_LOC u64 map_hash_int_8(voidptr pkey); VV_LOC void DenseArray_zeros_to_end(DenseArray* d); VV_LOC DenseArray new_dense_array(int key_bytes, int value_bytes); VV_LOC voidptr DenseArray_key(DenseArray* d, int i); VV_LOC voidptr DenseArray_value(DenseArray* d, int i); VV_LOC bool DenseArray_has_index(DenseArray* d, int i); VV_LOC int DenseArray_expand(DenseArray* d); VV_LOC bool map_eq_string(voidptr a, voidptr b); VV_LOC bool map_eq_int_1(voidptr a, voidptr b); VV_LOC bool map_eq_int_2(voidptr a, voidptr b); VV_LOC bool map_eq_int_4(voidptr a, voidptr b); VV_LOC bool map_eq_int_8(voidptr a, voidptr b); VV_LOC void map_clone_string(voidptr dest, voidptr pkey); VV_LOC void map_clone_int_1(voidptr dest, voidptr pkey); VV_LOC void map_clone_int_2(voidptr dest, voidptr pkey); VV_LOC void map_clone_int_4(voidptr dest, voidptr pkey); VV_LOC void map_clone_int_8(voidptr dest, voidptr pkey); VV_LOC void map_free_string(voidptr pkey); VV_LOC void map_free_nop(voidptr _d1); VV_LOC map new_map(int key_bytes, int value_bytes, u64 (*hash_fn)(voidptr ), bool (*key_eq_fn)(voidptr , voidptr ), void (*clone_fn)(voidptr , voidptr ), void (*free_fn)(voidptr )); VV_LOC map new_map_init(u64 (*hash_fn)(voidptr ), bool (*key_eq_fn)(voidptr , voidptr ), void (*clone_fn)(voidptr , voidptr ), void (*free_fn)(voidptr ), int n, int key_bytes, int value_bytes, voidptr keys, voidptr values); map map_move(map* m); void map_clear(map* m); VV_LOC multi_return_u32_u32 map_key_to_index(map* m, voidptr pkey); VV_LOC multi_return_u32_u32 map_meta_less(map* m, u32 _index, u32 _metas); VV_LOC void map_meta_greater(map* m, u32 _index, u32 _metas, u32 kvi); VV_LOC void map_ensure_extra_metas(map* m, u32 probe_count); VV_LOC void map_set(map* m, voidptr key, voidptr value); VV_LOC void map_expand(map* m); VV_LOC void map_rehash(map* m); void map_reserve(map* m, u32 meta_bytes); VV_LOC void map_cached_rehash(map* m, u32 old_cap); VV_LOC voidptr map_get_and_set(map* m, voidptr key, voidptr zero); VV_LOC voidptr map_get(map* m, voidptr key, voidptr zero); VV_LOC voidptr map_get_check(map* m, voidptr key); VV_LOC bool map_exists(map* m, voidptr key); VV_LOC void DenseArray_delete(DenseArray* d, int i); void map_delete(map* m, voidptr key); array map_keys(map* m); array map_values(map* m); VV_LOC DenseArray DenseArray_clone(DenseArray* d); map map_clone(map* m); void map_free(map* m); void IError_free(IError* ie); VV_LOC void _option_none(voidptr data, _option* option, int size); VV_LOC void _option_ok(voidptr data, _option* option, int size); VV_LOC void _option_clone(_option* current, _option* option, int size); VV_LOC string None___str(None__ _d1); string none_str(none _d1); VV_LOC void vmemory_abort_on_nil(voidptr p, isize bytes); VV_LOC VMemoryBlock* vmemory_block_new(VMemoryBlock* prev, isize at_least, isize align); VV_LOC u8* vmemory_block_malloc(isize n, isize align); VV_LOC u8* prealloc_malloc(isize n); VV_LOC u8* prealloc_realloc(u8* old_data, isize old_size, isize new_size); VV_LOC u8* prealloc_calloc(isize n); VV_LOC void _result_ok(voidptr data, _result* res, int size); string IError_str(IError err); string Error_msg(Error err); int Error_code(Error err); string MessageError_str(MessageError err); string MessageError_msg(MessageError err); int MessageError_code(MessageError err); void MessageError_free(MessageError* err); IError _v_error(string message); IError error_with_code(string message, int code); string rune_str(rune c); string Array_rune_string(Array_rune ra); int rune_length_in_bytes(rune c); rune rune_to_upper(rune c); rune rune_to_lower(rune c); VV_LOC rune rune_map_to(rune c, MapMode mode); VV_LOC mapnode* new_node(void); VV_LOC void mapnode_free(mapnode* n); Array_rune string_runes(string s); string cstring_to_vstring(const char* const_s); string tos_clone(const u8* const_s); string tos(u8* s, int len); string tos2(u8* s); string tos3(char* s); string tos4(u8* s); string u8_vstring(u8* bp); string u8_vstring_with_len(u8* bp, int len); bool string_is_pure_ascii(string s); VV_LOC string string_clone_static(string a); string string_clone(string a); string string_replace_once(string s, string rep, string with); string string_replace(string s, string rep, string with); string string_replace_each(string s, Array_string vals); bool string_bool(string s); int string_int(string s); i64 string_i64(string s); f32 string_f32(string s); f64 string_f64(string s); u64 string_u64(string s); VV_LOC bool string__eq(string s, string a); VV_LOC bool string__lt(string s, string a); VV_LOC string string__plus(string s, string a); VV_LOC string string_plus_two(string s, string a, string b); Array_string string_split_any(string s, string delim); Array_string string_split(string s, string delim); Array_string string_rsplit(string s, string delim); _option_multi_return_string_string string_split_once(string s, string delim); _option_multi_return_string_string string_rsplit_once(string s, string delim); Array_string string_split_nth(string s, string delim, int nth); Array_string string_rsplit_nth(string s, string delim, int nth); Array_string string_split_into_lines(string s); string string_substr(string s, int start, int _end); string string_substr_unsafe(string s, int start, int _end); _result_string string_substr_with_check(string s, int start, int _end); string string_substr_ni(string s, int _start, int _end); VV_LOC int string_index_(string s, string p); _option_int string_index(string s, string p); _option_int string_last_index(string s, string needle); VV_LOC int string_index_kmp(string s, string p); int string_index_any(string s, string chars); VV_LOC int string_index_last_(string s, string p); _option_int string_index_after(string s, string p, int start); int string_index_after_(string s, string p, int start); int string_index_u8(string s, u8 c); int string_last_index_u8(string s, u8 c); int string_count(string s, string substr); bool string_contains_u8(string s, u8 x); bool string_contains(string s, string substr); bool string_contains_any(string s, string chars); bool string_starts_with(string s, string p); bool string_ends_with(string s, string p); string string_to_lower_ascii(string s); string string_to_lower(string s); bool string_is_lower(string s); string string_to_upper_ascii(string s); string string_to_upper(string s); bool string_is_upper(string s); bool string_is_capital(string s); bool string_starts_with_capital(string s); string string_find_between(string s, string start, string end); string string_trim_space(string s); string string_trim(string s, string cutset); VV_LOC string string_trim_chars(string s, string cutset, TrimMode mode); VV_LOC string string_trim_runes(string s, string cutset, TrimMode mode); string string_trim_left(string s, string cutset); string string_trim_right(string s, string cutset); string string_trim_string_left(string s, string str); string string_trim_string_right(string s, string str); string string_str(string s); VV_LOC u8 string_at(string s, int idx); VV_LOC _option_u8 string_at_with_check(string s, int idx); bool string_is_int(string str); bool u8_is_space(u8 c); bool u8_is_digit(u8 c); bool u8_is_hex_digit(u8 c); bool u8_is_oct_digit(u8 c); bool u8_is_bin_digit(u8 c); bool u8_is_letter(u8 c); bool u8_is_alnum(u8 c); void string_free(string* s); string string_all_before(string s, string sub); string string_all_before_last(string s, string sub); string string_all_after(string s, string sub); string string_all_after_last(string s, string sub); string string_all_after_first(string s, string sub); string string_after(string s, string sub); string string_after_char(string s, u8 sub); string Array_string_join(Array_string a, string sep); Array_u8 string_bytes(string s); string string_repeat(string s, int count); Array_string string_fields(string s); string string_strip_margin(string s); string string_strip_margin_custom(string s, u8 del); bool string_is_blank(string s); bool string_match_glob(string name, string pattern); string string_wrap(string s, WrapConfig config); RunesIterator string_runes_iterator(string s); _option_rune RunesIterator_next(RunesIterator* ri); string charptr_vstring_literal(charptr cp); string StrIntpType_str(StrIntpType x); VV_LOC f32 fabs32(f32 x); VV_LOC f64 fabs64(f64 x); VV_LOC u64 abs64(i64 x); u32 get_str_intp_u32_format(StrIntpType fmt_type, int in_width, int in_precision, bool in_tail_zeros, bool in_sign, u8 in_pad_ch, int in_base, bool in_upper_case); VV_LOC void StrIntpData_process_str_intp_data(StrIntpData* data, strings__Builder* sb); string str_intp(int data_len, StrIntpData* input_base); string str_intp_sq(string in_str); string str_intp_rune(string in_str); string str_intp_g32(string in_str); string str_intp_g64(string in_str); string str_intp_sub(string base_str, string in_str); u16* string_to_wide(string _str); string string_from_wide(u16* _wstr); string string_from_wide2(u16* _wstr, int len); Array_u8 wide_to_ansi(u16* _wstr); int utf8_char_len(u8 b); string utf32_to_str(u32 code); string utf32_to_str_no_malloc(u32 code, u8* buf); int utf32_decode_to_buffer(u32 code, u8* buf); int string_utf32_code(string _rune); VV_LOC rune impl_utf8_to_utf32(u8* _bytes, int _bytes_len); int utf8_str_visible_length(string s); Array_u8 string_to_ansi_not_null_terminated(string _str); bool ArrayFlags_has(ArrayFlags* e, ArrayFlags flag_); bool ArrayFlags_all(ArrayFlags* e, ArrayFlags flag_); void ArrayFlags_set(ArrayFlags* e, ArrayFlags flag_); void ArrayFlags_clear(ArrayFlags* e, ArrayFlags flag_); strings__textscanner__TextScanner strings__textscanner__new(string input); void strings__textscanner__TextScanner_free(strings__textscanner__TextScanner* ss); int strings__textscanner__TextScanner_next(strings__textscanner__TextScanner* ss); void strings__textscanner__TextScanner_skip_n(strings__textscanner__TextScanner* ss, int n); int strings__textscanner__TextScanner_peek(strings__textscanner__TextScanner* ss); int strings__textscanner__TextScanner_peek_back(strings__textscanner__TextScanner* ss); int strings__textscanner__TextScanner_peek_back_n(strings__textscanner__TextScanner* ss, int n); int strings__textscanner__TextScanner_current(strings__textscanner__TextScanner* ss); i64 time__Duration_nanoseconds(time__Duration d); i64 time__Duration_microseconds(time__Duration d); i64 time__Duration_milliseconds(time__Duration d); string time__Duration_str(time__Duration d); VV_LOC void time__int_to_byte_array_no_pad(int value, Array_u8* arr, int size); string time__Time_format_ss(time__Time t); string time__Time_ymmdd(time__Time t); string time__Time_get_fmt_date_str(time__Time t, time__FormatDelimiter fmt_dlmtr, time__FormatDate fmt_date); bool time__Time__eq(time__Time t1, time__Time t2); bool time__Time__lt(time__Time t1, time__Time t2); time__Duration time__Time__minus(time__Time lhs, time__Time rhs); _result_time__Time time__parse_iso8601(string s); VV_LOC _result_multi_return_int_int_int time__parse_iso8601_date(string s); VV_LOC _result_multi_return_int_int_int_int_int_i64_bool time__parse_iso8601_time(string s); string time__TimeParseError_msg(time__TimeParseError err); VV_LOC IError time__error_invalid_time(int code, string message); time__StopWatch time__new_stopwatch(time__StopWatchOptions opts); void time__StopWatch_start(time__StopWatch* t); void time__StopWatch_pause(time__StopWatch* t); time__Duration time__StopWatch_elapsed(time__StopWatch t); time__Time time__now(void); time__Time time__utc(void); VV_LOC time__Time time__time_with_unix(time__Time t); string time__Time_str(time__Time t); VV_LOC time__Time time__convert_ctime(struct tm t, int nanosecond); string time__Time_strftime(time__Time t, string fmt); time__Time time__new(time__Time t); string time__Time_smonth(time__Time t); i64 time__Time_unix(time__Time t); i64 time__Time_unix_milli(time__Time t); time__Time time__Time_add(time__Time t, time__Duration duration_in_nanosecond); time__Time time__Time_add_days(time__Time t, int days); time__Time time__Time_as_local(time__Time t); VV_LOC u64 time__sys_mono_now_darwin(void); VV_LOC time__Time time__darwin_now(void); VV_LOC time__Time time__solaris_now(void); VV_LOC time__Time time__darwin_utc(void); VV_LOC time__Time time__solaris_utc(void); VV_LOC i64 time__make_unix_time(struct tm t); u64 time__sys_mono_now(void); VV_LOC time__Time time__linux_now(void); VV_LOC time__Time time__linux_utc(void); VV_LOC time__Time time__win_now(void); VV_LOC time__Time time__win_utc(void); void time__sleep(time__Duration duration); time__Time time__unix_nanosecond(i64 abs_unix_timestamp, int nanosecond); VV_LOC multi_return_int_int_int time__calculate_date_from_day_offset(i64 day_offset_); VV_LOC multi_return_int_int_int time__calculate_time_from_second_offset(i64 second_offset_); string os__cmdline__option(Array_string args, string param, string def); Array_string os__cmdline__options_before(Array_string args, Array_string what); Array_string os__cmdline__options_after(Array_string args, Array_string what); int v__token__KeywordsMatcherTrie_find(v__token__KeywordsMatcherTrie* km, string word); bool v__token__KeywordsMatcherTrie_matches(v__token__KeywordsMatcherTrie* km, string word); void v__token__KeywordsMatcherTrie_add_word(v__token__KeywordsMatcherTrie* km, string word, int value); v__token__KeywordsMatcherTrie v__token__KeywordsMatcherTrie__static__new(int cap); v__token__KeywordsMatcherTrie v__token__new_keywords_matcher_trie_T_int(Map_string_int kw_map); v__token__KeywordsMatcherTrie v__token__new_keywords_matcher_trie_T_v__token__Kind(Map_string_v__token__Kind kw_map); v__token__KeywordsMatcherTrie v__token__new_keywords_matcher_from_array_trie(Array_string names); v__token__TrieNode* v__token__new_trie_node(void); void v__token__TrieNode_add_word(v__token__TrieNode* node, string word, int value, int word_idx); int v__token__TrieNode_find(v__token__TrieNode* root, string word); void v__token__Pos_free(v__token__Pos* p); string v__token__Pos_line_str(v__token__Pos p); v__token__Pos v__token__Pos_extend(v__token__Pos pos, v__token__Pos end); v__token__Pos v__token__Pos_extend_with_last_line(v__token__Pos pos, v__token__Pos end, int last_line); void v__token__Pos_update_last_line(v__token__Pos* pos, int last_line); v__token__Pos v__token__Token_pos(v__token__Token* tok); VV_LOC Map_string_v__token__Kind v__token__build_keys(void); VV_LOC Array_string v__token__build_token_str(void); bool v__token__is_key(string key); bool v__token__is_decl(v__token__Kind t); bool v__token__Kind_is_assign(v__token__Kind t); string v__token__Kind_str(v__token__Kind t); bool v__token__Token_is_next_to(v__token__Token t, v__token__Token pre_token); string v__token__Token_str(v__token__Token t); Array_v__token__Precedence v__token__build_precedences(void); int v__token__Kind_precedence(v__token__Kind kind); bool v__token__Kind_is_relational(v__token__Kind tok); bool v__token__Kind_is_start_of_type(v__token__Kind k); bool v__token__Kind_is_infix(v__token__Kind kind); string v__token__kind_to_string(v__token__Kind k); void v__dotgraph__start_digraph(void); VV_LOC void anon_fn_40181cb3d9c4559e__81(void); v__dotgraph__DotGraph* v__dotgraph__new(string name, string label, string color); void v__dotgraph__DotGraph_writeln(v__dotgraph__DotGraph* d, string line); void v__dotgraph__DotGraph_finish(v__dotgraph__DotGraph* d); void v__dotgraph__DotGraph_new_node(v__dotgraph__DotGraph* d, string nlabel, v__dotgraph__NewNodeConfig cfg); void v__dotgraph__DotGraph_new_edge(v__dotgraph__DotGraph* d, string source, string target, v__dotgraph__NewEdgeConfig cfg); string v__dotgraph__node_name(string name, voidptr context); u64 hash__wyhash_c(u8* key, u64 len, u64 seed); u64 hash__sum64_string(string key, u64 seed); u64 hash__wymum(u64 a, u64 b); i64 sync__stdatomic__add_i64(i64* ptr, int delta); i64 sync__stdatomic__sub_i64(i64* ptr, int delta); u64 hash__fnv1a__sum64_string(string data); bool encoding__utf8__validate__utf8_string(string s); bool encoding__utf8__validate__utf8_data(u8* data, int len); VV_LOC bool encoding__utf8__validate__Utf8State_seq(encoding__utf8__validate__Utf8State* s, bool r0, bool r1, bool is_tail); VV_LOC void encoding__utf8__validate__Utf8State_next_state(encoding__utf8__validate__Utf8State* s, u8 c); VV_LOC string flag__UnknownFlagError_msg(flag__UnknownFlagError err); VV_LOC string flag__ArgsCountError_msg(flag__ArgsCountError err); VV_LOC void flag__Flag_free(flag__Flag* f); string flag__Flag_str(flag__Flag f); string Array_flag__Flag_str(Array_flag__Flag af); VV_LOC void flag__FlagParser_free(flag__FlagParser* f); flag__FlagParser* flag__new_flag_parser(Array_string args); void flag__FlagParser_application(flag__FlagParser* fs, string name); void flag__FlagParser_version(flag__FlagParser* fs, string vers); VV_LOC void flag__FlagParser_add_flag(flag__FlagParser* fs, string name, u8 abbr, string usage, string desc); VV_LOC Array_string flag__FlagParser_parse_value(flag__FlagParser* fs, string longhand, u8 shorthand); VV_LOC _result_string flag__FlagParser_parse_bool_value(flag__FlagParser* fs, string longhand, u8 shorthand); _result_bool flag__FlagParser_bool_opt(flag__FlagParser* fs, string name, u8 abbr, string usage, flag__FlagConfig c); bool flag__FlagParser_bool(flag__FlagParser* fs, string name, u8 abbr, bool bdefault, string usage, flag__FlagConfig c); _result_string flag__FlagParser_string_opt(flag__FlagParser* fs, string name, u8 abbr, string usage, flag__FlagConfig c); string flag__FlagParser_string(flag__FlagParser* fs, string name, u8 abbr, string sdefault, string usage, flag__FlagConfig c); string flag__FlagParser_usage(flag__FlagParser* fs); VV_LOC bool semver__compare_eq(semver__Version v1, semver__Version v2); VV_LOC bool semver__compare_lt(semver__Version v1, semver__Version v2); VV_LOC semver__RawVersion semver__parse(string input); VV_LOC bool semver__RawVersion_is_valid(semver__RawVersion ver); VV_LOC _option_semver__Version semver__RawVersion_validate(semver__RawVersion raw_ver); VV_LOC semver__Version semver__RawVersion_to_version(semver__RawVersion raw_ver); string semver__EmptyInputError_msg(semver__EmptyInputError err); string semver__InvalidVersionFormatError_msg(semver__InvalidVersionFormatError err); _result_semver__Version semver__from(string input); bool semver__Version__eq(semver__Version v1, semver__Version v2); bool semver__Version__lt(semver__Version v1, semver__Version v2); string semver__Version_str(semver__Version ver); VV_LOC bool semver__is_valid_string(string input); VV_LOC bool semver__is_valid_number(string input); string os__getenv(string key); _option_string os__getenv_opt(string key); int os__setenv(string name, string value, bool overwrite); Map_string_string os__environ(void); int os__fd_close(int fd); VV_LOC string os__NotExpected_msg(os__NotExpected err); VV_LOC int os__NotExpected_code(os__NotExpected err); _result_os__File os__create(string path); _result_int os__File_writeln(os__File* f, string s); _result_int os__File_write_string(os__File* f, string s); _result_void os__File_write_full_buffer(os__File* f, voidptr buffer, usize buffer_len); VV_LOC _result_int os__fread(voidptr ptr, int item_size, int items, FILE* stream); string os__FileNotOpenedError_msg(os__FileNotOpenedError err); string os__SizeOfTypeIs0Error_msg(os__SizeOfTypeIs0Error err); VV_LOC IError os__error_file_not_opened(void); bool os__is_abs_path(string path); string os__abs_path(string path); string os__norm_path(string path); VV_LOC string os__clean_path(string path); VV_LOC int os__win_volume_len(string path); VV_LOC bool os__is_slash(u8 b); VV_LOC bool os__is_unc_path(string path); VV_LOC bool os__has_drive_letter(string path); VV_LOC bool os__starts_w_slash_slash(string path); VV_LOC bool os__is_drive_rooted(string path); VV_LOC bool os__is_normal_path(string path); VV_LOC bool os__is_curr_dir_ref(int byte_one, int byte_two, int byte_three); _result_Array_u8 os__read_bytes(string path); VV_LOC _result_int os__find_cfile_size(FILE* fp); VV_LOC _result_strings__Builder os__slurp_file_in_builder(FILE* fp); _result_string os__read_file(string path); u64 os__file_size(string path); _result_void os__cp(string src, string dst); _result_FILE_ptr os__vfopen(string path, string mode); int os__fileno(voidptr cfile); VV_LOC voidptr os__vpopen(string path); VV_LOC multi_return_int_bool os__posix_wait4_to_exit_status(int waitret); string os__posix_get_error_msg(int code); VV_LOC int os__vpclose(voidptr f); int os__system(string cmd); bool os__exists(string path); bool os__is_executable(string path); bool os__is_readable(string path); _result_void os__rm(string path); _result_void os__rmdir(string path); VV_LOC void os__print_c_errno(void); string os__get_raw_line(void); string os__executable(void); _result_void os__chdir(string path); string os__getwd(void); string os__real_path(string fpath); VV_LOC void os__normalize_drive_letter(string path); int os__fork(void); i64 os__file_last_mod_unix(string path); _result_void os__chmod(string path, int mode); _result_void os__execvp(string cmdpath, Array_string cmdargs); _result_void os__execve(string cmdpath, Array_string cmdargs, Array_string envs); int os__is_atty(int fd); _result_void os__write_file_array(string path, array buffer); IError os__error_posix(os__SystemError e); IError os__error_win32(os__SystemError e); void os__Result_free(os__Result* result); VV_LOC string os__executable_fallback(void); _result_void os__cp_all(string src, string dst, bool overwrite); _result_void os__mv_by_cp(string source, string target, os__MvParams opts); _result_Array_string os__read_lines(string path); string os__sigint_to_signal_name(int si); _result_void os__rmdir_all(string path); string os__file_ext(string opath); string os__dir(string path); string os__base(string path); string os__file_name(string path); Array_string os__get_raw_lines(void); string os__get_raw_lines_joined(void); string os__user_os(void); string os__home_dir(void); _result_void os__write_file(string path, string text); string os__ExecutableNotFoundError_msg(os__ExecutableNotFoundError err); VV_LOC IError os__error_failed_to_find_executable(void); _result_string os__find_abs_path_of_executable(string exe_name); bool os__is_file(string path); string os__join_path(string base, Array_string dirs); string os__join_path_single(string base, string elem); VV_LOC void os__normalize_path_in_builder(strings__Builder* sb); Array_string os__walk_ext(string path, string ext, os__WalkParams opts); VV_LOC void os__impl_walk_ext(string path, string ext, Array_string* out, os__WalkParams opts); _result_void os__mkdir_all(string opath, os__MkdirParams params); VV_LOC void os__create_folder_when_it_does_not_exist(string path); VV_LOC string os__xdg_home_folder(string ename, string lpath); string os__cache_dir(void); string os__temp_dir(void); string os__vtmp_dir(void); VV_LOC string os__default_vmodules_path(void); string os__vmodules_dir(void); Array_string os__vmodules_paths(void); os__Result os__execute_or_exit(string cmd); _result_os__Result os__execute_opt(string cmd); string os__quoted_path(string path); os__Uname os__uname(void); _result_Array_string os__ls(string path); _result_void os__mkdir(string path, os__MkdirParams params); os__Result os__execute(string cmd); string os__get_error_msg(int code); void os__File_close(os__File* f); _result_void os__ensure_folder_is_writable(string folder); int os__getuid(void); VV_LOC _result_string os__get_long_path(string path); void os__Process_wait(os__Process* p); void os__Process_close(os__Process* p); void os__Process_free(os__Process* p); VV_LOC int os__Process__spawn(os__Process* p); VV_LOC void os__Process__wait(os__Process* p); os__Process* os__new_process(string filename); void os__Process_set_args(os__Process* p, Array_string pargs); VV_LOC int os__Process_unix_spawn_process(os__Process* p); VV_LOC void os__Process_unix_wait(os__Process* p); VV_LOC bool os__Process_impl_check_pid_status(os__Process* p, bool exit_early_on_ret0, int waitpid_options); VV_LOC int os__Process_win_spawn_process(os__Process* p); VV_LOC void os__Process_win_wait(os__Process* p); _result_anon_fn_os__signal os__signal_opt(os__Signal signum, void (*handler)(os__Signal )); VV_LOC void os__sleep_ms(i64 ms); _result_os__Stat os__stat(string path); _result_os__Stat os__lstat(string path); os__FileType os__Stat_get_filetype(os__Stat st); bool os__is_dir(string path); bool os__is_link(string path); os__filelock__FileLock os__filelock__new(string fileName); bool os__filelock__FileLock_wait_acquire(os__filelock__FileLock* l, time__Duration timeout); bool os__filelock__FileLock_release(os__filelock__FileLock* l); void os__filelock__FileLock_unlink(os__filelock__FileLock* l); VV_LOC int os__filelock__open_lockfile(string f); bool os__filelock__FileLock_try_acquire(os__filelock__FileLock* l); v__depgraph__OrderedDepMap v__depgraph__new_ordered_dependency_map(void); void v__depgraph__OrderedDepMap_set(v__depgraph__OrderedDepMap* o, string name, Array_string deps); void v__depgraph__OrderedDepMap_add(v__depgraph__OrderedDepMap* o, string name, Array_string deps); Array_string v__depgraph__OrderedDepMap_get(v__depgraph__OrderedDepMap* o, string name); void v__depgraph__OrderedDepMap_delete(v__depgraph__OrderedDepMap* o, string name); void v__depgraph__OrderedDepMap_apply_diff(v__depgraph__OrderedDepMap* o, string name, Array_string deps); int v__depgraph__OrderedDepMap_size(v__depgraph__OrderedDepMap* o); v__depgraph__DepGraph* v__depgraph__new_dep_graph(void); void v__depgraph__DepGraph_add(v__depgraph__DepGraph* graph, string mod, Array_string deps); void v__depgraph__DepGraph_add_with_value(v__depgraph__DepGraph* graph, string mod, Array_string deps, i64 value); v__depgraph__DepGraph* v__depgraph__DepGraph_resolve(v__depgraph__DepGraph* graph); string v__depgraph__DepGraph_display(v__depgraph__DepGraph* graph); string v__depgraph__DepGraph_display_cycles(v__depgraph__DepGraph* graph); VV_LOC multi_return_bool_Array_string v__depgraph__NodeNames_is_part_of_cycle(v__depgraph__NodeNames* nn, string name, Array_string already_seen); void v__depgraph__show(v__depgraph__DepGraph* graph, string path); VV_LOC u32 rand__seed__nr_next(u32 prev); Array_u32 rand__seed__time_seed_array(int count); u64 rand__seed__time_seed_64(void); string term__format(string msg, string open, string close); string term__bold(string msg); string term__red(string msg); string term__yellow(string msg); string term__magenta(string msg); string term__bg_cyan(string msg); string term__bright_blue(string msg); string term__bright_white(string msg); string term__highlight_command(string command); bool term__can_show_color_on_stdout(void); bool term__can_show_color_on_stderr(void); string term__ecolorize(string (*cfn)(string ), string s); VV_LOC bool term__supports_escape_sequences(int fd); VV_LOC string v__help__hdir(string base); VV_LOC string v__help__help_dir(void); void v__help__print_and_exit(string topic, v__help__ExitOptions opts); VV_LOC void v__help__print_topic_unknown(string topic); VV_LOC void v__help__print_known_topics(void); VV_LOC string v__help__get_vexe(void); string v__util__version__vhash(void); string v__util__version__full_hash(void); string v__util__version__full_v_version(bool is_verbose); _result_string v__util__version__githash(string path); VV_LOC void v__vcache__remove_old_cache_folder(void); v__vcache__CacheManager v__vcache__new_cache_manager(Array_string opts); void v__vcache__CacheManager_set_temporary_options(v__vcache__CacheManager* cm, Array_string new_opts); string v__vcache__CacheManager_key2cpath(v__vcache__CacheManager* cm, string key); string v__vcache__CacheManager_postfix_with_key2cpath(v__vcache__CacheManager* cm, string postfix, string key); VV_LOC string v__vcache__normalise_mod(string mod); string v__vcache__CacheManager_mod_postfix_with_key2cpath(v__vcache__CacheManager* cm, string mod, string postfix, string key); _result_string v__vcache__CacheManager_exists(v__vcache__CacheManager* cm, string postfix, string key); _result_string v__vcache__CacheManager_mod_exists(v__vcache__CacheManager* cm, string mod, string postfix, string key); _result_string v__vcache__CacheManager_save(v__vcache__CacheManager* cm, string postfix, string key, string content); _result_string v__vcache__CacheManager_mod_save(v__vcache__CacheManager* cm, string mod, string postfix, string key, string content); _result_string v__vcache__CacheManager_load(v__vcache__CacheManager* cm, string postfix, string key); string v__util__recompilation__disabling_file(string vroot); Array_string v__util__vflags__join_env_vflags_and_os_args(void); Array_string v__util__vflags__tokenize_to_args(string s); int runtime__nr_jobs(void); int runtime__nr_cpus(void); v__vmod__ModFileCacher* v__vmod__get_cache(void); v__vmod__ModFileCacher* v__vmod__new_mod_file_cacher(void); v__vmod__ModFileAndFolder v__vmod__ModFileCacher_get_by_file(v__vmod__ModFileCacher* mcache, string vfile); v__vmod__ModFileAndFolder v__vmod__ModFileCacher_get_by_folder(v__vmod__ModFileCacher* mcache, string vfolder); VV_LOC void v__vmod__ModFileCacher_add(v__vmod__ModFileCacher* cacher, string path, v__vmod__ModFileAndFolder result); VV_LOC multi_return_Array_string_v__vmod__ModFileAndFolder v__vmod__ModFileCacher_traverse(v__vmod__ModFileCacher* mcache, string mfolder); VV_LOC void v__vmod__ModFileCacher_mark_folders_with_vmod(v__vmod__ModFileCacher* mcache, Array_string folders_so_far, v__vmod__ModFileAndFolder vmod); VV_LOC void v__vmod__ModFileCacher_mark_folders_as_vmod_free(v__vmod__ModFileCacher* mcache, Array_string folders_so_far); VV_LOC bool v__vmod__ModFileCacher_check_for_stop(v__vmod__ModFileCacher* mcache, Array_string files); VV_LOC Array_string v__vmod__ModFileCacher_get_files(v__vmod__ModFileCacher* mcache, string cfolder); string v__cflag__CFlag_str(v__cflag__CFlag* c); VV_LOC multi_return_bool_string_int_Array_string v__cflag__find_first_existing_path(string remainder, string literal); _option_string v__cflag__CFlag_eval(v__cflag__CFlag* cf); _option_string v__cflag__CFlag_format(v__cflag__CFlag* cf); Array_string Array_v__cflag__CFlag_c_options_before_target_msvc(Array_v__cflag__CFlag cflags); Array_string Array_v__cflag__CFlag_c_options_after_target_msvc(Array_v__cflag__CFlag cflags); Array_string Array_v__cflag__CFlag_c_options_before_target(Array_v__cflag__CFlag cflags); Array_string Array_v__cflag__CFlag_c_options_after_target(Array_v__cflag__CFlag cflags); Array_string Array_v__cflag__CFlag_c_options_without_object_files(Array_v__cflag__CFlag cflags); Array_string Array_v__cflag__CFlag_c_options_only_object_files(Array_v__cflag__CFlag cflags); multi_return_Array_string_Array_string_Array_string Array_v__cflag__CFlag_defines_others_libs(Array_v__cflag__CFlag cflags); VV_LOC Array_string v__cflag__uniq_non_empty(Array_string args); void rand__wyrand__WyRandRNG_seed(rand__wyrand__WyRandRNG* rng, Array_u32 seed_data); u8 rand__wyrand__WyRandRNG_u8(rand__wyrand__WyRandRNG* rng); u16 rand__wyrand__WyRandRNG_u16(rand__wyrand__WyRandRNG* rng); u32 rand__wyrand__WyRandRNG_u32(rand__wyrand__WyRandRNG* rng); u64 rand__wyrand__WyRandRNG_u64(rand__wyrand__WyRandRNG* rng); int rand__wyrand__WyRandRNG_block_size(rand__wyrand__WyRandRNG* rng); void rand__wyrand__WyRandRNG_free(rand__wyrand__WyRandRNG* rng); VV_LOC _result_string v__pkgconfig__desc(string mod); _result_v__pkgconfig__Main_ptr v__pkgconfig__main(Array_string args); _result_string v__pkgconfig__Main_run(v__pkgconfig__Main* m); VV_LOC string v__pkgconfig__filter(Array_string libs, string prefix, string prefix2); VV_LOC v__pkgconfig__MainOptions* v__pkgconfig__parse_options(flag__FlagParser* fp); VV_LOC Array_string v__pkgconfig__PkgConfig_parse_list_no_comma(v__pkgconfig__PkgConfig* pc, string s); VV_LOC Array_string v__pkgconfig__PkgConfig_parse_list(v__pkgconfig__PkgConfig* pc, string s); VV_LOC string v__pkgconfig__PkgConfig_parse_line(v__pkgconfig__PkgConfig* pc, string s); VV_LOC void v__pkgconfig__PkgConfig_setvar(v__pkgconfig__PkgConfig* pc, string line); VV_LOC bool v__pkgconfig__PkgConfig_parse(v__pkgconfig__PkgConfig* pc, string file); VV_LOC _result_string v__pkgconfig__PkgConfig_resolve(v__pkgconfig__PkgConfig* pc, string pkgname); bool v__pkgconfig__atleast(string v); bool v__pkgconfig__PkgConfig_atleast(v__pkgconfig__PkgConfig* pc, string v); _result_string v__pkgconfig__PkgConfig_extend(v__pkgconfig__PkgConfig* pc, v__pkgconfig__PkgConfig* pcdep); VV_LOC _result_void v__pkgconfig__PkgConfig_load_requires(v__pkgconfig__PkgConfig* pc); VV_LOC _result_void v__pkgconfig__PkgConfig_load_require(v__pkgconfig__PkgConfig* pc, string dep); VV_LOC void v__pkgconfig__PkgConfig_add_path(v__pkgconfig__PkgConfig* pc, string path); VV_LOC void v__pkgconfig__PkgConfig_load_paths(v__pkgconfig__PkgConfig* pc); _result_v__pkgconfig__PkgConfig_ptr v__pkgconfig__load(string pkgname, v__pkgconfig__Options options); Array_string v__pkgconfig__list(void); VV_LOC string rand__internal_ulid_at_millisecond(rand__PRNG* rng, u64 unix_time_milli); VV_LOC void rand__deinit(void); VV_LOC void rand__init(void); _result_u32 rand__PRNG_u32n(rand__PRNG* rng, u32 max); _result_int rand__PRNG_intn(rand__PRNG* rng, int max); string rand__PRNG_ulid(rand__PRNG* rng); rand__PRNG* rand__new_default(rand__config__PRNGConfigStruct config_); _result_int rand__intn(int max); string rand__ulid(void); v__pref__Arch v__pref__get_host_arch(void); _result_v__pref__Arch v__pref__arch_from_string(string arch_str); void v__pref__set_build_flags_and_defines(Array_string facts, Array_string defines); VV_LOC void v__pref__Preferences_expand_lookup_paths(v__pref__Preferences* p); VV_LOC void v__pref__Preferences_expand_exclude_paths(v__pref__Preferences* p); VV_LOC void v__pref__Preferences_setup_os_and_arch_when_not_explicitly_set(v__pref__Preferences* p); string v__pref__Preferences_defines_map_unique_keys(v__pref__Preferences* p); void v__pref__Preferences_fill_with_defaults(v__pref__Preferences* p); VV_LOC void v__pref__Preferences_find_cc_if_cross_compiling(v__pref__Preferences* p); VV_LOC void v__pref__Preferences_try_to_use_tcc_by_default(v__pref__Preferences* p); string v__pref__default_tcc_compiler(void); void v__pref__Preferences_default_c_compiler(v__pref__Preferences* p); void v__pref__Preferences_default_cpp_compiler(v__pref__Preferences* p); string v__pref__vexe_path(void); string v__pref__Preferences_vcross_linker_name(v__pref__Preferences* p); string v__pref__Preferences_vcross_compiler_name(v__pref__Preferences* p); VV_LOC void v__pref__Preferences_parse_line_info(v__pref__Preferences* p, string line); string v__pref__add_line_info_expr_to_program_text(string raw_text, v__pref__LineInfo linfo); _result_v__pref__OS v__pref__os_from_string(string os_str); string v__pref__OS_lower(v__pref__OS o); string v__pref__OS_str(v__pref__OS o); v__pref__OS v__pref__get_host_os(void); bool v__pref__Backend_is_js(v__pref__Backend b); VV_LOC void v__pref__detect_musl(v__pref__Preferences* res); VV_LOC void v__pref__run_code_in_tmp_vfile_and_exit(Array_string args, v__pref__Preferences* res, string option_name, string extension, string content); multi_return_ref_v__pref__Preferences_string v__pref__parse_args_and_show_errors(Array_string known_external_commands, Array_string args, bool show_output); void v__pref__eprintln_exit(string s); void v__pref__eprintln_cond(bool condition, string s); void v__pref__Preferences_vrun_elog(v__pref__Preferences* pref, string s); bool v__pref__Preferences_should_output_to_stdout(v__pref__Preferences* pref); VV_LOC void v__pref__must_exist(string path); VV_LOC bool v__pref__is_source_file(string path); _result_v__pref__Backend v__pref__backend_from_string(string s); v__pref__CompilerType v__pref__cc_from_string(string s); VV_LOC void v__pref__Preferences_parse_define(v__pref__Preferences* prefs, string define); string v__pref__supported_test_runners_list(void); bool v__pref__Preferences_should_trace_fn_name(v__pref__Preferences* pref, string fname); bool v__pref__Preferences_should_use_segfault_handler(v__pref__Preferences* pref); Array_string v__pref__Preferences_should_compile_filtered_files(v__pref__Preferences* prefs, string dir, Array_string files_); VV_LOC string v__pref__fname_without_platform_postfix(string file); bool v__pref__Preferences_should_compile_native(v__pref__Preferences* prefs, string file); bool v__pref__Preferences_should_compile_c(v__pref__Preferences* prefs, string file); bool v__pref__Preferences_should_compile_asm(v__pref__Preferences* prefs, string path); bool v__pref__Preferences_should_compile_js(v__pref__Preferences* prefs, string file); _result_v__pref__Subsystem v__pref__Subsystem__static__from_T_string(string input); string sync__Channel_auto_str(sync__Channel* ch, string __v_typename); void sync__Channel_close(sync__Channel* ch); int sync__Channel_len(sync__Channel* ch); bool sync__Channel_closed(sync__Channel* ch); void sync__Channel_push(sync__Channel* ch, voidptr src); ChanState sync__Channel_try_push(sync__Channel* ch, voidptr src); VV_LOC ChanState sync__Channel_try_push_priv(sync__Channel* ch, voidptr src, bool no_block); bool sync__Channel_pop(sync__Channel* ch, voidptr dest); ChanState sync__Channel_try_pop(sync__Channel* ch, voidptr dest); VV_LOC ChanState sync__Channel_try_pop_priv(sync__Channel* ch, voidptr dest, bool no_block); string sync__Mutex_str(sync__Mutex* m); string sync__RwMutex_str(sync__RwMutex* m); VV_LOC void sync__cpanic(int res); VV_LOC void sync__cpanic_errno(void); void sync__SpinLock_lock(sync__SpinLock* s); void sync__SpinLock_unlock(sync__SpinLock* s); void sync__WaitGroup_init(sync__WaitGroup* wg); void sync__WaitGroup_add(sync__WaitGroup* wg, int delta); void sync__WaitGroup_done(sync__WaitGroup* wg); void sync__WaitGroup_wait(sync__WaitGroup* wg); void sync__Mutex_init(sync__Mutex* m); void sync__RwMutex_init(sync__RwMutex* m); void sync__Mutex_lock(sync__Mutex* m); void sync__Mutex_unlock(sync__Mutex* m); void sync__RwMutex_rlock(sync__RwMutex* m); void sync__RwMutex_lock(sync__RwMutex* m); void sync__RwMutex_runlock(sync__RwMutex* m); void sync__RwMutex_unlock(sync__RwMutex* m); void sync__Semaphore_init(sync__Semaphore* sem, u32 n); void sync__Semaphore_post(sync__Semaphore* sem); void sync__Semaphore_wait(sync__Semaphore* sem); bool sync__Semaphore_try_wait(sync__Semaphore* sem); _result_string v__util__resolve_d_value(Map_string_string compile_values, string str); _result_string v__util__resolve_env_value(string str, bool check_for_presence); v__util__EManager* v__util__new_error_manager(void); void v__util__EManager_set_support_color(v__util__EManager* e, bool b); string v__util__bold(string msg); string v__util__color(string kind, string msg); string v__util__path_styled_for_error_messages(string path); string v__util__formatted_error(string kind, string omsg, string filepath, v__token__Pos pos); Array_string v__util__cached_file2sourcelines(string path); Array_string v__util__set_source_for_path(string path, string source); Array_string v__util__source_file_context(string kind, string filepath, v__token__Pos pos); void v__util__verror(string kind, string s); string v__util__vlines_escape_path(string path, string ccompiler); void v__util__show_compiler_message(string kind, v__errors__CompilerMessage err); string v__util__qualify_import(v__pref__Preferences* pref_, string mod, string file_path); string v__util__qualify_module(v__pref__Preferences* pref_, string mod, string file_path); VV_LOC _result_string v__util__mod_path_to_full_name(v__pref__Preferences* pref_, string mod, string path); string v__util__smart_quote(string str, bool raw); VV_LOC _v_Array_fixed_bool_256 v__util__get_non_white_space_table(void); VV_LOC _v_Array_fixed_bool_256 v__util__get_name_char_table(void); VV_LOC _v_Array_fixed_bool_256 v__util__get_func_char_table(void); bool v__util__is_func_char(u8 c); bool v__util__contains_capital(string s); bool v__util__is_generic_type_name(string name); string v__util__cescaped_path(string s); v__util__Suggestion v__util__new_suggestion(string wanted, Array_string possibilities, v__util__SuggestionParams params); void v__util__Suggestion_add(v__util__Suggestion* s, string val); void v__util__Suggestion_add_many(v__util__Suggestion* s, Array_string many); void v__util__Suggestion_sort(v__util__Suggestion* s); string v__util__Suggestion_say(v__util__Suggestion s, string msg); string v__util__short_module_name(string name); string v__util__highlight_suggestion(string message); v__util__Surrounder v__util__new_surrounder(int expected_length); void v__util__Surrounder_add(v__util__Surrounder* s, string before, string after); void v__util__Surrounder_builder_write_befores(v__util__Surrounder* s, strings__Builder* sb); void v__util__Surrounder_builder_write_afters(v__util__Surrounder* s, strings__Builder* sb); void v__util__Surrounder_free(v__util__Surrounder* s); v__util__Timers* v__util__new_timers(v__util__TimerParams params); v__util__Timers* v__util__get_timers(void); void v__util__timing_start(string label); void v__util__timing_measure(string label); void v__util__timing_measure_cumulative(string label); void v__util__timing_set_should_print(bool should_print); void v__util__Timers_start(v__util__Timers* t, string name); i64 v__util__Timers_measure(v__util__Timers* t, string name); i64 v__util__Timers_measure_cumulative(v__util__Timers* t, string name); void v__util__Timers_measure_pause(v__util__Timers* t, string name); void v__util__Timers_measure_resume(v__util__Timers* t, string name); string v__util__Timers_message(v__util__Timers* t, string name); void v__util__Timers_show(v__util__Timers* t, string label); void v__util__Timers_show_if_exists(v__util__Timers* t, string label); void v__util__Timers_show_remaining(v__util__Timers* t); VV_LOC Array_string v__util__Timers_tsafe_get_keys(v__util__Timers* t); VV_LOC void v__util__Timers_tsafe_set_sw(v__util__Timers* t, string name, time__StopWatch sw); VV_LOC _option_time__StopWatch v__util__Timers_tsafe_get_sw(v__util__Timers* t, string name); string v__util__skip_bom(string file_content); bool v__util__module_is_builtin(string mod); string v__util__tabs(int n); time__Time v__util__get_build_time(void); void v__util__set_vroot_folder(string vroot_path); bool v__util__is_escape_sequence(u8 c); void v__util__launch_tool(bool is_verbose, string tool_name, Array_string args); VV_LOC void v__util__cmd_system(string cmd); bool v__util__should_recompile_tool(string vexe, string tool_source, string tool_name, string tool_exe); string v__util__quote_path(string s); string v__util__args_quote_paths(Array_string args); string v__util__path_of_executable(string path); _result_string v__util__cached_read_source_file(string path); string v__util__replace_op(string s); Array_string v__util__join_env_vflags_and_os_args(void); _result_bool v__util__check_module_is_installed(string modulename, bool is_verbose, bool need_update); string v__util__strip_mod_name(string name); string v__util__strip_main_name(string name); string v__util__no_dots(string s); string v__util__no_cur_mod(string __v_typename, string cur_mod); bool v__util__should_bundle_module(string mod); void v__util__free_caches(void); _result_string v__util__read_file(string file_path); _result_string v__util__resolve_vmodroot(string str, string dir); VV_LOC voidptr sync__pool__empty_cb(sync__pool__PoolProcessor* _p, int _idx, int _task_id); sync__pool__PoolProcessor* sync__pool__new_pool_processor(sync__pool__PoolProcessorConfig context); void sync__pool__PoolProcessor_set_max_jobs(sync__pool__PoolProcessor* pool, int njobs); void sync__pool__PoolProcessor_work_on_items_T___ptr__v__ast__File(sync__pool__PoolProcessor* pool, Array_v__ast__File_ptr items); void sync__pool__PoolProcessor_work_on_items_T_string(sync__pool__PoolProcessor* pool, Array_string items); void sync__pool__PoolProcessor_work_on_pointers(sync__pool__PoolProcessor* pool, Array_voidptr items); VV_LOC void sync__pool__process_in_thread(sync__pool__PoolProcessor* pool, int task_id); v__ast__File* sync__pool__PoolProcessor_get_item_T___ptr__v__ast__File(sync__pool__PoolProcessor* pool, int idx); string sync__pool__PoolProcessor_get_item_T_string(sync__pool__PoolProcessor* pool, int idx); Array_os__Result sync__pool__PoolProcessor_get_results_T_os__Result(sync__pool__PoolProcessor* pool); Array_v__gen__c__Gen_ptr sync__pool__PoolProcessor_get_results_ref_T_v__gen__c__Gen(sync__pool__PoolProcessor* pool); void sync__pool__PoolProcessor_set_shared_context(sync__pool__PoolProcessor* pool, voidptr context); voidptr sync__pool__PoolProcessor_get_shared_context(sync__pool__PoolProcessor* pool); string v__ast__ComptimeType_str(v__ast__ComptimeType cty); _option_v__ast__Ident v__ast__SelectorExpr_root_ident(v__ast__SelectorExpr* e); bool v__ast__StructField_equals(v__ast__StructField* f, v__ast__StructField* o); v__ast__FnDecl v__ast__FnDecl_new_method_with_receiver_type(v__ast__FnDecl* f, v__ast__Type new_type_); VV_LOC bool v__ast__Fn_method_equals(v__ast__Fn* f, v__ast__Fn* o); string v__ast__Param_specifier(v__ast__Param* p); v__ast__Fn v__ast__Fn_new_method_with_receiver_type(v__ast__Fn* f, v__ast__Type new_type_); VV_LOC bool v__ast__Param_equals(v__ast__Param* p, v__ast__Param* o); VV_LOC bool Array_v__ast__Param_equals(Array_v__ast__Param p, Array_v__ast__Param o); void v__ast__File_free(v__ast__File* f); string v__ast__Ident_full_name(v__ast__Ident* i); bool v__ast__Ident_is_auto_heap(v__ast__Ident* i); bool v__ast__Ident_is_mut(v__ast__Ident* i); v__ast__IdentVar v__ast__Ident_var_info(v__ast__Ident* i); _result_void v__ast__ComptimeCall_resolve_compile_value(v__ast__ComptimeCall* cc, Map_string_string compile_values); string v__ast__ComptimeCall_expr_str(v__ast__ComptimeCall _v_toheap_cc); bool v__ast__Expr_is_blank_ident(v__ast__Expr expr); bool v__ast__Expr_is_as_cast(v__ast__Expr expr); v__token__Pos v__ast__Expr_pos(v__ast__Expr expr); bool v__ast__Expr_is_lvalue(v__ast__Expr expr); bool v__ast__Expr_is_expr(v__ast__Expr expr); v__ast__Type v__ast__Expr_get_pure_type(v__ast__Expr expr); bool v__ast__Expr_is_pure_literal(v__ast__Expr expr); bool v__ast__Expr_is_auto_deref_var(v__ast__Expr expr); bool v__ast__Expr_is_lockable(v__ast__Expr* e); bool v__ast__Expr_has_fn_call(v__ast__Expr* e); v__token__Pos v__ast__Node_pos(v__ast__Node node); Array_v__ast__Node v__ast__Node_children(v__ast__Node node); void v__ast__IndexExpr_recursive_mapset_is_setter(v__ast__IndexExpr* lx, bool val); void v__ast__IndexExpr_recursive_arraymap_set_is_setter(v__ast__IndexExpr* lx); Map_string_v__ast__ScopeObject v__ast__all_registers(v__ast__Table* t, v__pref__Arch arch); VV_LOC Map_string_v__ast__ScopeObject v__ast__gen_all_registers(v__ast__Table* t, Array_string without_numbers, Map_string_int with_numbers, int bit_size); bool v__ast__Expr_is_reference(v__ast__Expr expr); v__ast__Expr v__ast__Expr_remove_par(v__ast__Expr* expr); bool v__ast__Expr_is_literal(v__ast__Expr expr); bool v__ast__Expr_is_nil(v__ast__Expr e); bool v__ast__type_can_start_with_token(v__token__Token* tok); _result_void v__ast__validate_type_string_is_pure_literal(v__ast__Type typ, string str); string v__ast__Attr_str(v__ast__Attr* a); bool Array_v__ast__Attr_contains(Array_v__ast__Attr attrs, string str); bool Array_v__ast__Attr_contains_arg(Array_v__ast__Attr attrs, string str, string arg); _option_v__ast__Attr Array_v__ast__Attr_find_first(Array_v__ast__Attr attrs, string aname); _option_int Array_v__ast__Attr_find_comptime_define(Array_v__ast__Attr attrs); bool v__ast__Table_has_cflag(v__ast__Table* t, v__cflag__CFlag flag); _result_void v__ast__Table_parse_cflag(v__ast__Table* t, string cflg, string mod, Array_string ctimedefines); _option_i8 v__ast__ComptTimeConstValue_i8(v__ast__ComptTimeConstValue val); _option_i16 v__ast__ComptTimeConstValue_i16(v__ast__ComptTimeConstValue val); _option_i32 v__ast__ComptTimeConstValue_i32(v__ast__ComptTimeConstValue val); _option_voidptr v__ast__ComptTimeConstValue_voidptr(v__ast__ComptTimeConstValue val); _option_i64 v__ast__ComptTimeConstValue_i64(v__ast__ComptTimeConstValue val); _option_u8 v__ast__ComptTimeConstValue_u8(v__ast__ComptTimeConstValue val); _option_u16 v__ast__ComptTimeConstValue_u16(v__ast__ComptTimeConstValue val); _option_u32 v__ast__ComptTimeConstValue_u32(v__ast__ComptTimeConstValue val); _option_u64 v__ast__ComptTimeConstValue_u64(v__ast__ComptTimeConstValue val); _option_f32 v__ast__ComptTimeConstValue_f32(v__ast__ComptTimeConstValue val); _option_f64 v__ast__ComptTimeConstValue_f64(v__ast__ComptTimeConstValue val); _option_string v__ast__ComptTimeConstValue_string(v__ast__ComptTimeConstValue val); _option_v__ast__ComptTimeConstValue v__ast__ConstField_comptime_expr_value(v__ast__ConstField obj); bool v__ast__ConstField_is_simple_define_const(v__ast__ConstField obj); bool v__ast__ScopeObject_is_simple_define_const(v__ast__ScopeObject obj); VV_LOC Array_string v__ast__all_valid_comptime_idents(void); u64 v__ast__EmbeddedFile_hash(v__ast__EmbeddedFile e); v__ast__Expr v__ast__Table_resolve_init(v__ast__Table* t, v__ast__StructInit node, v__ast__Type typ); void v__ast__Scope_free(v__ast__Scope* s); VV_LOC bool v__ast__Scope_dont_lookup_parent(v__ast__Scope* s); _option_v__ast__ScopeObject v__ast__Scope_find(v__ast__Scope* s, string name); v__ast__ScopeStructField* v__ast__Scope_find_struct_field(v__ast__Scope* s, string name, v__ast__Type struct_type, string field_name); _option_v__ast__Var_ptr v__ast__Scope_find_var(v__ast__Scope* s, string name); _option_v__ast__GlobalField_ptr v__ast__Scope_find_global(v__ast__Scope* s, string name); _option_v__ast__ConstField_ptr v__ast__Scope_find_const(v__ast__Scope* s, string name); bool v__ast__Scope_known_var(v__ast__Scope* s, string name); bool v__ast__Scope_known_global(v__ast__Scope* s, string name); bool v__ast__Scope_known_const(v__ast__Scope* s, string name); void v__ast__Scope_update_var_type(v__ast__Scope* s, string name, v__ast__Type typ); void v__ast__Scope_update_ct_var_kind(v__ast__Scope* s, string name, v__ast__ComptimeVarKind kind); void v__ast__Scope_update_smartcasts(v__ast__Scope* s, string name, v__ast__Type typ, bool is_unwrapped); void v__ast__Scope_register_struct_field(v__ast__Scope* s, string name, v__ast__ScopeStructField field); void v__ast__Scope_register(v__ast__Scope* s, v__ast__ScopeObject obj); v__ast__Scope* v__ast__Scope_innermost(v__ast__Scope* s, int pos); Array_v__ast__ScopeObject v__ast__Scope_get_all_vars(v__ast__Scope* s); bool v__ast__Scope_contains(v__ast__Scope* s, int pos); bool v__ast__Scope_has_inherited_vars(v__ast__Scope* s); bool v__ast__Scope_is_inherited_var(v__ast__Scope* s, string var_name); string v__ast__Scope_show(v__ast__Scope* sc, int depth, int max_depth); bool v__ast__Scope_mark_var_as_used(v__ast__Scope* sc, string varname); string v__ast__Scope_str(v__ast__Scope* sc); string v__ast__FnDecl_get_name(v__ast__FnDecl* f); string v__ast__Table_get_anon_fn_name(v__ast__Table* table, string prefix, v__ast__Fn* func, int pos); string v__ast__CallExpr_get_name(v__ast__CallExpr* f); string v__ast__FnDecl_modname(v__ast__FnDecl* node); string v__ast__FnDecl_fkey(v__ast__FnDecl* node); string v__ast__Fn_fkey(v__ast__Fn* node); string v__ast__CallExpr_fkey(v__ast__CallExpr* node); string v__ast__Table_stringify_fn_decl(v__ast__Table* t, v__ast__FnDecl* node, string cur_mod, Map_string_string m2a, bool needs_wrap); VV_LOC void v__ast__Table_stringify_fn_after_name(v__ast__Table* t, v__ast__FnDecl* node, strings__Builder* f, string cur_mod, Map_string_string m2a); VV_LOC void v__ast__write_comments(Array_v__ast__Comment comments, strings__Builder* f); VV_LOC void v__ast__write_comment(v__ast__Comment node, strings__Builder* f); VV_LOC string v__ast__shorten_full_name_based_on_aliases(string input, Map_string_string m2a); multi_return_string_bool v__ast__StringInterLiteral_get_fspec_braces(v__ast__StringInterLiteral* lit, int i); string v__ast__Expr_str(v__ast__Expr* x); string v__ast__CallArg_str(v__ast__CallArg a); string v__ast__args2str(Array_v__ast__CallArg args); string v__ast__BranchStmt_str(v__ast__BranchStmt* node); string v__ast__Stmt_str(v__ast__Stmt node); VV_LOC string v__ast__field_to_string(v__ast__ConstField f); string v__ast__ComptimeForKind_str(v__ast__ComptimeForKind e); void v__ast__UsedFeatures_free(v__ast__UsedFeatures* uf); void v__ast__Table_free(v__ast__Table* t); VV_LOC void v__ast__default_table_panic_handler(v__ast__Table* _t, string message); void v__ast__Table_panic(v__ast__Table* t, string message); v__ast__Table* v__ast__new_table(void); string v__ast__Table_fn_type_signature(v__ast__Table* t, v__ast__Fn* f); string v__ast__Table_fn_type_source_signature(v__ast__Table* t, v__ast__Fn* f); string v__ast__Table_is_same_method(v__ast__Table* t, v__ast__Fn* f, v__ast__Fn* func); _option_v__ast__Fn v__ast__Table_find_fn(v__ast__Table* t, string name); bool v__ast__Table_known_fn(v__ast__Table* t, string name); void v__ast__Table_register_fn(v__ast__Table* t, v__ast__Fn new_fn); void v__ast__Table_register_interface(v__ast__Table* t, v__ast__InterfaceDecl idecl); void v__ast__Table_register_sumtype(v__ast__Table* t, v__ast__SumTypeDecl sumtyp); int v__ast__TypeSymbol_register_method(v__ast__TypeSymbol* t, v__ast__Fn new_fn); int v__ast__TypeSymbol_update_method(v__ast__TypeSymbol* t, v__ast__Fn f); _result_v__ast__Fn v__ast__Table_register_aggregate_method(v__ast__Table* t, v__ast__TypeSymbol* sym, string name); _result_v__ast__Fn v__ast__Table_find_method(v__ast__Table* t, v__ast__TypeSymbol* s, string name); Array_Array_v__ast__Type v__ast__Table_get_embeds(v__ast__Table* t, v__ast__TypeSymbol* sym, v__ast__GetEmbedsOptions options); _result_multi_return_v__ast__Fn_Array_v__ast__Type v__ast__Table_find_method_from_embeds(v__ast__Table* t, v__ast__TypeSymbol* sym, string method_name); _result_v__ast__Fn v__ast__Table_find_method_with_embeds(v__ast__Table* t, v__ast__TypeSymbol* sym, string method_name); _option_i64 v__ast__Table_find_enum_field_val(v__ast__Table* t, string name, string field_); Array_string v__ast__Table_get_enum_field_names(v__ast__Table* t, string name); Array_i64 v__ast__Table_get_enum_field_vals(v__ast__Table* t, string name); Array_v__ast__Fn v__ast__Table_get_embed_methods(v__ast__Table* t, v__ast__TypeSymbol* sym); VV_LOC _result_v__ast__StructField v__ast__Table_register_aggregate_field(v__ast__Table* t, v__ast__TypeSymbol* sym, string name); bool v__ast__Table_struct_has_field(v__ast__Table* t, v__ast__TypeSymbol* struct_, string name); Array_v__ast__StructField v__ast__Table_struct_fields(v__ast__Table* t, v__ast__TypeSymbol* sym); _result_v__ast__StructField v__ast__Table_find_field(v__ast__Table* t, v__ast__TypeSymbol* s, string name); _result_multi_return_v__ast__StructField_Array_v__ast__Type v__ast__Table_find_field_from_embeds(v__ast__Table* t, v__ast__TypeSymbol* sym, string field_name); _result_v__ast__StructField v__ast__Table_find_field_with_embeds(v__ast__Table* t, v__ast__TypeSymbol* sym, string field_name); void v__ast__Table_resolve_common_sumtype_fields(v__ast__Table* t, v__ast__TypeSymbol* sym); v__ast__Type v__ast__Table_find_type(v__ast__Table* t, string name); int v__ast__Table_find_type_idx(v__ast__Table* t, string name); int v__ast__Table_find_type_idx_fn_scoped(v__ast__Table* t, string name, v__ast__Scope* scope); _option_v__ast__TypeSymbol_ptr v__ast__Table_find_sym(v__ast__Table* t, string name); multi_return_ref_v__ast__TypeSymbol_int v__ast__Table_find_sym_and_type_idx(v__ast__Table* t, string name); v__ast__TypeSymbol* v__ast__Table_sym_by_idx(v__ast__Table* t, int idx); v__ast__TypeSymbol* v__ast__Table_sym(v__ast__Table* t, v__ast__Type typ); v__ast__TypeSymbol* v__ast__Table_final_sym(v__ast__Table* t, v__ast__Type typ); v__ast__Type v__ast__Table_final_type(v__ast__Table* t, v__ast__Type typ); string v__ast__Table_get_type_name(v__ast__Table* t, v__ast__Type typ); v__ast__Type v__ast__Table_unalias_num_type(v__ast__Table* t, v__ast__Type typ); v__ast__Type v__ast__Table_unaliased_type(v__ast__Table* t, v__ast__Type typ); VV_LOC int v__ast__Table_rewrite_already_registered_symbol(v__ast__Table* t, v__ast__TypeSymbol typ, int existing_idx); int v__ast__Table_register_sym(v__ast__Table* t, v__ast__TypeSymbol sym); void v__ast__Table_register_enum_decl(v__ast__Table* t, v__ast__EnumDecl enum_decl); void v__ast__Table_register_anon_struct(v__ast__Table* t, string name, int sym_idx); void v__ast__Table_register_anon_union(v__ast__Table* t, string name, int sym_idx); bool v__ast__Table_known_type(v__ast__Table* t, string name); void v__ast__Table_start_parsing_type(v__ast__Table* t, string type_name); void v__ast__Table_reset_parsing_type(v__ast__Table* t); bool v__ast__Table_known_type_idx(v__ast__Table* t, v__ast__Type typ); string v__ast__Table_array_name(v__ast__Table* t, v__ast__Type elem_type); string v__ast__Table_array_cname(v__ast__Table* t, v__ast__Type elem_type); string v__ast__Table_array_fixed_name(v__ast__Table* t, v__ast__Type elem_type, int size, v__ast__Expr size_expr); string v__ast__Table_array_fixed_cname(v__ast__Table* t, v__ast__Type elem_type, int size); string v__ast__Table_chan_name(v__ast__Table* t, v__ast__Type elem_type, bool is_mut); string v__ast__Table_chan_cname(v__ast__Table* t, v__ast__Type elem_type, bool is_mut); string v__ast__Table_promise_name(v__ast__Table* t, v__ast__Type return_type); string v__ast__Table_promise_cname(v__ast__Table* t, v__ast__Type return_type); string v__ast__Table_thread_name(v__ast__Table* t, v__ast__Type return_type); string v__ast__Table_thread_cname(v__ast__Table* t, v__ast__Type return_type); string v__ast__Table_map_name(v__ast__Table* t, v__ast__Type key_type, v__ast__Type value_type); string v__ast__Table_map_cname(v__ast__Table* t, v__ast__Type key_type, v__ast__Type value_type); int v__ast__Table_find_or_register_chan(v__ast__Table* t, v__ast__Type elem_type, bool is_mut); int v__ast__Table_find_or_register_map(v__ast__Table* t, v__ast__Type key_type, v__ast__Type value_type); int v__ast__Table_find_or_register_thread(v__ast__Table* t, v__ast__Type return_type); int v__ast__Table_find_or_register_promise(v__ast__Table* t, v__ast__Type return_type); int v__ast__Table_find_or_register_array(v__ast__Table* t, v__ast__Type elem_type); int v__ast__Table_find_or_register_array_with_dims(v__ast__Table* t, v__ast__Type elem_type, int nr_dims); int v__ast__Table_find_or_register_array_fixed(v__ast__Table* t, v__ast__Type elem_type, int size, v__ast__Expr size_expr, bool is_fn_ret); int v__ast__Table_find_or_register_multi_return(v__ast__Table* t, Array_v__ast__Type mr_typs); int v__ast__Table_find_or_register_fn_type(v__ast__Table* t, v__ast__Fn f, bool is_anon, bool has_decl); int v__ast__Table_add_placeholder_type(v__ast__Table* t, string name, v__ast__Language language); v__ast__Type v__ast__Table_value_type(v__ast__Table* t, v__ast__Type typ); void v__ast__Table_register_fn_generic_types(v__ast__Table* t, string fn_name); bool v__ast__Table_register_fn_concrete_types(v__ast__Table* t, string fn_name, Array_v__ast__Type types); bool v__ast__Table_sumtype_has_variant(v__ast__Table* t, v__ast__Type parent, v__ast__Type variant, bool is_as); VV_LOC bool v__ast__Table_sumtype_check_function_variant(v__ast__Table* t, v__ast__SumType parent_info, v__ast__Type variant, bool is_as); VV_LOC bool v__ast__Table_sumtype_check_variant_in_type(v__ast__Table* t, v__ast__SumType parent_info, v__ast__Type variant, bool is_as); VV_LOC bool v__ast__Table_sumtype_check_aggregate_variant(v__ast__Table* t, v__ast__Type parent_type, v__ast__Type* aggregate_type, bool is_as); VV_LOC bool v__ast__Table_sumtype_check_alias_variant(v__ast__Table* t, v__ast__Type parent_type, v__ast__Type alias_type, bool is_as); bool v__ast__Table_is_sumtype_or_in_variant(v__ast__Table* t, v__ast__Type parent, v__ast__Type typ); bool v__ast__Table_is_interface_var(v__ast__Table* t, v__ast__ScopeObject var); bool v__ast__Table_is_interface_smartcast(v__ast__Table* t, v__ast__ScopeObject var); Array_string v__ast__Table_known_type_names(v__ast__Table* t); bool v__ast__Table_has_deep_child_no_ref(v__ast__Table* t, v__ast__TypeSymbol* ts, string name); void v__ast__Table_complete_interface_check(v__ast__Table* t); v__ast__Type v__ast__Table_bitsize_to_type(v__ast__Table* t, int bit_size); bool v__ast__Table_does_type_implement_interface(v__ast__Table* t, v__ast__Type typ, v__ast__Type inter_typ); multi_return_v__ast__Type_string v__ast__Table_convert_generic_static_type_name(v__ast__Table* t, string fn_name, Array_string generic_names, Array_v__ast__Type concrete_types); _option_v__ast__Type v__ast__Table_convert_generic_type(v__ast__Table* t, v__ast__Type generic_type, Array_string generic_names, Array_v__ast__Type to_types); VV_LOC void v__ast__generic_names_push_with_filter(Array_string* to_names, Array_string from_names); Array_string v__ast__Table_generic_type_names(v__ast__Table* t, v__ast__Type generic_type); v__ast__Type v__ast__Table_unwrap_generic_type(v__ast__Table* t, v__ast__Type typ, Array_string generic_names, Array_v__ast__Type concrete_types); v__ast__Type v__ast__Table_unwrap_generic_type_ex(v__ast__Table* t, v__ast__Type typ, Array_string generic_names, Array_v__ast__Type concrete_types, bool recheck_concrete_types); VV_LOC void v__ast__Table_unwrap_method_types(v__ast__Table* t, v__ast__TypeSymbol* ts, Array_string generic_names, Array_v__ast__Type concrete_types, Array_v__ast__Type final_concrete_types); void v__ast__Table_generic_insts_to_concrete(v__ast__Table* t); Array_string v__ast__Table_get_generic_names(v__ast__Table* t, Array_v__ast__Type generic_types); bool v__ast__Table_check_if_elements_need_unwrap(v__ast__Table* t, v__ast__Type root_typ, v__ast__Type typ); Array_string v__ast__Table_dependent_names_in_expr(v__ast__Table* t, v__ast__Expr expr); Array_string v__ast__Table_dependent_names_in_stmt(v__ast__Table* t, v__ast__Stmt stmt); multi_return_int_v__ast__Type v__ast__Table_get_array_dims(v__ast__Table* t, v__ast__Array arr); multi_return_string_string v__ast__Table_get_trace_fn_name(v__ast__Table* t, v__ast__FnDecl cur_fn, v__ast__CallExpr node); Array_v__ast__Attr v__ast__Table_get_attrs(v__ast__Table* t, v__ast__TypeSymbol sym); int v__ast__Table_get_veb_result_type_idx(v__ast__Table* t); v__ast__Type v__ast__idx_to_type(int idx); v__ast__Language v__ast__pref_arch_to_table_language(v__pref__Arch pref_arch); string v__ast__ShareType_str(v__ast__ShareType t); string v__ast__Type_atomic_typename(v__ast__Type t); v__ast__ShareType v__ast__sharetype_from_flags(bool is_shared, bool is_atomic); v__ast__ShareType v__ast__Type_share(v__ast__Type t); int v__ast__Type_idx(v__ast__Type t); bool v__ast__Type_is_void(v__ast__Type t); int v__ast__Type_nr_muls(v__ast__Type t); bool v__ast__Type_is_ptr(v__ast__Type t); bool v__ast__Type_is_pointer(v__ast__Type typ); bool v__ast__Type_is_voidptr(v__ast__Type typ); bool v__ast__Type_is_any_kind_of_pointer(v__ast__Type t); v__ast__Type v__ast__Type_set_nr_muls(v__ast__Type t, int nr_muls); v__ast__Type v__ast__Type_ref(v__ast__Type t); v__ast__Type v__ast__Type_deref(v__ast__Type t); bool v__ast__Type_has_flag(v__ast__Type t, v__ast__TypeFlag flag); v__ast__Type v__ast__Type_set_flag(v__ast__Type t, v__ast__TypeFlag flag); v__ast__Type v__ast__Type_clear_flag(v__ast__Type t, v__ast__TypeFlag flag); v__ast__Type v__ast__Type_clear_flags(v__ast__Type t, Array_v__ast__TypeFlag flags); v__ast__Type v__ast__Type_clear_option_and_result(v__ast__Type t); bool v__ast__Type_has_option_or_result(v__ast__Type t); string v__ast__TypeSymbol_scoped_name(v__ast__TypeSymbol* ts); string v__ast__TypeSymbol_scoped_cname(v__ast__TypeSymbol* ts); int v__ast__TypeSymbol_nr_dims(v__ast__TypeSymbol* ts); string v__ast__Type_str(v__ast__Type t); string v__ast__Table_type_str(v__ast__Table* t, v__ast__Type typ); Array_string v__ast__Type_debug(v__ast__Type t); v__ast__Type v__ast__Type_derive(v__ast__Type t, v__ast__Type t_from); v__ast__Type v__ast__Type_derive_add_muls(v__ast__Type t, v__ast__Type t_from); v__ast__Type v__ast__Type_idx_type(v__ast__Type t); v__ast__Type v__ast__new_type(int idx); bool v__ast__Type_is_float(v__ast__Type typ); bool v__ast__Type_is_int(v__ast__Type typ); bool v__ast__Type_is_int_valptr(v__ast__Type typ); bool v__ast__Type_is_float_valptr(v__ast__Type typ); bool v__ast__Type_is_pure_int(v__ast__Type typ); bool v__ast__Type_is_signed(v__ast__Type typ); bool v__ast__Type_is_unsigned(v__ast__Type typ); bool v__ast__Type_is_int_literal(v__ast__Type typ); bool v__ast__Type_is_number(v__ast__Type typ); bool v__ast__Type_is_string(v__ast__Type typ); bool v__ast__Type_is_bool(v__ast__Type typ); VV_LOC Array_v__ast__Type v__ast__new_charptr_types(void); VV_LOC Array_v__ast__Type v__ast__new_byteptr_types(void); VV_LOC Array_v__ast__Type v__ast__new_voidptr_types(void); Array_v__ast__Type v__ast__merge_types(Array_Array_v__ast__Type params); v__ast__Type v__ast__mktyp(v__ast__Type typ); v__ast__Kind v__ast__Table_type_kind(v__ast__Table* t, v__ast__Type typ); bool v__ast__Table_type_is_for_pointer_arithmetic(v__ast__Table* t, v__ast__Type typ); string v__ast__TypeSymbol_str(v__ast__TypeSymbol* t); string v__ast__TypeSymbol_str_with_correct_nr_muls(v__ast__TypeSymbol* t, int n); VV_LOC void v__ast__TypeSymbol_no_info_panic(v__ast__TypeSymbol* t, string fname); v__ast__Enum v__ast__TypeSymbol_enum_info(v__ast__TypeSymbol* t); v__ast__MultiReturn v__ast__TypeSymbol_mr_info(v__ast__TypeSymbol* t); v__ast__Array v__ast__TypeSymbol_array_info(v__ast__TypeSymbol* t); v__ast__ArrayFixed v__ast__TypeSymbol_array_fixed_info(v__ast__TypeSymbol* t); v__ast__Chan v__ast__TypeSymbol_chan_info(v__ast__TypeSymbol* t); v__ast__Thread v__ast__TypeSymbol_thread_info(v__ast__TypeSymbol* t); v__ast__Map v__ast__TypeSymbol_map_info(v__ast__TypeSymbol* t); v__ast__Struct v__ast__TypeSymbol_struct_info(v__ast__TypeSymbol* t); v__ast__SumType v__ast__TypeSymbol_sumtype_info(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_is_heap(v__ast__TypeSymbol* t); bool v__ast__ArrayFixed_is_compatible(v__ast__ArrayFixed* t, v__ast__ArrayFixed t2); bool v__ast__TypeSymbol_is_empty_struct_array(v__ast__TypeSymbol* t); bool v__ast__Struct_is_empty_struct(v__ast__Struct* t); bool v__ast__Struct_is_unresolved_generic(v__ast__Struct* t); bool v__ast__TypeSymbol_is_primitive_fixed_array(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_is_array_fixed(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_is_c_struct(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_is_array_fixed_ret(v__ast__TypeSymbol* t); void v__ast__Table_register_builtin_type_symbols(v__ast__Table* t); bool v__ast__TypeSymbol_is_pointer(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_is_int(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_is_float(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_is_string(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_is_number(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_is_bool(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_is_primitive(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_is_builtin(v__ast__TypeSymbol* t); multi_return_int_int v__ast__Table_type_size(v__ast__Table* t, v__ast__Type typ); VV_LOC int v__ast__round_up(int n, int multiple); string v__ast__Kind_str(v__ast__Kind k); string Array_v__ast__Kind_str(Array_v__ast__Kind kinds); string v__ast__Table_type_to_str(v__ast__Table* t, v__ast__Type typ); string v__ast__Table_type_to_code(v__ast__Table* t, v__ast__Type typ); string v__ast__Table_clean_generics_type_str(v__ast__Table* t, v__ast__Type typ); VV_LOC string v__ast__strip_extra_struct_types(string name); string v__ast__Table_type_to_str_using_aliases(v__ast__Table* t, v__ast__Type typ, Map_string_string import_aliases); VV_LOC string v__ast__Table_shorten_user_defined_typenames(v__ast__Table* t, string original_name, Map_string_string import_aliases); string v__ast__Table_fn_signature(v__ast__Table* t, v__ast__Fn* func, v__ast__FnSignatureOpts opts); string v__ast__Table_fn_signature_using_aliases(v__ast__Table* t, v__ast__Fn* func, Map_string_string import_aliases, v__ast__FnSignatureOpts opts); string v__ast__TypeSymbol_symbol_name_except_generic(v__ast__TypeSymbol* t); string v__ast__TypeSymbol_embed_name(v__ast__TypeSymbol* t); bool v__ast__TypeSymbol_has_method(v__ast__TypeSymbol* t, string name); bool v__ast__TypeSymbol_has_method_with_generic_parent(v__ast__TypeSymbol* t, string name); _option_v__ast__Fn v__ast__TypeSymbol_find_method(v__ast__TypeSymbol* t, string name); _option_v__ast__Fn v__ast__TypeSymbol_find_method_with_generic_parent(v__ast__TypeSymbol* t, string name); bool v__ast__TypeSymbol_is_js_compatible(v__ast__TypeSymbol* t); multi_return_bool_bool_int v__ast__TypeSymbol_str_method_info(v__ast__TypeSymbol* t); _option_v__ast__StructField v__ast__TypeSymbol_find_field(v__ast__TypeSymbol* t, string name); bool v__ast__TypeSymbol_has_field(v__ast__TypeSymbol* t, string name); VV_LOC _option_v__ast__StructField v__ast__Aggregate_find_field(v__ast__Aggregate* a, string name); _option_v__ast__StructField v__ast__Interface_find_field(v__ast__Interface* i, string name); bool v__ast__Interface_has_method(v__ast__Interface* i, string name); _option_v__ast__StructField v__ast__Struct_find_field(v__ast__Struct s, string name); _option_v__ast__StructField v__ast__SumType_find_sum_type_field(v__ast__SumType* s, string name); string v__ast__Table_find_missing_variants(v__ast__Table* t, v__ast__SumType* s, string field_name); bool v__ast__Interface_defines_method(v__ast__Interface i, string name); Array_string v__ast__Interface_get_methods(v__ast__Interface i); Array_v__ast__Fn v__ast__TypeSymbol_get_methods(v__ast__TypeSymbol* t); VV_LOC bool v__transformer__IndexState_safe_access(v__transformer__IndexState* i, string key, int __v_new); VV_LOC int v__transformer__IndexState_safe_offset(v__transformer__IndexState* i, string key); VV_LOC void v__transformer__IndexState_indent(v__transformer__IndexState* i, bool is_function); VV_LOC void v__transformer__IndexState_unindent(v__transformer__IndexState* i); v__transformer__Transformer* v__transformer__new_transformer(v__pref__Preferences* pref_); v__transformer__Transformer* v__transformer__new_transformer_with_table(v__ast__Table* table, v__pref__Preferences* pref_); void v__transformer__Transformer_transform_files(v__transformer__Transformer* t, Array_v__ast__File_ptr ast_files); void v__transformer__Transformer_transform(v__transformer__Transformer* t, v__ast__File* ast_file); void v__transformer__Transformer_find_new_array_len(v__transformer__Transformer* t, v__ast__AssignStmt node); void v__transformer__Transformer_find_new_range(v__transformer__Transformer* t, v__ast__AssignStmt node); void v__transformer__Transformer_find_mut_self_assign(v__transformer__Transformer* t, v__ast__AssignStmt node); void v__transformer__Transformer_check_safe_array(v__transformer__Transformer* t, v__ast__IndexExpr* node); v__ast__Stmt v__transformer__Transformer_stmt(v__transformer__Transformer* t, v__ast__Stmt* node); v__ast__Stmt v__transformer__Transformer_assert_stmt(v__transformer__Transformer* t, v__ast__AssertStmt* node); v__ast__Expr v__transformer__Transformer_expr_stmt_if_expr(v__transformer__Transformer* t, v__ast__IfExpr* node); v__ast__Expr v__transformer__Transformer_expr_stmt_match_expr(v__transformer__Transformer* t, v__ast__MatchExpr* node); v__ast__Stmt v__transformer__Transformer_for_c_stmt(v__transformer__Transformer* t, v__ast__ForCStmt* node); v__ast__Stmt v__transformer__Transformer_for_stmt(v__transformer__Transformer* t, v__ast__ForStmt* node); v__ast__Stmt v__transformer__Transformer_interface_decl(v__transformer__Transformer* t, v__ast__InterfaceDecl* node); v__ast__Expr v__transformer__Transformer_expr(v__transformer__Transformer* t, v__ast__Expr* node); VV_LOC void v__transformer__Transformer_trans_const_value_to_literal(v__transformer__Transformer* t, v__ast__Expr* expr); v__ast__Expr v__transformer__Transformer_infix_expr(v__transformer__Transformer* t, v__ast__InfixExpr* node); v__ast__Expr v__transformer__Transformer_if_expr(v__transformer__Transformer* t, v__ast__IfExpr* node); v__ast__Expr v__transformer__Transformer_match_expr(v__transformer__Transformer* t, v__ast__MatchExpr* node); v__ast__Expr v__transformer__Transformer_sql_expr(v__transformer__Transformer* t, v__ast__SqlExpr* node); void v__transformer__Transformer_fn_decl_trace_calls(v__transformer__Transformer* t, v__ast__FnDecl* node); bool v__transformer__Transformer_simplify_nested_interpolation_in_sb(v__transformer__Transformer* t, v__ast__Stmt* onode, v__ast__CallExpr* nexpr, v__ast__Type ntype); void v__markused__mark_used(v__ast__Table* table, v__pref__Preferences* pref_, Array_v__ast__File_ptr ast_files); VV_LOC multi_return_Map_string_v__ast__FnDecl_Map_string_v__ast__ConstField_Map_string_v__ast__GlobalField_Map_string_v__ast__TypeDecl_Map_string_v__ast__StructDecl v__markused__all_global_decl(Array_v__ast__File_ptr ast_files); VV_LOC void v__markused__mark_all_methods_used(v__ast__Table* table, Array_string* all_fn_root_names, v__ast__Type typ); VV_LOC void v__markused__handle_vweb(v__ast__Table* table, Array_string* all_fn_root_names, string result_name, string filter_name, string context_name); v__markused__Walker* v__markused__Walker__static__new(v__markused__Walker params); void v__markused__Walker_mark_fn_as_used(v__markused__Walker* w, string fkey); void v__markused__Walker_mark_builtin_array_method_as_used(v__markused__Walker* w, string method_name); void v__markused__Walker_mark_builtin_map_method_as_used(v__markused__Walker* w, string method_name); void v__markused__Walker_mark_builtin_type_method_as_used(v__markused__Walker* w, string k, string rk); void v__markused__Walker_mark_const_as_used(v__markused__Walker* w, string ckey); void v__markused__Walker_mark_global_as_used(v__markused__Walker* w, string ckey); void v__markused__Walker_mark_markused_fns(v__markused__Walker* w); void v__markused__Walker_mark_root_fns(v__markused__Walker* w, Array_string all_fn_root_names); void v__markused__Walker_mark_markused_consts(v__markused__Walker* w); void v__markused__Walker_mark_markused_globals(v__markused__Walker* w); void v__markused__Walker_mark_markused_syms(v__markused__Walker* w); void v__markused__Walker_mark_markused_decltypes(v__markused__Walker* w); void v__markused__Walker_stmt(v__markused__Walker* w, v__ast__Stmt node_); VV_LOC void v__markused__Walker_asm_io(v__markused__Walker* w, Array_v__ast__AsmIO ios); VV_LOC void v__markused__Walker_defer_stmts(v__markused__Walker* w, Array_v__ast__DeferStmt stmts); VV_LOC void v__markused__Walker_stmts(v__markused__Walker* w, Array_v__ast__Stmt stmts); VV_LOC void v__markused__Walker_exprs(v__markused__Walker* w, Array_v__ast__Expr exprs); VV_LOC void v__markused__Walker_expr(v__markused__Walker* w, v__ast__Expr node_); void v__markused__Walker_fn_decl(v__markused__Walker* w, v__ast__FnDecl* node); void v__markused__Walker_call_expr(v__markused__Walker* w, v__ast__CallExpr* node); void v__markused__Walker_fn_by_name(v__markused__Walker* w, string fn_name); void v__markused__Walker_struct_fields(v__markused__Walker* w, Array_v__ast__StructField sfields); void v__markused__Walker_const_fields(v__markused__Walker* w, Array_v__ast__ConstField cfields); void v__markused__Walker_or_block(v__markused__Walker* w, v__ast__OrExpr node); void v__markused__Walker_mark_fn_ret_and_params(v__markused__Walker* w, v__ast__Type return_type, Array_v__ast__Param params); void v__markused__Walker_mark_by_sym_name(v__markused__Walker* w, string name); void v__markused__Walker_mark_by_type(v__markused__Walker* w, v__ast__Type typ); void v__markused__Walker_mark_by_sym(v__markused__Walker* w, v__ast__TypeSymbol isym); VV_LOC void v__markused__Walker_remove_unused_fn_generic_types(v__markused__Walker* w); VV_LOC void v__markused__Walker_remove_unused_dump_type(v__markused__Walker* w); VV_LOC void v__markused__Walker_mark_resource_dependencies(v__markused__Walker* w); void v__markused__Walker_finalize(v__markused__Walker* w, bool include_panic_deps); void v__markused__Walker_mark_generic_types(v__markused__Walker* w); multi_return_v__ast__StructField_string v__type_resolver__TypeResolver_get_comptime_selector_var_type(v__type_resolver__TypeResolver* t, v__ast__ComptimeSelector node); bool v__type_resolver__ResolverInfo_has_comptime_expr(v__type_resolver__ResolverInfo* t, v__ast__Expr node); bool v__type_resolver__ResolverInfo_is_comptime(v__type_resolver__ResolverInfo* t, v__ast__Expr node); bool v__type_resolver__ResolverInfo_is_comptime_variant_var(v__type_resolver__ResolverInfo* t, v__ast__Ident node); v__ast__Type v__type_resolver__TypeResolver_typeof_type(v__type_resolver__TypeResolver* t, v__ast__Expr node, v__ast__Type default_type); v__ast__Type v__type_resolver__TypeResolver_typeof_field_type(v__type_resolver__TypeResolver* t, v__ast__Type typ, string field_name); v__ast__ComptimeVarKind v__type_resolver__ResolverInfo_get_ct_type_var(v__type_resolver__ResolverInfo* t, v__ast__Expr node); v__ast__Type v__type_resolver__TypeResolver_get_type_from_comptime_var(v__type_resolver__TypeResolver* t, v__ast__Ident var); v__ast__Type v__type_resolver__TypeResolver_get_comptime_selector_type(v__type_resolver__TypeResolver* t, v__ast__ComptimeSelector node, v__ast__Type default_type); bool v__type_resolver__ResolverInfo_is_comptime_selector_field_name(v__type_resolver__ResolverInfo* t, v__ast__SelectorExpr node, string field_name); bool v__type_resolver__ResolverInfo_is_comptime_selector_type(v__type_resolver__ResolverInfo* t, v__ast__SelectorExpr node); bool v__type_resolver__ResolverInfo_check_comptime_is_field_selector(v__type_resolver__ResolverInfo* t, v__ast__SelectorExpr node); bool v__type_resolver__ResolverInfo_check_comptime_is_field_selector_bool(v__type_resolver__ResolverInfo* t, v__ast__SelectorExpr node); bool v__type_resolver__TypeResolver_get_comptime_selector_bool_field(v__type_resolver__TypeResolver* t, string field_name); bool v__type_resolver__TypeResolver_is_comptime_type(v__type_resolver__TypeResolver* t, v__ast__Type x, v__ast__ComptimeType y); v__ast__Type v__type_resolver__TypeResolver_unwrap_generic_expr(v__type_resolver__TypeResolver* ct, v__ast__Expr expr, v__ast__Type default_typ); bool v__type_resolver__TypeResolver_is_generic_param_var(v__type_resolver__TypeResolver* t, v__ast__Expr node); bool v__type_resolver__TypeResolver_is_generic_expr(v__type_resolver__TypeResolver* t, v__ast__Expr node); v__ast__Type v__type_resolver__TypeResolver_get_generic_array_fixed_element_type(v__type_resolver__TypeResolver* t, v__ast__ArrayFixed __v_array); v__ast__Type v__type_resolver__TypeResolver_get_generic_array_element_type(v__type_resolver__TypeResolver* t, v__ast__Array __v_array); Map_int_v__ast__Type v__type_resolver__TypeResolver_resolve_args(v__type_resolver__TypeResolver* t, v__ast__FnDecl* cur_fn, v__ast__Fn* func, v__ast__CallExpr* node_, Array_v__ast__Type concrete_types); multi_return_bool_Array_v__ast__Type v__type_resolver__TypeResolver_resolve_fn_generic_args(v__type_resolver__TypeResolver* t, v__ast__FnDecl* cur_fn, v__ast__Fn* func, v__ast__CallExpr* node); VV_LOC v__ast__Type v__type_resolver__DummyResolver_unwrap_generic(v__type_resolver__DummyResolver d, v__ast__Type t); v__type_resolver__TypeResolver* v__type_resolver__TypeResolver__static__new(v__ast__Table* table, v__type_resolver__IResolverType* resolver); void v__type_resolver__TypeResolver_update_ct_type(v__type_resolver__TypeResolver* t, string key, v__ast__Type var_type); v__ast__Type v__type_resolver__TypeResolver_get_ct_type_or_default(v__type_resolver__TypeResolver* t, string key, v__ast__Type default_type); VV_LOC void v__type_resolver__TypeResolver_error(v__type_resolver__TypeResolver* t, string s, v__token__Pos pos); v__ast__Type v__type_resolver__TypeResolver_promote_type(v__type_resolver__TypeResolver* t, v__ast__Type left_type, v__ast__Type right_type); v__ast__Type v__type_resolver__TypeResolver_get_type_or_default(v__type_resolver__TypeResolver* t, v__ast__Expr node, v__ast__Type default_typ); v__ast__Type v__type_resolver__TypeResolver_get_type(v__type_resolver__TypeResolver* t, v__ast__Expr node); _result_v__scanner__Scanner_ptr v__scanner__new_scanner_file(string file_path, v__scanner__CommentsMode comments_mode, v__pref__Preferences* pref_); v__scanner__Scanner* v__scanner__new_scanner(string text, v__scanner__CommentsMode comments_mode, v__pref__Preferences* pref_); void v__scanner__Scanner_free(v__scanner__Scanner* s); VV_LOC bool v__scanner__Scanner_should_parse_comment(v__scanner__Scanner* s); void v__scanner__Scanner_set_is_inside_toplevel_statement(v__scanner__Scanner* s, bool newstate); void v__scanner__Scanner_set_current_tidx(v__scanner__Scanner* s, int cidx); VV_LOC v__token__Token v__scanner__Scanner_new_token(v__scanner__Scanner* s, v__token__Kind tok_kind, string lit, int len); VV_LOC v__token__Token v__scanner__Scanner_new_eof_token(v__scanner__Scanner* s); VV_LOC v__token__Token v__scanner__Scanner_new_multiline_token(v__scanner__Scanner* s, v__token__Kind tok_kind, string lit, int len, int start_line); VV_LOC string v__scanner__Scanner_ident_name(v__scanner__Scanner* s); VV_LOC string v__scanner__Scanner_num_lit(v__scanner__Scanner* s, int start, int end); VV_LOC string v__scanner__Scanner_ident_bin_number(v__scanner__Scanner* s); VV_LOC string v__scanner__Scanner_ident_hex_number(v__scanner__Scanner* s); VV_LOC string v__scanner__Scanner_ident_oct_number(v__scanner__Scanner* s); VV_LOC string v__scanner__Scanner_ident_dec_number(v__scanner__Scanner* s); VV_LOC string v__scanner__Scanner_ident_number(v__scanner__Scanner* s); VV_LOC void v__scanner__Scanner_skip_whitespace(v__scanner__Scanner* s); VV_LOC v__token__Token v__scanner__Scanner_end_of_file(v__scanner__Scanner* s); VV_LOC void v__scanner__Scanner_scan_all_tokens_in_buffer(v__scanner__Scanner* s); VV_LOC void v__scanner__Scanner_scan_remaining_text(v__scanner__Scanner* s); v__token__Token v__scanner__Scanner_scan(v__scanner__Scanner* s); v__token__Token v__scanner__Scanner_peek_token(v__scanner__Scanner* s, int n); VV_LOC u8 v__scanner__Scanner_look_ahead(v__scanner__Scanner* s, int n); v__token__Token v__scanner__Scanner_text_scan(v__scanner__Scanner* s); VV_LOC void v__scanner__Scanner_invalid_character(v__scanner__Scanner* s); VV_LOC int v__scanner__Scanner_current_column(v__scanner__Scanner* s); VV_LOC int v__scanner__Scanner_count_symbol_before(v__scanner__Scanner* s, int p, u8 sym); string v__scanner__Scanner_ident_string(v__scanner__Scanner* s); VV_LOC multi_return_int_string v__scanner__Scanner_decode_h_escape_single(v__scanner__Scanner* s, string str, int idx); VV_LOC string v__scanner__Scanner_decode_h_escapes(v__scanner__Scanner* s, string sinput, int start, Array_int escapes_pos); VV_LOC string v__scanner__Scanner_decode_o_escapes(v__scanner__Scanner* s, string sinput, int start, Array_int escapes_pos); VV_LOC multi_return_int_string v__scanner__Scanner_decode_u16_escape_single(v__scanner__Scanner* s, string str, int idx); VV_LOC string v__scanner__Scanner_decode_u16erune(v__scanner__Scanner* s, string str); VV_LOC multi_return_int_string v__scanner__Scanner_decode_u32_escape_single(v__scanner__Scanner* s, string str, int idx); VV_LOC string v__scanner__Scanner_decode_u32erune(v__scanner__Scanner* s, string str); VV_LOC string v__scanner__trim_slash_line_break(string s); string v__scanner__Scanner_ident_char(v__scanner__Scanner* s); VV_LOC bool v__scanner__Scanner_expect(v__scanner__Scanner* s, string want, int start_pos); VV_LOC void v__scanner__Scanner_ignore_line(v__scanner__Scanner* s); VV_LOC void v__scanner__Scanner_eat_to_end_of_line(v__scanner__Scanner* s); VV_LOC void v__scanner__Scanner_inc_line_number(v__scanner__Scanner* s); v__token__Pos v__scanner__Scanner_current_pos(v__scanner__Scanner* s); void v__scanner__Scanner_add_error_detail(v__scanner__Scanner* s, string msg); void v__scanner__Scanner_add_error_detail_with_pos(v__scanner__Scanner* s, string msg, v__token__Pos pos); VV_LOC string v__scanner__Scanner_eat_details(v__scanner__Scanner* s); void v__scanner__Scanner_warn(v__scanner__Scanner* s, string msg); void v__scanner__Scanner_warn_with_pos(v__scanner__Scanner* s, string msg, v__token__Pos pos); void v__scanner__Scanner_error(v__scanner__Scanner* s, string msg); void v__scanner__Scanner_error_with_pos(v__scanner__Scanner* s, string msg, v__token__Pos pos); VV_LOC bool v__ast__walker__empty_callback(v__ast__Node* node, voidptr data); _result_void v__ast__walker__Inspector_visit(v__ast__walker__Inspector* i, v__ast__Node* node); void v__ast__walker__walk(v__ast__walker__Visitor* visitor, v__ast__Node* node); VV_LOC void v__checker__Checker_assign_stmt(v__checker__Checker* c, v__ast__AssignStmt* node); VV_LOC void v__checker__Checker_change_flags_if_comptime_expr(v__checker__Checker* c, v__ast__Ident* left, v__ast__Expr right); VV_LOC void v__checker__Checker_ident_autocomplete(v__checker__Checker* c, v__ast__Ident node); VV_LOC string v__checker__build_method_summary(v__ast__Fn method); VV_LOC bool v__checker__Checker_check_types(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected); VV_LOC bool v__checker__Checker_check_multiple_ptr_match(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected, v__ast__Param param, v__ast__CallArg arg); VV_LOC _result_void v__checker__Checker_check_expected_call_arg(v__checker__Checker* c, v__ast__Type got_, v__ast__Type expected_, v__ast__Language language, v__ast__CallArg arg); VV_LOC multi_return_string_string v__checker__Checker_get_string_names_of(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected); VV_LOC bool v__checker__Checker_check_same_module(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected); VV_LOC bool v__checker__Checker_check_basic(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected); VV_LOC bool v__checker__Checker_check_matching_function_symbols(v__checker__Checker* c, v__ast__TypeSymbol* got_type_sym, v__ast__TypeSymbol* exp_type_sym); VV_LOC v__ast__Type v__checker__Checker_check_shift(v__checker__Checker* c, v__ast__InfixExpr* node, v__ast__Type left_type_, v__ast__Type right_type_); VV_LOC v__ast__Type v__checker__Checker_promote_keeping_aliases(v__checker__Checker* c, v__ast__Type left_type, v__ast__Type right_type, v__ast__Kind left_kind, v__ast__Kind right_kind); VV_LOC v__ast__Type v__checker__Checker_promote(v__checker__Checker* c, v__ast__Type left_type, v__ast__Type right_type); VV_LOC v__ast__Type v__checker__Checker_promote_num(v__checker__Checker* c, v__ast__Type left_type, v__ast__Type right_type); VV_LOC _result_void v__checker__Checker_check_expected(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected); VV_LOC string v__checker__Checker_expected_msg(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected); VV_LOC bool v__checker__Checker_symmetric_check(v__checker__Checker* c, v__ast__Type left, v__ast__Type right); VV_LOC Array_v__ast__Type v__checker__Checker_infer_struct_generic_types(v__checker__Checker* c, v__ast__Type typ, v__ast__StructInit node); VV_LOC void v__checker__Checker_infer_fn_generic_types(v__checker__Checker* c, v__ast__Fn* func, v__ast__CallExpr* node); VV_LOC bool v__checker__Checker_is_contains_any_kind_of_pointer(v__checker__Checker* c, v__ast__Type typ, Array_v__ast__Type* checked_types); v__checker__Checker* v__checker__new_checker(v__ast__Table* table, v__pref__Preferences* pref_); VV_LOC void v__checker__Checker_reset_checker_state_at_start_of_new_file(v__checker__Checker* c); void v__checker__Checker_check(v__checker__Checker* c, v__ast__File* ast_file); void v__checker__Checker_check_scope_vars(v__checker__Checker* c, v__ast__Scope* sc); void v__checker__Checker_change_current_file(v__checker__Checker* c, v__ast__File* file); void v__checker__Checker_check_files(v__checker__Checker* c, Array_v__ast__File_ptr ast_files); VV_LOC bool v__checker__Checker_file_has_main_fn(v__checker__Checker* c, v__ast__File* file); VV_LOC void v__checker__Checker_check_valid_snake_case(v__checker__Checker* c, string name, string identifier, v__token__Pos pos); VV_LOC string v__checker__stripped_name(string name); VV_LOC void v__checker__Checker_check_valid_pascal_case(v__checker__Checker* c, string name, string identifier, v__token__Pos pos); VV_LOC void v__checker__Checker_type_decl(v__checker__Checker* c, v__ast__TypeDecl* node); VV_LOC void v__checker__Checker_alias_type_decl(v__checker__Checker* c, v__ast__AliasTypeDecl* node); VV_LOC void v__checker__Checker_check_alias_vs_element_type_of_parent(v__checker__Checker* c, v__ast__AliasTypeDecl node, v__ast__Type element_type_of_parent, string label); VV_LOC void v__checker__Checker_check_any_type(v__checker__Checker* c, v__ast__Type typ, v__ast__TypeSymbol* sym, v__token__Pos pos); VV_LOC void v__checker__Checker_fn_type_decl(v__checker__Checker* c, v__ast__FnTypeDecl* node); VV_LOC void v__checker__Checker_sum_type_decl(v__checker__Checker* c, v__ast__SumTypeDecl* node); VV_LOC Array_v__ast__InterfaceEmbedding v__checker__Checker_expand_iface_embeds(v__checker__Checker* c, v__ast__InterfaceDecl* idecl, int level, Array_v__ast__InterfaceEmbedding iface_embeds); VV_LOC bool v__checker__Checker_fail_if_immutable_to_mutable(v__checker__Checker* c, v__ast__Type left_type, v__ast__Type right_type, v__ast__Expr right); VV_LOC multi_return_string_v__token__Pos v__checker__Checker_fail_if_immutable(v__checker__Checker* c, v__ast__Expr* expr); VV_LOC bool v__checker__Checker_type_implements(v__checker__Checker* c, v__ast__Type typ, v__ast__Type interface_type, v__token__Pos pos); VV_LOC string v__checker__is_field_to_description(string expr_name, bool is_field); VV_LOC void v__checker__Checker_expr_or_block_err(v__checker__Checker* c, v__ast__OrKind kind, string expr_name, v__token__Pos pos, bool is_field); VV_LOC v__ast__Type v__checker__Checker_check_expr_option_or_result_call(v__checker__Checker* c, v__ast__Expr expr, v__ast__Type ret_type); VV_LOC void v__checker__Checker_check_or_expr(v__checker__Checker* c, v__ast__OrExpr node, v__ast__Type ret_type, v__ast__Type expr_return_type, v__ast__Expr expr); VV_LOC void v__checker__Checker_check_or_last_stmt(v__checker__Checker* c, v__ast__Stmt* stmt, v__ast__Type ret_type, v__ast__Type expr_return_type); VV_LOC v__ast__Type v__checker__Checker_selector_expr(v__checker__Checker* c, v__ast__SelectorExpr* node); VV_LOC void v__checker__Checker_const_decl(v__checker__Checker* c, v__ast__ConstDecl* node); VV_LOC void v__checker__Checker_enum_decl(v__checker__Checker* c, v__ast__EnumDecl* node); VV_LOC void v__checker__Checker_check_enum_field_integer_literal(v__checker__Checker* c, v__ast__IntegerLiteral expr, bool is_signed, bool is_multi_allowed, string styp, v__token__Pos pos, Array_u64* useen, u64 umin, u64 umax, Array_i64* iseen, i64 imin, i64 imax); VV_LOC void v__checker__Checker_check_loop_labels(v__checker__Checker* c, string label, v__token__Pos pos); VV_LOC void v__checker__Checker_stmt(v__checker__Checker* c, v__ast__Stmt* node); VV_LOC void v__checker__Checker_assert_stmt(v__checker__Checker* c, v__ast__AssertStmt* node); VV_LOC void v__checker__Checker_block(v__checker__Checker* c, v__ast__Block* node); VV_LOC void v__checker__Checker_branch_stmt(v__checker__Checker* c, v__ast__BranchStmt node); VV_LOC void v__checker__Checker_global_decl(v__checker__Checker* c, v__ast__GlobalDecl* node); VV_LOC void v__checker__Checker_asm_stmt(v__checker__Checker* c, v__ast__AsmStmt* stmt); VV_LOC void v__checker__Checker_asm_arg(v__checker__Checker* c, v__ast__AsmArg arg, v__ast__AsmStmt stmt, Array_string aliases); VV_LOC Array_string v__checker__Checker_asm_ios(v__checker__Checker* c, Array_v__ast__AsmIO* ios, v__ast__Scope* scope, bool output); VV_LOC void v__checker__Checker_hash_stmt(v__checker__Checker* c, v__ast__HashStmt* node); VV_LOC void v__checker__Checker_import_stmt(v__checker__Checker* c, v__ast__Import node); VV_LOC void v__checker__Checker_stmts(v__checker__Checker* c, Array_v__ast__Stmt* stmts); VV_LOC void v__checker__Checker_stmts_ending_with_expression(v__checker__Checker* c, Array_v__ast__Stmt* stmts, v__ast__Type expected_or_type); VV_LOC v__ast__Type v__checker__Checker_unwrap_generic(v__checker__Checker* c, v__ast__Type typ); v__ast__Type v__checker__Checker_expr(v__checker__Checker* c, v__ast__Expr* node); VV_LOC v__ast__Type v__checker__Checker_cast_expr(v__checker__Checker* c, v__ast__CastExpr* node); VV_LOC v__ast__Type v__checker__Checker_at_expr(v__checker__Checker* c, v__ast__AtExpr* node); VV_LOC v__ast__Type v__checker__Checker_resolve_var_fn(v__checker__Checker* c, v__ast__Fn* func, v__ast__Ident* node, string name); VV_LOC v__ast__Type v__checker__Checker_ident(v__checker__Checker* c, v__ast__Ident* node); VV_LOC v__ast__Type v__checker__Checker_concat_expr(v__checker__Checker* c, v__ast__ConcatExpr* node); VV_LOC void v__checker__Checker_smartcast(v__checker__Checker* c, v__ast__Expr* expr, v__ast__Type cur_type, v__ast__Type to_type_, v__ast__Scope* scope, bool is_comptime, bool is_option_unwrap); VV_LOC v__ast__Type v__checker__Checker_select_expr(v__checker__Checker* c, v__ast__SelectExpr* node); VV_LOC v__ast__Type v__checker__Checker_lock_expr(v__checker__Checker* c, v__ast__LockExpr* node); VV_LOC v__ast__Type v__checker__Checker_unsafe_expr(v__checker__Checker* c, v__ast__UnsafeExpr* node); VV_LOC _result_v__ast__Expr v__checker__Checker_find_definition(v__checker__Checker* c, v__ast__Ident ident); VV_LOC _result_v__ast__Expr v__checker__Checker_find_obj_definition(v__checker__Checker* c, v__ast__ScopeObject obj); VV_LOC _option_bool v__checker__Checker_has_return(v__checker__Checker* c, Array_v__ast__Stmt stmts); VV_LOC void v__checker__Checker_mark_as_referenced(v__checker__Checker* c, v__ast__Expr* node, bool as_interface); VV_LOC string v__checker__Checker_get_base_name(v__checker__Checker* c, v__ast__Expr* node); VV_LOC v__ast__Type v__checker__Checker_prefix_expr(v__checker__Checker* c, v__ast__PrefixExpr* node); VV_LOC void v__checker__Checker_type_error_for_operator(v__checker__Checker* c, string op_label, string types_label, string found_type_label, v__token__Pos pos); VV_LOC void v__checker__Checker_check_index(v__checker__Checker* c, v__ast__TypeSymbol* typ_sym, v__ast__Expr index, v__ast__Type index_type, v__token__Pos pos, bool range_index, bool is_gated); VV_LOC v__ast__Type v__checker__Checker_index_expr(v__checker__Checker* c, v__ast__IndexExpr* node); VV_LOC v__ast__Type v__checker__Checker_enum_val(v__checker__Checker* c, v__ast__EnumVal* node); VV_LOC v__ast__Type v__checker__Checker_chan_init(v__checker__Checker* c, v__ast__ChanInit* node); VV_LOC v__ast__Type v__checker__Checker_offset_of(v__checker__Checker* c, v__ast__OffsetOf node); VV_LOC void v__checker__Checker_check_dup_keys(v__checker__Checker* c, v__ast__MapInit* node, int i); VV_LOC bool v__checker__Checker_check_struct_signature_init_fields(v__checker__Checker* c, v__ast__Struct from, v__ast__Struct to, v__ast__StructInit node); VV_LOC bool v__checker__Checker_check_struct_signature(v__checker__Checker* c, v__ast__Struct from, v__ast__Struct to); VV_LOC string v__checker__Checker_fetch_field_name(v__checker__Checker* c, v__ast__StructField field); VV_LOC bool v__checker__Checker_ensure_generic_type_specify_type_names(v__checker__Checker* c, v__ast__Type typ, v__token__Pos pos, bool is_container_typ, bool is_generic_container); VV_LOC bool v__checker__Checker_ensure_type_exists(v__checker__Checker* c, v__ast__Type typ, v__token__Pos pos); VV_LOC bool v__checker__Checker_fail_if_unreadable(v__checker__Checker* c, v__ast__Expr expr, v__ast__Type typ, string what); VV_LOC void v__checker__Checker_fail_if_stack_struct_action_outside_unsafe(v__checker__Checker* c, v__ast__Ident* ident, string failed_action); VV_LOC void v__checker__Checker_goto_label(v__checker__Checker* c, v__ast__GotoLabel node); VV_LOC void v__checker__Checker_goto_stmt(v__checker__Checker* c, v__ast__GotoStmt node); VV_LOC void v__checker__Checker_check_unused_labels(v__checker__Checker* c); VV_LOC bool v__checker__Checker_check_import_sym_conflict(v__checker__Checker* c, string ident); void v__checker__Checker_update_unresolved_fixed_sizes(v__checker__Checker* c); VV_LOC string v__checker__Checker_dir_path(v__checker__Checker* c); VV_LOC v__ast__Type v__checker__Checker_comptime_call(v__checker__Checker* c, v__ast__ComptimeCall* node); VV_LOC string v__checker__Checker_comptime_call_msg(v__checker__Checker* c, v__ast__ComptimeCall _v_toheap_node); VV_LOC v__ast__Type v__checker__Checker_comptime_selector(v__checker__Checker* c, v__ast__ComptimeSelector* node); VV_LOC void v__checker__Checker_comptime_for(v__checker__Checker* c, v__ast__ComptimeFor* node); VV_LOC _option_v__ast__ComptTimeConstValue v__checker__Checker_eval_comptime_const_expr(v__checker__Checker* c, v__ast__Expr expr, int nlevel); VV_LOC multi_return_bool_int_int v__checker__Checker_verify_vweb_params_for_method(v__checker__Checker* c, v__ast__Fn* node); VV_LOC void v__checker__Checker_verify_all_vweb_routes(v__checker__Checker* c); VV_LOC bool v__checker__Checker_evaluate_once_comptime_if_attribute(v__checker__Checker* c, v__ast__Attr* node); VV_LOC v__checker__ComptimeBranchSkipState v__checker__Checker_comptime_if_cond(v__checker__Checker* c, v__ast__Expr* cond, v__token__Pos pos); VV_LOC void v__checker__Checker_push_new_comptime_info(v__checker__Checker* c); VV_LOC void v__checker__Checker_pop_comptime_info(v__checker__Checker* c); VV_LOC bool v__checker__overflows_i32(i64 val); VV_LOC v__ast__Type v__checker__Checker_array_init(v__checker__Checker* c, v__ast__ArrayInit* node); VV_LOC void v__checker__Checker_check_array_init_default_expr(v__checker__Checker* c, v__ast__ArrayInit* node); VV_LOC void v__checker__Checker_check_array_init_para_type(v__checker__Checker* c, string para, v__ast__Expr* expr, v__token__Pos pos); VV_LOC v__ast__Type v__checker__Checker_eval_array_fixed_sizes(v__checker__Checker* c, v__ast__Expr* size_expr, int size, v__ast__Type elem_type); VV_LOC bool v__checker__Checker_array_fixed_has_unresolved_size(v__checker__Checker* c, v__ast__ArrayFixed* info); VV_LOC v__ast__Type v__checker__Checker_map_init(v__checker__Checker* c, v__ast__MapInit* node); VV_LOC void v__checker__Checker_check_elements_ref_fields_initialized(v__checker__Checker* c, v__ast__Type typ, v__token__Pos* pos); VV_LOC void v__checker__Checker_do_check_elements_ref_fields_initialized(v__checker__Checker* c, v__ast__TypeSymbol* sym, Array_v__ast__Type* checked_types, v__token__Pos* pos); VV_LOC _result_void v__checker__Checker_check_elements_initialized(v__checker__Checker* c, v__ast__Type typ); VV_LOC v__ast__Type v__checker__Checker_check_append(v__checker__Checker* c, v__ast__InfixExpr* node, v__ast__Type left_type, v__ast__Type right_type, v__ast__TypeSymbol right_final_sym); VV_LOC void v__checker__Checker_add_error_detail(v__checker__Checker* c, string s); VV_LOC void v__checker__Checker_add_error_detail_with_pos(v__checker__Checker* c, string msg, v__token__Pos pos); VV_LOC void v__checker__Checker_add_instruction_for_option_type(v__checker__Checker* c); VV_LOC void v__checker__Checker_add_instruction_for_result_type(v__checker__Checker* c); VV_LOC void v__checker__Checker_warn(v__checker__Checker* c, string s, v__token__Pos pos); VV_LOC void v__checker__Checker_warn_alloc(v__checker__Checker* c, string s, v__token__Pos pos); VV_LOC void v__checker__Checker_error(v__checker__Checker* c, string message, v__token__Pos pos); VV_LOC void v__checker__Checker_fatal(v__checker__Checker* c, string message, v__token__Pos pos); VV_LOC void v__checker__Checker_note(v__checker__Checker* c, string message, v__token__Pos pos); VV_LOC void v__checker__Checker_warn_or_error(v__checker__Checker* c, string message, v__token__Pos pos, bool warn); VV_LOC void v__checker__Checker_deprecate(v__checker__Checker* c, string kind, string name, Array_v__ast__Attr attrs, v__token__Pos pos); VV_LOC string v__checker__semicolonize(string main, string details); VV_LOC void v__checker__Checker_fn_decl(v__checker__Checker* c, v__ast__FnDecl* node); VV_LOC bool v__checker__Checker_check_same_type_ignoring_pointers(v__checker__Checker* c, v__ast__Type type_a, v__ast__Type type_b); VV_LOC v__ast__Type v__checker__Checker_anon_fn(v__checker__Checker* c, v__ast__AnonFn* node); VV_LOC v__ast__Type v__checker__Checker_call_expr(v__checker__Checker* c, v__ast__CallExpr* node); VV_LOC void v__checker__Checker_builtin_args(v__checker__Checker* c, v__ast__CallExpr* node, string fn_name, v__ast__Fn* func); VV_LOC bool v__checker__Checker_needs_unwrap_generic_type(v__checker__Checker* c, v__ast__Type typ); VV_LOC v__ast__Type v__checker__Checker_fn_call(v__checker__Checker* c, v__ast__CallExpr* node, bool* continue_check); VV_LOC void v__checker__Checker_register_trace_call(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Fn* func); VV_LOC v__ast__Type v__checker__Checker_cast_fixed_array_ret(v__checker__Checker* c, v__ast__Type typ, v__ast__TypeSymbol sym); VV_LOC v__ast__Type v__checker__Checker_cast_to_fixed_array_ret(v__checker__Checker* c, v__ast__Type typ, v__ast__TypeSymbol sym); VV_LOC bool v__checker__Checker_check_type_sym_kind(v__checker__Checker* c, string name, int type_idx, v__ast__Kind* expected_kind, v__token__Pos* pos); VV_LOC bool v__checker__Checker_check_type_and_visibility(v__checker__Checker* c, string name, int type_idx, v__ast__Kind* expected_kind, v__token__Pos* pos); VV_LOC v__ast__Type v__checker__Checker_method_call(v__checker__Checker* c, v__ast__CallExpr* node, bool* continue_check); VV_LOC void v__checker__Checker_handle_generic_lambda_arg(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__LambdaExpr* lambda); VV_LOC v__ast__Type v__checker__Checker_spawn_expr(v__checker__Checker* c, v__ast__SpawnExpr* node); VV_LOC v__ast__Type v__checker__Checker_go_expr(v__checker__Checker* c, v__ast__GoExpr* node); VV_LOC void v__checker__Checker_set_node_expected_arg_types(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Fn* func); VV_LOC _result_void v__checker__Checker_post_process_generic_fns(v__checker__Checker* c); VV_LOC _result_void v__checker__Checker_check_expected_arg_count(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Fn* f); VV_LOC void v__checker__Checker_fn_call_error_have_want(v__checker__Checker* c, v__checker__HaveWantParams p); VV_LOC void v__checker__Checker_check_predicate_param(v__checker__Checker* c, bool is_map, v__ast__Type elem_typ, v__ast__CallExpr node); VV_LOC v__ast__Type v__checker__Checker_map_builtin_method_call(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Type left_type_); VV_LOC void v__checker__Checker_ensure_same_array_return_type(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Type left_type); VV_LOC v__ast__Type v__checker__Checker_array_builtin_method_call(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Type left_type); VV_LOC v__ast__Type v__checker__Checker_fixed_array_builtin_method_call(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Type left_type); VV_LOC multi_return_string_v__token__Pos v__checker__Checker_check_for_mut_receiver(v__checker__Checker* c, v__ast__Expr* expr); VV_LOC void v__checker__scope_register_it(v__ast__Scope* s, v__token__Pos pos, v__ast__Type typ); VV_LOC void v__checker__scope_register_a_b(v__ast__Scope* s, v__token__Pos pos, v__ast__Type typ); VV_LOC void v__checker__scope_register_var_name(v__ast__Scope* s, v__token__Pos pos, v__ast__Type typ, string name); VV_LOC v__ast__Type v__checker__Checker_resolve_fn_return_type(v__checker__Checker* c, v__ast__Fn* func, v__ast__CallExpr node, Array_v__ast__Type concrete_types); VV_LOC void v__checker__Checker_check_must_use_call_result(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Fn* f, string label); VV_LOC bool v__checker__Checker_has_veb_context(v__checker__Checker* c, v__ast__Type typ); VV_LOC void v__checker__Checker_for_c_stmt(v__checker__Checker* c, v__ast__ForCStmt* node); VV_LOC void v__checker__Checker_for_in_stmt(v__checker__Checker* c, v__ast__ForInStmt* node); VV_LOC void v__checker__Checker_for_stmt(v__checker__Checker* c, v__ast__ForStmt* node); VV_LOC v__checker__ComptimeBranchSkipState v__checker__Checker_check_compatible_types(v__checker__Checker* c, v__ast__Type left_type, v__ast__TypeNode right); VV_LOC v__ast__Type v__checker__Checker_if_expr(v__checker__Checker* c, v__ast__IfExpr* node); VV_LOC void v__checker__Checker_smartcast_if_conds(v__checker__Checker* c, v__ast__Expr* node, v__ast__Scope* scope, v__ast__Expr control_expr); VV_LOC void v__checker__Checker_check_non_expr_branch_last_stmt(v__checker__Checker* c, Array_v__ast__Stmt stmts); VV_LOC v__ast__Type v__checker__Checker_infix_expr(v__checker__Checker* c, v__ast__InfixExpr* node); VV_LOC void v__checker__Checker_check_div_mod_by_zero(v__checker__Checker* c, v__ast__Expr expr, v__token__Kind op_kind); VV_LOC void v__checker__Checker_check_duplicated_items(v__checker__Checker* c, v__ast__ArrayInit* node); VV_LOC v__ast__Type v__checker__Checker_check_like_operator(v__checker__Checker* c, v__ast__InfixExpr* node); VV_LOC void v__checker__Checker_invalid_operator_error(v__checker__Checker* c, v__token__Kind op, v__ast__Type left_type, v__ast__Type right_type, v__token__Pos pos); VV_LOC void v__checker__Checker_autocast_in_if_conds(v__checker__Checker* c, v__ast__Expr* right, v__ast__Expr from_expr, v__ast__Type from_type, v__ast__Type to_type); VV_LOC bool v__checker__Checker_check_sort_external_variable_access(v__checker__Checker* c, v__ast__Expr node); VV_LOC void v__checker__Checker_interface_decl(v__checker__Checker* c, v__ast__InterfaceDecl* node); VV_LOC v__ast__Type v__checker__Checker_unwrap_generic_interface(v__checker__Checker* c, v__ast__Type typ, v__ast__Type interface_type, v__token__Pos pos); v__ast__Type v__checker__Checker_lambda_expr(v__checker__Checker* c, v__ast__LambdaExpr* node, v__ast__Type exp_typ); void v__checker__Checker_lambda_expr_fix_type_of_param(v__checker__Checker* c, v__ast__LambdaExpr* node, v__ast__Ident* pident, v__ast__Type ptype); void v__checker__Checker_support_lambda_expr_in_sort(v__checker__Checker* c, v__ast__Type param_type, v__ast__Type return_type, v__ast__LambdaExpr* expr); void v__checker__Checker_support_lambda_expr_one_param(v__checker__Checker* c, v__ast__Type param_type, v__ast__Type return_type, v__ast__LambdaExpr* expr); VV_LOC v__ast__Type v__checker__Checker_match_expr(v__checker__Checker* c, v__ast__MatchExpr* node); VV_LOC void v__checker__Checker_check_match_branch_last_stmt(v__checker__Checker* c, v__ast__ExprStmt last_stmt, v__ast__Type ret_type, v__ast__Type expr_type); VV_LOC _option_i64 v__checker__Checker_get_comptime_number_value(v__checker__Checker* c, v__ast__Expr* expr); VV_LOC void v__checker__Checker_match_exprs(v__checker__Checker* c, v__ast__MatchExpr* node, v__ast__TypeSymbol cond_type_sym); VV_LOC v__ast__Type v__checker__Checker_sql_expr(v__checker__Checker* c, v__ast__SqlExpr* node); VV_LOC v__ast__Type v__checker__Checker_sql_stmt(v__checker__Checker* c, v__ast__SqlStmt* node); VV_LOC v__ast__Type v__checker__Checker_sql_stmt_line(v__checker__Checker* c, v__ast__SqlStmtLine* node); VV_LOC void v__checker__Checker_check_orm_struct_field_attrs(v__checker__Checker* c, v__ast__SqlStmtLine node, v__ast__StructField field); VV_LOC void v__checker__Checker_check_orm_non_primitive_struct_field_attrs(v__checker__Checker* c, v__ast__StructField field); VV_LOC Array_v__ast__StructField v__checker__Checker_fetch_and_check_orm_fields(v__checker__Checker* c, v__ast__Struct info, v__token__Pos pos, string table_name); VV_LOC void v__checker__Checker_check_sql_value_expr_is_comptime_with_natural_number_or_expr_with_int_type(v__checker__Checker* c, v__ast__Expr* expr, string sql_keyword); VV_LOC void v__checker__Checker_check_sql_expr_type_is_int(v__checker__Checker* c, v__ast__Expr* expr, string sql_keyword); VV_LOC void v__checker__Checker_orm_error(v__checker__Checker* c, string message, v__token__Pos pos); VV_LOC void v__checker__Checker_check_expr_has_no_fn_calls_with_non_orm_return_type(v__checker__Checker* c, v__ast__Expr* expr); VV_LOC void v__checker__Checker_check_where_expr_has_no_pointless_exprs(v__checker__Checker* c, v__ast__TypeSymbol* table_type_symbol, Array_string field_names, v__ast__Expr* expr); VV_LOC string v__checker__Checker_fn_return_type_flag_to_string(v__checker__Checker* _d1, v__ast__Type typ); VV_LOC void v__checker__Checker_check_orm_or_expr(v__checker__Checker* c, v__checker__ORMExpr* expr); VV_LOC bool v__checker__Checker_check_db_expr(v__checker__Checker* c, v__ast__Expr* db_expr); VV_LOC bool v__checker__Checker_check_orm_table_expr_type(v__checker__Checker* c, v__ast__TypeNode* type_node); VV_LOC v__ast__Type v__checker__Checker_get_field_foreign_table_type(v__checker__Checker* c, v__ast__StructField* table_field); VV_LOC Array_v__ast__StructField v__checker__Checker_get_orm_non_primitive_fields(v__checker__Checker* c, Array_v__ast__StructField fields); VV_LOC bool v__checker__Checker_check_field_of_inserting_struct_is_uninitialized(v__checker__Checker* _d1, v__ast__SqlStmtLine* node, string field_name); VV_LOC bool v__checker__Checker_check_recursive_structs(v__checker__Checker* c, v__ast__TypeSymbol* ts, string struct_name); VV_LOC multi_return_v__ast__Type_ref_v__ast__TypeSymbol v__checker__Checker_get_non_array_type(v__checker__Checker* c, v__ast__Type typ_); VV_LOC v__ast__Type v__checker__Checker_postfix_expr(v__checker__Checker* c, v__ast__PostfixExpr* node); VV_LOC string v__checker__Checker_error_type_name(v__checker__Checker* c, v__ast__Type exp_type); VV_LOC void v__checker__Checker_return_stmt(v__checker__Checker* c, v__ast__Return* node); VV_LOC void v__checker__Checker_find_unreachable_statements_after_noreturn_calls(v__checker__Checker* c, Array_v__ast__Stmt stmts); VV_LOC bool v__checker__has_top_return(Array_v__ast__Stmt stmts); VV_LOC void v__checker__Checker_check_noreturn_fn_decl(v__checker__Checker* c, v__ast__FnDecl* node); VV_LOC bool v__checker__uses_return_stmt(Array_v__ast__Stmt stmts); VV_LOC bool v__checker__is_noreturn_callexpr(v__ast__Expr expr); VV_LOC u8 v__checker__Checker_get_default_fmt(v__checker__Checker* c, v__ast__Type ftyp, v__ast__Type typ); VV_LOC v__ast__Type v__checker__Checker_string_inter_lit(v__checker__Checker* c, v__ast__StringInterLiteral* node); VV_LOC v__ast__Type v__checker__Checker_string_lit(v__checker__Checker* c, v__ast__StringLiteral* node); VV_LOC v__ast__Type v__checker__Checker_int_lit(v__checker__Checker* c, v__ast__IntegerLiteral* node); VV_LOC _result_void v__checker__Checker_check_num_literal(v__checker__Checker* c, v__checker__LoHiLimit lohi, bool is_neg, string lit); VV_LOC void v__checker__Checker_num_lit_overflow_error(v__checker__Checker* c, v__ast__IntegerLiteral* node); VV_LOC void v__checker__Checker_struct_decl(v__checker__Checker* c, v__ast__StructDecl* node); VV_LOC int v__checker__minify_sort_fn(v__ast__StructField* a, v__ast__StructField* b); VV_LOC v__ast__Type v__checker__Checker_struct_init(v__checker__Checker* c, v__ast__StructInit* node, bool is_field_zero_struct_init, Array_string* inited_fields); VV_LOC void v__checker__Checker_check_uninitialized_struct_fields_and_embeds(v__checker__Checker* c, v__ast__StructInit node, v__ast__TypeSymbol type_sym, v__ast__Struct* info, Array_string* inited_fields); VV_LOC void v__checker__Checker_check_ref_fields_initialized(v__checker__Checker* c, v__ast__TypeSymbol* struct_sym, Array_v__ast__Type* checked_types, string linked_name, v__token__Pos* pos); VV_LOC void v__checker__Checker_check_ref_fields_initialized_note(v__checker__Checker* c, v__ast__TypeSymbol* struct_sym, Array_v__ast__Type* checked_types, string linked_name, v__token__Pos* pos); VV_LOC bool v__checker__Checker_is_anon_struct_compatible(v__checker__Checker* c, v__ast__Struct s1, v__ast__Struct s2); VV_LOC void v__checker__Checker_markused_comptime_call(v__checker__Checker* c, bool check, string key); VV_LOC void v__checker__Checker_markused_assertstmt_auto_str(v__checker__Checker* c, v__ast__AssertStmt* node); VV_LOC void v__checker__Checker_markused_dumpexpr(v__checker__Checker* c, v__ast__DumpExpr* node); VV_LOC void v__checker__Checker_markused_used_maps(v__checker__Checker* c, bool check); VV_LOC void v__checker__Checker_markused_castexpr(v__checker__Checker* c, v__ast__CastExpr* node, v__ast__Type to_type, v__ast__TypeSymbol* final_to_sym); VV_LOC void v__checker__Checker_markused_comptimecall(v__checker__Checker* c, v__ast__ComptimeCall* node); VV_LOC void v__checker__Checker_markused_comptimefor(v__checker__Checker* c, v__ast__ComptimeFor* node, v__ast__Type unwrapped_expr_type); VV_LOC void v__checker__Checker_markused_call_expr(v__checker__Checker* c, v__ast__Type left_type, v__ast__CallExpr* node); VV_LOC void v__checker__Checker_markused_fn_call(v__checker__Checker* c, v__ast__CallExpr* node); VV_LOC void v__checker__Checker_markused_method_call(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Expr* left_expr, v__ast__Type left_type); VV_LOC void v__checker__Checker_markused_string_inter_lit(v__checker__Checker* c, v__ast__StringInterLiteral* node, v__ast__Type ftyp); VV_LOC void v__checker__Checker_markused_infixexpr(v__checker__Checker* c, bool check); VV_LOC void v__checker__Checker_markused_array_method(v__checker__Checker* c, bool check, string method_name); VV_LOC v__ast__AsmStmt v__parser__Parser_asm_stmt(v__parser__Parser* p, bool is_top_level); VV_LOC v__ast__AsmArg v__parser__Parser_reg_or_alias(v__parser__Parser* p); VV_LOC v__ast__AsmAddressing v__parser__Parser_asm_addressing(v__parser__Parser* p); VV_LOC Array_v__ast__AsmIO v__parser__Parser_asm_ios(v__parser__Parser* p, bool output); VV_LOC v__ast__Stmt v__parser__Parser_assign_stmt(v__parser__Parser* p); VV_LOC _result_void v__parser__Parser_check_undefined_variables(v__parser__Parser* p, Array_string names, v__ast__Expr val); VV_LOC bool v__parser__Parser_check_cross_variables(v__parser__Parser* p, Array_v__ast__Expr exprs, v__ast__Expr val); VV_LOC v__ast__Stmt v__parser__Parser_partial_assign_stmt(v__parser__Parser* p, Array_v__ast__Expr left); VV_LOC v__ast__Attr v__parser__Parser_parse_attr(v__parser__Parser* p, bool is_at); VV_LOC bool v__parser__Parser_is_attributes(v__parser__Parser* p); VV_LOC void v__parser__Parser_attributes(v__parser__Parser* p); VV_LOC bool v__parser__Parser_is_fn_type_decl(v__parser__Parser* p); VV_LOC bool v__parser__Parser_has_prev_newline(v__parser__Parser* p); VV_LOC bool v__parser__Parser_has_prev_line_comment_or_label(v__parser__Parser* p); VV_LOC bool v__parser__Parser_is_array_type(v__parser__Parser* p); VV_LOC bool v__parser__Parser_is_following_concrete_types(v__parser__Parser* p); VV_LOC bool v__parser__Parser_is_generic_struct_init(v__parser__Parser* p); VV_LOC bool v__parser__Parser_is_typename(v__parser__Parser* p, v__token__Token t); VV_LOC bool v__parser__Parser_is_generic_call(v__parser__Parser* p); VV_LOC bool v__parser__Parser_is_generic_cast(v__parser__Parser* p); VV_LOC bool v__parser__Parser_is_generic_name(v__parser__Parser* p); void v__parser__Parser_codegen(v__parser__Parser* p, string code); VV_LOC void v__parser__Parser_handle_codegen_for_file(v__parser__Parser* p); VV_LOC void v__parser__handle_codegen_for_multiple_files(Array_v__ast__File_ptr* files); VV_LOC v__ast__ComptimeType v__parser__Parser_parse_comptime_type(v__parser__Parser* p); VV_LOC v__ast__HashStmt v__parser__Parser_hash(v__parser__Parser* p); VV_LOC v__ast__ComptimeCall v__parser__Parser_comptime_call(v__parser__Parser* p); VV_LOC v__ast__ComptimeFor v__parser__Parser_comptime_for(v__parser__Parser* p); VV_LOC v__ast__AtExpr v__parser__Parser_at(v__parser__Parser* p); VV_LOC v__ast__Expr v__parser__Parser_comptime_selector(v__parser__Parser* p, v__ast__Expr left); VV_LOC v__ast__ArrayInit v__parser__Parser_array_init(v__parser__Parser* p, bool is_option, v__ast__Type alias_array_type); VV_LOC v__ast__MapInit v__parser__Parser_map_init(v__parser__Parser* p); VV_LOC void v__parser__Parser_scope_register_index(v__parser__Parser* p); VV_LOC bool v__parser__Parser_handle_index_variable(v__parser__Parser* p, v__ast__Expr* default_expr); VV_LOC v__ast__EnumVal v__parser__Parser_enum_val_expr(v__parser__Parser* p, string mod); VV_LOC v__ast__EnumVal v__parser__Parser_enum_val(v__parser__Parser* p); VV_LOC v__ast__EnumDecl v__parser__Parser_enum_decl(v__parser__Parser* p); VV_LOC _result_void v__parser__Parser_check_expr_level(v__parser__Parser* p); VV_LOC v__ast__Expr v__parser__Parser_expr_no_value(v__parser__Parser* p, int precedence); VV_LOC v__ast__Expr v__parser__Parser_expr(v__parser__Parser* p, int precedence); VV_LOC _result_v__ast__Expr v__parser__Parser_check_expr(v__parser__Parser* p, int precedence); VV_LOC v__ast__Expr v__parser__Parser_expr_with_left(v__parser__Parser* p, v__ast__Expr left, int precedence, bool is_stmt_ident); VV_LOC v__ast__OrExpr v__parser__Parser_gen_or_block(v__parser__Parser* p); VV_LOC v__ast__Expr v__parser__Parser_infix_expr(v__parser__Parser* p, v__ast__Expr left); VV_LOC v__ast__Expr v__parser__Parser_prefix_expr(v__parser__Parser* p); VV_LOC void v__parser__Parser_recast_as_pointer(v__parser__Parser* p, v__ast__CastExpr* cast_expr, v__token__Pos pos); VV_LOC void v__parser__Parser_prefix_inc_dec_error(v__parser__Parser* p); VV_LOC void v__parser__Parser_process_custom_orm_operators(v__parser__Parser* p); VV_LOC _option_v__ast__LambdaExpr v__parser__Parser_lambda_expr(v__parser__Parser* p); VV_LOC v__ast__CallExpr v__parser__Parser_call_expr(v__parser__Parser* p, v__ast__Language language, string mod); VV_LOC Array_v__ast__CallArg v__parser__Parser_call_args(v__parser__Parser* p); VV_LOC v__ast__FnDecl v__parser__Parser_fn_decl(v__parser__Parser* p); VV_LOC _result_void v__parser__Parser_fn_receiver(v__parser__Parser* p, Array_v__ast__Param* params, v__parser__ReceiverParsingInfo* rec); VV_LOC v__ast__AnonFn v__parser__Parser_anon_fn(v__parser__Parser* p); VV_LOC multi_return_Array_v__ast__Param_bool_bool_bool v__parser__Parser_fn_params(v__parser__Parser* p); VV_LOC v__ast__SpawnExpr v__parser__Parser_spawn_expr(v__parser__Parser* p); VV_LOC v__ast__GoExpr v__parser__Parser_go_expr(v__parser__Parser* p); VV_LOC Array_v__ast__Param v__parser__Parser_closure_vars(v__parser__Parser* p); VV_LOC void v__parser__Parser_check_fn_mutable_arguments(v__parser__Parser* p, v__ast__Type typ, v__token__Pos pos); VV_LOC void v__parser__Parser_check_fn_shared_arguments(v__parser__Parser* p, v__ast__Type typ, v__token__Pos pos); VV_LOC void v__parser__Parser_check_fn_atomic_arguments(v__parser__Parser* p, v__ast__Type typ, v__token__Pos pos); VV_LOC v__ast__Stmt v__parser__Parser_for_stmt(v__parser__Parser* p); VV_LOC v__ast__IfExpr v__parser__Parser_if_expr(v__parser__Parser* p, bool is_comptime, bool is_expr); VV_LOC bool v__parser__Parser_is_only_array_type(v__parser__Parser* p); VV_LOC bool v__parser__Parser_is_match_sumtype_type(v__parser__Parser* p); VV_LOC v__ast__MatchExpr v__parser__Parser_match_expr(v__parser__Parser* p); VV_LOC v__ast__SelectExpr v__parser__Parser_select_expr(v__parser__Parser* p); VV_LOC v__ast__Expr v__parser__Parser_lockable(v__parser__Parser* p); VV_LOC Array_v__ast__Expr v__parser__Parser_lockable_list(v__parser__Parser* p); VV_LOC v__ast__LockExpr v__parser__Parser_lock_expr(v__parser__Parser* p); VV_LOC void v__parser__Parser_language_not_allowed_error(v__parser__Parser* p, v__ast__Language language, v__token__Pos pos); VV_LOC void v__parser__Parser_language_not_allowed_warning(v__parser__Parser* p, v__ast__Language language, v__token__Pos pos); VV_LOC void v__parser__Parser_check_for_impure_v(v__parser__Parser* p, v__ast__Language language, v__token__Pos pos); VV_LOC v__ast__NodeError v__parser__Parser_error(v__parser__Parser* p, string s); VV_LOC void v__parser__Parser_warn(v__parser__Parser* p, string s); VV_LOC v__ast__NodeError v__parser__Parser_error_with_pos(v__parser__Parser* p, string s, v__token__Pos pos); VV_LOC void v__parser__Parser_error_with_error(v__parser__Parser* p, v__errors__Error __v_error); VV_LOC void v__parser__Parser_warn_with_pos(v__parser__Parser* p, string s, v__token__Pos pos); VV_LOC void v__parser__Parser_note_with_pos(v__parser__Parser* p, string s, v__token__Pos pos); VV_LOC v__ast__NodeError v__parser__Parser_unexpected(v__parser__Parser* p, v__parser__ParamsForUnexpected params); VV_LOC v__ast__NodeError v__parser__Parser_unexpected_with_pos(v__parser__Parser* p, v__token__Pos pos, v__parser__ParamsForUnexpected params); VV_LOC bool v__parser__Parser_known_import(v__parser__Parser* p, string mod); VV_LOC string v__parser__Parser_prepend_mod(v__parser__Parser* p, string name); VV_LOC bool v__parser__Parser_is_used_import(v__parser__Parser* p, string alias); VV_LOC void v__parser__Parser_register_used_import(v__parser__Parser* p, string alias); VV_LOC void v__parser__Parser_register_used_import_for_symbol_name(v__parser__Parser* p, string sym_name); VV_LOC void v__parser__Parser_register_auto_import(v__parser__Parser* p, string alias); VV_LOC void v__parser__Parser_check_unused_imports(v__parser__Parser* p); VV_LOC v__ast__Module v__parser__Parser_module_decl(v__parser__Parser* p); VV_LOC v__ast__Import v__parser__Parser_import_stmt(v__parser__Parser* p); VV_LOC void v__parser__Parser_import_syms(v__parser__Parser* p, v__ast__Import* parent); VV_LOC v__ast__Expr v__parser__Parser_sql_expr(v__parser__Parser* p); VV_LOC v__ast__SqlStmt v__parser__Parser_sql_stmt(v__parser__Parser* p); VV_LOC v__ast__OrExpr v__parser__Parser_parse_sql_or_block(v__parser__Parser* p); VV_LOC v__ast__SqlStmtLine v__parser__Parser_parse_sql_stmt_line(v__parser__Parser* p); VV_LOC _option_bool v__parser__Parser_check_sql_keyword(v__parser__Parser* p, string name); VV_LOC v__ast__Expr v__parser__Parser_check_sql_where_expr_has_no_undefined_variables(v__parser__Parser* p, v__ast__Expr* expr, Array_string unacceptable_variable_names); VV_LOC v__ast__Type v__parser__Parser_parse_array_type(v__parser__Parser* p, v__token__Kind expecting, bool is_option); VV_LOC v__ast__Type v__parser__Parser_parse_map_type(v__parser__Parser* p); VV_LOC v__ast__Type v__parser__Parser_parse_chan_type(v__parser__Parser* p); VV_LOC v__ast__Type v__parser__Parser_parse_thread_type(v__parser__Parser* p); VV_LOC v__ast__Type v__parser__Parser_parse_multi_return_type(v__parser__Parser* p); VV_LOC v__ast__Type v__parser__Parser_parse_fn_type(v__parser__Parser* p, string name, Array_v__ast__Type generic_types); VV_LOC v__ast__Type v__parser__Parser_parse_type_with_mut(v__parser__Parser* p, bool is_mut); VV_LOC v__ast__Language v__parser__Parser_parse_language(v__parser__Parser* p); VV_LOC v__ast__Type v__parser__Parser_parse_inline_sum_type(v__parser__Parser* p); VV_LOC Array_v__ast__TypeNode v__parser__Parser_parse_sum_type_variants(v__parser__Parser* p); VV_LOC v__ast__Type v__parser__Parser_parse_type(v__parser__Parser* p); VV_LOC v__ast__Type v__parser__Parser_parse_any_type(v__parser__Parser* p, v__ast__Language language, bool is_ptr, bool check_dot, bool is_option); VV_LOC v__ast__Type v__parser__Parser_find_type_or_add_placeholder(v__parser__Parser* p, string name, v__ast__Language language); VV_LOC v__ast__Type v__parser__Parser_parse_generic_type(v__parser__Parser* p, string name); VV_LOC v__ast__Type v__parser__Parser_parse_generic_inst_type(v__parser__Parser* p, string name); VV_LOC _result_Array_string v__parser__Parser_types_to_names(v__parser__Parser* p, Array_v__ast__Type types, v__token__Pos pos, string error_label); v__ast__File* v__parser__parse_comptime(string tmpl_path, string text, v__ast__Table* table, v__pref__Preferences* pref_, v__ast__Scope* scope); v__ast__File* v__parser__parse_text(string text, string path, v__ast__Table* table, v__scanner__CommentsMode comments_mode, v__pref__Preferences* pref_); void v__parser__Parser_free(v__parser__Parser* p); VV_LOC void v__parser__Parser_free_scanner(v__parser__Parser* p); void v__parser__Parser_set_path(v__parser__Parser* p, string path); v__ast__File* v__parser__parse_file(string path, v__ast__Table* table, v__scanner__CommentsMode comments_mode, v__pref__Preferences* pref_); v__ast__File* v__parser__Parser_parse(v__parser__Parser* p); Array_v__ast__File_ptr v__parser__parse_files(Array_string paths, v__ast__Table* table, v__pref__Preferences* pref_); VV_LOC void v__parser__Parser_init_parse_fns(v__parser__Parser* p); VV_LOC void v__parser__Parser_read_first_token(v__parser__Parser* p); VV_LOC v__token__Token v__parser__Parser_peek_token(v__parser__Parser* p, int n); VV_LOC v__token__Token v__parser__Parser_peek_token_after_var_list(v__parser__Parser* p); VV_LOC void v__parser__Parser_open_scope(v__parser__Parser* p); VV_LOC void v__parser__Parser_close_scope(v__parser__Parser* p); VV_LOC Array_v__ast__Stmt v__parser__Parser_parse_block(v__parser__Parser* p); VV_LOC Array_v__ast__Stmt v__parser__Parser_parse_block_no_scope(v__parser__Parser* p, bool is_top_level); VV_LOC void v__parser__Parser_mark_last_call_return_as_used(v__parser__Parser* p, v__ast__Stmt* last_stmt); VV_LOC void v__parser__Parser_next(v__parser__Parser* p); VV_LOC void v__parser__Parser_check(v__parser__Parser* p, v__token__Kind expected); VV_LOC string v__parser__Parser_check_js_name(v__parser__Parser* p); VV_LOC bool v__parser__is_ident_name(string name); VV_LOC string v__parser__Parser_check_name(v__parser__Parser* p); VV_LOC v__ast__Stmt v__parser__Parser_top_stmt(v__parser__Parser* p); VV_LOC bool v__parser__comptime_if_expr_contains_top_stmt(v__ast__IfExpr if_expr); VV_LOC v__ast__Stmt v__parser__Parser_other_stmts(v__parser__Parser* p, v__ast__Stmt cur_stmt); VV_LOC v__ast__Comment v__parser__Parser_check_comment(v__parser__Parser* p); VV_LOC v__ast__Comment v__parser__Parser_comment(v__parser__Parser* p); VV_LOC v__ast__ExprStmt v__parser__Parser_comment_stmt(v__parser__Parser* p); VV_LOC Array_v__ast__Comment v__parser__Parser_eat_comments(v__parser__Parser* p, v__parser__EatCommentsConfig cfg); VV_LOC void v__parser__Parser_goto_eof(v__parser__Parser* p); VV_LOC v__ast__Stmt v__parser__Parser_stmt(v__parser__Parser* p, bool is_top_level); VV_LOC v__ast__DebuggerStmt v__parser__Parser_dbg_stmt(v__parser__Parser* p); VV_LOC v__ast__SemicolonStmt v__parser__Parser_semicolon_stmt(v__parser__Parser* p); VV_LOC Array_v__ast__Expr v__parser__Parser_expr_list(v__parser__Parser* p, bool expect_value); VV_LOC v__ast__Stmt v__parser__Parser_parse_multi_expr(v__parser__Parser* p, bool is_top_level); VV_LOC v__ast__Ident v__parser__Parser_ident(v__parser__Parser* p, v__ast__Language language); VV_LOC v__ast__Type v__parser__Parser_alias_array_type(v__parser__Parser* p); VV_LOC v__ast__Expr v__parser__Parser_name_expr(v__parser__Parser* p); VV_LOC multi_return_Array_v__ast__Stmt_v__token__Pos v__parser__Parser_or_block(v__parser__Parser* p, v__parser__OrBlockErrVarMode err_var_mode); VV_LOC v__ast__IndexExpr v__parser__Parser_index_expr(v__parser__Parser* p, v__ast__Expr left, bool is_gated); VV_LOC v__ast__Expr v__parser__Parser_dot_expr(v__parser__Parser* p, v__ast__Expr left); VV_LOC multi_return_Array_v__ast__Type_Array_string v__parser__Parser_parse_generic_types(v__parser__Parser* p); VV_LOC Array_v__ast__Type v__parser__Parser_parse_concrete_types(v__parser__Parser* p); VV_LOC v__ast__Expr v__parser__Parser_string_expr(v__parser__Parser* p); VV_LOC v__ast__Expr v__parser__Parser_parse_number_literal(v__parser__Parser* p); VV_LOC v__ast__ConstDecl v__parser__Parser_const_decl(v__parser__Parser* p); VV_LOC v__ast__Return v__parser__Parser_return_stmt(v__parser__Parser* p); VV_LOC v__ast__GlobalDecl v__parser__Parser_global_decl(v__parser__Parser* p); VV_LOC string v__parser__source_name(string name); VV_LOC v__ast__TypeDecl v__parser__Parser_type_decl(v__parser__Parser* p); VV_LOC v__ast__Expr v__parser__Parser_new_true_expr(v__parser__Parser* p); VV_LOC void v__parser__Parser_top_level_statement_start(v__parser__Parser* p); VV_LOC void v__parser__Parser_top_level_statement_end(v__parser__Parser* p); VV_LOC void v__parser__Parser_rewind_scanner_to_current_token_in_new_mode(v__parser__Parser* p); VV_LOC v__ast__Stmt v__parser__Parser_unsafe_stmt(v__parser__Parser* p); VV_LOC bool v__parser__Parser_disallow_declarations_in_script_mode(v__parser__Parser* p); VV_LOC void v__parser__Parser_add_defer_var(v__parser__Parser* p, v__ast__Ident ident); VV_LOC v__ast__StructDecl v__parser__Parser_struct_decl(v__parser__Parser* p, bool is_anon); VV_LOC v__ast__StructInit v__parser__Parser_struct_init(v__parser__Parser* p, string typ_str, v__ast__StructInitKind kind, bool is_option); VV_LOC v__ast__InterfaceDecl v__parser__Parser_interface_decl(v__parser__Parser* p); VV_LOC void v__parser__State_update(v__parser__State* state, string line); VV_LOC bool v__parser__is_html_open_tag(string name, string s); VV_LOC string v__parser__insert_template_code(string fn_name, string tmpl_str_start, string line); VV_LOC string v__parser__IncludeError_msg(v__parser__IncludeError err); VV_LOC int v__parser__IncludeError_line_nr(v__parser__IncludeError err); VV_LOC int v__parser__IncludeError_pos(v__parser__IncludeError err); VV_LOC string v__parser__IncludeError_calling_file(v__parser__IncludeError err); VV_LOC int v__parser__IncludeError_col(v__parser__IncludeError err); VV_LOC _result_Array_string v__parser__Parser_process_includes(v__parser__Parser* p, string calling_file, int line_number, string line, v__parser__DependencyCache* dc); string v__parser__Parser_compile_template_file(v__parser__Parser* p, string template_file, string fn_name); void v__callgraph__show(v__ast__Table* table, v__pref__Preferences* pref_, Array_v__ast__File_ptr ast_files); VV_LOC string v__callgraph__Mapper_dot_normalise_node_name(v__callgraph__Mapper* m, string name); VV_LOC string v__callgraph__Mapper_fn_name(v__callgraph__Mapper* m, string fname, v__ast__Type receiver_type, bool is_method); VV_LOC string v__callgraph__Mapper_dot_fn_name(v__callgraph__Mapper* m, string fname, v__ast__Type recv_type, bool is_method); VV_LOC _result_void v__callgraph__Mapper_visit(v__callgraph__Mapper* m, v__ast__Node* node); VV_LOC void v__gen__c__Gen_array_init(v__gen__c__Gen* g, v__ast__ArrayInit node, string var_name); VV_LOC void v__gen__c__Gen_fixed_array_init(v__gen__c__Gen* g, v__ast__ArrayInit node, v__gen__c__Type array_type, string var_name, bool is_amp); VV_LOC void v__gen__c__Gen_expr_with_init(v__gen__c__Gen* g, v__ast__ArrayInit node); VV_LOC bool v__gen__c__Gen_struct_has_array_or_map_field(v__gen__c__Gen* g, v__ast__Type elem_typ); VV_LOC void v__gen__c__Gen_array_init_with_fields(v__gen__c__Gen* g, v__ast__ArrayInit node, v__gen__c__Type elem_type, bool is_amp, string shared_styp, string var_name); VV_LOC void v__gen__c__Gen_declare_closure_fn(v__gen__c__Gen* g, v__ast__AnonFn* expr, string var_name); VV_LOC void v__gen__c__Gen_write_closure_fn(v__gen__c__Gen* g, v__ast__AnonFn* expr, string var_name, string declared_var); VV_LOC void v__gen__c__Gen_gen_array_map(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_array_sorted(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_array_sort(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_array_sort_call(v__gen__c__Gen* g, v__ast__CallExpr node, string compare_fn, bool is_array); VV_LOC void v__gen__c__Gen_gen_fixed_array_sorted_with_compare(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_fixed_array_sort_with_compare(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_fixed_array_reverse(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_fixed_array_reverse_in_place(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_array_filter(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_array_insert(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_array_prepend(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC string v__gen__c__Gen_get_array_contains_method(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_gen_array_contains_methods(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_gen_array_contains(v__gen__c__Gen* g, v__ast__Type left_type, v__ast__Expr left, v__ast__Type right_type, v__ast__Expr right); VV_LOC string v__gen__c__Gen_get_array_index_method(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_gen_array_index_methods(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_gen_array_index(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_array_wait(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_fixed_array_wait(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_array_any(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_array_count(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_array_all(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC bool v__gen__c__Gen_write_prepared_tmp_value(v__gen__c__Gen* g, string tmp, v__ast__CallExpr* node, string tmp_stype, string initial_value); VV_LOC void v__gen__c__Gen_write_prepared_var(v__gen__c__Gen* g, string var_name, v__ast__Type elem_type, string inp_elem_type, string tmp, string i, bool is_array, bool auto_heap); VV_LOC void v__gen__c__Gen_fixed_array_init_with_cast(v__gen__c__Gen* g, v__ast__ArrayInit expr, v__ast__Type typ); VV_LOC void v__gen__c__Gen_fixed_array_update_expr_field(v__gen__c__Gen* g, string expr_str, v__ast__Type field_type, string field_name, bool is_auto_deref, v__ast__Type elem_type, int size, bool is_update_embed); VV_LOC void v__gen__c__Gen_fixed_array_var_init(v__gen__c__Gen* g, string expr_str, bool is_auto_deref, v__ast__Type elem_type, int size); VV_LOC string v__gen__c__Gen_get_array_expr_param_name(v__gen__c__Gen* g, v__ast__Expr* expr); VV_LOC void v__gen__c__Gen_add_commas_and_prevent_long_lines(v__gen__c__Gen* g, int i, int len); VV_LOC bool v__gen__c__Gen_can_use_c99_designators(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_write_all_n_elements_for_array(v__gen__c__Gen* g, int len, string value); VV_LOC void v__gen__c__Gen_write_c99_elements_for_array(v__gen__c__Gen* g, int len, string value); VV_LOC void v__gen__c__Gen_write_c99_0_elements_for_array(v__gen__c__Gen* g, int len); VV_LOC void v__gen__c__Gen_assert_stmt(v__gen__c__Gen* g, v__ast__AssertStmt original_assert_statement); VV_LOC _result_v__ast__Expr v__gen__c__Gen_assert_subexpression_to_ctemp(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_type); VV_LOC void v__gen__c__Gen_gen_assert_postfailure_mode(v__gen__c__Gen* g, v__ast__AssertStmt node); VV_LOC string v__gen__c__Gen_gen_assert_metainfo(v__gen__c__Gen* g, v__ast__AssertStmt node, v__gen__c__AssertMetainfoKind kind); VV_LOC void v__gen__c__Gen_gen_assert_single_expr(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type typ); VV_LOC void v__gen__c__Gen_expr_with_opt_or_block(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_typ, v__ast__Expr var_expr, v__ast__Type ret_typ, bool in_heap); VV_LOC string v__gen__c__Gen_expr_opt_with_alias(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_typ, v__ast__Type ret_typ); VV_LOC string v__gen__c__Gen_expr_opt_with_cast(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_typ, v__ast__Type ret_typ); VV_LOC string v__gen__c__Gen_expr_with_opt(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_typ, v__ast__Type ret_typ); VV_LOC void v__gen__c__Gen_assign_stmt(v__gen__c__Gen* g, v__ast__AssignStmt node_); VV_LOC void v__gen__c__Gen_gen_multi_return_assign(v__gen__c__Gen* g, v__ast__AssignStmt* node, v__ast__Type return_type, v__ast__TypeSymbol return_sym); VV_LOC void v__gen__c__Gen_gen_cross_var_assign(v__gen__c__Gen* g, v__ast__AssignStmt* node); VV_LOC void v__gen__c__Gen_gen_cross_tmp_variable(v__gen__c__Gen* g, Array_v__ast__Expr left, v__ast__Expr val); VV_LOC string v__gen__c__Gen_equality_fn(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_gen_equality_fns(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_gen_sumtype_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type); VV_LOC string v__gen__c__Gen_read_opt(v__gen__c__Gen* g, v__ast__Type typ, string var_name); VV_LOC string v__gen__c__Gen_read_field(v__gen__c__Gen* g, v__ast__Type struct_type, string field_name, string var_name); VV_LOC string v__gen__c__Gen_read_map_from_option(v__gen__c__Gen* g, v__ast__Type typ, string var_name); VV_LOC string v__gen__c__Gen_read_map_field_from_option(v__gen__c__Gen* g, v__ast__Type typ, string field_name, string var_name); VV_LOC string v__gen__c__Gen_read_opt_field(v__gen__c__Gen* g, v__ast__Type struct_type, string field_name, string var_name, v__ast__Type field_typ); VV_LOC string v__gen__c__Gen_gen_struct_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type); VV_LOC string v__gen__c__Gen_gen_alias_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type); VV_LOC string v__gen__c__Gen_gen_array_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type); VV_LOC string v__gen__c__Gen_gen_fixed_array_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type); VV_LOC string v__gen__c__Gen_gen_map_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type); VV_LOC string v__gen__c__Gen_gen_interface_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type); VV_LOC void v__gen__c__Gen_register_free_method(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC string v__gen__c__Gen_get_free_method(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_gen_free_methods(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_gen_free_method(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_gen_free_for_interface(v__gen__c__Gen* g, v__ast__TypeSymbol sym, v__ast__Interface info, string styp, string fn_name); VV_LOC void v__gen__c__Gen_gen_free_for_struct(v__gen__c__Gen* g, v__ast__Type typ, v__ast__Struct info, string styp, string fn_name); VV_LOC string v__gen__c__Gen_gen_type_name_for_free_call(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_gen_free_for_array(v__gen__c__Gen* g, v__ast__Array info, string styp, string fn_name); VV_LOC void v__gen__c__Gen_gen_free_for_map(v__gen__c__Gen* g, v__ast__Type typ, string styp, string fn_name); VV_LOC string v__gen__c__styp_to_free_fn_name(string styp); VV_LOC void v__gen__c__Gen_gen_str_default(v__gen__c__Gen* g, v__ast__TypeSymbol sym, string styp, string str_fn_name); VV_LOC string v__gen__c__Gen_get_str_fn(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_final_gen_str(v__gen__c__Gen* g, v__gen__c__StrType typ); VV_LOC void v__gen__c__Gen_gen_str_for_option(v__gen__c__Gen* g, v__ast__Type typ, string styp, string str_fn_name); VV_LOC void v__gen__c__Gen_gen_str_for_result(v__gen__c__Gen* g, v__ast__Type typ, string styp, string str_fn_name); VV_LOC void v__gen__c__Gen_gen_str_for_alias(v__gen__c__Gen* g, v__ast__Alias info, string styp, string str_fn_name); VV_LOC void v__gen__c__Gen_gen_str_for_multi_return(v__gen__c__Gen* g, v__ast__MultiReturn info, string styp, string str_fn_name); VV_LOC void v__gen__c__Gen_gen_str_for_enum(v__gen__c__Gen* g, v__ast__Enum info, string styp, string str_fn_name); VV_LOC void v__gen__c__Gen_gen_str_for_interface(v__gen__c__Gen* g, v__ast__Interface info, string styp, string typ_str, string str_fn_name); VV_LOC void v__gen__c__Gen_gen_str_for_union_sum_type(v__gen__c__Gen* g, v__ast__SumType info, string styp, string typ_str, string str_fn_name); VV_LOC string v__gen__c__Gen_fn_decl_str(v__gen__c__Gen* g, v__ast__FnType info); VV_LOC void v__gen__c__Gen_gen_str_for_fn_type(v__gen__c__Gen* g, v__ast__FnType info, string styp, string str_fn_name); VV_LOC void v__gen__c__Gen_gen_str_for_chan(v__gen__c__Gen* g, v__ast__Chan info, string styp, string str_fn_name); VV_LOC void v__gen__c__Gen_gen_str_for_thread(v__gen__c__Gen* g, v__ast__Thread info, string styp, string str_fn_name); VV_LOC string v__gen__c__styp_to_str_fn_name(string styp); VV_LOC multi_return_string_string v__gen__c__deref_kind(bool str_method_expects_ptr, bool is_elem_ptr, v__ast__Type typ); VV_LOC void v__gen__c__Gen_gen_str_for_array(v__gen__c__Gen* g, v__ast__Array info, string styp, string str_fn_name); VV_LOC void v__gen__c__Gen_gen_str_for_array_fixed(v__gen__c__Gen* g, v__ast__ArrayFixed info, string styp, string str_fn_name); VV_LOC void v__gen__c__Gen_gen_str_for_map(v__gen__c__Gen* g, v__ast__Map info, string styp, string str_fn_name); VV_LOC StrIntpType v__gen__c__Gen_type_to_fmt(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_gen_str_for_struct(v__gen__c__Gen* g, v__ast__Struct info, v__ast__Language lang, string styp, string typ_str, string str_fn_name); VV_LOC string v__gen__c__c_struct_ptr(v__ast__TypeSymbol* sym, v__ast__Type typ, bool expects_ptr); VV_LOC multi_return_string_bool v__gen__c__struct_auto_str_func(v__ast__TypeSymbol* sym, v__ast__Language lang, v__ast__Type _field_type, string fn_name, string field_name, bool has_custom_str, bool expects_ptr); VV_LOC string v__gen__c__data_str(StrIntpType x); VV_LOC bool v__gen__c__should_use_indent_func(v__ast__Kind kind); VV_LOC multi_return_string_int v__gen__c__Gen_get_enum_type_idx_from_fn_name(v__gen__c__Gen* g, string fn_name); VV_LOC void v__gen__c__Gen_gen_enum_static_from_string(v__gen__c__Gen* g, string fn_name, string mod_enum_name, int idx); VV_LOC void v__gen__c__Gen_autofree_scope_vars(v__gen__c__Gen* g, int pos, int line_nr, bool free_parent_scopes); VV_LOC void v__gen__c__Gen_autofree_scope_vars_stop(v__gen__c__Gen* g, int pos, int line_nr, bool free_parent_scopes, int stop_pos); VV_LOC void v__gen__c__Gen_print_autofree_var(v__gen__c__Gen* g, v__ast__Var var, string comment); VV_LOC void v__gen__c__Gen_autofree_scope_vars2(v__gen__c__Gen* g, v__ast__Scope* scope, int start_pos, int end_pos, int line_nr, bool free_parent_scopes, int stop_pos); VV_LOC void v__gen__c__Gen_autofree_variable(v__gen__c__Gen* g, v__ast__Var v); VV_LOC void v__gen__c__Gen_autofree_var_call(v__gen__c__Gen* g, string free_fn_name, v__ast__Var v); v__gen__c__GenOutput v__gen__c__gen(Array_v__ast__File_ptr files, v__ast__Table* table, v__pref__Preferences* pref_); VV_LOC v__gen__c__Gen* v__gen__c__cgen_process_one_file_cb(sync__pool__PoolProcessor* p, int idx, int wid); void v__gen__c__Gen_free_builders(v__gen__c__Gen* g); void v__gen__c__Gen_gen_file(v__gen__c__Gen* g); string v__gen__c__Gen_hashes(v__gen__c__Gen* g); void v__gen__c__Gen_init(v__gen__c__Gen* g); void v__gen__c__Gen_finish(v__gen__c__Gen* g); string v__gen__c__Gen_get_sumtype_variant_type_name(v__gen__c__Gen* g, v__ast__Type typ, v__ast__TypeSymbol sym); string v__gen__c__Gen_get_sumtype_variant_name(v__gen__c__Gen* g, v__ast__Type typ, v__ast__TypeSymbol sym); void v__gen__c__Gen_write_typeof_functions(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_styp(v__gen__c__Gen* g, v__ast__Type t); VV_LOC string v__gen__c__Gen_base_type(v__gen__c__Gen* g, v__ast__Type _t); VV_LOC string v__gen__c__Gen_generic_fn_name(v__gen__c__Gen* g, Array_v__ast__Type types, string before); VV_LOC string v__gen__c__Gen_expr_string(v__gen__c__Gen* g, v__ast__Expr expr); VV_LOC string v__gen__c__Gen_expr_string_opt(v__gen__c__Gen* g, v__ast__Type typ, v__ast__Expr expr); VV_LOC string v__gen__c__Gen_expr_string_with_cast(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type typ, v__ast__Type exp); VV_LOC string v__gen__c__Gen_expr_string_surround(v__gen__c__Gen* g, string prepend, v__ast__Expr expr, string append); VV_LOC multi_return_string_string v__gen__c__Gen_option_type_name(v__gen__c__Gen* g, v__ast__Type t); VV_LOC multi_return_string_string v__gen__c__Gen_result_type_name(v__gen__c__Gen* g, v__ast__Type t); VV_LOC string v__gen__c__Gen_option_type_text(v__gen__c__Gen* g, string styp, string base); VV_LOC string v__gen__c__Gen_result_type_text(v__gen__c__Gen* g, string styp, string base); VV_LOC string v__gen__c__Gen_register_option(v__gen__c__Gen* g, v__ast__Type t); VV_LOC string v__gen__c__Gen_register_result(v__gen__c__Gen* g, v__ast__Type t); VV_LOC void v__gen__c__Gen_write_options(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_write_results(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_find_or_register_shared(v__gen__c__Gen* g, v__ast__Type t, string base); VV_LOC void v__gen__c__Gen_write_shareds(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_register_thread_void_wait_call(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_register_thread_array_wait_call(v__gen__c__Gen* g, string eltyp); VV_LOC string v__gen__c__Gen_register_thread_fixed_array_wait_call(v__gen__c__Gen* g, v__ast__CallExpr node, string eltyp); VV_LOC void v__gen__c__Gen_register_chan_pop_option_call(v__gen__c__Gen* g, string opt_el_type, string styp); VV_LOC void v__gen__c__Gen_write_chan_pop_option_fns(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_register_chan_push_option_fn(v__gen__c__Gen* g, string el_type, string styp); VV_LOC void v__gen__c__Gen_write_chan_push_option_fns(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_cc_type(v__gen__c__Gen* g, v__ast__Type typ, bool is_prefix_struct); VV_LOC string v__gen__c__Gen_type_sidx(v__gen__c__Gen* g, v__ast__Type t); void v__gen__c__Gen_write_typedef_types(v__gen__c__Gen* g); void v__gen__c__Gen_write_alias_typesymbol_declaration(v__gen__c__Gen* g, v__ast__TypeSymbol sym); void v__gen__c__Gen_write_interface_typedef(v__gen__c__Gen* g, v__ast__TypeSymbol sym); void v__gen__c__Gen_write_interface_typesymbol_declaration(v__gen__c__Gen* g, v__ast__TypeSymbol sym); void v__gen__c__Gen_write_fn_typesymbol_declaration(v__gen__c__Gen* g, v__ast__TypeSymbol sym); void v__gen__c__Gen_write_array_fixed_return_types(v__gen__c__Gen* g); void v__gen__c__Gen_write_multi_return_types(v__gen__c__Gen* g); VV_LOC string v__gen__c__prefix_with_counter(string prefix, int counter); string v__gen__c__Gen_new_tmp_var(v__gen__c__Gen* g); int v__gen__c__Gen_reset_tmp_count(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_decrement_inside_ternary(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_stmts(v__gen__c__Gen* g, Array_v__ast__Stmt stmts); VV_LOC bool v__gen__c__is_noreturn_callexpr(v__ast__Expr expr); VV_LOC bool v__gen__c__Gen_stmts_with_tmp_var(v__gen__c__Gen* g, Array_v__ast__Stmt stmts, string tmp_var); VV_LOC void v__gen__c__Gen_expr_with_tmp_var(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_typ, v__ast__Type ret_typ, string tmp_var); VV_LOC void v__gen__c__Gen_write_v_source_line_info_pos(v__gen__c__Gen* g, v__token__Pos pos); VV_LOC void v__gen__c__Gen_write_v_source_line_info(v__gen__c__Gen* g, v__ast__Node node); VV_LOC void v__gen__c__Gen_write_v_source_line_info_stmt(v__gen__c__Gen* g, v__ast__Stmt stmt); VV_LOC void v__gen__c__Gen_stmt(v__gen__c__Gen* g, v__ast__Stmt node); VV_LOC void v__gen__c__Gen_write_defer_stmts(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_get_sumtype_casting_fn(v__gen__c__Gen* g, v__ast__Type got_, v__ast__Type exp_); VV_LOC void v__gen__c__Gen_write_sumtype_casting_fn(v__gen__c__Gen* g, v__gen__c__SumtypeCastingFn fun); VV_LOC void v__gen__c__Gen_call_cfn_for_casting_expr(v__gen__c__Gen* g, string fname, v__ast__Expr expr, v__ast__Type exp, v__ast__Type got, string exp_styp, bool got_is_ptr, bool got_is_fn, string got_styp); VV_LOC string v__gen__c__Gen_expr_with_var(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expected_type, bool do_cast); VV_LOC string v__gen__c__Gen_expr_with_fixed_array(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type got_type_raw, v__ast__Type expected_type); VV_LOC void v__gen__c__Gen_expr_with_cast(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type got_type_raw, v__ast__Type expected_type); VV_LOC void v__gen__c__write_octal_escape(strings__Builder* b, u8 c); VV_LOC string v__gen__c__cescape_nonascii(string original); VV_LOC string v__gen__c__cestring(string s); VV_LOC string v__gen__c__ctoslit(string s); VV_LOC void v__gen__c__Gen_gen_attrs(v__gen__c__Gen* g, Array_v__ast__Attr attrs); VV_LOC void v__gen__c__Gen_asm_stmt(v__gen__c__Gen* g, v__ast__AsmStmt stmt); VV_LOC void v__gen__c__Gen_asm_arg(v__gen__c__Gen* g, v__ast__AsmArg arg, v__ast__AsmStmt stmt); VV_LOC void v__gen__c__Gen_gen_asm_ios(v__gen__c__Gen* g, Array_v__ast__AsmIO ios); VV_LOC string v__gen__c__cnewlines(string s); VV_LOC void v__gen__c__Gen_write_fn_ptr_decl(v__gen__c__Gen* g, v__ast__FnType* func, string ptr_name); VV_LOC void v__gen__c__Gen_register_ternary_name(v__gen__c__Gen* g, string name); VV_LOC string v__gen__c__Gen_get_ternary_name(v__gen__c__Gen* g, string name); VV_LOC bool v__gen__c__Gen_gen_clone_assignment(v__gen__c__Gen* g, v__ast__Type var_type, v__ast__Expr val, v__ast__Type typ, bool add_eq); VV_LOC multi_return_string_string_string_string v__gen__c__Gen_map_fn_ptrs(v__gen__c__Gen* g, v__ast__TypeSymbol key_sym); VV_LOC void v__gen__c__Gen_expr(v__gen__c__Gen* g, v__ast__Expr node_); VV_LOC void v__gen__c__Gen_char_literal(v__gen__c__Gen* g, v__ast__CharLiteral node); VV_LOC void v__gen__c__Gen_type_name(v__gen__c__Gen* g, v__ast__Type raw_type); VV_LOC void v__gen__c__Gen_typeof_expr(v__gen__c__Gen* g, v__ast__TypeOf node); VV_LOC void v__gen__c__Gen_selector_expr(v__gen__c__Gen* g, v__ast__SelectorExpr node); VV_LOC void v__gen__c__Gen_gen_closure_fn(v__gen__c__Gen* g, string expr_styp, v__ast__Fn m, string name); VV_LOC void v__gen__c__Gen_write_selector_expr_embed_name(v__gen__c__Gen* g, v__ast__SelectorExpr node, Array_v__ast__Type embed_types); VV_LOC bool v__gen__c__Gen_check_var_scope(v__gen__c__Gen* g, v__ast__Var obj, int node_pos); VV_LOC void v__gen__c__Gen_debugger_stmt(v__gen__c__Gen* g, v__ast__DebuggerStmt node); VV_LOC void v__gen__c__Gen_enum_decl(v__gen__c__Gen* g, v__ast__EnumDecl node); VV_LOC void v__gen__c__Gen_enum_expr(v__gen__c__Gen* g, v__ast__Expr node); VV_LOC void v__gen__c__Gen_lock_expr(v__gen__c__Gen* g, v__ast__LockExpr node); VV_LOC void v__gen__c__Gen_unlock_locks(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_map_init(v__gen__c__Gen* g, v__ast__MapInit node); VV_LOC void v__gen__c__Gen_select_expr(v__gen__c__Gen* g, v__ast__SelectExpr node); VV_LOC string v__gen__c__Gen_get_const_name(v__gen__c__Gen* g, v__ast__Ident node); VV_LOC void v__gen__c__Gen_ident(v__gen__c__Gen* g, v__ast__Ident node); VV_LOC void v__gen__c__Gen_cast_expr(v__gen__c__Gen* g, v__ast__CastExpr node); VV_LOC void v__gen__c__Gen_concat_expr(v__gen__c__Gen* g, v__ast__ConcatExpr node); VV_LOC bool v__gen__c__Gen_expr_is_multi_return_call(v__gen__c__Gen* g, v__ast__Expr expr); VV_LOC void v__gen__c__Gen_gen_result_error(v__gen__c__Gen* g, v__ast__Type target_type, v__ast__Expr expr); VV_LOC void v__gen__c__Gen_gen_option_error(v__gen__c__Gen* g, v__ast__Type target_type, v__ast__Expr expr); VV_LOC string v__gen__c__Gen_hash_stmt_guarded_include(v__gen__c__Gen* g, v__ast__HashStmt node); VV_LOC void v__gen__c__Gen_hash_stmt(v__gen__c__Gen* g, v__ast__HashStmt node); VV_LOC void v__gen__c__Gen_branch_stmt(v__gen__c__Gen* g, v__ast__BranchStmt node); VV_LOC void v__gen__c__Gen_return_stmt(v__gen__c__Gen* g, v__ast__Return node); VV_LOC bool v__gen__c__Gen_check_expr_is_const(v__gen__c__Gen* g, v__ast__Expr expr); VV_LOC void v__gen__c__Gen_assoc(v__gen__c__Gen* g, v__ast__Assoc node); VV_LOC void v__gen__c__verror(string s); VV_LOC void v__gen__c__Gen_error(v__gen__c__Gen* g, string s, v__token__Pos pos); VV_LOC void v__gen__c__Gen_checker_bug(v__gen__c__Gen* g, string s, v__token__Pos pos); VV_LOC void v__gen__c__Gen_write_debug_calls_typeof_functions(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_write_init_function(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_write_builtin_types(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_write_sorted_types(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_write_types(v__gen__c__Gen* g, Array_v__ast__TypeSymbol_ptr symbols); VV_LOC void v__gen__c__Gen_write_sorted_fn_typesymbol_declaration(v__gen__c__Gen* g); VV_LOC Array_v__ast__TypeSymbol_ptr v__gen__c__Gen_sort_structs(v__gen__c__Gen* g, Array_v__ast__TypeSymbol_ptr typesa); VV_LOC void v__gen__c__Gen_gen_or_block_stmts(v__gen__c__Gen* g, string cvar_name, string cast_typ, Array_v__ast__Stmt stmts, v__ast__Type return_type, bool is_option); VV_LOC void v__gen__c__Gen_or_block(v__gen__c__Gen* g, string var_name, v__ast__OrExpr or_block, v__ast__Type return_type); VV_LOC string v__gen__c__c_name(string name_); VV_LOC string v__gen__c__c_fn_name(string name_); VV_LOC string v__gen__c__Gen_type_default_sumtype(v__gen__c__Gen* g, v__ast__Type typ_, v__ast__TypeSymbol sym); VV_LOC string v__gen__c__Gen_type_default_no_sumtype(v__gen__c__Gen* g, v__ast__Type typ_); VV_LOC string v__gen__c__Gen_type_default(v__gen__c__Gen* g, v__ast__Type typ_); VV_LOC string v__gen__c__Gen_type_default_impl(v__gen__c__Gen* g, v__ast__Type typ_, bool decode_sumtype); VV_LOC Array_string v__gen__c__Gen_get_all_test_function_names(v__gen__c__Gen* g); VV_LOC v__ast__Type v__gen__c__Gen_get_type(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_size_of(v__gen__c__Gen* g, v__ast__SizeOf node); VV_LOC string v__gen__c__Gen_gen_enum_prefix(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_enum_val(v__gen__c__Gen* g, v__ast__EnumVal node); VV_LOC void v__gen__c__Gen_as_cast(v__gen__c__Gen* g, v__ast__AsCast node); VV_LOC string v__gen__c__Gen_as_cast_name_table(v__gen__c__Gen* g); VV_LOC bool v__gen__c__Gen_has_been_referenced(v__gen__c__Gen* g, string fn_name); VV_LOC void v__gen__c__Gen_register_iface_return_types(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_interface_table(v__gen__c__Gen* g); VV_LOC multi_return_int_string_string_string v__gen__c__Gen_panic_debug_info(v__gen__c__Gen* g, v__token__Pos pos); string v__gen__c__get_guarded_include_text(string iname, string imessage); string v__gen__c__Gen_ret_styp(v__gen__c__Gen* g, v__ast__Type typ); int v__gen__c__Gen_get_array_depth(v__gen__c__Gen* g, v__ast__Type el_typ); bool v__gen__c__Gen_contains_ptr(v__gen__c__Gen* g, v__ast__Type el_typ); VV_LOC string v__gen__c__Gen_check_noscan(v__gen__c__Gen* g, v__ast__Type elem_typ); void v__gen__c__Gen_gen_c_main(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_gen_vlines_reset(v__gen__c__Gen* g); strings__Builder v__gen__c__fix_reset_dbg_line(strings__Builder src, string out_file); VV_LOC void v__gen__c__Gen_gen_c_main_function_only_header(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_gen_c_main_function_header(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_gen_c_main_header(v__gen__c__Gen* g); void v__gen__c__Gen_gen_c_main_footer(v__gen__c__Gen* g); void v__gen__c__Gen_gen_c_android_sokol_main(v__gen__c__Gen* g); void v__gen__c__Gen_write_tests_definitions(v__gen__c__Gen* g); void v__gen__c__Gen_gen_failing_error_propagation_for_test_fn(v__gen__c__Gen* g, v__ast__OrExpr or_block, string cvar_name); void v__gen__c__Gen_gen_failing_return_error_for_test_fn(v__gen__c__Gen* g, v__ast__Return return_stmt, string cvar_name); void v__gen__c__Gen_gen_c_main_profile_hook(v__gen__c__Gen* g); void v__gen__c__Gen_gen_c_main_for_tests(v__gen__c__Gen* g); Array_string v__gen__c__Gen_filter_only_matching_fn_names(v__gen__c__Gen* g, Array_string fnames); void v__gen__c__Gen_gen_c_main_trace_calls_hook(v__gen__c__Gen* g); void v__gen__c__Gen_gen_dll_main(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_comptime_selector(v__gen__c__Gen* g, v__ast__ComptimeSelector node); VV_LOC string v__gen__c__Gen_gen_comptime_selector(v__gen__c__Gen* g, v__ast__ComptimeSelector expr); VV_LOC void v__gen__c__Gen_comptime_call(v__gen__c__Gen* g, v__ast__ComptimeCall* node); VV_LOC Array_string v__gen__c__cgen_attrs(Array_v__ast__Attr attrs); VV_LOC void v__gen__c__Gen_comptime_at(v__gen__c__Gen* g, v__ast__AtExpr node); VV_LOC void v__gen__c__Gen_comptime_if(v__gen__c__Gen* g, v__ast__IfExpr node); VV_LOC v__ast__Type v__gen__c__Gen_get_expr_type(v__gen__c__Gen* g, v__ast__Expr cond); VV_LOC multi_return_bool_bool v__gen__c__Gen_comptime_if_cond(v__gen__c__Gen* g, v__ast__Expr cond, bool pkg_exist); VV_LOC void v__gen__c__Gen_push_new_comptime_info(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_pop_comptime_info(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_comptime_for(v__gen__c__Gen* g, v__ast__ComptimeFor node); VV_LOC v__ast__Type v__gen__c__Gen_comptime_selector_type(v__gen__c__Gen* g, v__ast__SelectorExpr node); VV_LOC _result_string v__gen__c__Gen_comptime_if_to_ifdef(v__gen__c__Gen* g, string name, bool is_comptime_option); VV_LOC void v__gen__c__Gen_const_decl(v__gen__c__Gen* g, v__ast__ConstDecl node); VV_LOC bool v__gen__c__Gen_const_decl_precomputed(v__gen__c__Gen* g, string mod, string name, string field_name, v__ast__ComptTimeConstValue ct_value, v__ast__Type typ); VV_LOC void v__gen__c__Gen_const_decl_write_precomputed(v__gen__c__Gen* g, string mod, string styp, string cname, string field_name, string ct_value); VV_LOC void v__gen__c__Gen_const_decl_simple_define(v__gen__c__Gen* g, string mod, string name, string val); VV_LOC string v__gen__c__Gen_c_const_name(v__gen__c__Gen* g, string name); VV_LOC void v__gen__c__Gen_const_decl_init_later(v__gen__c__Gen* g, string mod, string name, v__ast__Expr expr, v__ast__Type typ, bool surround_cbr); VV_LOC void v__gen__c__Gen_const_decl_init_later_msvc_string_fixed_array(v__gen__c__Gen* g, string mod, string name, v__ast__ArrayInit expr, v__ast__Type typ); VV_LOC void v__gen__c__Gen_global_decl(v__gen__c__Gen* g, v__ast__GlobalDecl node); VV_LOC void v__gen__c__Gen_sort_globals_consts(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_write_coverage_point(v__gen__c__Gen* g, v__token__Pos pos); VV_LOC void v__gen__c__Gen_write_coverage_stats(v__gen__c__Gen* g); VV_LOC string v__gen__c__cesc(string s); VV_LOC string v__gen__c__jesc(string s); VV_LOC v__ast__CTempVar v__gen__c__Gen_new_ctemp_var(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_type); VV_LOC v__ast__CTempVar v__gen__c__Gen_new_ctemp_var_then_gen(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_type); VV_LOC void v__gen__c__Gen_gen_ctemp_var(v__gen__c__Gen* g, v__ast__CTempVar* tvar); VV_LOC void v__gen__c__Gen_dump_expr(v__gen__c__Gen* g, v__ast__DumpExpr node); VV_LOC void v__gen__c__Gen_dump_expr_definitions(v__gen__c__Gen* g); VV_LOC bool v__gen__c__Gen_writeln_fn_header(v__gen__c__Gen* g, string s, strings__Builder* sb); VV_LOC bool v__gen__c__Gen_should_really_embed_file(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_handle_embedded_files_finish(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_gen_embed_file_init(v__gen__c__Gen* g, v__ast__ComptimeCall* node); VV_LOC void v__gen__c__Gen_gen_embedded_metadata(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_gen_embedded_data(v__gen__c__Gen* g); VV_LOC bool v__gen__c__Gen_is_used_by_main(v__gen__c__Gen* g, v__ast__FnDecl node); VV_LOC void v__gen__c__Gen_fn_decl(v__gen__c__Gen* g, v__ast__FnDecl node); VV_LOC void v__gen__c__Gen_gen_fn_decl(v__gen__c__Gen* g, v__ast__FnDecl* node, bool skip); VV_LOC string v__gen__c__Gen_c_fn_name(v__gen__c__Gen* g, v__ast__FnDecl* node); VV_LOC string v__gen__c__Gen_gen_closure_fn_name(v__gen__c__Gen* g, v__ast__AnonFn node); VV_LOC string v__gen__c__Gen_closure_ctx(v__gen__c__Gen* g, v__ast__FnDecl node); VV_LOC void v__gen__c__Gen_gen_anon_fn(v__gen__c__Gen* g, v__ast__AnonFn* node); VV_LOC void v__gen__c__Gen_gen_anon_fn_decl(v__gen__c__Gen* g, v__ast__AnonFn* node); VV_LOC string v__gen__c__Gen_defer_flag_var(v__gen__c__Gen* g, v__ast__DeferStmt* stmt); VV_LOC void v__gen__c__Gen_write_defer_stmts_when_needed(v__gen__c__Gen* g); VV_LOC multi_return_Array_string_Array_string_Array_bool v__gen__c__Gen_fn_decl_params(v__gen__c__Gen* g, Array_v__ast__Param params, v__ast__Scope* scope, bool is_variadic, bool is_c_variadic); VV_LOC string v__gen__c__Gen_get_anon_fn_type_name(v__gen__c__Gen* g, v__ast__AnonFn* node, string var_name); VV_LOC void v__gen__c__Gen_call_expr(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_conversion_function_call(v__gen__c__Gen* g, string prefix, string postfix, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_arg_from_type(v__gen__c__Gen* g, v__ast__Type node_type, v__ast__Expr node); VV_LOC bool v__gen__c__Gen_gen_map_method_call(v__gen__c__Gen* g, v__ast__CallExpr node, v__ast__Type left_type, v__ast__TypeSymbol left_sym); VV_LOC bool v__gen__c__Gen_gen_array_method_call(v__gen__c__Gen* g, v__ast__CallExpr node, v__ast__Type left_type, v__ast__TypeSymbol left_sym); VV_LOC bool v__gen__c__Gen_gen_fixed_array_method_call(v__gen__c__Gen* g, v__ast__CallExpr node, v__ast__Type left_type); VV_LOC bool v__gen__c__Gen_gen_to_str_method_call(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC v__ast__Type v__gen__c__Gen_resolve_return_type(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC string v__gen__c__Gen_resolve_receiver_name(v__gen__c__Gen* g, v__ast__CallExpr node, v__ast__Type unwrapped_rec_type, v__ast__TypeSymbol final_left_sym, v__ast__TypeSymbol left_sym, v__ast__TypeSymbol typ_sym); VV_LOC multi_return_v__ast__Type_ref_v__ast__TypeSymbol v__gen__c__Gen_unwrap_receiver_type(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_method_call(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_fn_call(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_gen_trace_call(v__gen__c__Gen* g, v__ast__CallExpr node, string name); VV_LOC void v__gen__c__Gen_autofree_call_pregen(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_call_args(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC int v__gen__c__Gen_keep_alive_call_pregen(v__gen__c__Gen* g, v__ast__CallExpr node); VV_LOC void v__gen__c__Gen_keep_alive_call_postgen(v__gen__c__Gen* g, v__ast__CallExpr node, int tmp_cnt_save); VV_LOC void v__gen__c__Gen_ref_or_deref_arg(v__gen__c__Gen* g, v__ast__CallArg arg, v__ast__Type expected_type, v__ast__Language lang, bool is_smartcast); VV_LOC bool v__gen__c__Gen_is_gui_app(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_write_fn_attrs(v__gen__c__Gen* g, Array_v__ast__Attr attrs); VV_LOC string v__gen__c__call_convention_attribute(string cconvention, bool is_cc_msvc); VV_LOC void v__gen__c__Gen_for_c_stmt(v__gen__c__Gen* g, v__ast__ForCStmt node); VV_LOC void v__gen__c__Gen_for_stmt(v__gen__c__Gen* g, v__ast__ForStmt node); VV_LOC void v__gen__c__Gen_for_in_stmt(v__gen__c__Gen* g, v__ast__ForInStmt node_); VV_LOC bool v__gen__c__Gen_need_tmp_var_in_if(v__gen__c__Gen* g, v__ast__IfExpr node); VV_LOC bool v__gen__c__Gen_need_tmp_var_in_expr(v__gen__c__Gen* g, v__ast__Expr expr); VV_LOC bool v__gen__c__Gen_needs_conds_order(v__gen__c__Gen* g, v__ast__IfExpr node); VV_LOC void v__gen__c__Gen_if_expr(v__gen__c__Gen* g, v__ast__IfExpr node); VV_LOC void v__gen__c__Gen_index_expr(v__gen__c__Gen* g, v__ast__IndexExpr node); VV_LOC void v__gen__c__Gen_index_range_expr(v__gen__c__Gen* g, v__ast__IndexExpr node, v__ast__RangeExpr range); VV_LOC void v__gen__c__Gen_index_of_array(v__gen__c__Gen* g, v__ast__IndexExpr node, v__ast__TypeSymbol sym); VV_LOC void v__gen__c__Gen_index_of_fixed_array(v__gen__c__Gen* g, v__ast__IndexExpr node, v__ast__TypeSymbol sym); VV_LOC void v__gen__c__Gen_index_of_map(v__gen__c__Gen* g, v__ast__IndexExpr node, v__ast__TypeSymbol sym); VV_LOC void v__gen__c__Gen_infix_expr(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC void v__gen__c__Gen_infix_expr_arrow_op(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC void v__gen__c__Gen_infix_expr_eq_op(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC void v__gen__c__Gen_infix_expr_cmp_op(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC void v__gen__c__Gen_infix_expr_in_sumtype_interface_array(v__gen__c__Gen* g, Array_v__ast__InfixExpr infix_exprs); VV_LOC void v__gen__c__Gen_infix_expr_in_op(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC void v__gen__c__Gen_infix_expr_in_optimization(v__gen__c__Gen* g, v__ast__Expr left, v__ast__Type left_type, v__ast__ArrayInit right); VV_LOC void v__gen__c__Gen_infix_expr_is_op(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC void v__gen__c__Gen_gen_interface_is_op(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC void v__gen__c__Gen_infix_expr_arithmetic_op(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC void v__gen__c__Gen_infix_expr_left_shift_op(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC bool v__gen__c__Gen_need_tmp_var_in_array_call(v__gen__c__Gen* g, v__ast__Expr node); VV_LOC void v__gen__c__Gen_infix_expr_and_or_op(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC void v__gen__c__Gen_gen_is_none_check(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC void v__gen__c__Gen_gen_plain_infix_expr(v__gen__c__Gen* g, v__ast__InfixExpr node); VV_LOC void v__gen__c__Gen_op_arg(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expected, v__ast__Type got); VV_LOC void v__gen__c__Gen_gen_safe_integer_infix_expr(v__gen__c__Gen* g, v__gen__c__GenSafeIntegerCfg cfg); VV_LOC void v__gen__c__Gen_gen_json_for_type(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_gen_jsons(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_gen_enum_to_str(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__TypeSymbol sym, string enum_var, string result_var, string ident, strings__Builder* enc); VV_LOC void v__gen__c__Gen_gen_str_to_enum(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__TypeSymbol sym, string val_var, string result_var, string ident, strings__Builder* dec); VV_LOC bool v__gen__c__Gen_is_enum_as_int(v__gen__c__Gen* g, v__ast__TypeSymbol sym); VV_LOC void v__gen__c__Gen_gen_enum_enc_dec(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__TypeSymbol sym, strings__Builder* enc, strings__Builder* dec); VV_LOC void v__gen__c__Gen_gen_prim_enc_dec(v__gen__c__Gen* g, v__ast__Type typ, strings__Builder* enc, strings__Builder* dec); VV_LOC void v__gen__c__Gen_gen_option_enc_dec(v__gen__c__Gen* g, v__ast__Type typ, strings__Builder* enc, strings__Builder* dec); VV_LOC void v__gen__c__Gen_gen_sumtype_enc_dec(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__TypeSymbol sym, strings__Builder* enc, strings__Builder* dec, string ret_styp); VV_LOC void v__gen__c__Gen_gen_prim_type_validation(v__gen__c__Gen* g, string name, v__ast__Type typ, string tmp, bool is_required, string ret_styp, strings__Builder* dec); VV_LOC void v__gen__c__Gen_gen_struct_enc_dec(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__TypeInfo type_info, string styp, strings__Builder* enc, strings__Builder* dec, string embed_prefix); VV_LOC void v__gen__c__gen_js_get(string styp, string tmp, string name, strings__Builder* dec, bool is_required); VV_LOC void v__gen__c__gen_js_get_opt(string dec_name, string field_type, string styp, string tmp, string name, strings__Builder* dec, bool is_required); VV_LOC string v__gen__c__js_enc_name(string typ); VV_LOC string v__gen__c__js_dec_name(string typ); VV_LOC bool v__gen__c__is_js_prim(string typ); VV_LOC string v__gen__c__Gen_decode_array(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__Type value_type, int fixed_array_size, string ret_styp); VV_LOC string v__gen__c__Gen_encode_array(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__Type value_type, int fixed_array_size); VV_LOC string v__gen__c__Gen_decode_map(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__Type key_type, v__ast__Type value_type, string ustyp); VV_LOC string v__gen__c__Gen_encode_map(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__Type key_type, v__ast__Type value_type); VV_LOC void v__gen__c__verror_suggest_json_no_inline_sumtypes(string sumtype_name, string type_name1, string type_name2); VV_LOC void v__gen__c__Gen_generate_hotcode_reloading_declarations(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_generate_hotcode_reloader_code(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_generate_hotcode_reloading_main_caller(v__gen__c__Gen* g); VV_LOC bool v__gen__c__Gen_need_tmp_var_in_match(v__gen__c__Gen* g, v__ast__MatchExpr node); VV_LOC void v__gen__c__Gen_match_expr(v__gen__c__Gen* g, v__ast__MatchExpr node); VV_LOC void v__gen__c__Gen_match_expr_sumtype(v__gen__c__Gen* g, v__ast__MatchExpr node, bool is_expr, string cond_var, string tmp_var); VV_LOC void v__gen__c__Gen_match_expr_switch(v__gen__c__Gen* g, v__ast__MatchExpr node, bool is_expr, string cond_var, string tmp_var, v__ast__TypeSymbol cond_fsym); VV_LOC bool v__gen__c__Gen_should_check_low_bound_in_range_expr(v__gen__c__Gen* g, v__ast__RangeExpr expr, bool node_cond_type_unsigned); VV_LOC void v__gen__c__Gen_match_expr_classic(v__gen__c__Gen* g, v__ast__MatchExpr node, bool is_expr, string cond_var, string tmp_var); VV_LOC bool v__gen__c__Gen_match_must_reset_if(v__gen__c__Gen* g, v__ast__Expr node); VV_LOC void v__gen__c__Gen_sql_select_expr(v__gen__c__Gen* g, v__ast__SqlExpr node); VV_LOC void v__gen__c__Gen_sql_insert_expr(v__gen__c__Gen* g, v__ast__SqlExpr node); VV_LOC void v__gen__c__Gen_sql_stmt(v__gen__c__Gen* g, v__ast__SqlStmt node); VV_LOC void v__gen__c__Gen_sql_stmt_line(v__gen__c__Gen* g, v__ast__SqlStmtLine stmt_line, string connection_var_name, v__ast__OrExpr or_expr); VV_LOC void v__gen__c__Gen_write_orm_connection_init(v__gen__c__Gen* g, string connection_var_name, v__ast__Expr* db_expr); VV_LOC void v__gen__c__Gen_write_orm_table_struct(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_write_orm_create_table(v__gen__c__Gen* g, v__ast__SqlStmtLine node, string table_name, string connection_var_name, string result_var_name, Array_v__ast__Attr table_attrs); VV_LOC void v__gen__c__Gen_write_orm_drop_table(v__gen__c__Gen* g, v__ast__SqlStmtLine node, string table_name, string connection_var_name, string result_var_name, Array_v__ast__Attr table_attrs); VV_LOC void v__gen__c__Gen_write_orm_insert(v__gen__c__Gen* g, v__ast__SqlStmtLine* node, string table_name, string connection_var_name, string result_var_name, v__ast__OrExpr* or_expr, Array_v__ast__Attr table_attrs); VV_LOC void v__gen__c__Gen_write_orm_update(v__gen__c__Gen* g, v__ast__SqlStmtLine* node, string table_name, string connection_var_name, string result_var_name, Array_v__ast__Attr table_attrs); VV_LOC void v__gen__c__Gen_write_orm_delete(v__gen__c__Gen* g, v__ast__SqlStmtLine* node, string table_name, string connection_var_name, string result_var_name, Array_v__ast__Attr table_attrs); VV_LOC void v__gen__c__Gen_write_orm_insert_with_last_ids(v__gen__c__Gen* g, v__ast__SqlStmtLine node, string connection_var_name, string table_name, string last_ids_arr, string res, string pid, string fkey, v__ast__OrExpr or_expr); VV_LOC void v__gen__c__Gen_write_orm_expr_to_primitive(v__gen__c__Gen* g, v__ast__Expr expr); VV_LOC void v__gen__c__Gen_write_orm_primitive(v__gen__c__Gen* g, v__ast__Type t, v__ast__Expr expr); VV_LOC void v__gen__c__Gen_write_orm_where(v__gen__c__Gen* g, v__ast__Expr where_expr); VV_LOC void v__gen__c__Gen_write_orm_where_expr(v__gen__c__Gen* g, v__ast__Expr expr, Array_string* fields, Array_Array_int* parentheses, Array_string* kinds, Array_v__ast__Expr* data, Array_bool* is_and); VV_LOC void v__gen__c__Gen_write_orm_select(v__gen__c__Gen* g, v__ast__SqlExpr node, string connection_var_name, string result_var); VV_LOC Array_v__ast__StructField v__gen__c__Gen_filter_struct_fields_by_orm_attrs(v__gen__c__Gen* _d1, Array_v__ast__StructField fields); VV_LOC _option_v__ast__Type v__gen__c__Gen_get_db_expr_type(v__gen__c__Gen* g, v__ast__Expr expr); VV_LOC Array_v__ast__Attr v__gen__c__Gen_get_table_attrs_by_struct_type(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC string v__gen__c__Gen_get_table_name_by_struct_type(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC _option_v__ast__StructField v__gen__c__Gen_get_orm_current_table_field(v__gen__c__Gen* g, string name); VV_LOC string v__gen__c__Gen_get_orm_column_name_from_struct_field(v__gen__c__Gen* g, v__ast__StructField field); VV_LOC _option_v__ast__StructField v__gen__c__Gen_get_orm_struct_primary_field(v__gen__c__Gen* _d1, Array_v__ast__StructField fields); VV_LOC Array_int v__gen__c__get_auto_field_idxs(Array_v__ast__StructField fields); VV_LOC v__gen__c__PastTmpVar v__gen__c__Gen_past_tmp_var_new(v__gen__c__Gen* g); VV_LOC v__gen__c__PastTmpVar v__gen__c__Gen_past_tmp_var_from_var_name(v__gen__c__Gen* g, string var_name); VV_LOC void v__gen__c__Gen_past_tmp_var_done(v__gen__c__Gen* g, v__gen__c__PastTmpVar* p); VV_LOC void v__gen__c__Gen_profile_fn(v__gen__c__Gen* g, v__ast__FnDecl fn_decl); void v__gen__c__Gen_gen_vprint_profile_stats(v__gen__c__Gen* g); VV_LOC int v__gen__c__Gen_reflection_string(v__gen__c__Gen* g, string str); VV_LOC void v__gen__c__Gen_gen_reflection_strings(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_gen_empty_array(v__gen__c__Gen* g, string type_name); VV_LOC string v__gen__c__Gen_gen_functionarg_array(v__gen__c__Gen* g, string type_name, v__ast__Fn node); VV_LOC string v__gen__c__Gen_gen_function_array(v__gen__c__Gen* g, Array_v__ast__Fn nodes); VV_LOC string v__gen__c__Gen_gen_reflection_fn(v__gen__c__Gen* g, v__ast__Fn node); VV_LOC string v__gen__c__Gen_gen_reflection_sym(v__gen__c__Gen* g, v__ast__TypeSymbol tsym); VV_LOC string v__gen__c__Gen_gen_attrs_array(v__gen__c__Gen* g, Array_v__ast__Attr attrs); VV_LOC string v__gen__c__Gen_gen_fields_array(v__gen__c__Gen* g, Array_v__ast__StructField fields); VV_LOC string v__gen__c__Gen_gen_type_array(v__gen__c__Gen* g, Array_v__ast__Type types); VV_LOC string v__gen__c__Gen_gen_string_array(v__gen__c__Gen* g, Array_string strs); VV_LOC string v__gen__c__Gen_gen_reflection_sym_info(v__gen__c__Gen* g, v__ast__TypeSymbol tsym); VV_LOC void v__gen__c__Gen_gen_reflection_data(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_spawn_and_go_expr(v__gen__c__Gen* g, v__ast__SpawnExpr node, v__gen__c__SpawnGoMode mode); VV_LOC string v__gen__c__Gen_get_cur_thread_stack_size(v__gen__c__Gen* g, string name); VV_LOC string v__gen__c__Gen_gen_gohandle_name(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC void v__gen__c__Gen_create_waiter_handler(v__gen__c__Gen* g, v__ast__Type call_ret_type, string s_ret_typ, string gohandle_name); VV_LOC void v__gen__c__Gen_string_literal(v__gen__c__Gen* g, v__ast__StringLiteral node); VV_LOC void v__gen__c__Gen_string_inter_literal_sb_optimized(v__gen__c__Gen* g, v__ast__CallExpr call_expr); VV_LOC void v__gen__c__Gen_gen_expr_to_string(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type etype); VV_LOC u8 v__gen__c__Gen_get_default_fmt(v__gen__c__Gen* g, v__ast__Type ftyp, v__ast__Type typ); VV_LOC multi_return_u64_string v__gen__c__Gen_str_format(v__gen__c__Gen* g, v__ast__StringInterLiteral node, int i, Array_u8 fmts); VV_LOC void v__gen__c__Gen_str_val(v__gen__c__Gen* g, v__ast__StringInterLiteral node, int i, Array_u8 fmts); VV_LOC void v__gen__c__Gen_string_inter_literal(v__gen__c__Gen* g, v__ast__StringInterLiteral node); VV_LOC void v__gen__c__Gen_struct_init(v__gen__c__Gen* g, v__ast__StructInit node); VV_LOC string v__gen__c__Gen_get_embed_field_name(v__gen__c__Gen* g, v__ast__Type field_type, string field_name); VV_LOC void v__gen__c__Gen_init_shared_field(v__gen__c__Gen* g, v__ast__StructField field); VV_LOC bool v__gen__c__Gen_zero_struct_field(v__gen__c__Gen* g, v__ast__StructField field); VV_LOC void v__gen__c__Gen_struct_decl(v__gen__c__Gen* g, v__ast__Struct s, string name, bool is_anon, bool is_option); VV_LOC void v__gen__c__Gen_struct_init_field(v__gen__c__Gen* g, v__ast__StructInitField sfield, v__ast__Language language); VV_LOC void v__gen__c__Gen_struct_init_field_default(v__gen__c__Gen* g, v__ast__Type field_unwrap_typ, v__ast__StructInitField* sfield, v__ast__TypeSymbol field_unwrap_sym); VV_LOC void v__gen__c__Gen_write(v__gen__c__Gen* g, string s); VV_LOC void v__gen__c__Gen_write2(v__gen__c__Gen* g, string s1, string s2); VV_LOC void v__gen__c__Gen_write_decimal(v__gen__c__Gen* g, i64 x); VV_LOC void v__gen__c__Gen_writeln(v__gen__c__Gen* g, string s); VV_LOC void v__gen__c__Gen_writeln2(v__gen__c__Gen* g, string s1, string s2); VV_LOC void v__gen__c__Gen_go_back(v__gen__c__Gen* g, int n); VV_LOC void v__gen__c__Gen_go_back_to(v__gen__c__Gen* g, int n); VV_LOC int v__gen__c__Gen_nth_stmt_pos(v__gen__c__Gen* g, int n); VV_LOC void v__gen__c__Gen_set_current_pos_as_last_stmt_pos(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_go_before_last_stmt(v__gen__c__Gen* g); VV_LOC string v__gen__c__Gen_go_before_ternary(v__gen__c__Gen* g); VV_LOC void v__gen__c__Gen_insert_before_stmt(v__gen__c__Gen* g, string s); VV_LOC void v__gen__c__Gen_insert_at(v__gen__c__Gen* g, int pos, string s); VV_LOC v__ast__Type v__gen__c__Gen_unwrap_generic(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC v__gen__c__Type v__gen__c__Gen_unwrap(v__gen__c__Gen* g, v__ast__Type typ); VV_LOC string v__gen__c__Gen_fn_var_signature(v__gen__c__Gen* g, v__ast__Type return_type, Array_v__ast__Type arg_types, string var_name); VV_LOC string v__gen__c__Gen_anon_fn_cname(v__gen__c__Gen* g, v__ast__Type return_type, Array_v__ast__Type arg_types); VV_LOC string v__gen__c__escape_quotes(string val); VV_LOC string v__gen__c__Gen_dot_or_ptr(v__gen__c__Gen* g, v__ast__Type val_type); VV_LOC void v__gen__c__Gen_unwrap_option_type(v__gen__c__Gen* g, v__ast__Type typ, string name, bool is_auto_heap); v__builder__Builder v__builder__new_builder(v__pref__Preferences* pref_); _result_void v__builder__Builder_front_stages(v__builder__Builder* b, Array_string v_files); _result_void v__builder__Builder_middle_stages(v__builder__Builder* b); _result_void v__builder__Builder_front_and_middle_stages(v__builder__Builder* b, Array_string v_files); void v__builder__Builder_parse_imports(v__builder__Builder* b); void v__builder__Builder_resolve_deps(v__builder__Builder* b); v__depgraph__DepGraph* v__builder__Builder_import_graph(v__builder__Builder* b); Array_string v__builder__Builder_v_files_from_dir(v__builder__Builder* b, string dir); void v__builder__Builder_log(v__builder__Builder* b, string s); void v__builder__Builder_info(v__builder__Builder* b, string s); string v__builder__module_path(string mod); _result_string v__builder__Builder_find_module_path(v__builder__Builder* b, string mod, string fpath); void v__builder__Builder_show_total_warns_and_errors_stats(v__builder__Builder* b); void v__builder__Builder_print_warnings_and_errors(v__builder__Builder* b); v__errors__Error v__builder__Builder_error_with_pos(v__builder__Builder* b, string s, string fpath, v__token__Pos pos); void v__builder__verror(string s); void v__builder__Builder_show_parsed_files(v__builder__Builder* b); VV_LOC void v__builder__Builder_show_c_compiler_output(v__builder__Builder* v, string ccompiler, os__Result res); VV_LOC void v__builder__Builder_post_process_c_compiler_output(v__builder__Builder* v, string ccompiler, os__Result res); VV_LOC void v__builder__Builder_show_cc(v__builder__Builder* v, string cmd, string response_file, string response_file_content); VV_LOC void v__builder__Builder_setup_ccompiler_options(v__builder__Builder* v, string ccompiler); VV_LOC Array_string v__builder__Builder_all_args(v__builder__Builder* v, v__builder__CcompilerOptions ccoptions); Array_string v__builder__Builder_get_compile_args(v__builder__Builder* v); VV_LOC Array_string v__builder__Builder_only_compile_args(v__builder__Builder* v, v__builder__CcompilerOptions ccoptions); Array_string v__builder__Builder_get_linker_args(v__builder__Builder* v); VV_LOC Array_string v__builder__Builder_only_linker_args(v__builder__Builder* v, v__builder__CcompilerOptions ccoptions); VV_LOC Array_string v__builder__Builder_thirdparty_object_args(v__builder__Builder* v, v__builder__CcompilerOptions ccoptions, Array_string middle, bool cpp_file); VV_LOC void v__builder__Builder_setup_output_name(v__builder__Builder* v); string v__builder__Builder_tcc_quoted_path(v__builder__Builder* v, string p); void v__builder__Builder_cc(v__builder__Builder* v); VV_LOC void v__builder__Builder_ensure_linuxroot_exists(v__builder__Builder* b, string sysroot); VV_LOC void v__builder__Builder_ensure_freebsdroot_exists(v__builder__Builder* b, string sysroot); VV_LOC string v__builder__Builder_get_subsystem_flag(v__builder__Builder* b); VV_LOC void v__builder__Builder_cc_linux_cross(v__builder__Builder* b); VV_LOC void v__builder__Builder_cc_freebsd_cross(v__builder__Builder* b); VV_LOC void v__builder__Builder_cc_windows_cross(v__builder__Builder* c); VV_LOC void v__builder__Builder_build_thirdparty_obj_files(v__builder__Builder* b); VV_LOC void v__builder__Builder_build_thirdparty_obj_file(v__builder__Builder* v, string mod, string path, Array_v__cflag__CFlag moduleflags); VV_LOC string v__builder__missing_compiler_info(void); VV_LOC string v__builder__highlight_word(string keyword); VV_LOC Array_string v__builder__error_context_lines(string text, string keyword, int before, int after); string v__builder__Builder_quote_compiler_name(v__builder__Builder* v, string name); VV_LOC void v__builder__write_response_file(string response_file, string response_file_content); VV_LOC void v__builder__write_response_file_error(string response_file, IError err); _result_void v__builder__Builder_find_win_cc(v__builder__Builder* v); VV_LOC Array_v__cflag__CFlag v__builder__Builder_get_os_cflags(v__builder__Builder* v); VV_LOC Array_v__cflag__CFlag v__builder__Builder_get_rest_of_module_cflags(v__builder__Builder* v, v__cflag__CFlag* c); void v__builder__compile(string command, v__pref__Preferences* pref_, void (*backend_cb)(v__builder__Builder* b)); VV_LOC void v__builder__check_if_output_folder_is_writable(v__pref__Preferences* pref_); VV_LOC void v__builder__Builder_myfree(v__builder__Builder* b); VV_LOC void v__builder__Builder_exit_on_invalid_syntax(v__builder__Builder* b); VV_LOC void v__builder__Builder_run_compiled_executable_and_exit(v__builder__Builder* b); VV_LOC void v__builder__eshcb(os__Signal _d1); VV_LOC void v__builder__serror(string reason, IError e); VV_LOC void v__builder__Builder_cleanup_run_executable_after_exit(v__builder__Builder* v, string exefile); void v__builder__Builder_set_module_lookup_paths(v__builder__Builder* v); Array_string v__builder__Builder_get_builtin_files(v__builder__Builder v); Array_string v__builder__Builder_get_user_files(v__builder__Builder* v); void v__builder__Builder_dump_c_options(v__builder__Builder* b, Array_string all_args); void v__builder__Builder_dump_modules(v__builder__Builder* b, Array_string mods); void v__builder__Builder_dump_files(v__builder__Builder* b, Array_string files); VV_LOC void v__builder__dump_list(string file_path, Array_string list); void v__builder__Builder_dump_defines(v__builder__Builder* b); VV_LOC _result_string v__builder__find_windows_kit_internal(v__builder__RegKey key, Array_string versions); VV_LOC _result_v__builder__WindowsKit v__builder__find_windows_kit_root(string target_arch); VV_LOC _result_v__builder__WindowsKit v__builder__find_windows_kit_root_by_reg(string target_arch); VV_LOC _result_v__builder__WindowsKit v__builder__new_windows_kit(string kit_root, string target_arch); VV_LOC _result_v__builder__WindowsKit v__builder__find_windows_kit_root_by_env(string target_arch); VV_LOC _result_v__builder__VsInstallation v__builder__find_vs(string vswhere_dir, string host_arch, string target_arch); VV_LOC _result_v__builder__VsInstallation v__builder__find_vs_by_reg(string vswhere_dir, string host_arch, string target_arch); VV_LOC _result_v__builder__VsInstallation v__builder__find_vs_by_env(string host_arch, string target_arch); VV_LOC _result_v__builder__MsvcResult v__builder__find_msvc(bool m64_target); void v__builder__Builder_cc_msvc(v__builder__Builder* v); VV_LOC void v__builder__Builder_build_thirdparty_obj_file_with_msvc(v__builder__Builder* v, string _mod, string path, Array_v__cflag__CFlag moduleflags); v__builder__MsvcStringFlags v__builder__msvc_string_flags(Array_v__cflag__CFlag cflags); VV_LOC Array_string v__builder__MsvcResult_include_paths(v__builder__MsvcResult r); VV_LOC Array_string v__builder__MsvcResult_library_paths(v__builder__MsvcResult r); void v__builder__Builder_rebuild_modules(v__builder__Builder* b); Array_string v__builder__Builder_find_invalidated_modules_by_files(v__builder__Builder* b, Array_string all_files); VV_LOC void v__builder__Builder_v_build_module(v__builder__Builder* b, string vexe, string imp_path); VV_LOC string v__builder__Builder_rebuild_cached_module(v__builder__Builder* b, string vexe, string imp_path); VV_LOC void v__builder__Builder_handle_usecache(v__builder__Builder* b, string vexe); bool v__builder__Builder_should_rebuild(v__builder__Builder* b); VV_LOC i64 v__builder__most_recent_timestamp(Array_string files); void v__builder__Builder_rebuild(v__builder__Builder* b, void (*backend_cb)(v__builder__Builder* b)); string v__builder__Builder_get_vtmp_filename(v__builder__Builder* b, string base_file_name, string postfix); void v__builder__cbuilder__compile_c(v__builder__Builder* b); void v__builder__cbuilder__build_c(v__builder__Builder* b, Array_string v_files, string out_file); strings__Builder v__builder__cbuilder__gen_c(v__builder__Builder* b, Array_string v_files); VV_LOC _result_void v__builder__cbuilder__parallel_cc(v__builder__Builder* b, v__gen__c__GenOutput _v_toheap_result); VV_LOC os__Result* v__builder__cbuilder__build_parallel_o_cb(sync__pool__PoolProcessor* p, int idx, int _wid); VV_LOC void v__builder__cbuilder__eprint_result_time(time__StopWatch sw, string label, string cmd, os__Result res); VV_LOC void v__builder__cbuilder__eprint_time(time__StopWatch sw, string label); VV_LOC v__util__Timers* main__timers_pointer(v__util__Timers* p); VV_LOC void main__main(void); VV_LOC void anon_fn_6a0ddf9f315b536f__1865(void); VV_LOC void main__invoke_help_and_exit(Array_string remaining); VV_LOC void main__rebuild(v__pref__Preferences* prefs); VV_LOC void main__setup_vbuild_env_vars(v__pref__Preferences* prefs); string _v_dump_expr_string(string fpath, int line, string sexpr, string dump_arg); static string time__FormatDate_str(time__FormatDate it); static string v__pref__Arch_str(v__pref__Arch it); static string v__pref__Backend_str(v__pref__Backend it); static string Array_v__ast__Expr_str(Array_v__ast__Expr a); static string indent_Array_v__ast__Expr_str(Array_v__ast__Expr a, int indent_count); static string v__ast__CallExpr_str(v__ast__CallExpr it); static string indent_v__ast__CallExpr_str(v__ast__CallExpr it, int indent_count); static string v__ast__UsedFeatures_str(v__ast__UsedFeatures it); static string indent_v__ast__UsedFeatures_str(v__ast__UsedFeatures it, int indent_count); static string Array_int_str(Array_int a); static string indent_Array_int_str(Array_int a, int indent_count); static string v__ast__IdentKind_str(v__ast__IdentKind it); static string v__token__Pos_str(v__token__Pos it); static string indent_v__token__Pos_str(v__token__Pos it, int indent_count); static string Array_v__ast__Attr_str(Array_v__ast__Attr a); static string indent_Array_v__ast__Attr_str(Array_v__ast__Attr a, int indent_count); static string v__checker__ComptimeBranchSkipState_str(v__checker__ComptimeBranchSkipState it); static string Array_v__ast__Type_str(Array_v__ast__Type a); static string indent_Array_v__ast__Type_str(Array_v__ast__Type a, int indent_count); static string Array_Array_v__ast__Type_str(Array_Array_v__ast__Type a); static string indent_Array_Array_v__ast__Type_str(Array_Array_v__ast__Type a, int indent_count); static string v__ast__Ident_str(v__ast__Ident it); static string indent_v__ast__Ident_str(v__ast__Ident it, int indent_count); static string v__ast__Language_str(v__ast__Language it); static string v__scanner__CommentsMode_str(v__scanner__CommentsMode it); static string v__parser__State_str(v__parser__State it); static string v__gen__c__StrType_str(v__gen__c__StrType it); static string indent_v__gen__c__StrType_str(v__gen__c__StrType it, int indent_count); static string v__ast__Enum_str(v__ast__Enum it); static string indent_v__ast__Enum_str(v__ast__Enum it, int indent_count); static string v__ast__AttrKind_str(v__ast__AttrKind it); static string v__ast__ComptTimeConstValue_str(v__ast__ComptTimeConstValue x); static string indent_v__ast__ComptTimeConstValue_str(v__ast__ComptTimeConstValue x, int indent_count); static string v__errors__Reporter_str(v__errors__Reporter it); static string v__builder__CcompilerOptions_str(v__builder__CcompilerOptions it); static string indent_v__builder__CcompilerOptions_str(v__builder__CcompilerOptions it, int indent_count); static string Array_v__cflag__CFlag_str(Array_v__cflag__CFlag a); static string indent_Array_v__cflag__CFlag_str(Array_v__cflag__CFlag a, int indent_count); static string Map_string_int_str(Map_string_int m); static string indent_Map_string_int_str(Map_string_int m, int indent_count); static string v__pref__CompilerType_str(v__pref__CompilerType it); static string Array_v__ast__CallArg_str(Array_v__ast__CallArg a); static string indent_Array_v__ast__CallArg_str(Array_v__ast__CallArg a, int indent_count); static string v__ast__OrExpr_str(v__ast__OrExpr it); static string indent_v__ast__OrExpr_str(v__ast__OrExpr it, int indent_count); static string Array_v__ast__Comment_str(Array_v__ast__Comment a); static string indent_Array_v__ast__Comment_str(Array_v__ast__Comment a, int indent_count); static string Map_int_bool_str(Map_int_bool m); static string indent_Map_int_bool_str(Map_int_bool m, int indent_count); static string Map_string_bool_str(Map_string_bool m); static string indent_Map_string_bool_str(Map_string_bool m, int indent_count); static string Map_v__ast__Type_bool_str(Map_v__ast__Type_bool m); static string indent_Map_v__ast__Type_bool_str(Map_v__ast__Type_bool m, int indent_count); static string v__ast__ScopeObject_str(v__ast__ScopeObject x); static string indent_v__ast__ScopeObject_str(v__ast__ScopeObject x, int indent_count); static string v__ast__IdentInfo_str(v__ast__IdentInfo x); static string indent_v__ast__IdentInfo_str(v__ast__IdentInfo x, int indent_count); static string Map_string_Array_v__ast__Attr_str(Map_string_Array_v__ast__Attr m); static string indent_Map_string_Array_v__ast__Attr_str(Map_string_Array_v__ast__Attr m, int indent_count); static string v__ast__EmptyExpr_str(v__ast__EmptyExpr it); static string indent_v__ast__EmptyExpr_str(v__ast__EmptyExpr it, int indent_count); static string v__builder__CC_str(v__builder__CC it); static string v__ast__OrKind_str(v__ast__OrKind it); static string Array_v__ast__Stmt_str(Array_v__ast__Stmt a); static string indent_Array_v__ast__Stmt_str(Array_v__ast__Stmt a, int indent_count); static string v__ast__Comment_str(v__ast__Comment it); static string indent_v__ast__Comment_str(v__ast__Comment it, int indent_count); static string v__ast__EmptyScopeObject_str(v__ast__EmptyScopeObject it); static string indent_v__ast__EmptyScopeObject_str(v__ast__EmptyScopeObject it, int indent_count); static string v__ast__AsmRegister_str(v__ast__AsmRegister it); static string indent_v__ast__AsmRegister_str(v__ast__AsmRegister it, int indent_count); static string v__ast__ConstField_str(v__ast__ConstField it); static string indent_v__ast__ConstField_str(v__ast__ConstField it, int indent_count); static string v__ast__GlobalField_str(v__ast__GlobalField it); static string indent_v__ast__GlobalField_str(v__ast__GlobalField it, int indent_count); static string v__ast__Var_str(v__ast__Var it); static string indent_v__ast__Var_str(v__ast__Var it, int indent_count); static string v__ast__IdentFn_str(v__ast__IdentFn it); static string indent_v__ast__IdentFn_str(v__ast__IdentFn it, int indent_count); static string v__ast__IdentVar_str(v__ast__IdentVar it); static string indent_v__ast__IdentVar_str(v__ast__IdentVar it, int indent_count); static string v__ast__ComptimeVarKind_str(v__ast__ComptimeVarKind it); v__ast__Expr v__ast__EmptyExpr_to_sumtype_v__ast__Expr(v__ast__EmptyExpr* x); v__ast__Stmt v__ast__EmptyStmt_to_sumtype_v__ast__Stmt(v__ast__EmptyStmt* x); v__ast__ScopeObject v__ast__EmptyScopeObject_to_sumtype_v__ast__ScopeObject(v__ast__EmptyScopeObject* x); v__ast__ComptTimeConstValue v__ast__EmptyExpr_to_sumtype_v__ast__ComptTimeConstValue(v__ast__EmptyExpr* x); v__ast__Node v__ast__Expr_to_sumtype_v__ast__Node(v__ast__Expr* x); v__ast__Expr v__ast__Ident_to_sumtype_v__ast__Expr(v__ast__Ident* x); v__ast__Node v__ast__Stmt_to_sumtype_v__ast__Node(v__ast__Stmt* x); v__ast__Node v__ast__StructInitField_to_sumtype_v__ast__Node(v__ast__StructInitField* x); v__ast__Stmt v__ast__FnDecl_to_sumtype_v__ast__Stmt(v__ast__FnDecl* x); v__ast__Node v__ast__CallArg_to_sumtype_v__ast__Node(v__ast__CallArg* x); v__ast__Expr v__ast__OrExpr_to_sumtype_v__ast__Expr(v__ast__OrExpr* x); v__ast__Node v__ast__IfBranch_to_sumtype_v__ast__Node(v__ast__IfBranch* x); v__ast__Node v__ast__MatchBranch_to_sumtype_v__ast__Node(v__ast__MatchBranch* x); v__ast__Node v__ast__SelectBranch_to_sumtype_v__ast__Node(v__ast__SelectBranch* x); v__ast__Node v__ast__StructField_to_sumtype_v__ast__Node(v__ast__StructField* x); v__ast__Node v__ast__GlobalField_to_sumtype_v__ast__Node(v__ast__GlobalField* x); v__ast__Node v__ast__ConstField_to_sumtype_v__ast__Node(v__ast__ConstField* x); v__ast__Node v__ast__EnumField_to_sumtype_v__ast__Node(v__ast__EnumField* x); v__ast__Node v__ast__Param_to_sumtype_v__ast__Node(v__ast__Param* x); v__ast__Expr v__ast__TypeNode_to_sumtype_v__ast__Expr(v__ast__TypeNode* x); v__ast__ScopeObject v__ast__AsmRegister_to_sumtype_v__ast__ScopeObject(v__ast__AsmRegister* x); v__ast__Expr v__ast__ArrayInit_to_sumtype_v__ast__Expr(v__ast__ArrayInit* x); v__ast__Expr v__ast__StringLiteral_to_sumtype_v__ast__Expr(v__ast__StringLiteral* x); v__ast__Expr v__ast__MapInit_to_sumtype_v__ast__Expr(v__ast__MapInit* x); v__ast__Expr v__ast__StructInit_to_sumtype_v__ast__Expr(v__ast__StructInit* x); v__ast__TypeInfo v__ast__SumType_to_sumtype_v__ast__TypeInfo(v__ast__SumType* x); v__ast__TypeInfo v__ast__Chan_to_sumtype_v__ast__TypeInfo(v__ast__Chan* x); v__ast__TypeInfo v__ast__Map_to_sumtype_v__ast__TypeInfo(v__ast__Map* x); v__ast__TypeInfo v__ast__Thread_to_sumtype_v__ast__TypeInfo(v__ast__Thread* x); v__ast__TypeInfo v__ast__Struct_to_sumtype_v__ast__TypeInfo(v__ast__Struct* x); v__ast__TypeInfo v__ast__Array_to_sumtype_v__ast__TypeInfo(v__ast__Array* x); v__ast__TypeInfo v__ast__ArrayFixed_to_sumtype_v__ast__TypeInfo(v__ast__ArrayFixed* x); v__ast__TypeInfo v__ast__MultiReturn_to_sumtype_v__ast__TypeInfo(v__ast__MultiReturn* x); v__ast__TypeInfo v__ast__FnType_to_sumtype_v__ast__TypeInfo(v__ast__FnType* x); v__ast__Expr v__ast__None_to_sumtype_v__ast__Expr(v__ast__None* x); v__ast__TypeInfo v__ast__Interface_to_sumtype_v__ast__TypeInfo(v__ast__Interface* x); v__ast__Stmt v__ast__AssertStmt_to_sumtype_v__ast__Stmt(v__ast__AssertStmt* x); v__ast__Expr v__ast__IfExpr_to_sumtype_v__ast__Expr(v__ast__IfExpr* x); v__ast__Expr v__ast__BoolLiteral_to_sumtype_v__ast__Expr(v__ast__BoolLiteral* x); v__ast__Expr v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(v__ast__IntegerLiteral* x); v__ast__Expr v__ast__FloatLiteral_to_sumtype_v__ast__Expr(v__ast__FloatLiteral* x); v__ast__Expr v__ast__MatchExpr_to_sumtype_v__ast__Expr(v__ast__MatchExpr* x); v__ast__Stmt v__ast__ForCStmt_to_sumtype_v__ast__Stmt(v__ast__ForCStmt* x); v__ast__Stmt v__ast__ForStmt_to_sumtype_v__ast__Stmt(v__ast__ForStmt* x); v__ast__Stmt v__ast__InterfaceDecl_to_sumtype_v__ast__Stmt(v__ast__InterfaceDecl* x); v__ast__Expr v__ast__CallExpr_to_sumtype_v__ast__Expr(v__ast__CallExpr* x); v__ast__Expr v__ast__InfixExpr_to_sumtype_v__ast__Expr(v__ast__InfixExpr* x); v__ast__Expr v__ast__SqlExpr_to_sumtype_v__ast__Expr(v__ast__SqlExpr* x); v__ast__Stmt v__ast__ExprStmt_to_sumtype_v__ast__Stmt(v__ast__ExprStmt* x); v__ast__Stmt v__ast__Block_to_sumtype_v__ast__Stmt(v__ast__Block* x); v__ast__Expr v__ast__AnonFn_to_sumtype_v__ast__Expr(v__ast__AnonFn* x); v__ast__Expr v__ast__IndexExpr_to_sumtype_v__ast__Expr(v__ast__IndexExpr* x); v__ast__Expr v__ast__PrefixExpr_to_sumtype_v__ast__Expr(v__ast__PrefixExpr* x); v__ast__IdentInfo v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(v__ast__IdentVar* x); v__ast__Expr v__ast__CastExpr_to_sumtype_v__ast__Expr(v__ast__CastExpr* x); v__ast__Stmt v__ast__TypeDecl_to_sumtype_v__ast__Stmt(v__ast__TypeDecl* x); v__ast__TypeDecl v__ast__AliasTypeDecl_to_sumtype_v__ast__TypeDecl(v__ast__AliasTypeDecl* x); v__ast__Expr v__ast__SelectorExpr_to_sumtype_v__ast__Expr(v__ast__SelectorExpr* x); v__ast__AsmArg v__ast__AsmRegister_to_sumtype_v__ast__AsmArg(v__ast__AsmRegister* x); v__ast__ScopeObject v__ast__Var_to_sumtype_v__ast__ScopeObject(v__ast__Var* x); v__ast__IdentInfo v__ast__IdentFn_to_sumtype_v__ast__IdentInfo(v__ast__IdentFn* x); v__ast__ScopeObject v__ast__ConstField_to_sumtype_v__ast__ScopeObject(v__ast__ConstField* x); v__ast__Expr v__ast__ComptimeCall_to_sumtype_v__ast__Expr(v__ast__ComptimeCall* x); v__ast__ComptTimeConstValue i64_to_sumtype_v__ast__ComptTimeConstValue(i64* x); v__ast__ComptTimeConstValue f64_to_sumtype_v__ast__ComptTimeConstValue(f64* x); v__ast__ComptTimeConstValue u64_to_sumtype_v__ast__ComptTimeConstValue(u64* x); v__ast__ComptTimeConstValue string_to_sumtype_v__ast__ComptTimeConstValue(string* x); v__ast__ComptTimeConstValue rune_to_sumtype_v__ast__ComptTimeConstValue(rune* x); v__ast__ComptTimeConstValue i32_to_sumtype_v__ast__ComptTimeConstValue(i32* x); v__ast__ComptTimeConstValue i8_to_sumtype_v__ast__ComptTimeConstValue(i8* x); v__ast__ComptTimeConstValue i16_to_sumtype_v__ast__ComptTimeConstValue(i16* x); v__ast__ComptTimeConstValue u8_to_sumtype_v__ast__ComptTimeConstValue(u8* x); v__ast__ComptTimeConstValue u16_to_sumtype_v__ast__ComptTimeConstValue(u16* x); v__ast__ComptTimeConstValue u32_to_sumtype_v__ast__ComptTimeConstValue(u32* x); v__ast__ComptTimeConstValue f32_to_sumtype_v__ast__ComptTimeConstValue(f32* x); v__ast__ComptTimeConstValue voidptr_to_sumtype_v__ast__ComptTimeConstValue(voidptr* x); v__ast__Stmt v__ast__Return_to_sumtype_v__ast__Stmt(v__ast__Return* x); v__ast__Expr v__ast__AsCast_to_sumtype_v__ast__Expr(v__ast__AsCast* x); v__ast__Expr v__ast__ParExpr_to_sumtype_v__ast__Expr(v__ast__ParExpr* x); v__ast__TypeInfo v__ast__Aggregate_to_sumtype_v__ast__TypeInfo(v__ast__Aggregate* x); v__checker__ORMExpr v__ast__SqlExpr_to_sumtype_v__checker__ORMExpr(v__ast__SqlExpr* x); v__checker__ORMExpr v__ast__SqlStmt_to_sumtype_v__checker__ORMExpr(v__ast__SqlStmt* x); v__ast__Expr v__ast__PostfixExpr_to_sumtype_v__ast__Expr(v__ast__PostfixExpr* x); v__ast__AsmArg string_to_sumtype_v__ast__AsmArg(string* x); v__ast__AsmArg v__ast__FloatLiteral_to_sumtype_v__ast__AsmArg(v__ast__FloatLiteral* x); v__ast__AsmArg v__ast__AsmDisp_to_sumtype_v__ast__AsmArg(v__ast__AsmDisp* x); v__ast__AsmArg v__ast__IntegerLiteral_to_sumtype_v__ast__AsmArg(v__ast__IntegerLiteral* x); v__ast__AsmArg v__ast__CharLiteral_to_sumtype_v__ast__AsmArg(v__ast__CharLiteral* x); v__ast__AsmArg v__ast__AsmAddressing_to_sumtype_v__ast__AsmArg(v__ast__AsmAddressing* x); v__ast__AsmArg v__ast__AsmAlias_to_sumtype_v__ast__AsmArg(v__ast__AsmAlias* x); v__ast__Stmt v__ast__NodeError_to_sumtype_v__ast__Stmt(v__ast__NodeError* x); v__ast__Stmt v__ast__AssignStmt_to_sumtype_v__ast__Stmt(v__ast__AssignStmt* x); v__ast__Expr v__ast__ComptimeSelector_to_sumtype_v__ast__Expr(v__ast__ComptimeSelector* x); v__ast__TypeInfo v__ast__Enum_to_sumtype_v__ast__TypeInfo(v__ast__Enum* x); v__ast__Expr v__ast__NodeError_to_sumtype_v__ast__Expr(v__ast__NodeError* x); v__ast__Expr v__ast__Comment_to_sumtype_v__ast__Expr(v__ast__Comment* x); v__ast__Expr v__ast__EnumVal_to_sumtype_v__ast__Expr(v__ast__EnumVal* x); v__ast__Expr v__ast__AtExpr_to_sumtype_v__ast__Expr(v__ast__AtExpr* x); v__ast__Expr v__ast__ComptimeType_to_sumtype_v__ast__Expr(v__ast__ComptimeType* x); v__ast__Expr v__ast__CharLiteral_to_sumtype_v__ast__Expr(v__ast__CharLiteral* x); v__ast__Expr v__ast__GoExpr_to_sumtype_v__ast__Expr(v__ast__GoExpr* x); v__ast__Expr v__ast__SpawnExpr_to_sumtype_v__ast__Expr(v__ast__SpawnExpr* x); v__ast__Expr v__ast__SelectExpr_to_sumtype_v__ast__Expr(v__ast__SelectExpr* x); v__ast__Expr v__ast__Nil_to_sumtype_v__ast__Expr(v__ast__Nil* x); v__ast__Expr v__ast__UnsafeExpr_to_sumtype_v__ast__Expr(v__ast__UnsafeExpr* x); v__ast__Expr v__ast__LambdaExpr_to_sumtype_v__ast__Expr(v__ast__LambdaExpr* x); v__ast__Expr v__ast__LockExpr_to_sumtype_v__ast__Expr(v__ast__LockExpr* x); v__ast__Expr v__ast__TypeOf_to_sumtype_v__ast__Expr(v__ast__TypeOf* x); v__ast__Expr v__ast__IsRefType_to_sumtype_v__ast__Expr(v__ast__IsRefType* x); v__ast__Expr v__ast__SizeOf_to_sumtype_v__ast__Expr(v__ast__SizeOf* x); v__ast__Expr v__ast__DumpExpr_to_sumtype_v__ast__Expr(v__ast__DumpExpr* x); v__ast__Expr v__ast__OffsetOf_to_sumtype_v__ast__Expr(v__ast__OffsetOf* x); v__ast__Expr v__ast__Likely_to_sumtype_v__ast__Expr(v__ast__Likely* x); v__ast__Stmt v__ast__StructDecl_to_sumtype_v__ast__Stmt(v__ast__StructDecl* x); v__ast__Expr v__ast__RangeExpr_to_sumtype_v__ast__Expr(v__ast__RangeExpr* x); v__ast__Expr v__ast__ArrayDecompose_to_sumtype_v__ast__Expr(v__ast__ArrayDecompose* x); v__ast__Stmt v__ast__ForInStmt_to_sumtype_v__ast__Stmt(v__ast__ForInStmt* x); v__ast__Expr v__ast__IfGuardExpr_to_sumtype_v__ast__Expr(v__ast__IfGuardExpr* x); v__ast__TypeInfo v__ast__GenericInst_to_sumtype_v__ast__TypeInfo(v__ast__GenericInst* x); v__ast__Stmt v__ast__Module_to_sumtype_v__ast__Stmt(v__ast__Module* x); v__ast__Stmt v__ast__Import_to_sumtype_v__ast__Stmt(v__ast__Import* x); v__ast__Stmt v__ast__ConstDecl_to_sumtype_v__ast__Stmt(v__ast__ConstDecl* x); v__ast__Stmt v__ast__EnumDecl_to_sumtype_v__ast__Stmt(v__ast__EnumDecl* x); v__ast__Stmt v__ast__GlobalDecl_to_sumtype_v__ast__Stmt(v__ast__GlobalDecl* x); v__ast__Stmt v__ast__ComptimeFor_to_sumtype_v__ast__Stmt(v__ast__ComptimeFor* x); v__ast__Stmt v__ast__HashStmt_to_sumtype_v__ast__Stmt(v__ast__HashStmt* x); v__ast__Stmt v__ast__SemicolonStmt_to_sumtype_v__ast__Stmt(v__ast__SemicolonStmt* x); v__ast__Stmt v__ast__AsmStmt_to_sumtype_v__ast__Stmt(v__ast__AsmStmt* x); v__ast__Stmt v__ast__SqlStmt_to_sumtype_v__ast__Stmt(v__ast__SqlStmt* x); v__ast__Stmt v__ast__GotoLabel_to_sumtype_v__ast__Stmt(v__ast__GotoLabel* x); v__ast__Stmt v__ast__DebuggerStmt_to_sumtype_v__ast__Stmt(v__ast__DebuggerStmt* x); v__ast__Stmt v__ast__BranchStmt_to_sumtype_v__ast__Stmt(v__ast__BranchStmt* x); v__ast__Stmt v__ast__DeferStmt_to_sumtype_v__ast__Stmt(v__ast__DeferStmt* x); v__ast__Stmt v__ast__GotoStmt_to_sumtype_v__ast__Stmt(v__ast__GotoStmt* x); v__ast__Expr v__ast__ConcatExpr_to_sumtype_v__ast__Expr(v__ast__ConcatExpr* x); v__ast__Expr v__ast__ChanInit_to_sumtype_v__ast__Expr(v__ast__ChanInit* x); v__ast__Expr v__ast__StringInterLiteral_to_sumtype_v__ast__Expr(v__ast__StringInterLiteral* x); v__ast__ScopeObject v__ast__GlobalField_to_sumtype_v__ast__ScopeObject(v__ast__GlobalField* x); v__ast__TypeDecl v__ast__SumTypeDecl_to_sumtype_v__ast__TypeDecl(v__ast__SumTypeDecl* x); v__ast__TypeDecl v__ast__FnTypeDecl_to_sumtype_v__ast__TypeDecl(v__ast__FnTypeDecl* x); v__ast__TypeInfo v__ast__Alias_to_sumtype_v__ast__TypeInfo(v__ast__Alias* x); v__ast__Node v__ast__File_to_sumtype_v__ast__Node(v__ast__File* x); v__ast__Expr v__ast__CTempVar_to_sumtype_v__ast__Expr(v__ast__CTempVar* x); bool Array_string_arr_eq(Array_string a, Array_string b); bool v__ast__Type_alias_eq(v__ast__Type a, v__ast__Type b); bool Array_v__ast__Type_arr_eq(Array_v__ast__Type a, Array_v__ast__Type b); bool v__token__Pos_struct_eq(v__token__Pos a, v__token__Pos b); bool v__ast__Stmt_sumtype_eq(v__ast__Stmt a, v__ast__Stmt b); bool v__ast__AsmStmt_struct_eq(v__ast__AsmStmt a, v__ast__AsmStmt b); bool Array_v__ast__AsmClobbered_arr_eq(Array_v__ast__AsmClobbered a, Array_v__ast__AsmClobbered b); bool v__ast__AsmClobbered_struct_eq(v__ast__AsmClobbered a, v__ast__AsmClobbered b); bool v__ast__AsmRegister_struct_eq(v__ast__AsmRegister a, v__ast__AsmRegister b); bool Array_v__ast__Comment_arr_eq(Array_v__ast__Comment a, Array_v__ast__Comment b); bool v__ast__Comment_struct_eq(v__ast__Comment a, v__ast__Comment b); bool Array_v__ast__AsmTemplate_arr_eq(Array_v__ast__AsmTemplate a, Array_v__ast__AsmTemplate b); bool v__ast__AsmTemplate_struct_eq(v__ast__AsmTemplate a, v__ast__AsmTemplate b); bool Array_v__ast__AsmArg_arr_eq(Array_v__ast__AsmArg a, Array_v__ast__AsmArg b); bool v__ast__AsmArg_sumtype_eq(v__ast__AsmArg a, v__ast__AsmArg b); bool v__ast__AsmAddressing_struct_eq(v__ast__AsmAddressing a, v__ast__AsmAddressing b); bool v__ast__AsmAlias_struct_eq(v__ast__AsmAlias a, v__ast__AsmAlias b); bool v__ast__AsmDisp_struct_eq(v__ast__AsmDisp a, v__ast__AsmDisp b); bool v__ast__BoolLiteral_struct_eq(v__ast__BoolLiteral a, v__ast__BoolLiteral b); bool v__ast__CharLiteral_struct_eq(v__ast__CharLiteral a, v__ast__CharLiteral b); bool v__ast__FloatLiteral_struct_eq(v__ast__FloatLiteral a, v__ast__FloatLiteral b); bool v__ast__IntegerLiteral_struct_eq(v__ast__IntegerLiteral a, v__ast__IntegerLiteral b); bool Array_v__ast__AsmIO_arr_eq(Array_v__ast__AsmIO a, Array_v__ast__AsmIO b); bool v__ast__AsmIO_struct_eq(v__ast__AsmIO a, v__ast__AsmIO b); bool v__ast__Expr_sumtype_eq(v__ast__Expr a, v__ast__Expr b); bool v__ast__NodeError_struct_eq(v__ast__NodeError a, v__ast__NodeError b); bool v__ast__AnonFn_struct_eq(v__ast__AnonFn a, v__ast__AnonFn b); bool v__ast__FnDecl_struct_eq(v__ast__FnDecl a, v__ast__FnDecl b); bool v__ast__StructField_struct_eq(v__ast__StructField a, v__ast__StructField b); bool Array_v__ast__Attr_arr_eq(Array_v__ast__Attr a, Array_v__ast__Attr b); bool v__ast__Attr_struct_eq(v__ast__Attr a, v__ast__Attr b); bool v__ast__StructDecl_struct_eq(v__ast__StructDecl a, v__ast__StructDecl b); bool Array_v__ast__Embed_arr_eq(Array_v__ast__Embed a, Array_v__ast__Embed b); bool v__ast__Embed_struct_eq(v__ast__Embed a, v__ast__Embed b); bool Array_v__ast__TypeNode_arr_eq(Array_v__ast__TypeNode a, Array_v__ast__TypeNode b); bool v__ast__TypeNode_struct_eq(v__ast__TypeNode a, v__ast__TypeNode b); bool Array_v__ast__StructField_arr_eq(Array_v__ast__StructField a, Array_v__ast__StructField b); bool Array_v__ast__Param_arr_eq(Array_v__ast__Param a, Array_v__ast__Param b); bool v__ast__Param_struct_eq(v__ast__Param a, v__ast__Param b); bool Array_v__ast__Stmt_arr_eq(Array_v__ast__Stmt a, Array_v__ast__Stmt b); bool Array_v__ast__DeferStmt_arr_eq(Array_v__ast__DeferStmt a, Array_v__ast__DeferStmt b); bool v__ast__DeferStmt_struct_eq(v__ast__DeferStmt a, v__ast__DeferStmt b); bool Array_v__ast__Ident_arr_eq(Array_v__ast__Ident a, Array_v__ast__Ident b); bool v__ast__Ident_struct_eq(v__ast__Ident a, v__ast__Ident b); bool v__ast__ScopeObject_sumtype_eq(v__ast__ScopeObject a, v__ast__ScopeObject b); bool v__ast__EmptyScopeObject_struct_eq(v__ast__EmptyScopeObject a, v__ast__EmptyScopeObject b); bool v__ast__ConstField_struct_eq(v__ast__ConstField a, v__ast__ConstField b); bool v__ast__ComptTimeConstValue_sumtype_eq(v__ast__ComptTimeConstValue a, v__ast__ComptTimeConstValue b); bool v__ast__EmptyExpr_alias_eq(v__ast__EmptyExpr a, v__ast__EmptyExpr b); bool v__ast__GlobalField_struct_eq(v__ast__GlobalField a, v__ast__GlobalField b); bool v__ast__Var_struct_eq(v__ast__Var a, v__ast__Var b); bool v__ast__IdentInfo_sumtype_eq(v__ast__IdentInfo a, v__ast__IdentInfo b); bool v__ast__IdentFn_struct_eq(v__ast__IdentFn a, v__ast__IdentFn b); bool v__ast__IdentVar_struct_eq(v__ast__IdentVar a, v__ast__IdentVar b); bool v__ast__OrExpr_struct_eq(v__ast__OrExpr a, v__ast__OrExpr b); bool Map_string_v__ast__FnTrace_map_eq(Map_string_v__ast__FnTrace a, Map_string_v__ast__FnTrace b); bool v__ast__FnTrace_struct_eq(v__ast__FnTrace a, v__ast__FnTrace b); bool Map_string_bool_map_eq(Map_string_bool a, Map_string_bool b); bool v__ast__ArrayDecompose_struct_eq(v__ast__ArrayDecompose a, v__ast__ArrayDecompose b); bool v__ast__ArrayInit_struct_eq(v__ast__ArrayInit a, v__ast__ArrayInit b); bool Array_Array_v__ast__Comment_arr_eq(Array_Array_v__ast__Comment a, Array_Array_v__ast__Comment b); bool Array_v__ast__Expr_arr_eq(Array_v__ast__Expr a, Array_v__ast__Expr b); bool v__ast__AsCast_struct_eq(v__ast__AsCast a, v__ast__AsCast b); bool v__ast__Assoc_struct_eq(v__ast__Assoc a, v__ast__Assoc b); bool v__ast__AtExpr_struct_eq(v__ast__AtExpr a, v__ast__AtExpr b); bool v__ast__CTempVar_struct_eq(v__ast__CTempVar a, v__ast__CTempVar b); bool v__ast__CallExpr_struct_eq(v__ast__CallExpr a, v__ast__CallExpr b); bool Array_v__ast__CallArg_arr_eq(Array_v__ast__CallArg a, Array_v__ast__CallArg b); bool v__ast__CallArg_struct_eq(v__ast__CallArg a, v__ast__CallArg b); bool v__ast__CastExpr_struct_eq(v__ast__CastExpr a, v__ast__CastExpr b); bool v__ast__ChanInit_struct_eq(v__ast__ChanInit a, v__ast__ChanInit b); bool v__ast__ComptimeCall_struct_eq(v__ast__ComptimeCall a, v__ast__ComptimeCall b); bool v__ast__File_struct_eq(v__ast__File a, v__ast__File b); bool v__ast__Module_struct_eq(v__ast__Module a, v__ast__Module b); bool Array_v__ast__Import_arr_eq(Array_v__ast__Import a, Array_v__ast__Import b); bool v__ast__Import_struct_eq(v__ast__Import a, v__ast__Import b); bool Array_v__ast__ImportSymbol_arr_eq(Array_v__ast__ImportSymbol a, Array_v__ast__ImportSymbol b); bool v__ast__ImportSymbol_struct_eq(v__ast__ImportSymbol a, v__ast__ImportSymbol b); bool Array_v__ast__EmbeddedFile_arr_eq(Array_v__ast__EmbeddedFile a, Array_v__ast__EmbeddedFile b); bool v__ast__EmbeddedFile_struct_eq(v__ast__EmbeddedFile a, v__ast__EmbeddedFile b); bool Array_u8_arr_eq(Array_u8 a, Array_u8 b); bool Map_string_string_map_eq(Map_string_string a, Map_string_string b); bool Array_v__errors__Error_arr_eq(Array_v__errors__Error a, Array_v__errors__Error b); bool v__errors__Error_struct_eq(v__errors__Error a, v__errors__Error b); bool v__errors__CompilerMessage_struct_eq(v__errors__CompilerMessage a, v__errors__CompilerMessage b); bool Array_v__errors__Warning_arr_eq(Array_v__errors__Warning a, Array_v__errors__Warning b); bool v__errors__Warning_struct_eq(v__errors__Warning a, v__errors__Warning b); bool Array_v__errors__Notice_arr_eq(Array_v__errors__Notice a, Array_v__errors__Notice b); bool v__errors__Notice_struct_eq(v__errors__Notice a, v__errors__Notice b); bool Array_v__ast__FnDecl_ptr_arr_eq(Array_v__ast__FnDecl_ptr a, Array_v__ast__FnDecl_ptr b); bool v__ast__ComptimeSelector_struct_eq(v__ast__ComptimeSelector a, v__ast__ComptimeSelector b); bool v__ast__ComptimeType_struct_eq(v__ast__ComptimeType a, v__ast__ComptimeType b); bool v__ast__ConcatExpr_struct_eq(v__ast__ConcatExpr a, v__ast__ConcatExpr b); bool v__ast__DumpExpr_struct_eq(v__ast__DumpExpr a, v__ast__DumpExpr b); bool v__ast__EnumVal_struct_eq(v__ast__EnumVal a, v__ast__EnumVal b); bool v__ast__GoExpr_struct_eq(v__ast__GoExpr a, v__ast__GoExpr b); bool v__ast__IfExpr_struct_eq(v__ast__IfExpr a, v__ast__IfExpr b); bool Array_v__ast__IfBranch_arr_eq(Array_v__ast__IfBranch a, Array_v__ast__IfBranch b); bool v__ast__IfBranch_struct_eq(v__ast__IfBranch a, v__ast__IfBranch b); bool v__ast__IfGuardExpr_struct_eq(v__ast__IfGuardExpr a, v__ast__IfGuardExpr b); bool Array_v__ast__IfGuardVar_arr_eq(Array_v__ast__IfGuardVar a, Array_v__ast__IfGuardVar b); bool v__ast__IfGuardVar_struct_eq(v__ast__IfGuardVar a, v__ast__IfGuardVar b); bool v__ast__IndexExpr_struct_eq(v__ast__IndexExpr a, v__ast__IndexExpr b); bool v__ast__InfixExpr_struct_eq(v__ast__InfixExpr a, v__ast__InfixExpr b); bool v__ast__IsRefType_struct_eq(v__ast__IsRefType a, v__ast__IsRefType b); bool v__ast__LambdaExpr_struct_eq(v__ast__LambdaExpr a, v__ast__LambdaExpr b); bool v__ast__Likely_struct_eq(v__ast__Likely a, v__ast__Likely b); bool v__ast__LockExpr_struct_eq(v__ast__LockExpr a, v__ast__LockExpr b); bool Array_bool_arr_eq(Array_bool a, Array_bool b); bool v__ast__MapInit_struct_eq(v__ast__MapInit a, v__ast__MapInit b); bool v__ast__MatchExpr_struct_eq(v__ast__MatchExpr a, v__ast__MatchExpr b); bool Array_v__ast__MatchBranch_arr_eq(Array_v__ast__MatchBranch a, Array_v__ast__MatchBranch b); bool v__ast__MatchBranch_struct_eq(v__ast__MatchBranch a, v__ast__MatchBranch b); bool v__ast__Nil_struct_eq(v__ast__Nil a, v__ast__Nil b); bool v__ast__None_struct_eq(v__ast__None a, v__ast__None b); bool v__ast__OffsetOf_struct_eq(v__ast__OffsetOf a, v__ast__OffsetOf b); bool v__ast__ParExpr_struct_eq(v__ast__ParExpr a, v__ast__ParExpr b); bool v__ast__PostfixExpr_struct_eq(v__ast__PostfixExpr a, v__ast__PostfixExpr b); bool v__ast__PrefixExpr_struct_eq(v__ast__PrefixExpr a, v__ast__PrefixExpr b); bool v__ast__RangeExpr_struct_eq(v__ast__RangeExpr a, v__ast__RangeExpr b); bool v__ast__SelectExpr_struct_eq(v__ast__SelectExpr a, v__ast__SelectExpr b); bool Array_v__ast__SelectBranch_arr_eq(Array_v__ast__SelectBranch a, Array_v__ast__SelectBranch b); bool v__ast__SelectBranch_struct_eq(v__ast__SelectBranch a, v__ast__SelectBranch b); bool v__ast__SelectorExpr_struct_eq(v__ast__SelectorExpr a, v__ast__SelectorExpr b); bool Array_Array_v__ast__Type_arr_eq(Array_Array_v__ast__Type a, Array_Array_v__ast__Type b); bool v__ast__SizeOf_struct_eq(v__ast__SizeOf a, v__ast__SizeOf b); bool v__ast__SpawnExpr_struct_eq(v__ast__SpawnExpr a, v__ast__SpawnExpr b); bool v__ast__SqlExpr_struct_eq(v__ast__SqlExpr a, v__ast__SqlExpr b); bool Map_int_v__ast__SqlExpr_map_eq(Map_int_v__ast__SqlExpr a, Map_int_v__ast__SqlExpr b); bool v__ast__StringInterLiteral_struct_eq(v__ast__StringInterLiteral a, v__ast__StringInterLiteral b); bool Array_int_arr_eq(Array_int a, Array_int b); bool Array_v__token__Pos_arr_eq(Array_v__token__Pos a, Array_v__token__Pos b); bool v__ast__StringLiteral_struct_eq(v__ast__StringLiteral a, v__ast__StringLiteral b); bool v__ast__StructInit_struct_eq(v__ast__StructInit a, v__ast__StructInit b); bool Array_v__ast__StructInitField_arr_eq(Array_v__ast__StructInitField a, Array_v__ast__StructInitField b); bool v__ast__StructInitField_struct_eq(v__ast__StructInitField a, v__ast__StructInitField b); bool v__ast__TypeOf_struct_eq(v__ast__TypeOf a, v__ast__TypeOf b); bool v__ast__UnsafeExpr_struct_eq(v__ast__UnsafeExpr a, v__ast__UnsafeExpr b); bool v__ast__AssertStmt_struct_eq(v__ast__AssertStmt a, v__ast__AssertStmt b); bool v__ast__AssignStmt_struct_eq(v__ast__AssignStmt a, v__ast__AssignStmt b); bool v__ast__Block_struct_eq(v__ast__Block a, v__ast__Block b); bool v__ast__BranchStmt_struct_eq(v__ast__BranchStmt a, v__ast__BranchStmt b); bool v__ast__ComptimeFor_struct_eq(v__ast__ComptimeFor a, v__ast__ComptimeFor b); bool v__ast__ConstDecl_struct_eq(v__ast__ConstDecl a, v__ast__ConstDecl b); bool Array_v__ast__ConstField_arr_eq(Array_v__ast__ConstField a, Array_v__ast__ConstField b); bool v__ast__DebuggerStmt_struct_eq(v__ast__DebuggerStmt a, v__ast__DebuggerStmt b); bool v__ast__EmptyStmt_struct_eq(v__ast__EmptyStmt a, v__ast__EmptyStmt b); bool v__ast__EnumDecl_struct_eq(v__ast__EnumDecl a, v__ast__EnumDecl b); bool Array_v__ast__EnumField_arr_eq(Array_v__ast__EnumField a, Array_v__ast__EnumField b); bool v__ast__EnumField_struct_eq(v__ast__EnumField a, v__ast__EnumField b); bool v__ast__ExprStmt_struct_eq(v__ast__ExprStmt a, v__ast__ExprStmt b); bool v__ast__ForCStmt_struct_eq(v__ast__ForCStmt a, v__ast__ForCStmt b); bool v__ast__ForInStmt_struct_eq(v__ast__ForInStmt a, v__ast__ForInStmt b); bool v__ast__ForStmt_struct_eq(v__ast__ForStmt a, v__ast__ForStmt b); bool v__ast__GlobalDecl_struct_eq(v__ast__GlobalDecl a, v__ast__GlobalDecl b); bool Array_v__ast__GlobalField_arr_eq(Array_v__ast__GlobalField a, Array_v__ast__GlobalField b); bool v__ast__GotoLabel_struct_eq(v__ast__GotoLabel a, v__ast__GotoLabel b); bool v__ast__GotoStmt_struct_eq(v__ast__GotoStmt a, v__ast__GotoStmt b); bool v__ast__HashStmt_struct_eq(v__ast__HashStmt a, v__ast__HashStmt b); bool v__ast__InterfaceDecl_struct_eq(v__ast__InterfaceDecl a, v__ast__InterfaceDecl b); bool Array_v__ast__FnDecl_arr_eq(Array_v__ast__FnDecl a, Array_v__ast__FnDecl b); bool Array_v__ast__InterfaceEmbedding_arr_eq(Array_v__ast__InterfaceEmbedding a, Array_v__ast__InterfaceEmbedding b); bool v__ast__InterfaceEmbedding_struct_eq(v__ast__InterfaceEmbedding a, v__ast__InterfaceEmbedding b); bool v__ast__Return_struct_eq(v__ast__Return a, v__ast__Return b); bool v__ast__SemicolonStmt_struct_eq(v__ast__SemicolonStmt a, v__ast__SemicolonStmt b); bool v__ast__SqlStmt_struct_eq(v__ast__SqlStmt a, v__ast__SqlStmt b); bool Array_v__ast__SqlStmtLine_arr_eq(Array_v__ast__SqlStmtLine a, Array_v__ast__SqlStmtLine b); bool v__ast__SqlStmtLine_struct_eq(v__ast__SqlStmtLine a, v__ast__SqlStmtLine b); bool Map_int_v__ast__SqlStmtLine_map_eq(Map_int_v__ast__SqlStmtLine a, Map_int_v__ast__SqlStmtLine b); bool v__ast__TypeDecl_sumtype_eq(v__ast__TypeDecl a, v__ast__TypeDecl b); bool v__ast__AliasTypeDecl_struct_eq(v__ast__AliasTypeDecl a, v__ast__AliasTypeDecl b); bool v__ast__FnTypeDecl_struct_eq(v__ast__FnTypeDecl a, v__ast__FnTypeDecl b); bool v__ast__SumTypeDecl_struct_eq(v__ast__SumTypeDecl a, v__ast__SumTypeDecl b); bool v__gen__c__StrType_struct_eq(v__gen__c__StrType a, v__gen__c__StrType b); bool v__gen__c__SumtypeCastingFn_struct_eq(v__gen__c__SumtypeCastingFn a, v__gen__c__SumtypeCastingFn b); static void v__ast__TypeSymbol_free(v__ast__TypeSymbol* it); static void Array_v__ast__Fn_free(Array_v__ast__Fn* it); static void v__ast__Fn_free(v__ast__Fn* it); static void Array_v__ast__Param_free(Array_v__ast__Param* it); static void v__ast__Param_free(v__ast__Param* it); static void Array_v__ast__Attr_free(Array_v__ast__Attr* it); static void v__ast__Attr_free(v__ast__Attr* it); static void Array_v__ast__Type_free(Array_v__ast__Type* it); // V global/const non-precomputed definitions: string _const_strconv__digit_pairs; // a string literal, inited later string _const_strconv__base_digits; // a string literal, inited later string _const_digit_pairs; // a string literal, inited later string _const_si_s_code; // a string literal, inited later string _const_si_g32_code; // a string literal, inited later string _const_si_g64_code; // a string literal, inited later string _const_time__months_string; // a string literal, inited later string _const_flag__space; // a string literal, inited later string _const_flag__underline; // a string literal, inited later string _const_os__fslash_str; // a string literal, inited later string _const_os__dot_dot; // a string literal, inited later string _const_os__empty_str; // a string literal, inited later string _const_os__dot_str; // a string literal, inited later string _const_os__path_separator; // a string literal, inited later string _const_os__path_delimiter; // a string literal, inited later string _const_v__util__version__v_version; // a string literal, inited later string _const_v__cflag__fexisting_literal; // a string literal, inited later string _const_v__cflag__wexisting_literal; // a string literal, inited later string _const_v__pkgconfig__version; // a string literal, inited later string _const_rand__ulid_encoding; // a string literal, inited later string _const_v__util__d_sig; // a string literal, inited later string _const_v__util__double_escape; // a string literal, inited later string _const_v__util__map_prefix; // a string literal, inited later string _const_v__ast__result_name; // a string literal, inited later string _const_v__ast__option_name; // a string literal, inited later string _const_v__ast__int_type_name; // str inited later string _const_v__scanner__internally_generated_v_code; // a string literal, inited later string _const_v__checker__unicode_lit_overflow_message; // a string literal, inited later string _const_v__parser__error_msg; // a string literal, inited later string _const_v__parser__tmpl_str_end; // a string literal, inited later string _const_v__gen__c__si_s_code; // a string literal, inited later string _const_v__gen__c__result_name; // str inited later string _const_v__gen__c__option_name; // str inited later string _const_v__gen__c__c_commit_hash_default; // a string literal, inited later string _const_v__gen__c__c_concurrency_helpers; // a string literal, inited later string _const_v__gen__c__c_headers; // a string literal, inited later string _const_v__gen__c__c_builtin_types; // a string literal, inited later string _const_v__gen__c__c_mapfn_callback_types; // a string literal, inited later string _const_v__gen__c__c_bare_headers; // a string literal, inited later string _const_v__gen__c__c_wyhash_headers; // a string literal, inited later string _const_v__gen__c__reset_dbg_line; // a string literal, inited later string _const_v__gen__c__closure_ctx; // a string literal, inited later string _const_v__gen__c__posix_hotcode_definitions_1; // a string literal, inited later string _const_v__gen__c__windows_hotcode_definitions_1; // a string literal, inited later string _const_v__gen__c__cprefix; // a string literal, inited later string _const_v__builder__c_std; // a string literal, inited later string _const_v__builder__c_std_gnu; // a string literal, inited later string _const_v__builder__cpp_std; // a string literal, inited later string _const_v__builder__cpp_std_gnu; // a string literal, inited later string _const_v__builder__c_verror_message_marker; // a string literal, inited later string _const_v__builder__c_compilation_error_title; // a string literal, inited later builtin__closure__Closure g_closure; // global 6 Array_u8 _const_builtin__closure__closure_thunk; // inited later Array_u8 _const_builtin__closure__closure_get_data_bytes; // inited later const u32 _const_math__bits__de_bruijn32 = 125613361; // precomputed2 Array_fixed_u8_32 _const_math__bits__de_bruijn32tab = {((u8)(0)), 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9}; // fixed array const const u64 _const_math__bits__de_bruijn64 = 285870213051353865U; // precomputed2 Array_fixed_u8_64 _const_math__bits__de_bruijn64tab = {((u8)(0)), 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4, 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5, 63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11, 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6}; // fixed array const const u64 _const_math__bits__two32 = 4294967296U; // precomputed2 const u64 _const_math__bits__mask32 = 4294967295U; // precomputed2 Array_fixed_u8_256 _const_math__bits__len_8_tab = {((u8)(0x00)), 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; // fixed array const const u32 _const_strconv__single_plus_zero = 0; // precomputed2 const u32 _const_strconv__single_minus_zero = 2147483648; // precomputed2 const u32 _const_strconv__single_plus_infinity = 2139095040; // precomputed2 const u32 _const_strconv__single_minus_infinity = 4286578688; // precomputed2 const u64 _const_strconv__double_plus_zero = 0U; // precomputed2 const u64 _const_strconv__double_minus_zero = 9223372036854775808U; // precomputed2 const u64 _const_strconv__double_plus_infinity = 9218868437227405312U; // precomputed2 const u64 _const_strconv__double_minus_infinity = 18442240474082181120U; // precomputed2 const u32 _const_strconv__c_ten = 10; // precomputed2 Array_fixed_u32_10 _const_strconv__ten_pow_table_32 = {((u32)(1U)), ((u32)(10U)), ((u32)(100U)), ((u32)(1000U)), ((u32)(10000U)), ((u32)(100000U)), ((u32)(1000000U)), ((u32)(10000000U)), ((u32)(100000000U)), ((u32)(1000000000U))}; // fixed array const const u32 _const_strconv__mantbits32 = 23; // precomputed2 const u32 _const_strconv__expbits32 = 8; // precomputed2 Array_fixed_u64_20 _const_strconv__ten_pow_table_64 = {((u64)(1U)), ((u64)(10U)), ((u64)(100U)), ((u64)(1000U)), ((u64)(10000U)), ((u64)(100000U)), ((u64)(1000000U)), ((u64)(10000000U)), ((u64)(100000000U)), ((u64)(1000000000U)), ((u64)(10000000000U)), ((u64)(100000000000U)), ((u64)(1000000000000U)), ((u64)(10000000000000U)), ((u64)(100000000000000U)), ((u64)(1000000000000000U)), ((u64)(10000000000000000U)), ((u64)(100000000000000000U)), ((u64)(1000000000000000000U)), ((u64)(10000000000000000000U))}; // fixed array const const u32 _const_strconv__mantbits64 = 52; // precomputed2 const u32 _const_strconv__expbits64 = 11; // precomputed2 Array_fixed_f64_36 _const_strconv__dec_round = {((f64)(0.5)), 0.05, 0.005, 0.0005, 0.00005, 0.000005, 0.0000005, 0.00000005, 0.000000005, 0.0000000005, 0.00000000005, 0.000000000005, 0.0000000000005, 0.00000000000005, 0.000000000000005, 0.0000000000000005, 0.00000000000000005, 0.000000000000000005, 0.0000000000000000005, 0.00000000000000000005, 0.000000000000000000005, 0.0000000000000000000005, 0.00000000000000000000005, 0.000000000000000000000005, 0.0000000000000000000000005, 0.00000000000000000000000005, 0.000000000000000000000000005, 0.0000000000000000000000000005, 0.00000000000000000000000000005, 0.000000000000000000000000000005, 0.0000000000000000000000000000005, 0.00000000000000000000000000000005, 0.000000000000000000000000000000005, 0.0000000000000000000000000000000005, 0.00000000000000000000000000000000005, 0.000000000000000000000000000000000005}; // fixed array const Array_fixed_u64_47 _const_strconv__pow5_split_32 = {((u64)(1152921504606846976U)), ((u64)(1441151880758558720U)), ((u64)(1801439850948198400U)), ((u64)(2251799813685248000U)), ((u64)(1407374883553280000U)), ((u64)(1759218604441600000U)), ((u64)(2199023255552000000U)), ((u64)(1374389534720000000U)), ((u64)(1717986918400000000U)), ((u64)(2147483648000000000U)), ((u64)(1342177280000000000U)), ((u64)(1677721600000000000U)), ((u64)(2097152000000000000U)), ((u64)(1310720000000000000U)), ((u64)(1638400000000000000U)), ((u64)(2048000000000000000U)), ((u64)(1280000000000000000U)), ((u64)(1600000000000000000U)), ((u64)(2000000000000000000U)), ((u64)(1250000000000000000U)), ((u64)(1562500000000000000U)), ((u64)(1953125000000000000U)), ((u64)(1220703125000000000U)), ((u64)(1525878906250000000U)), ((u64)(1907348632812500000U)), ((u64)(1192092895507812500U)), ((u64)(1490116119384765625U)), ((u64)(1862645149230957031U)), ((u64)(1164153218269348144U)), ((u64)(1455191522836685180U)), ((u64)(1818989403545856475U)), ((u64)(2273736754432320594U)), ((u64)(1421085471520200371U)), ((u64)(1776356839400250464U)), ((u64)(2220446049250313080U)), ((u64)(1387778780781445675U)), ((u64)(1734723475976807094U)), ((u64)(2168404344971008868U)), ((u64)(1355252715606880542U)), ((u64)(1694065894508600678U)), ((u64)(2117582368135750847U)), ((u64)(1323488980084844279U)), ((u64)(1654361225106055349U)), ((u64)(2067951531382569187U)), ((u64)(1292469707114105741U)), ((u64)(1615587133892632177U)), ((u64)(2019483917365790221U))}; // fixed array const Array_fixed_u64_31 _const_strconv__pow5_inv_split_32 = {((u64)(576460752303423489U)), ((u64)(461168601842738791U)), ((u64)(368934881474191033U)), ((u64)(295147905179352826U)), ((u64)(472236648286964522U)), ((u64)(377789318629571618U)), ((u64)(302231454903657294U)), ((u64)(483570327845851670U)), ((u64)(386856262276681336U)), ((u64)(309485009821345069U)), ((u64)(495176015714152110U)), ((u64)(396140812571321688U)), ((u64)(316912650057057351U)), ((u64)(507060240091291761U)), ((u64)(405648192073033409U)), ((u64)(324518553658426727U)), ((u64)(519229685853482763U)), ((u64)(415383748682786211U)), ((u64)(332306998946228969U)), ((u64)(531691198313966350U)), ((u64)(425352958651173080U)), ((u64)(340282366920938464U)), ((u64)(544451787073501542U)), ((u64)(435561429658801234U)), ((u64)(348449143727040987U)), ((u64)(557518629963265579U)), ((u64)(446014903970612463U)), ((u64)(356811923176489971U)), ((u64)(570899077082383953U)), ((u64)(456719261665907162U)), ((u64)(365375409332725730U))}; // fixed array const Array_fixed_u64_652 _const_strconv__pow5_split_64_x = {((u64)(0x0000000000000000U)), ((u64)(0x0100000000000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x0140000000000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x0190000000000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x01f4000000000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x0138800000000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x0186a00000000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x01e8480000000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x01312d0000000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x017d784000000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x01dcd65000000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x012a05f200000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x0174876e80000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x01d1a94a20000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x012309ce54000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x016bcc41e9000000U)), ((u64)(0x0000000000000000U)), ((u64)(0x01c6bf5263400000U)), ((u64)(0x0000000000000000U)), ((u64)(0x011c37937e080000U)), ((u64)(0x0000000000000000U)), ((u64)(0x016345785d8a0000U)), ((u64)(0x0000000000000000U)), ((u64)(0x01bc16d674ec8000U)), ((u64)(0x0000000000000000U)), ((u64)(0x01158e460913d000U)), ((u64)(0x0000000000000000U)), ((u64)(0x015af1d78b58c400U)), ((u64)(0x0000000000000000U)), ((u64)(0x01b1ae4d6e2ef500U)), ((u64)(0x0000000000000000U)), ((u64)(0x010f0cf064dd5920U)), ((u64)(0x0000000000000000U)), ((u64)(0x0152d02c7e14af68U)), ((u64)(0x0000000000000000U)), ((u64)(0x01a784379d99db42U)), ((u64)(0x4000000000000000U)), ((u64)(0x0108b2a2c2802909U)), ((u64)(0x9000000000000000U)), ((u64)(0x014adf4b7320334bU)), ((u64)(0x7400000000000000U)), ((u64)(0x019d971e4fe8401eU)), ((u64)(0x0880000000000000U)), ((u64)(0x01027e72f1f12813U)), ((u64)(0xcaa0000000000000U)), ((u64)(0x01431e0fae6d7217U)), ((u64)(0xbd48000000000000U)), ((u64)(0x0193e5939a08ce9dU)), ((u64)(0x2c9a000000000000U)), ((u64)(0x01f8def8808b0245U)), ((u64)(0x3be0400000000000U)), ((u64)(0x013b8b5b5056e16bU)), ((u64)(0x0ad8500000000000U)), ((u64)(0x018a6e32246c99c6U)), ((u64)(0x8d8e640000000000U)), ((u64)(0x01ed09bead87c037U)), ((u64)(0xb878fe8000000000U)), ((u64)(0x013426172c74d822U)), ((u64)(0x66973e2000000000U)), ((u64)(0x01812f9cf7920e2bU)), ((u64)(0x403d0da800000000U)), ((u64)(0x01e17b84357691b6U)), ((u64)(0xe826288900000000U)), ((u64)(0x012ced32a16a1b11U)), ((u64)(0x622fb2ab40000000U)), ((u64)(0x0178287f49c4a1d6U)), ((u64)(0xfabb9f5610000000U)), ((u64)(0x01d6329f1c35ca4bU)), ((u64)(0x7cb54395ca000000U)), ((u64)(0x0125dfa371a19e6fU)), ((u64)(0x5be2947b3c800000U)), ((u64)(0x016f578c4e0a060bU)), ((u64)(0x32db399a0ba00000U)), ((u64)(0x01cb2d6f618c878eU)), ((u64)(0xdfc9040047440000U)), ((u64)(0x011efc659cf7d4b8U)), ((u64)(0x17bb450059150000U)), ((u64)(0x0166bb7f0435c9e7U)), ((u64)(0xddaa16406f5a4000U)), ((u64)(0x01c06a5ec5433c60U)), ((u64)(0x8a8a4de845986800U)), ((u64)(0x0118427b3b4a05bcU)), ((u64)(0xad2ce16256fe8200U)), ((u64)(0x015e531a0a1c872bU)), ((u64)(0x987819baecbe2280U)), ((u64)(0x01b5e7e08ca3a8f6U)), ((u64)(0x1f4b1014d3f6d590U)), ((u64)(0x0111b0ec57e6499aU)), ((u64)(0xa71dd41a08f48af4U)), ((u64)(0x01561d276ddfdc00U)), ((u64)(0xd0e549208b31adb1U)), ((u64)(0x01aba4714957d300U)), ((u64)(0x828f4db456ff0c8eU)), ((u64)(0x010b46c6cdd6e3e0U)), ((u64)(0xa33321216cbecfb2U)), ((u64)(0x014e1878814c9cd8U)), ((u64)(0xcbffe969c7ee839eU)), ((u64)(0x01a19e96a19fc40eU)), ((u64)(0x3f7ff1e21cf51243U)), ((u64)(0x0105031e2503da89U)), ((u64)(0x8f5fee5aa43256d4U)), ((u64)(0x014643e5ae44d12bU)), ((u64)(0x7337e9f14d3eec89U)), ((u64)(0x0197d4df19d60576U)), ((u64)(0x1005e46da08ea7abU)), ((u64)(0x01fdca16e04b86d4U)), ((u64)(0x8a03aec4845928cbU)), ((u64)(0x013e9e4e4c2f3444U)), ((u64)(0xac849a75a56f72fdU)), ((u64)(0x018e45e1df3b0155U)), ((u64)(0x17a5c1130ecb4fbdU)), ((u64)(0x01f1d75a5709c1abU)), ((u64)(0xeec798abe93f11d6U)), ((u64)(0x013726987666190aU)), ((u64)(0xaa797ed6e38ed64bU)), ((u64)(0x0184f03e93ff9f4dU)), ((u64)(0x1517de8c9c728bdeU)), ((u64)(0x01e62c4e38ff8721U)), ((u64)(0xad2eeb17e1c7976bU)), ((u64)(0x012fdbb0e39fb474U)), ((u64)(0xd87aa5ddda397d46U)), ((u64)(0x017bd29d1c87a191U)), ((u64)(0x4e994f5550c7dc97U)), ((u64)(0x01dac74463a989f6U)), ((u64)(0xf11fd195527ce9deU)), ((u64)(0x0128bc8abe49f639U)), ((u64)(0x6d67c5faa71c2456U)), ((u64)(0x0172ebad6ddc73c8U)), ((u64)(0x88c1b77950e32d6cU)), ((u64)(0x01cfa698c95390baU)), ((u64)(0x957912abd28dfc63U)), ((u64)(0x0121c81f7dd43a74U)), ((u64)(0xbad75756c7317b7cU)), ((u64)(0x016a3a275d494911U)), ((u64)(0x298d2d2c78fdda5bU)), ((u64)(0x01c4c8b1349b9b56U)), ((u64)(0xd9f83c3bcb9ea879U)), ((u64)(0x011afd6ec0e14115U)), ((u64)(0x50764b4abe865297U)), ((u64)(0x0161bcca7119915bU)), ((u64)(0x2493de1d6e27e73dU)), ((u64)(0x01ba2bfd0d5ff5b2U)), ((u64)(0x56dc6ad264d8f086U)), ((u64)(0x01145b7e285bf98fU)), ((u64)(0x2c938586fe0f2ca8U)), ((u64)(0x0159725db272f7f3U)), ((u64)(0xf7b866e8bd92f7d2U)), ((u64)(0x01afcef51f0fb5efU)), ((u64)(0xfad34051767bdae3U)), ((u64)(0x010de1593369d1b5U)), ((u64)(0x79881065d41ad19cU)), ((u64)(0x015159af80444623U)), ((u64)(0x57ea147f49218603U)), ((u64)(0x01a5b01b605557acU)), ((u64)(0xb6f24ccf8db4f3c1U)), ((u64)(0x01078e111c3556cbU)), ((u64)(0xa4aee003712230b2U)), ((u64)(0x014971956342ac7eU)), ((u64)(0x4dda98044d6abcdfU)), ((u64)(0x019bcdfabc13579eU)), ((u64)(0xf0a89f02b062b60bU)), ((u64)(0x010160bcb58c16c2U)), ((u64)(0xacd2c6c35c7b638eU)), ((u64)(0x0141b8ebe2ef1c73U)), ((u64)(0x98077874339a3c71U)), ((u64)(0x01922726dbaae390U)), ((u64)(0xbe0956914080cb8eU)), ((u64)(0x01f6b0f092959c74U)), ((u64)(0xf6c5d61ac8507f38U)), ((u64)(0x013a2e965b9d81c8U)), ((u64)(0x34774ba17a649f07U)), ((u64)(0x0188ba3bf284e23bU)), ((u64)(0x01951e89d8fdc6c8U)), ((u64)(0x01eae8caef261acaU)), ((u64)(0x40fd3316279e9c3dU)), ((u64)(0x0132d17ed577d0beU)), ((u64)(0xd13c7fdbb186434cU)), ((u64)(0x017f85de8ad5c4edU)), ((u64)(0x458b9fd29de7d420U)), ((u64)(0x01df67562d8b3629U)), ((u64)(0xcb7743e3a2b0e494U)), ((u64)(0x012ba095dc7701d9U)), ((u64)(0x3e5514dc8b5d1db9U)), ((u64)(0x017688bb5394c250U)), ((u64)(0x4dea5a13ae346527U)), ((u64)(0x01d42aea2879f2e4U)), ((u64)(0xb0b2784c4ce0bf38U)), ((u64)(0x01249ad2594c37ceU)), ((u64)(0x5cdf165f6018ef06U)), ((u64)(0x016dc186ef9f45c2U)), ((u64)(0xf416dbf7381f2ac8U)), ((u64)(0x01c931e8ab871732U)), ((u64)(0xd88e497a83137abdU)), ((u64)(0x011dbf316b346e7fU)), ((u64)(0xceb1dbd923d8596cU)), ((u64)(0x01652efdc6018a1fU)), ((u64)(0xc25e52cf6cce6fc7U)), ((u64)(0x01be7abd3781eca7U)), ((u64)(0xd97af3c1a40105dcU)), ((u64)(0x01170cb642b133e8U)), ((u64)(0x0fd9b0b20d014754U)), ((u64)(0x015ccfe3d35d80e3U)), ((u64)(0xd3d01cde90419929U)), ((u64)(0x01b403dcc834e11bU)), ((u64)(0x6462120b1a28ffb9U)), ((u64)(0x01108269fd210cb1U)), ((u64)(0xbd7a968de0b33fa8U)), ((u64)(0x0154a3047c694fddU)), ((u64)(0x2cd93c3158e00f92U)), ((u64)(0x01a9cbc59b83a3d5U)), ((u64)(0x3c07c59ed78c09bbU)), ((u64)(0x010a1f5b81324665U)), ((u64)(0x8b09b7068d6f0c2aU)), ((u64)(0x014ca732617ed7feU)), ((u64)(0x2dcc24c830cacf34U)), ((u64)(0x019fd0fef9de8dfeU)), ((u64)(0xdc9f96fd1e7ec180U)), ((u64)(0x0103e29f5c2b18beU)), ((u64)(0x93c77cbc661e71e1U)), ((u64)(0x0144db473335deeeU)), ((u64)(0x38b95beb7fa60e59U)), ((u64)(0x01961219000356aaU)), ((u64)(0xc6e7b2e65f8f91efU)), ((u64)(0x01fb969f40042c54U)), ((u64)(0xfc50cfcffbb9bb35U)), ((u64)(0x013d3e2388029bb4U)), ((u64)(0x3b6503c3faa82a03U)), ((u64)(0x018c8dac6a0342a2U)), ((u64)(0xca3e44b4f9523484U)), ((u64)(0x01efb1178484134aU)), ((u64)(0xbe66eaf11bd360d2U)), ((u64)(0x0135ceaeb2d28c0eU)), ((u64)(0x6e00a5ad62c83907U)), ((u64)(0x0183425a5f872f12U)), ((u64)(0x0980cf18bb7a4749U)), ((u64)(0x01e412f0f768fad7U)), ((u64)(0x65f0816f752c6c8dU)), ((u64)(0x012e8bd69aa19cc6U)), ((u64)(0xff6ca1cb527787b1U)), ((u64)(0x017a2ecc414a03f7U)), ((u64)(0xff47ca3e2715699dU)), ((u64)(0x01d8ba7f519c84f5U)), ((u64)(0xbf8cde66d86d6202U)), ((u64)(0x0127748f9301d319U)), ((u64)(0x2f7016008e88ba83U)), ((u64)(0x017151b377c247e0U)), ((u64)(0x3b4c1b80b22ae923U)), ((u64)(0x01cda62055b2d9d8U)), ((u64)(0x250f91306f5ad1b6U)), ((u64)(0x012087d4358fc827U)), ((u64)(0xee53757c8b318623U)), ((u64)(0x0168a9c942f3ba30U)), ((u64)(0x29e852dbadfde7acU)), ((u64)(0x01c2d43b93b0a8bdU)), ((u64)(0x3a3133c94cbeb0ccU)), ((u64)(0x0119c4a53c4e6976U)), ((u64)(0xc8bd80bb9fee5cffU)), ((u64)(0x016035ce8b6203d3U)), ((u64)(0xbaece0ea87e9f43eU)), ((u64)(0x01b843422e3a84c8U)), ((u64)(0x74d40c9294f238a7U)), ((u64)(0x01132a095ce492fdU)), ((u64)(0xd2090fb73a2ec6d1U)), ((u64)(0x0157f48bb41db7bcU)), ((u64)(0x068b53a508ba7885U)), ((u64)(0x01adf1aea12525acU)), ((u64)(0x8417144725748b53U)), ((u64)(0x010cb70d24b7378bU)), ((u64)(0x651cd958eed1ae28U)), ((u64)(0x014fe4d06de5056eU)), ((u64)(0xfe640faf2a8619b2U)), ((u64)(0x01a3de04895e46c9U)), ((u64)(0x3efe89cd7a93d00fU)), ((u64)(0x01066ac2d5daec3eU)), ((u64)(0xcebe2c40d938c413U)), ((u64)(0x014805738b51a74dU)), ((u64)(0x426db7510f86f518U)), ((u64)(0x019a06d06e261121U)), ((u64)(0xc9849292a9b4592fU)), ((u64)(0x0100444244d7cab4U)), ((u64)(0xfbe5b73754216f7aU)), ((u64)(0x01405552d60dbd61U)), ((u64)(0x7adf25052929cb59U)), ((u64)(0x01906aa78b912cbaU)), ((u64)(0x1996ee4673743e2fU)), ((u64)(0x01f485516e7577e9U)), ((u64)(0xaffe54ec0828a6ddU)), ((u64)(0x0138d352e5096af1U)), ((u64)(0x1bfdea270a32d095U)), ((u64)(0x018708279e4bc5aeU)), ((u64)(0xa2fd64b0ccbf84baU)), ((u64)(0x01e8ca3185deb719U)), ((u64)(0x05de5eee7ff7b2f4U)), ((u64)(0x01317e5ef3ab3270U)), ((u64)(0x0755f6aa1ff59fb1U)), ((u64)(0x017dddf6b095ff0cU)), ((u64)(0x092b7454a7f3079eU)), ((u64)(0x01dd55745cbb7ecfU)), ((u64)(0x65bb28b4e8f7e4c3U)), ((u64)(0x012a5568b9f52f41U)), ((u64)(0xbf29f2e22335ddf3U)), ((u64)(0x0174eac2e8727b11U)), ((u64)(0x2ef46f9aac035570U)), ((u64)(0x01d22573a28f19d6U)), ((u64)(0xdd58c5c0ab821566U)), ((u64)(0x0123576845997025U)), ((u64)(0x54aef730d6629ac0U)), ((u64)(0x016c2d4256ffcc2fU)), ((u64)(0x29dab4fd0bfb4170U)), ((u64)(0x01c73892ecbfbf3bU)), ((u64)(0xfa28b11e277d08e6U)), ((u64)(0x011c835bd3f7d784U)), ((u64)(0x38b2dd65b15c4b1fU)), ((u64)(0x0163a432c8f5cd66U)), ((u64)(0xc6df94bf1db35de7U)), ((u64)(0x01bc8d3f7b3340bfU)), ((u64)(0xdc4bbcf772901ab0U)), ((u64)(0x0115d847ad000877U)), ((u64)(0xd35eac354f34215cU)), ((u64)(0x015b4e5998400a95U)), ((u64)(0x48365742a30129b4U)), ((u64)(0x01b221effe500d3bU)), ((u64)(0x0d21f689a5e0ba10U)), ((u64)(0x010f5535fef20845U)), ((u64)(0x506a742c0f58e894U)), ((u64)(0x01532a837eae8a56U)), ((u64)(0xe4851137132f22b9U)), ((u64)(0x01a7f5245e5a2cebU)), ((u64)(0x6ed32ac26bfd75b4U)), ((u64)(0x0108f936baf85c13U)), ((u64)(0x4a87f57306fcd321U)), ((u64)(0x014b378469b67318U)), ((u64)(0x5d29f2cfc8bc07e9U)), ((u64)(0x019e056584240fdeU)), ((u64)(0xfa3a37c1dd7584f1U)), ((u64)(0x0102c35f729689eaU)), ((u64)(0xb8c8c5b254d2e62eU)), ((u64)(0x014374374f3c2c65U)), ((u64)(0x26faf71eea079fb9U)), ((u64)(0x01945145230b377fU)), ((u64)(0xf0b9b4e6a48987a8U)), ((u64)(0x01f965966bce055eU)), ((u64)(0x5674111026d5f4c9U)), ((u64)(0x013bdf7e0360c35bU)), ((u64)(0x2c111554308b71fbU)), ((u64)(0x018ad75d8438f432U)), ((u64)(0xb7155aa93cae4e7aU)), ((u64)(0x01ed8d34e547313eU)), ((u64)(0x326d58a9c5ecf10cU)), ((u64)(0x013478410f4c7ec7U)), ((u64)(0xff08aed437682d4fU)), ((u64)(0x01819651531f9e78U)), ((u64)(0x3ecada89454238a3U)), ((u64)(0x01e1fbe5a7e78617U)), ((u64)(0x873ec895cb496366U)), ((u64)(0x012d3d6f88f0b3ceU)), ((u64)(0x290e7abb3e1bbc3fU)), ((u64)(0x01788ccb6b2ce0c2U)), ((u64)(0xb352196a0da2ab4fU)), ((u64)(0x01d6affe45f818f2U)), ((u64)(0xb0134fe24885ab11U)), ((u64)(0x01262dfeebbb0f97U)), ((u64)(0x9c1823dadaa715d6U)), ((u64)(0x016fb97ea6a9d37dU)), ((u64)(0x031e2cd19150db4bU)), ((u64)(0x01cba7de5054485dU)), ((u64)(0x21f2dc02fad2890fU)), ((u64)(0x011f48eaf234ad3aU)), ((u64)(0xaa6f9303b9872b53U)), ((u64)(0x01671b25aec1d888U)), ((u64)(0xd50b77c4a7e8f628U)), ((u64)(0x01c0e1ef1a724eaaU)), ((u64)(0xc5272adae8f199d9U)), ((u64)(0x01188d357087712aU)), ((u64)(0x7670f591a32e004fU)), ((u64)(0x015eb082cca94d75U)), ((u64)(0xd40d32f60bf98063U)), ((u64)(0x01b65ca37fd3a0d2U)), ((u64)(0xc4883fd9c77bf03eU)), ((u64)(0x0111f9e62fe44483U)), ((u64)(0xb5aa4fd0395aec4dU)), ((u64)(0x0156785fbbdd55a4U)), ((u64)(0xe314e3c447b1a760U)), ((u64)(0x01ac1677aad4ab0dU)), ((u64)(0xaded0e5aaccf089cU)), ((u64)(0x010b8e0acac4eae8U)), ((u64)(0xd96851f15802cac3U)), ((u64)(0x014e718d7d7625a2U)), ((u64)(0x8fc2666dae037d74U)), ((u64)(0x01a20df0dcd3af0bU)), ((u64)(0x39d980048cc22e68U)), ((u64)(0x010548b68a044d67U)), ((u64)(0x084fe005aff2ba03U)), ((u64)(0x01469ae42c8560c1U)), ((u64)(0x4a63d8071bef6883U)), ((u64)(0x0198419d37a6b8f1U)), ((u64)(0x9cfcce08e2eb42a4U)), ((u64)(0x01fe52048590672dU)), ((u64)(0x821e00c58dd309a7U)), ((u64)(0x013ef342d37a407cU)), ((u64)(0xa2a580f6f147cc10U)), ((u64)(0x018eb0138858d09bU)), ((u64)(0x8b4ee134ad99bf15U)), ((u64)(0x01f25c186a6f04c2U)), ((u64)(0x97114cc0ec80176dU)), ((u64)(0x0137798f428562f9U)), ((u64)(0xfcd59ff127a01d48U)), ((u64)(0x018557f31326bbb7U)), ((u64)(0xfc0b07ed7188249aU)), ((u64)(0x01e6adefd7f06aa5U)), ((u64)(0xbd86e4f466f516e0U)), ((u64)(0x01302cb5e6f642a7U)), ((u64)(0xace89e3180b25c98U)), ((u64)(0x017c37e360b3d351U)), ((u64)(0x1822c5bde0def3beU)), ((u64)(0x01db45dc38e0c826U)), ((u64)(0xcf15bb96ac8b5857U)), ((u64)(0x01290ba9a38c7d17U)), ((u64)(0xc2db2a7c57ae2e6dU)), ((u64)(0x01734e940c6f9c5dU)), ((u64)(0x3391f51b6d99ba08U)), ((u64)(0x01d022390f8b8375U)), ((u64)(0x403b393124801445U)), ((u64)(0x01221563a9b73229U)), ((u64)(0x904a077d6da01956U)), ((u64)(0x016a9abc9424feb3U)), ((u64)(0x745c895cc9081facU)), ((u64)(0x01c5416bb92e3e60U)), ((u64)(0x48b9d5d9fda513cbU)), ((u64)(0x011b48e353bce6fcU)), ((u64)(0x5ae84b507d0e58beU)), ((u64)(0x01621b1c28ac20bbU)), ((u64)(0x31a25e249c51eeeeU)), ((u64)(0x01baa1e332d728eaU)), ((u64)(0x5f057ad6e1b33554U)), ((u64)(0x0114a52dffc67992U)), ((u64)(0xf6c6d98c9a2002aaU)), ((u64)(0x0159ce797fb817f6U)), ((u64)(0xb4788fefc0a80354U)), ((u64)(0x01b04217dfa61df4U)), ((u64)(0xf0cb59f5d8690214U)), ((u64)(0x010e294eebc7d2b8U)), ((u64)(0x2cfe30734e83429aU)), ((u64)(0x0151b3a2a6b9c767U)), ((u64)(0xf83dbc9022241340U)), ((u64)(0x01a6208b50683940U)), ((u64)(0x9b2695da15568c08U)), ((u64)(0x0107d457124123c8U)), ((u64)(0xc1f03b509aac2f0aU)), ((u64)(0x0149c96cd6d16cbaU)), ((u64)(0x726c4a24c1573acdU)), ((u64)(0x019c3bc80c85c7e9U)), ((u64)(0xe783ae56f8d684c0U)), ((u64)(0x0101a55d07d39cf1U)), ((u64)(0x616499ecb70c25f0U)), ((u64)(0x01420eb449c8842eU)), ((u64)(0xf9bdc067e4cf2f6cU)), ((u64)(0x019292615c3aa539U)), ((u64)(0x782d3081de02fb47U)), ((u64)(0x01f736f9b3494e88U)), ((u64)(0x4b1c3e512ac1dd0cU)), ((u64)(0x013a825c100dd115U)), ((u64)(0x9de34de57572544fU)), ((u64)(0x018922f31411455aU)), ((u64)(0x455c215ed2cee963U)), ((u64)(0x01eb6bafd91596b1U)), ((u64)(0xcb5994db43c151deU)), ((u64)(0x0133234de7ad7e2eU)), ((u64)(0x7e2ffa1214b1a655U)), ((u64)(0x017fec216198ddbaU)), ((u64)(0x1dbbf89699de0febU)), ((u64)(0x01dfe729b9ff1529U)), ((u64)(0xb2957b5e202ac9f3U)), ((u64)(0x012bf07a143f6d39U)), ((u64)(0x1f3ada35a8357c6fU)), ((u64)(0x0176ec98994f4888U)), ((u64)(0x270990c31242db8bU)), ((u64)(0x01d4a7bebfa31aaaU)), ((u64)(0x5865fa79eb69c937U)), ((u64)(0x0124e8d737c5f0aaU)), ((u64)(0xee7f791866443b85U)), ((u64)(0x016e230d05b76cd4U)), ((u64)(0x2a1f575e7fd54a66U)), ((u64)(0x01c9abd04725480aU)), ((u64)(0x5a53969b0fe54e80U)), ((u64)(0x011e0b622c774d06U)), ((u64)(0xf0e87c41d3dea220U)), ((u64)(0x01658e3ab7952047U)), ((u64)(0xed229b5248d64aa8U)), ((u64)(0x01bef1c9657a6859U)), ((u64)(0x3435a1136d85eea9U)), ((u64)(0x0117571ddf6c8138U)), ((u64)(0x4143095848e76a53U)), ((u64)(0x015d2ce55747a186U)), ((u64)(0xd193cbae5b2144e8U)), ((u64)(0x01b4781ead1989e7U)), ((u64)(0xe2fc5f4cf8f4cb11U)), ((u64)(0x0110cb132c2ff630U)), ((u64)(0x1bbb77203731fdd5U)), ((u64)(0x0154fdd7f73bf3bdU)), ((u64)(0x62aa54e844fe7d4aU)), ((u64)(0x01aa3d4df50af0acU)), ((u64)(0xbdaa75112b1f0e4eU)), ((u64)(0x010a6650b926d66bU)), ((u64)(0xad15125575e6d1e2U)), ((u64)(0x014cffe4e7708c06U)), ((u64)(0x585a56ead360865bU)), ((u64)(0x01a03fde214caf08U)), ((u64)(0x37387652c41c53f8U)), ((u64)(0x010427ead4cfed65U)), ((u64)(0x850693e7752368f7U)), ((u64)(0x014531e58a03e8beU)), ((u64)(0x264838e1526c4334U)), ((u64)(0x01967e5eec84e2eeU)), ((u64)(0xafda4719a7075402U)), ((u64)(0x01fc1df6a7a61ba9U)), ((u64)(0x0de86c7008649481U)), ((u64)(0x013d92ba28c7d14aU)), ((u64)(0x9162878c0a7db9a1U)), ((u64)(0x018cf768b2f9c59cU)), ((u64)(0xb5bb296f0d1d280aU)), ((u64)(0x01f03542dfb83703U)), ((u64)(0x5194f9e568323906U)), ((u64)(0x01362149cbd32262U)), ((u64)(0xe5fa385ec23ec747U)), ((u64)(0x0183a99c3ec7eafaU)), ((u64)(0x9f78c67672ce7919U)), ((u64)(0x01e494034e79e5b9U)), ((u64)(0x03ab7c0a07c10bb0U)), ((u64)(0x012edc82110c2f94U)), ((u64)(0x04965b0c89b14e9cU)), ((u64)(0x017a93a2954f3b79U)), ((u64)(0x45bbf1cfac1da243U)), ((u64)(0x01d9388b3aa30a57U)), ((u64)(0x8b957721cb92856aU)), ((u64)(0x0127c35704a5e676U)), ((u64)(0x2e7ad4ea3e7726c4U)), ((u64)(0x0171b42cc5cf6014U)), ((u64)(0x3a198a24ce14f075U)), ((u64)(0x01ce2137f7433819U)), ((u64)(0xc44ff65700cd1649U)), ((u64)(0x0120d4c2fa8a030fU)), ((u64)(0xb563f3ecc1005bdbU)), ((u64)(0x016909f3b92c83d3U)), ((u64)(0xa2bcf0e7f14072d2U)), ((u64)(0x01c34c70a777a4c8U)), ((u64)(0x65b61690f6c847c3U)), ((u64)(0x011a0fc668aac6fdU)), ((u64)(0xbf239c35347a59b4U)), ((u64)(0x016093b802d578bcU)), ((u64)(0xeeec83428198f021U)), ((u64)(0x01b8b8a6038ad6ebU)), ((u64)(0x7553d20990ff9615U)), ((u64)(0x01137367c236c653U)), ((u64)(0x52a8c68bf53f7b9aU)), ((u64)(0x01585041b2c477e8U)), ((u64)(0x6752f82ef28f5a81U)), ((u64)(0x01ae64521f7595e2U)), ((u64)(0x8093db1d57999890U)), ((u64)(0x010cfeb353a97dadU)), ((u64)(0xe0b8d1e4ad7ffeb4U)), ((u64)(0x01503e602893dd18U)), ((u64)(0x18e7065dd8dffe62U)), ((u64)(0x01a44df832b8d45fU)), ((u64)(0x6f9063faa78bfefdU)), ((u64)(0x0106b0bb1fb384bbU)), ((u64)(0x4b747cf9516efebcU)), ((u64)(0x01485ce9e7a065eaU)), ((u64)(0xde519c37a5cabe6bU)), ((u64)(0x019a742461887f64U)), ((u64)(0x0af301a2c79eb703U)), ((u64)(0x01008896bcf54f9fU)), ((u64)(0xcdafc20b798664c4U)), ((u64)(0x0140aabc6c32a386U)), ((u64)(0x811bb28e57e7fdf5U)), ((u64)(0x0190d56b873f4c68U)), ((u64)(0xa1629f31ede1fd72U)), ((u64)(0x01f50ac6690f1f82U)), ((u64)(0xa4dda37f34ad3e67U)), ((u64)(0x013926bc01a973b1U)), ((u64)(0x0e150c5f01d88e01U)), ((u64)(0x0187706b0213d09eU)), ((u64)(0x919a4f76c24eb181U)), ((u64)(0x01e94c85c298c4c5U)), ((u64)(0x7b0071aa39712ef1U)), ((u64)(0x0131cfd3999f7afbU)), ((u64)(0x59c08e14c7cd7aadU)), ((u64)(0x017e43c8800759baU)), ((u64)(0xf030b199f9c0d958U)), ((u64)(0x01ddd4baa0093028U)), ((u64)(0x961e6f003c1887d7U)), ((u64)(0x012aa4f4a405be19U)), ((u64)(0xfba60ac04b1ea9cdU)), ((u64)(0x01754e31cd072d9fU)), ((u64)(0xfa8f8d705de65440U)), ((u64)(0x01d2a1be4048f907U)), ((u64)(0xfc99b8663aaff4a8U)), ((u64)(0x0123a516e82d9ba4U)), ((u64)(0x3bc0267fc95bf1d2U)), ((u64)(0x016c8e5ca239028eU)), ((u64)(0xcab0301fbbb2ee47U)), ((u64)(0x01c7b1f3cac74331U)), ((u64)(0x1eae1e13d54fd4ecU)), ((u64)(0x011ccf385ebc89ffU)), ((u64)(0xe659a598caa3ca27U)), ((u64)(0x01640306766bac7eU)), ((u64)(0x9ff00efefd4cbcb1U)), ((u64)(0x01bd03c81406979eU)), ((u64)(0x23f6095f5e4ff5efU)), ((u64)(0x0116225d0c841ec3U)), ((u64)(0xecf38bb735e3f36aU)), ((u64)(0x015baaf44fa52673U)), ((u64)(0xe8306ea5035cf045U)), ((u64)(0x01b295b1638e7010U)), ((u64)(0x911e4527221a162bU)), ((u64)(0x010f9d8ede39060aU)), ((u64)(0x3565d670eaa09bb6U)), ((u64)(0x015384f295c7478dU)), ((u64)(0x82bf4c0d2548c2a3U)), ((u64)(0x01a8662f3b391970U)), ((u64)(0x51b78f88374d79a6U)), ((u64)(0x01093fdd8503afe6U)), ((u64)(0xe625736a4520d810U)), ((u64)(0x014b8fd4e6449bdfU)), ((u64)(0xdfaed044d6690e14U)), ((u64)(0x019e73ca1fd5c2d7U)), ((u64)(0xebcd422b0601a8ccU)), ((u64)(0x0103085e53e599c6U)), ((u64)(0xa6c092b5c78212ffU)), ((u64)(0x0143ca75e8df0038U)), ((u64)(0xd070b763396297bfU)), ((u64)(0x0194bd136316c046U)), ((u64)(0x848ce53c07bb3dafU)), ((u64)(0x01f9ec583bdc7058U)), ((u64)(0x52d80f4584d5068dU)), ((u64)(0x013c33b72569c637U)), ((u64)(0x278e1316e60a4831U)), ((u64)(0x018b40a4eec437c5U))}; // fixed array const Array_fixed_u64_584 _const_strconv__pow5_inv_split_64_x = {((u64)(0x0000000000000001U)), ((u64)(0x0400000000000000U)), ((u64)(0x3333333333333334U)), ((u64)(0x0333333333333333U)), ((u64)(0x28f5c28f5c28f5c3U)), ((u64)(0x028f5c28f5c28f5cU)), ((u64)(0xed916872b020c49cU)), ((u64)(0x020c49ba5e353f7cU)), ((u64)(0xaf4f0d844d013a93U)), ((u64)(0x0346dc5d63886594U)), ((u64)(0x8c3f3e0370cdc876U)), ((u64)(0x029f16b11c6d1e10U)), ((u64)(0xd698fe69270b06c5U)), ((u64)(0x0218def416bdb1a6U)), ((u64)(0xf0f4ca41d811a46eU)), ((u64)(0x035afe535795e90aU)), ((u64)(0xf3f70834acdae9f1U)), ((u64)(0x02af31dc4611873bU)), ((u64)(0x5cc5a02a23e254c1U)), ((u64)(0x0225c17d04dad296U)), ((u64)(0xfad5cd10396a2135U)), ((u64)(0x036f9bfb3af7b756U)), ((u64)(0xfbde3da69454e75eU)), ((u64)(0x02bfaffc2f2c92abU)), ((u64)(0x2fe4fe1edd10b918U)), ((u64)(0x0232f33025bd4223U)), ((u64)(0x4ca19697c81ac1bfU)), ((u64)(0x0384b84d092ed038U)), ((u64)(0x3d4e1213067bce33U)), ((u64)(0x02d09370d4257360U)), ((u64)(0x643e74dc052fd829U)), ((u64)(0x024075f3dceac2b3U)), ((u64)(0x6d30baf9a1e626a7U)), ((u64)(0x039a5652fb113785U)), ((u64)(0x2426fbfae7eb5220U)), ((u64)(0x02e1dea8c8da92d1U)), ((u64)(0x1cebfcc8b9890e80U)), ((u64)(0x024e4bba3a487574U)), ((u64)(0x94acc7a78f41b0ccU)), ((u64)(0x03b07929f6da5586U)), ((u64)(0xaa23d2ec729af3d7U)), ((u64)(0x02f394219248446bU)), ((u64)(0xbb4fdbf05baf2979U)), ((u64)(0x025c768141d369efU)), ((u64)(0xc54c931a2c4b758dU)), ((u64)(0x03c7240202ebdcb2U)), ((u64)(0x9dd6dc14f03c5e0bU)), ((u64)(0x0305b66802564a28U)), ((u64)(0x4b1249aa59c9e4d6U)), ((u64)(0x026af8533511d4edU)), ((u64)(0x44ea0f76f60fd489U)), ((u64)(0x03de5a1ebb4fbb15U)), ((u64)(0x6a54d92bf80caa07U)), ((u64)(0x0318481895d96277U)), ((u64)(0x21dd7a89933d54d2U)), ((u64)(0x0279d346de4781f9U)), ((u64)(0x362f2a75b8622150U)), ((u64)(0x03f61ed7ca0c0328U)), ((u64)(0xf825bb91604e810dU)), ((u64)(0x032b4bdfd4d668ecU)), ((u64)(0xc684960de6a5340bU)), ((u64)(0x0289097fdd7853f0U)), ((u64)(0xd203ab3e521dc33cU)), ((u64)(0x02073accb12d0ff3U)), ((u64)(0xe99f7863b696052cU)), ((u64)(0x033ec47ab514e652U)), ((u64)(0x87b2c6b62bab3757U)), ((u64)(0x02989d2ef743eb75U)), ((u64)(0xd2f56bc4efbc2c45U)), ((u64)(0x0213b0f25f69892aU)), ((u64)(0x1e55793b192d13a2U)), ((u64)(0x0352b4b6ff0f41deU)), ((u64)(0x4b77942f475742e8U)), ((u64)(0x02a8909265a5ce4bU)), ((u64)(0xd5f9435905df68baU)), ((u64)(0x022073a8515171d5U)), ((u64)(0x565b9ef4d6324129U)), ((u64)(0x03671f73b54f1c89U)), ((u64)(0xdeafb25d78283421U)), ((u64)(0x02b8e5f62aa5b06dU)), ((u64)(0x188c8eb12cecf681U)), ((u64)(0x022d84c4eeeaf38bU)), ((u64)(0x8dadb11b7b14bd9bU)), ((u64)(0x037c07a17e44b8deU)), ((u64)(0x7157c0e2c8dd647cU)), ((u64)(0x02c99fb46503c718U)), ((u64)(0x8ddfcd823a4ab6caU)), ((u64)(0x023ae629ea696c13U)), ((u64)(0x1632e269f6ddf142U)), ((u64)(0x0391704310a8acecU)), ((u64)(0x44f581ee5f17f435U)), ((u64)(0x02dac035a6ed5723U)), ((u64)(0x372ace584c1329c4U)), ((u64)(0x024899c4858aac1cU)), ((u64)(0xbeaae3c079b842d3U)), ((u64)(0x03a75c6da27779c6U)), ((u64)(0x6555830061603576U)), ((u64)(0x02ec49f14ec5fb05U)), ((u64)(0xb7779c004de6912bU)), ((u64)(0x0256a18dd89e626aU)), ((u64)(0xf258f99a163db512U)), ((u64)(0x03bdcf495a9703ddU)), ((u64)(0x5b7a614811caf741U)), ((u64)(0x02fe3f6de212697eU)), ((u64)(0xaf951aa00e3bf901U)), ((u64)(0x0264ff8b1b41edfeU)), ((u64)(0x7f54f7667d2cc19bU)), ((u64)(0x03d4cc11c5364997U)), ((u64)(0x32aa5f8530f09ae3U)), ((u64)(0x0310a3416a91d479U)), ((u64)(0xf55519375a5a1582U)), ((u64)(0x0273b5cdeedb1060U)), ((u64)(0xbbbb5b8bc3c3559dU)), ((u64)(0x03ec56164af81a34U)), ((u64)(0x2fc916096969114aU)), ((u64)(0x03237811d593482aU)), ((u64)(0x596dab3ababa743cU)), ((u64)(0x0282c674aadc39bbU)), ((u64)(0x478aef622efb9030U)), ((u64)(0x0202385d557cfafcU)), ((u64)(0xd8de4bd04b2c19e6U)), ((u64)(0x0336c0955594c4c6U)), ((u64)(0xad7ea30d08f014b8U)), ((u64)(0x029233aaaadd6a38U)), ((u64)(0x24654f3da0c01093U)), ((u64)(0x020e8fbbbbe454faU)), ((u64)(0x3a3bb1fc346680ebU)), ((u64)(0x034a7f92c63a2190U)), ((u64)(0x94fc8e635d1ecd89U)), ((u64)(0x02a1ffa89e94e7a6U)), ((u64)(0xaa63a51c4a7f0ad4U)), ((u64)(0x021b32ed4baa52ebU)), ((u64)(0xdd6c3b607731aaedU)), ((u64)(0x035eb7e212aa1e45U)), ((u64)(0x1789c919f8f488bdU)), ((u64)(0x02b22cb4dbbb4b6bU)), ((u64)(0xac6e3a7b2d906d64U)), ((u64)(0x022823c3e2fc3c55U)), ((u64)(0x13e390c515b3e23aU)), ((u64)(0x03736c6c9e606089U)), ((u64)(0xdcb60d6a77c31b62U)), ((u64)(0x02c2bd23b1e6b3a0U)), ((u64)(0x7d5e7121f968e2b5U)), ((u64)(0x0235641c8e52294dU)), ((u64)(0xc8971b698f0e3787U)), ((u64)(0x0388a02db0837548U)), ((u64)(0xa078e2bad8d82c6cU)), ((u64)(0x02d3b357c0692aa0U)), ((u64)(0xe6c71bc8ad79bd24U)), ((u64)(0x0242f5dfcd20eee6U)), ((u64)(0x0ad82c7448c2c839U)), ((u64)(0x039e5632e1ce4b0bU)), ((u64)(0x3be023903a356cfaU)), ((u64)(0x02e511c24e3ea26fU)), ((u64)(0x2fe682d9c82abd95U)), ((u64)(0x0250db01d8321b8cU)), ((u64)(0x4ca4048fa6aac8eeU)), ((u64)(0x03b4919c8d1cf8e0U)), ((u64)(0x3d5003a61eef0725U)), ((u64)(0x02f6dae3a4172d80U)), ((u64)(0x9773361e7f259f51U)), ((u64)(0x025f1582e9ac2466U)), ((u64)(0x8beb89ca6508fee8U)), ((u64)(0x03cb559e42ad070aU)), ((u64)(0x6fefa16eb73a6586U)), ((u64)(0x0309114b688a6c08U)), ((u64)(0xf3261abef8fb846bU)), ((u64)(0x026da76f86d52339U)), ((u64)(0x51d691318e5f3a45U)), ((u64)(0x03e2a57f3e21d1f6U)), ((u64)(0x0e4540f471e5c837U)), ((u64)(0x031bb798fe8174c5U)), ((u64)(0xd8376729f4b7d360U)), ((u64)(0x027c92e0cb9ac3d0U)), ((u64)(0xf38bd84321261effU)), ((u64)(0x03fa849adf5e061aU)), ((u64)(0x293cad0280eb4bffU)), ((u64)(0x032ed07be5e4d1afU)), ((u64)(0xedca240200bc3cccU)), ((u64)(0x028bd9fcb7ea4158U)), ((u64)(0xbe3b50019a3030a4U)), ((u64)(0x02097b309321cde0U)), ((u64)(0xc9f88002904d1a9fU)), ((u64)(0x03425eb41e9c7c9aU)), ((u64)(0x3b2d3335403daee6U)), ((u64)(0x029b7ef67ee396e2U)), ((u64)(0x95bdc291003158b8U)), ((u64)(0x0215ff2b98b6124eU)), ((u64)(0x892f9db4cd1bc126U)), ((u64)(0x035665128df01d4aU)), ((u64)(0x07594af70a7c9a85U)), ((u64)(0x02ab840ed7f34aa2U)), ((u64)(0x6c476f2c0863aed1U)), ((u64)(0x0222d00bdff5d54eU)), ((u64)(0x13a57eacda3917b4U)), ((u64)(0x036ae67966562217U)), ((u64)(0x0fb7988a482dac90U)), ((u64)(0x02bbeb9451de81acU)), ((u64)(0xd95fad3b6cf156daU)), ((u64)(0x022fefa9db1867bcU)), ((u64)(0xf565e1f8ae4ef15cU)), ((u64)(0x037fe5dc91c0a5faU)), ((u64)(0x911e4e608b725ab0U)), ((u64)(0x02ccb7e3a7cd5195U)), ((u64)(0xda7ea51a0928488dU)), ((u64)(0x023d5fe9530aa7aaU)), ((u64)(0xf7310829a8407415U)), ((u64)(0x039566421e7772aaU)), ((u64)(0x2c2739baed005cdeU)), ((u64)(0x02ddeb68185f8eefU)), ((u64)(0xbcec2e2f24004a4bU)), ((u64)(0x024b22b9ad193f25U)), ((u64)(0x94ad16b1d333aa11U)), ((u64)(0x03ab6ac2ae8ecb6fU)), ((u64)(0xaa241227dc2954dbU)), ((u64)(0x02ef889bbed8a2bfU)), ((u64)(0x54e9a81fe35443e2U)), ((u64)(0x02593a163246e899U)), ((u64)(0x2175d9cc9eed396aU)), ((u64)(0x03c1f689ea0b0dc2U)), ((u64)(0xe7917b0a18bdc788U)), ((u64)(0x03019207ee6f3e34U)), ((u64)(0xb9412f3b46fe393aU)), ((u64)(0x0267a8065858fe90U)), ((u64)(0xf535185ed7fd285cU)), ((u64)(0x03d90cd6f3c1974dU)), ((u64)(0xc42a79e57997537dU)), ((u64)(0x03140a458fce12a4U)), ((u64)(0x03552e512e12a931U)), ((u64)(0x02766e9e0ca4dbb7U)), ((u64)(0x9eeeb081e3510eb4U)), ((u64)(0x03f0b0fce107c5f1U)), ((u64)(0x4bf226ce4f740bc3U)), ((u64)(0x0326f3fd80d304c1U)), ((u64)(0xa3281f0b72c33c9cU)), ((u64)(0x02858ffe00a8d09aU)), ((u64)(0x1c2018d5f568fd4aU)), ((u64)(0x020473319a20a6e2U)), ((u64)(0xf9ccf48988a7fba9U)), ((u64)(0x033a51e8f69aa49cU)), ((u64)(0xfb0a5d3ad3b99621U)), ((u64)(0x02950e53f87bb6e3U)), ((u64)(0x2f3b7dc8a96144e7U)), ((u64)(0x0210d8432d2fc583U)), ((u64)(0xe52bfc7442353b0cU)), ((u64)(0x034e26d1e1e608d1U)), ((u64)(0xb756639034f76270U)), ((u64)(0x02a4ebdb1b1e6d74U)), ((u64)(0x2c451c735d92b526U)), ((u64)(0x021d897c15b1f12aU)), ((u64)(0x13a1c71efc1deea3U)), ((u64)(0x0362759355e981ddU)), ((u64)(0x761b05b2634b2550U)), ((u64)(0x02b52adc44bace4aU)), ((u64)(0x91af37c1e908eaa6U)), ((u64)(0x022a88b036fbd83bU)), ((u64)(0x82b1f2cfdb417770U)), ((u64)(0x03774119f192f392U)), ((u64)(0xcef4c23fe29ac5f3U)), ((u64)(0x02c5cdae5adbf60eU)), ((u64)(0x3f2a34ffe87bd190U)), ((u64)(0x0237d7beaf165e72U)), ((u64)(0x984387ffda5fb5b2U)), ((u64)(0x038c8c644b56fd83U)), ((u64)(0xe0360666484c915bU)), ((u64)(0x02d6d6b6a2abfe02U)), ((u64)(0x802b3851d3707449U)), ((u64)(0x024578921bbccb35U)), ((u64)(0x99dec082ebe72075U)), ((u64)(0x03a25a835f947855U)), ((u64)(0xae4bcd358985b391U)), ((u64)(0x02e8486919439377U)), ((u64)(0xbea30a913ad15c74U)), ((u64)(0x02536d20e102dc5fU)), ((u64)(0xfdd1aa81f7b560b9U)), ((u64)(0x03b8ae9b019e2d65U)), ((u64)(0x97daeece5fc44d61U)), ((u64)(0x02fa2548ce182451U)), ((u64)(0xdfe258a51969d781U)), ((u64)(0x0261b76d71ace9daU)), ((u64)(0x996a276e8f0fbf34U)), ((u64)(0x03cf8be24f7b0fc4U)), ((u64)(0xe121b9253f3fcc2aU)), ((u64)(0x030c6fe83f95a636U)), ((u64)(0xb41afa8432997022U)), ((u64)(0x02705986994484f8U)), ((u64)(0xecf7f739ea8f19cfU)), ((u64)(0x03e6f5a4286da18dU)), ((u64)(0x23f99294bba5ae40U)), ((u64)(0x031f2ae9b9f14e0bU)), ((u64)(0x4ffadbaa2fb7be99U)), ((u64)(0x027f5587c7f43e6fU)), ((u64)(0x7ff7c5dd1925fdc2U)), ((u64)(0x03feef3fa6539718U)), ((u64)(0xccc637e4141e649bU)), ((u64)(0x033258ffb842df46U)), ((u64)(0xd704f983434b83afU)), ((u64)(0x028ead9960357f6bU)), ((u64)(0x126a6135cf6f9c8cU)), ((u64)(0x020bbe144cf79923U)), ((u64)(0x83dd685618b29414U)), ((u64)(0x0345fced47f28e9eU)), ((u64)(0x9cb12044e08edcddU)), ((u64)(0x029e63f1065ba54bU)), ((u64)(0x16f419d0b3a57d7dU)), ((u64)(0x02184ff405161dd6U)), ((u64)(0x8b20294dec3bfbfbU)), ((u64)(0x035a19866e89c956U)), ((u64)(0x3c19baa4bcfcc996U)), ((u64)(0x02ae7ad1f207d445U)), ((u64)(0xc9ae2eea30ca3adfU)), ((u64)(0x02252f0e5b39769dU)), ((u64)(0x0f7d17dd1add2afdU)), ((u64)(0x036eb1b091f58a96U)), ((u64)(0x3f97464a7be42264U)), ((u64)(0x02bef48d41913babU)), ((u64)(0xcc790508631ce850U)), ((u64)(0x02325d3dce0dc955U)), ((u64)(0xe0c1a1a704fb0d4dU)), ((u64)(0x0383c862e3494222U)), ((u64)(0x4d67b4859d95a43eU)), ((u64)(0x02cfd3824f6dce82U)), ((u64)(0x711fc39e17aae9cbU)), ((u64)(0x023fdc683f8b0b9bU)), ((u64)(0xe832d2968c44a945U)), ((u64)(0x039960a6cc11ac2bU)), ((u64)(0xecf575453d03ba9eU)), ((u64)(0x02e11a1f09a7bcefU)), ((u64)(0x572ac4376402fbb1U)), ((u64)(0x024dae7f3aec9726U)), ((u64)(0x58446d256cd192b5U)), ((u64)(0x03af7d985e47583dU)), ((u64)(0x79d0575123dadbc4U)), ((u64)(0x02f2cae04b6c4697U)), ((u64)(0x94a6ac40e97be303U)), ((u64)(0x025bd5803c569edfU)), ((u64)(0x8771139b0f2c9e6cU)), ((u64)(0x03c62266c6f0fe32U)), ((u64)(0x9f8da948d8f07ebdU)), ((u64)(0x0304e85238c0cb5bU)), ((u64)(0xe60aedd3e0c06564U)), ((u64)(0x026a5374fa33d5e2U)), ((u64)(0xa344afb9679a3bd2U)), ((u64)(0x03dd5254c3862304U)), ((u64)(0xe903bfc78614fca8U)), ((u64)(0x031775109c6b4f36U)), ((u64)(0xba6966393810ca20U)), ((u64)(0x02792a73b055d8f8U)), ((u64)(0x2a423d2859b4769aU)), ((u64)(0x03f510b91a22f4c1U)), ((u64)(0xee9b642047c39215U)), ((u64)(0x032a73c7481bf700U)), ((u64)(0xbee2b680396941aaU)), ((u64)(0x02885c9f6ce32c00U)), ((u64)(0xff1bc53361210155U)), ((u64)(0x0206b07f8a4f5666U)), ((u64)(0x31c6085235019bbbU)), ((u64)(0x033de73276e5570bU)), ((u64)(0x27d1a041c4014963U)), ((u64)(0x0297ec285f1ddf3cU)), ((u64)(0xeca7b367d0010782U)), ((u64)(0x021323537f4b18fcU)), ((u64)(0xadd91f0c8001a59dU)), ((u64)(0x0351d21f3211c194U)), ((u64)(0xf17a7f3d3334847eU)), ((u64)(0x02a7db4c280e3476U)), ((u64)(0x279532975c2a0398U)), ((u64)(0x021fe2a3533e905fU)), ((u64)(0xd8eeb75893766c26U)), ((u64)(0x0366376bb8641a31U)), ((u64)(0x7a5892ad42c52352U)), ((u64)(0x02b82c562d1ce1c1U)), ((u64)(0xfb7a0ef102374f75U)), ((u64)(0x022cf044f0e3e7cdU)), ((u64)(0xc59017e8038bb254U)), ((u64)(0x037b1a07e7d30c7cU)), ((u64)(0x37a67986693c8eaaU)), ((u64)(0x02c8e19feca8d6caU)), ((u64)(0xf951fad1edca0bbbU)), ((u64)(0x023a4e198a20abd4U)), ((u64)(0x28832ae97c76792bU)), ((u64)(0x03907cf5a9cddfbbU)), ((u64)(0x2068ef21305ec756U)), ((u64)(0x02d9fd9154a4b2fcU)), ((u64)(0x19ed8c1a8d189f78U)), ((u64)(0x0247fe0ddd508f30U)), ((u64)(0x5caf4690e1c0ff26U)), ((u64)(0x03a66349621a7eb3U)), ((u64)(0x4a25d20d81673285U)), ((u64)(0x02eb82a11b48655cU)), ((u64)(0x3b5174d79ab8f537U)), ((u64)(0x0256021a7c39eab0U)), ((u64)(0x921bee25c45b21f1U)), ((u64)(0x03bcd02a605caab3U)), ((u64)(0xdb498b5169e2818eU)), ((u64)(0x02fd735519e3bbc2U)), ((u64)(0x15d46f7454b53472U)), ((u64)(0x02645c4414b62fcfU)), ((u64)(0xefba4bed545520b6U)), ((u64)(0x03d3c6d35456b2e4U)), ((u64)(0xf2fb6ff110441a2bU)), ((u64)(0x030fd242a9def583U)), ((u64)(0x8f2f8cc0d9d014efU)), ((u64)(0x02730e9bbb18c469U)), ((u64)(0xb1e5ae015c80217fU)), ((u64)(0x03eb4a92c4f46d75U)), ((u64)(0xc1848b344a001accU)), ((u64)(0x0322a20f03f6bdf7U)), ((u64)(0xce03a2903b3348a3U)), ((u64)(0x02821b3f365efe5fU)), ((u64)(0xd802e873628f6d4fU)), ((u64)(0x0201af65c518cb7fU)), ((u64)(0x599e40b89db2487fU)), ((u64)(0x0335e56fa1c14599U)), ((u64)(0xe14b66fa17c1d399U)), ((u64)(0x029184594e3437adU)), ((u64)(0x81091f2e7967dc7aU)), ((u64)(0x020e037aa4f692f1U)), ((u64)(0x9b41cb7d8f0c93f6U)), ((u64)(0x03499f2aa18a84b5U)), ((u64)(0xaf67d5fe0c0a0ff8U)), ((u64)(0x02a14c221ad536f7U)), ((u64)(0xf2b977fe70080cc7U)), ((u64)(0x021aa34e7bddc592U)), ((u64)(0x1df58cca4cd9ae0bU)), ((u64)(0x035dd2172c9608ebU)), ((u64)(0xe4c470a1d7148b3cU)), ((u64)(0x02b174df56de6d88U)), ((u64)(0x83d05a1b1276d5caU)), ((u64)(0x022790b2abe5246dU)), ((u64)(0x9fb3c35e83f1560fU)), ((u64)(0x0372811ddfd50715U)), ((u64)(0xb2f635e5365aab3fU)), ((u64)(0x02c200e4b310d277U)), ((u64)(0xf591c4b75eaeef66U)), ((u64)(0x0234cd83c273db92U)), ((u64)(0xef4fa125644b18a3U)), ((u64)(0x0387af39371fc5b7U)), ((u64)(0x8c3fb41de9d5ad4fU)), ((u64)(0x02d2f2942c196af9U)), ((u64)(0x3cffc34b2177bdd9U)), ((u64)(0x02425ba9bce12261U)), ((u64)(0x94cc6bab68bf9628U)), ((u64)(0x039d5f75fb01d09bU)), ((u64)(0x10a38955ed6611b9U)), ((u64)(0x02e44c5e6267da16U)), ((u64)(0xda1c6dde5784dafbU)), ((u64)(0x02503d184eb97b44U)), ((u64)(0xf693e2fd58d49191U)), ((u64)(0x03b394f3b128c53aU)), ((u64)(0xc5431bfde0aa0e0eU)), ((u64)(0x02f610c2f4209dc8U)), ((u64)(0x6a9c1664b3bb3e72U)), ((u64)(0x025e73cf29b3b16dU)), ((u64)(0x10f9bd6dec5eca4fU)), ((u64)(0x03ca52e50f85e8afU)), ((u64)(0xda616457f04bd50cU)), ((u64)(0x03084250d937ed58U)), ((u64)(0xe1e783798d09773dU)), ((u64)(0x026d01da475ff113U)), ((u64)(0x030c058f480f252eU)), ((u64)(0x03e19c9072331b53U)), ((u64)(0x68d66ad906728425U)), ((u64)(0x031ae3a6c1c27c42U)), ((u64)(0x8711ef14052869b7U)), ((u64)(0x027be952349b969bU)), ((u64)(0x0b4fe4ecd50d75f2U)), ((u64)(0x03f97550542c242cU)), ((u64)(0xa2a650bd773df7f5U)), ((u64)(0x032df7737689b689U)), ((u64)(0xb551da312c31932aU)), ((u64)(0x028b2c5c5ed49207U)), ((u64)(0x5ddb14f4235adc22U)), ((u64)(0x0208f049e576db39U)), ((u64)(0x2fc4ee536bc49369U)), ((u64)(0x034180763bf15ec2U)), ((u64)(0xbfd0bea92303a921U)), ((u64)(0x029acd2b63277f01U)), ((u64)(0x9973cbba8269541aU)), ((u64)(0x021570ef8285ff34U)), ((u64)(0x5bec792a6a42202aU)), ((u64)(0x0355817f373ccb87U)), ((u64)(0xe3239421ee9b4cefU)), ((u64)(0x02aacdff5f63d605U)), ((u64)(0xb5b6101b25490a59U)), ((u64)(0x02223e65e5e97804U)), ((u64)(0x22bce691d541aa27U)), ((u64)(0x0369fd6fd64259a1U)), ((u64)(0xb563eba7ddce21b9U)), ((u64)(0x02bb31264501e14dU)), ((u64)(0xf78322ecb171b494U)), ((u64)(0x022f5a850401810aU)), ((u64)(0x259e9e47824f8753U)), ((u64)(0x037ef73b399c01abU)), ((u64)(0x1e187e9f9b72d2a9U)), ((u64)(0x02cbf8fc2e1667bcU)), ((u64)(0x4b46cbb2e2c24221U)), ((u64)(0x023cc73024deb963U)), ((u64)(0x120adf849e039d01U)), ((u64)(0x039471e6a1645bd2U)), ((u64)(0xdb3be603b19c7d9aU)), ((u64)(0x02dd27ebb4504974U)), ((u64)(0x7c2feb3627b0647cU)), ((u64)(0x024a865629d9d45dU)), ((u64)(0x2d197856a5e7072cU)), ((u64)(0x03aa7089dc8fba2fU)), ((u64)(0x8a7ac6abb7ec05bdU)), ((u64)(0x02eec06e4a0c94f2U)), ((u64)(0xd52f05562cbcd164U)), ((u64)(0x025899f1d4d6dd8eU)), ((u64)(0x21e4d556adfae8a0U)), ((u64)(0x03c0f64fbaf1627eU)), ((u64)(0xe7ea444557fbed4dU)), ((u64)(0x0300c50c958de864U)), ((u64)(0xecbb69d1132ff10aU)), ((u64)(0x0267040a113e5383U)), ((u64)(0xadf8a94e851981aaU)), ((u64)(0x03d8067681fd526cU)), ((u64)(0x8b2d543ed0e13488U)), ((u64)(0x0313385ece6441f0U)), ((u64)(0xd5bddcff0d80f6d3U)), ((u64)(0x0275c6b23eb69b26U)), ((u64)(0x892fc7fe7c018aebU)), ((u64)(0x03efa45064575ea4U)), ((u64)(0x3a8c9ffec99ad589U)), ((u64)(0x03261d0d1d12b21dU)), ((u64)(0xc8707fff07af113bU)), ((u64)(0x0284e40a7da88e7dU)), ((u64)(0x39f39998d2f2742fU)), ((u64)(0x0203e9a1fe2071feU)), ((u64)(0x8fec28f484b7204bU)), ((u64)(0x033975cffd00b663U)), ((u64)(0xd989ba5d36f8e6a2U)), ((u64)(0x02945e3ffd9a2b82U)), ((u64)(0x47a161e42bfa521cU)), ((u64)(0x02104b66647b5602U)), ((u64)(0x0c35696d132a1cf9U)), ((u64)(0x034d4570a0c5566aU)), ((u64)(0x09c454574288172dU)), ((u64)(0x02a4378d4d6aab88U)), ((u64)(0xa169dd129ba0128bU)), ((u64)(0x021cf93dd7888939U)), ((u64)(0x0242fb50f9001dabU)), ((u64)(0x03618ec958da7529U)), ((u64)(0x9b68c90d940017bcU)), ((u64)(0x02b4723aad7b90edU)), ((u64)(0x4920a0d7a999ac96U)), ((u64)(0x0229f4fbbdfc73f1U)), ((u64)(0x750101590f5c4757U)), ((u64)(0x037654c5fcc71fe8U)), ((u64)(0x2a6734473f7d05dfU)), ((u64)(0x02c5109e63d27fedU)), ((u64)(0xeeb8f69f65fd9e4cU)), ((u64)(0x0237407eb641fff0U)), ((u64)(0xe45b24323cc8fd46U)), ((u64)(0x038b9a6456cfffe7U)), ((u64)(0xb6af502830a0ca9fU)), ((u64)(0x02d6151d123fffecU)), ((u64)(0xf88c402026e7087fU)), ((u64)(0x0244ddb0db666656U)), ((u64)(0x2746cd003e3e73feU)), ((u64)(0x03a162b4923d708bU)), ((u64)(0x1f6bd73364fec332U)), ((u64)(0x02e7822a0e978d3cU)), ((u64)(0xe5efdf5c50cbcf5bU)), ((u64)(0x0252ce880bac70fcU)), ((u64)(0x3cb2fefa1adfb22bU)), ((u64)(0x03b7b0d9ac471b2eU)), ((u64)(0x308f3261af195b56U)), ((u64)(0x02f95a47bd05af58U)), ((u64)(0x5a0c284e25ade2abU)), ((u64)(0x0261150630d15913U)), ((u64)(0x29ad0d49d5e30445U)), ((u64)(0x03ce8809e7b55b52U)), ((u64)(0x548a7107de4f369dU)), ((u64)(0x030ba007ec9115dbU)), ((u64)(0xdd3b8d9fe50c2bb1U)), ((u64)(0x026fb3398a0dab15U)), ((u64)(0x952c15cca1ad12b5U)), ((u64)(0x03e5eb8f434911bcU)), ((u64)(0x775677d6e7bda891U)), ((u64)(0x031e560c35d40e30U)), ((u64)(0xc5dec645863153a7U)), ((u64)(0x027eab3cf7dcd826U))}; // fixed array const bool v_memory_panic = false; // global 6 i64 total_m = ((i64)(0)); // global 6 int g_main_argc = ((int)(0)); // global 6 voidptr g_main_argv = ((void*)0); // global 6 voidptr g_live_reload_info; // global 6 Array_VCastTypeIndexName as_cast_type_indexes; // global 6 const i8 _const_min_i8 = -128; // precomputed2 const i8 _const_max_i8 = 127; // precomputed2 const i16 _const_min_i16 = -32768; // precomputed2 const i16 _const_max_i16 = 32767; // precomputed2 const i32 _const_min_i32 = -2147483648; // precomputed2 const i32 _const_max_i32 = 2147483647; // precomputed2 i64 _const_min_i64; // inited later i64 _const_max_i64; // inited later const u8 _const_min_u8 = 0; // precomputed2 const u8 _const_max_u8 = 255; // precomputed2 const u16 _const_min_u16 = 0; // precomputed2 const u16 _const_max_u16 = 65535; // precomputed2 const u32 _const_min_u32 = 0; // precomputed2 const u32 _const_max_u32 = 4294967295; // precomputed2 const u64 _const_min_u64 = 0U; // precomputed2 const u64 _const_max_u64 = 18446744073709551615U; // precomputed2 const f64 _const_max_load_factor = 0.8; // precomputed2 const u32 _const_hash_mask = 16777215; // precomputed2 const u32 _const_probe_inc = 16777216; // precomputed2 IError _const_none__; // inited later VMemoryBlock* g_memory_block; // global 6 Array_fixed_i32_1264 _const_rune_maps = {((i32)(0xB5)), 0xB5, 743, 0, 0xC0, 0xD6, 0, 32, 0xD8, 0xDE, 0, 32, 0xE0, 0xF6, -32, 0, 0xF8, 0xFE, -32, 0, 0xFF, 0xFF, 121, 0, 0x100, 0x12F, -3, -3, 0x130, 0x130, 0, -199, 0x131, 0x131, -232, 0, 0x132, 0x137, -3, -3, 0x139, 0x148, -3, -3, 0x14A, 0x177, -3, -3, 0x178, 0x178, 0, -121, 0x179, 0x17E, -3, -3, 0x17F, 0x17F, -300, 0, 0x180, 0x180, 195, 0, 0x181, 0x181, 0, 210, 0x182, 0x185, -3, -3, 0x186, 0x186, 0, 206, 0x187, 0x188, -3, -3, 0x189, 0x18A, 0, 205, 0x18B, 0x18C, -3, -3, 0x18E, 0x18E, 0, 79, 0x18F, 0x18F, 0, 202, 0x190, 0x190, 0, 203, 0x191, 0x192, -3, -3, 0x193, 0x193, 0, 205, 0x194, 0x194, 0, 207, 0x195, 0x195, 97, 0, 0x196, 0x196, 0, 211, 0x197, 0x197, 0, 209, 0x198, 0x199, -3, -3, 0x19A, 0x19A, 163, 0, 0x19C, 0x19C, 0, 211, 0x19D, 0x19D, 0, 213, 0x19E, 0x19E, 130, 0, 0x19F, 0x19F, 0, 214, 0x1A0, 0x1A5, -3, -3, 0x1A6, 0x1A6, 0, 218, 0x1A7, 0x1A8, -3, -3, 0x1A9, 0x1A9, 0, 218, 0x1AC, 0x1AD, -3, -3, 0x1AE, 0x1AE, 0, 218, 0x1AF, 0x1B0, -3, -3, 0x1B1, 0x1B2, 0, 217, 0x1B3, 0x1B6, -3, -3, 0x1B7, 0x1B7, 0, 219, 0x1B8, 0x1B9, -3, -3, 0x1BC, 0x1BD, -3, -3, 0x1BF, 0x1BF, 56, 0, 0x1C4, 0x1CC, -2, -2, 0x1CD, 0x1DC, -3, -3, 0x1DD, 0x1DD, -79, 0, 0x1DE, 0x1EF, -3, -3, 0x1F1, 0x1F3, -2, -2, 0x1F4, 0x1F5, -3, -3, 0x1F6, 0x1F6, 0, -97, 0x1F7, 0x1F7, 0, -56, 0x1F8, 0x21F, -3, -3, 0x220, 0x220, 0, -130, 0x222, 0x233, -3, -3, 0x23A, 0x23A, 0, 10795, 0x23B, 0x23C, -3, -3, 0x23D, 0x23D, 0, -163, 0x23E, 0x23E, 0, 10792, 0x23F, 0x240, 10815, 0, 0x241, 0x242, -3, -3, 0x243, 0x243, 0, -195, 0x244, 0x244, 0, 69, 0x245, 0x245, 0, 71, 0x246, 0x24F, -3, -3, 0x250, 0x250, 10783, 0, 0x251, 0x251, 10780, 0, 0x252, 0x252, 10782, 0, 0x253, 0x253, -210, 0, 0x254, 0x254, -206, 0, 0x256, 0x257, -205, 0, 0x259, 0x259, -202, 0, 0x25B, 0x25B, -203, 0, 0x25C, 0x25C, 42319, 0, 0x260, 0x260, -205, 0, 0x261, 0x261, 42315, 0, 0x263, 0x263, -207, 0, 0x265, 0x265, 42280, 0, 0x266, 0x266, 42308, 0, 0x268, 0x268, -209, 0, 0x269, 0x269, -211, 0, 0x26A, 0x26A, 42308, 0, 0x26B, 0x26B, 10743, 0, 0x26C, 0x26C, 42305, 0, 0x26F, 0x26F, -211, 0, 0x271, 0x271, 10749, 0, 0x272, 0x272, -213, 0, 0x275, 0x275, -214, 0, 0x27D, 0x27D, 10727, 0, 0x280, 0x280, -218, 0, 0x282, 0x282, 42307, 0, 0x283, 0x283, -218, 0, 0x287, 0x287, 42282, 0, 0x288, 0x288, -218, 0, 0x289, 0x289, -69, 0, 0x28A, 0x28B, -217, 0, 0x28C, 0x28C, -71, 0, 0x292, 0x292, -219, 0, 0x29D, 0x29D, 42261, 0, 0x29E, 0x29E, 42258, 0, 0x345, 0x345, 84, 0, 0x370, 0x373, -3, -3, 0x376, 0x377, -3, -3, 0x37B, 0x37D, 130, 0, 0x37F, 0x37F, 0, 116, 0x386, 0x386, 0, 38, 0x388, 0x38A, 0, 37, 0x38C, 0x38C, 0, 64, 0x38E, 0x38F, 0, 63, 0x391, 0x3A1, 0, 32, 0x3A3, 0x3AB, 0, 32, 0x3AC, 0x3AC, -38, 0, 0x3AD, 0x3AF, -37, 0, 0x3B1, 0x3C1, -32, 0, 0x3C2, 0x3C2, -31, 0, 0x3C3, 0x3CB, -32, 0, 0x3CC, 0x3CC, -64, 0, 0x3CD, 0x3CE, -63, 0, 0x3CF, 0x3CF, 0, 8, 0x3D0, 0x3D0, -62, 0, 0x3D1, 0x3D1, -57, 0, 0x3D5, 0x3D5, -47, 0, 0x3D6, 0x3D6, -54, 0, 0x3D7, 0x3D7, -8, 0, 0x3D8, 0x3EF, -3, -3, 0x3F0, 0x3F0, -86, 0, 0x3F1, 0x3F1, -80, 0, 0x3F2, 0x3F2, 7, 0, 0x3F3, 0x3F3, -116, 0, 0x3F4, 0x3F4, 0, -60, 0x3F5, 0x3F5, -96, 0, 0x3F7, 0x3F8, -3, -3, 0x3F9, 0x3F9, 0, -7, 0x3FA, 0x3FB, -3, -3, 0x3FD, 0x3FF, 0, -130, 0x400, 0x40F, 0, 80, 0x410, 0x42F, 0, 32, 0x430, 0x44F, -32, 0, 0x450, 0x45F, -80, 0, 0x460, 0x481, -3, -3, 0x48A, 0x4BF, -3, -3, 0x4C0, 0x4C0, 0, 15, 0x4C1, 0x4CE, -3, -3, 0x4CF, 0x4CF, -15, 0, 0x4D0, 0x52F, -3, -3, 0x531, 0x556, 0, 48, 0x561, 0x586, -48, 0, 0x10A0, 0x10C5, 0, 7264, 0x10C7, 0x10C7, 0, 7264, 0x10CD, 0x10CD, 0, 7264, 0x10D0, 0x10FA, 3008, 0, 0x10FD, 0x10FF, 3008, 0, 0x13A0, 0x13EF, 0, 38864, 0x13F0, 0x13F5, 0, 8, 0x13F8, 0x13FD, -8, 0, 0x1C80, 0x1C80, -6254, 0, 0x1C81, 0x1C81, -6253, 0, 0x1C82, 0x1C82, -6244, 0, 0x1C83, 0x1C84, -6242, 0, 0x1C85, 0x1C85, -6243, 0, 0x1C86, 0x1C86, -6236, 0, 0x1C87, 0x1C87, -6181, 0, 0x1C88, 0x1C88, 35266, 0, 0x1C90, 0x1CBA, 0, -3008, 0x1CBD, 0x1CBF, 0, -3008, 0x1D79, 0x1D79, 35332, 0, 0x1D7D, 0x1D7D, 3814, 0, 0x1D8E, 0x1D8E, 35384, 0, 0x1E00, 0x1E95, -3, -3, 0x1E9B, 0x1E9B, -59, 0, 0x1E9E, 0x1E9E, 0, -7615, 0x1EA0, 0x1EFF, -3, -3, 0x1F00, 0x1F07, 8, 0, 0x1F08, 0x1F0F, 0, -8, 0x1F10, 0x1F15, 8, 0, 0x1F18, 0x1F1D, 0, -8, 0x1F20, 0x1F27, 8, 0, 0x1F28, 0x1F2F, 0, -8, 0x1F30, 0x1F37, 8, 0, 0x1F38, 0x1F3F, 0, -8, 0x1F40, 0x1F45, 8, 0, 0x1F48, 0x1F4D, 0, -8, 0x1F51, 0x1F51, 8, 0, 0x1F53, 0x1F53, 8, 0, 0x1F55, 0x1F55, 8, 0, 0x1F57, 0x1F57, 8, 0, 0x1F59, 0x1F59, 0, -8, 0x1F5B, 0x1F5B, 0, -8, 0x1F5D, 0x1F5D, 0, -8, 0x1F5F, 0x1F5F, 0, -8, 0x1F60, 0x1F67, 8, 0, 0x1F68, 0x1F6F, 0, -8, 0x1F70, 0x1F71, 74, 0, 0x1F72, 0x1F75, 86, 0, 0x1F76, 0x1F77, 100, 0, 0x1F78, 0x1F79, 128, 0, 0x1F7A, 0x1F7B, 112, 0, 0x1F7C, 0x1F7D, 126, 0, 0x1F80, 0x1F87, 8, 0, 0x1F88, 0x1F8F, 0, -8, 0x1F90, 0x1F97, 8, 0, 0x1F98, 0x1F9F, 0, -8, 0x1FA0, 0x1FA7, 8, 0, 0x1FA8, 0x1FAF, 0, -8, 0x1FB0, 0x1FB1, 8, 0, 0x1FB3, 0x1FB3, 9, 0, 0x1FB8, 0x1FB9, 0, -8, 0x1FBA, 0x1FBB, 0, -74, 0x1FBC, 0x1FBC, 0, -9, 0x1FBE, 0x1FBE, -7205, 0, 0x1FC3, 0x1FC3, 9, 0, 0x1FC8, 0x1FCB, 0, -86, 0x1FCC, 0x1FCC, 0, -9, 0x1FD0, 0x1FD1, 8, 0, 0x1FD8, 0x1FD9, 0, -8, 0x1FDA, 0x1FDB, 0, -100, 0x1FE0, 0x1FE1, 8, 0, 0x1FE5, 0x1FE5, 7, 0, 0x1FE8, 0x1FE9, 0, -8, 0x1FEA, 0x1FEB, 0, -112, 0x1FEC, 0x1FEC, 0, -7, 0x1FF3, 0x1FF3, 9, 0, 0x1FF8, 0x1FF9, 0, -128, 0x1FFA, 0x1FFB, 0, -126, 0x1FFC, 0x1FFC, 0, -9, 0x2126, 0x2126, 0, -7517, 0x212A, 0x212A, 0, -8383, 0x212B, 0x212B, 0, -8262, 0x2132, 0x2132, 0, 28, 0x214E, 0x214E, -28, 0, 0x2160, 0x216F, 0, 16, 0x2170, 0x217F, -16, 0, 0x2183, 0x2184, -3, -3, 0x24B6, 0x24CF, 0, 26, 0x24D0, 0x24E9, -26, 0, 0x2C00, 0x2C2F, 0, 48, 0x2C30, 0x2C5F, -48, 0, 0x2C60, 0x2C61, -3, -3, 0x2C62, 0x2C62, 0, -10743, 0x2C63, 0x2C63, 0, -3814, 0x2C64, 0x2C64, 0, -10727, 0x2C65, 0x2C65, -10795, 0, 0x2C66, 0x2C66, -10792, 0, 0x2C67, 0x2C6C, -3, -3, 0x2C6D, 0x2C6D, 0, -10780, 0x2C6E, 0x2C6E, 0, -10749, 0x2C6F, 0x2C6F, 0, -10783, 0x2C70, 0x2C70, 0, -10782, 0x2C72, 0x2C73, -3, -3, 0x2C75, 0x2C76, -3, -3, 0x2C7E, 0x2C7F, 0, -10815, 0x2C80, 0x2CE3, -3, -3, 0x2CEB, 0x2CEE, -3, -3, 0x2CF2, 0x2CF3, -3, -3, 0x2D00, 0x2D25, -7264, 0, 0x2D27, 0x2D27, -7264, 0, 0x2D2D, 0x2D2D, -7264, 0, 0xA640, 0xA66D, -3, -3, 0xA680, 0xA69B, -3, -3, 0xA722, 0xA72F, -3, -3, 0xA732, 0xA76F, -3, -3, 0xA779, 0xA77C, -3, -3, 0xA77D, 0xA77D, 0, -35332, 0xA77E, 0xA787, -3, -3, 0xA78B, 0xA78C, -3, -3, 0xA78D, 0xA78D, 0, -42280, 0xA790, 0xA793, -3, -3, 0xA794, 0xA794, 48, 0, 0xA796, 0xA7A9, -3, -3, 0xA7AA, 0xA7AA, 0, -42308, 0xA7AB, 0xA7AB, 0, -42319, 0xA7AC, 0xA7AC, 0, -42315, 0xA7AD, 0xA7AD, 0, -42305, 0xA7AE, 0xA7AE, 0, -42308, 0xA7B0, 0xA7B0, 0, -42258, 0xA7B1, 0xA7B1, 0, -42282, 0xA7B2, 0xA7B2, 0, -42261, 0xA7B3, 0xA7B3, 0, 928, 0xA7B4, 0xA7C3, -3, -3, 0xA7C4, 0xA7C4, 0, -48, 0xA7C5, 0xA7C5, 0, -42307, 0xA7C6, 0xA7C6, 0, -35384, 0xA7C7, 0xA7CA, -3, -3, 0xA7D0, 0xA7D1, -3, -3, 0xA7D6, 0xA7D9, -3, -3, 0xA7F5, 0xA7F6, -3, -3, 0xAB53, 0xAB53, -928, 0, 0xAB70, 0xABBF, -38864, 0, 0xFF21, 0xFF3A, 0, 32, 0xFF41, 0xFF5A, -32, 0, 0x10400, 0x10427, 0, 40, 0x10428, 0x1044F, -40, 0, 0x104B0, 0x104D3, 0, 40, 0x104D8, 0x104FB, -40, 0, 0x10570, 0x1057A, 0, 39, 0x1057C, 0x1058A, 0, 39, 0x1058C, 0x10592, 0, 39, 0x10594, 0x10595, 0, 39, 0x10597, 0x105A1, -39, 0, 0x105A3, 0x105B1, -39, 0, 0x105B3, 0x105B9, -39, 0, 0x105BB, 0x105BC, -39, 0, 0x10C80, 0x10CB2, 0, 64, 0x10CC0, 0x10CF2, -64, 0, 0x118A0, 0x118BF, 0, 32, 0x118C0, 0x118DF, -32, 0, 0x16E40, 0x16E5F, 0, 32, 0x16E60, 0x16E7F, -32, 0, 0x1E900, 0x1E921, 0, 34, 0x1E922, 0x1E943, -34, 0}; // fixed array const time__Duration _const_time__nanosecond; // inited later time__Duration _const_time__infinite; // inited later Array_string _const_v__token__orm_custom_operators; // inited later Array_v__token__Kind _const_v__token__assign_tokens; // inited later Array_string _const_v__token__valid_at_tokens; // inited later Array_string _const_v__token__token_str; // inited later Array_v__token__Precedence _const_v__token__precedences; // inited later const u64 _const_hash__fnv1a__fnv64_prime = 1099511628211U; // precomputed2 const u64 _const_hash__fnv1a__fnv64_offset_basis = 14695981039346656037U; // precomputed2 string _const_os__wd_at_startup; // inited later Array_string _const_os__executable_suffixes; // inited later _option_bool can_show_color_on_stdout_cache; // global 6 _option_bool can_show_color_on_stderr_cache; // global 6 Array_string _const_v__help__cli_topics; // inited later Array_string _const_v__vmod__mod_file_stop_paths; // inited later v__vmod__ModFileCacher* _const_v__vmod__private_file_cacher; // inited later const u64 _const_rand__wyrand__wyp0 = 11562461410679940143U; // precomputed2 const u64 _const_rand__wyrand__wyp1 = 16646288086500911323U; // precomputed2 Array_string _const_v__pkgconfig__default_paths; // inited later rand__PRNG* default_rng; // global 6 Array_string _const_v__pref__supported_test_runners; // inited later bool _const_v__util__verror_paths_absolute; // inited later v__util__LinesCache* lines_cache; // global 6 Array_u8 _const_v__util__invalid_escapes; // inited later Array_fixed_bool_256 _const_v__util__name_char_table; // inited later Array_fixed_bool_256 _const_v__util__func_char_table; // inited later Array_fixed_bool_256 _const_v__util__non_whitespace_table; // inited later v__util__Timers* g_timers; // global 6 Array_string _const_v__util__builtin_module_parts; // inited later Array_fixed_string_8 _const_v__util__bundle_modules = {_S("clipboard"), _S("fontstash"), _S("gg"), _S("gx"), _S("sokol"), _S("szip"), _S("ui"), _S("builtin.closure")}; // fixed array const Map_string_Array_string _const_v__util__external_module_dependencies_for_tool; // inited later Array_fixed_string_11 _const_v__util__const_tabs = {_S(""), _S("\t"), _S("\t\t"), _S("\t\t\t"), _S("\t\t\t\t"), _S("\t\t\t\t\t"), _S("\t\t\t\t\t\t"), _S("\t\t\t\t\t\t\t"), _S("\t\t\t\t\t\t\t\t"), _S("\t\t\t\t\t\t\t\t\t"), _S("\t\t\t\t\t\t\t\t\t\t")}; // fixed array const int _const_v__util__nr_jobs; // inited later Array_string _const_v__ast__global_reserved_type_names; // inited later v__ast__Expr _const_v__ast__empty_expr; // inited later v__ast__Stmt _const_v__ast__empty_stmt; // inited later v__ast__ScopeObject _const_v__ast__empty_scope_object; // inited later v__ast__ComptTimeConstValue _const_v__ast__empty_comptime_const_value; // inited later Map_int_Array_string _const_v__ast__x86_no_number_register_list; // inited later Map_int_Map_string_int _const_v__ast__x86_with_number_register_list; // inited later Array_string _const_v__ast__arm_no_number_register_list; // inited later Map_string_int _const_v__ast__arm_with_number_register_list; // inited later Array_string _const_v__ast__riscv_no_number_register_list; // inited later Map_string_int _const_v__ast__riscv_with_number_register_list; // inited later Array_string _const_v__ast__s390x_no_number_register_list; // inited later Map_string_int _const_v__ast__s390x_with_number_register_list; // inited later Array_string _const_v__ast__ppc64le_no_number_register_list; // inited later Map_string_int _const_v__ast__ppc64le_with_number_register_list; // inited later Array_string _const_v__ast__loongarch64_no_number_register_list; // inited later Map_string_int _const_v__ast__loongarch64_with_number_register_list; // inited later i64 nested_expr_pos_calls = ((i64)(0)); // global 6 Array_string _const_v__ast__valid_comptime_if_os; // inited later Array_string _const_v__ast__valid_comptime_if_compilers; // inited later Array_string _const_v__ast__valid_comptime_if_platforms; // inited later Array_string _const_v__ast__valid_comptime_if_cpu_features; // inited later Array_string _const_v__ast__valid_comptime_if_other; // inited later Array_string _const_v__ast__valid_comptime_compression_types; // inited later Array_string _const_v__ast__native_builtins; // inited later i64 nested_expr_str_calls = ((i64)(0)); // global 6 Array_string _const_v__ast__fn_type_escape_seq; // inited later Array_string _const_v__ast__map_cname_escape_seq; // inited later v__ast__Table* global_table; // global 6 Array_string _const_v__ast__builtin_type_names; // inited later Array_string _const_v__checker__array_builtin_methods; // inited later Array_string _const_v__checker__fixed_array_builtin_methods; // inited later Array_string _const_v__checker__reserved_type_names; // inited later Array_string _const_v__checker__print_everything_fns; // inited later Map_rune_v__checker__LoHiLimit _const_v__checker__iencoding_map; // inited later Array_string _const_v__parser__allowed_lock_prefix_ins; // inited later Array_v__token__Kind _const_v__parser__valid_tokens_inside_types; // inited later Array_v__ast__File_ptr codegen_files; // global 6 Array_string _const_v__parser__supported_comptime_calls; // inited later Array_string _const_v__parser__comptime_types; // inited later IError _const_v__gen__c__unsupported_ctemp_assert_transform; // inited later Array_string _const_v__gen__c__c_reserved; // inited later Array_string _const_v__gen__c__cmp_str; // inited later Array_string _const_v__gen__c__cmp_rev; // inited later Array_string _const_v__gen__c__c_fn_name_escape_seq; // inited later Array_string _const_v__gen__c__skip_struct_init; // inited later string _const_v__builder__current_os; // inited later v__builder__RegKey _const_v__builder__hkey_local_machine; // inited later string _const_v__builder__cbuilder__cc_compiler; // inited later string _const_v__builder__cbuilder__cc_ldflags; // inited later string _const_v__builder__cbuilder__cc_cflags; // inited later string _const_v__builder__cbuilder__cc_cflags_opt; // inited later Array_string _const_main__external_tools; // inited later u32 _const_builtin__closure__closure_size_1; // inited later time__Duration _const_time__microsecond; // inited later Map_string_v__token__Kind _const_v__token__keywords; // inited later Array_string _const_os__args; // inited later string _const_v__pref__default_module_path; // inited later v__util__EManager* _const_v__util__emanager; // inited later string _const_v__util__normalised_workdir; // inited later time__Time _const_v__util__stable_build_time; // inited later Array_string _const_v__ast__builtins; // inited later Array_string _const_v__ast__valid_comptime_not_user_defined; // inited later v__ast__TypeSymbol* _const_v__ast__invalid_type_symbol; // inited later v__token__KeywordsMatcherTrie _const_v__ast__builtin_type_names_matcher; // inited later Array_int _const_v__ast__integer_type_idxs; // inited later Array_int _const_v__ast__signed_integer_type_idxs; // inited later Array_int _const_v__ast__unsigned_integer_type_idxs; // inited later Array_int _const_v__ast__int_promoted_type_idxs; // inited later Array_int _const_v__ast__float_type_idxs; // inited later Array_int _const_v__ast__number_type_idxs; // inited later Array_int _const_v__ast__pointer_type_idxs; // inited later v__ast__Type _const_v__ast__invalid_type; // inited later v__ast__Type _const_v__ast__no_type; // inited later v__ast__Type _const_v__ast__void_type; // inited later v__ast__Type _const_v__ast__ovoid_type; // inited later v__ast__Type _const_v__ast__rvoid_type; // inited later v__ast__Type _const_v__ast__voidptr_type; // inited later v__ast__Type _const_v__ast__byteptr_type; // inited later v__ast__Type _const_v__ast__charptr_type; // inited later v__ast__Type _const_v__ast__i8_type; // inited later v__ast__Type _const_v__ast__i16_type; // inited later v__ast__Type _const_v__ast__i32_type; // inited later v__ast__Type _const_v__ast__int_type; // inited later v__ast__Type _const_v__ast__i64_type; // inited later v__ast__Type _const_v__ast__isize_type; // inited later v__ast__Type _const_v__ast__u8_type; // inited later v__ast__Type _const_v__ast__u16_type; // inited later v__ast__Type _const_v__ast__u32_type; // inited later v__ast__Type _const_v__ast__u64_type; // inited later v__ast__Type _const_v__ast__usize_type; // inited later v__ast__Type _const_v__ast__f32_type; // inited later v__ast__Type _const_v__ast__f64_type; // inited later v__ast__Type _const_v__ast__char_type; // inited later v__ast__Type _const_v__ast__bool_type; // inited later v__ast__Type _const_v__ast__none_type; // inited later v__ast__Type _const_v__ast__string_type; // inited later v__ast__Type _const_v__ast__rune_type; // inited later v__ast__Type _const_v__ast__array_type; // inited later v__ast__Type _const_v__ast__map_type; // inited later v__ast__Type _const_v__ast__chan_type; // inited later v__ast__Type _const_v__ast__any_type; // inited later v__ast__Type _const_v__ast__float_literal_type; // inited later v__ast__Type _const_v__ast__int_literal_type; // inited later v__ast__Type _const_v__ast__thread_type; // inited later v__ast__Type _const_v__ast__error_type; // inited later v__ast__Type _const_v__ast__nil_type; // inited later v__token__KeywordsMatcherTrie _const_v__checker__array_builtin_methods_chk; // inited later v__token__KeywordsMatcherTrie _const_v__checker__fixed_array_builtin_methods_chk; // inited later v__token__KeywordsMatcherTrie _const_v__checker__reserved_type_names_chk; // inited later string _const_v__parser__normalised_working_folder; // inited later v__token__KeywordsMatcherTrie _const_v__gen__c__c_reserved_chk; // inited later int _const_builtin__closure__closure_size; // inited later time__Duration _const_time__millisecond; // inited later v__token__KeywordsMatcherTrie _const_v__token__scanner_matcher; // inited later Array_v__ast__Type _const_v__ast__charptr_types; // inited later Array_v__ast__Type _const_v__ast__byteptr_types; // inited later Array_v__ast__Type _const_v__ast__voidptr_types; // inited later IError _const_v__checker__err_ref_uninitialized; // inited later IError _const_v__checker__err_interface_uninitialized; // inited later IError _const_v__checker__err_sumtype_uninitialized; // inited later time__Duration _const_time__second; // inited later Array_v__ast__Type _const_v__ast__cptr_types; // inited later i64 _const_v__builder__thirdparty_obj_build_retry_delay; // inited later time__Duration _const_time__minute; // inited later time__Duration _const_time__hour; // inited later // V interface table: static IError I_None___to_Interface_IError(None__* x); const int _IError_None___index = 0; static IError I_voidptr_to_Interface_IError(voidptr* x); const int _IError_voidptr_index = 1; static IError I_Error_to_Interface_IError(Error* x); const int _IError_Error_index = 2; static IError I_MessageError_to_Interface_IError(MessageError* x); const int _IError_MessageError_index = 3; static IError I_time__TimeParseError_to_Interface_IError(time__TimeParseError* x); const int _IError_time__TimeParseError_index = 4; static IError I_flag__UnknownFlagError_to_Interface_IError(flag__UnknownFlagError* x); const int _IError_flag__UnknownFlagError_index = 5; static IError I_flag__ArgsCountError_to_Interface_IError(flag__ArgsCountError* x); const int _IError_flag__ArgsCountError_index = 6; static IError I_semver__InvalidComparatorFormatError_to_Interface_IError(semver__InvalidComparatorFormatError* x); const int _IError_semver__InvalidComparatorFormatError_index = 7; static IError I_semver__EmptyInputError_to_Interface_IError(semver__EmptyInputError* x); const int _IError_semver__EmptyInputError_index = 8; static IError I_semver__InvalidVersionFormatError_to_Interface_IError(semver__InvalidVersionFormatError* x); const int _IError_semver__InvalidVersionFormatError_index = 9; static IError I_os__Eof_to_Interface_IError(os__Eof* x); const int _IError_os__Eof_index = 10; static IError I_os__NotExpected_to_Interface_IError(os__NotExpected* x); const int _IError_os__NotExpected_index = 11; static IError I_os__FileNotOpenedError_to_Interface_IError(os__FileNotOpenedError* x); const int _IError_os__FileNotOpenedError_index = 12; static IError I_os__SizeOfTypeIs0Error_to_Interface_IError(os__SizeOfTypeIs0Error* x); const int _IError_os__SizeOfTypeIs0Error_index = 13; static IError I_os__ExecutableNotFoundError_to_Interface_IError(os__ExecutableNotFoundError* x); const int _IError_os__ExecutableNotFoundError_index = 14; static IError I_v__parser__IncludeError_to_Interface_IError(v__parser__IncludeError* x); const int _IError_v__parser__IncludeError_index = 15; static IError I_v__gen__c__UnsupportedAssertCtempTransform_to_Interface_IError(v__gen__c__UnsupportedAssertCtempTransform* x); const int _IError_v__gen__c__UnsupportedAssertCtempTransform_index = 16; // ^^^ number of types for interface IError: 17 // Methods wrapper for interface "IError" static inline int None___code_Interface_IError_method_wrapper(None__* err) { return Error_code(err->Error); } static inline string None___msg_Interface_IError_method_wrapper(None__* err) { return Error_msg(err->Error); } static inline int Error_code_Interface_IError_method_wrapper(Error* err) { return Error_code(*err); } static inline string Error_msg_Interface_IError_method_wrapper(Error* err) { return Error_msg(*err); } static inline int MessageError_code_Interface_IError_method_wrapper(MessageError* err) { return MessageError_code(*err); } static inline string MessageError_msg_Interface_IError_method_wrapper(MessageError* err) { return MessageError_msg(*err); } static inline int time__TimeParseError_code_Interface_IError_method_wrapper(time__TimeParseError* err) { return Error_code(err->Error); } static inline string time__TimeParseError_msg_Interface_IError_method_wrapper(time__TimeParseError* err) { return time__TimeParseError_msg(*err); } static inline int flag__UnknownFlagError_code_Interface_IError_method_wrapper(flag__UnknownFlagError* err) { return Error_code(err->Error); } static inline string flag__UnknownFlagError_msg_Interface_IError_method_wrapper(flag__UnknownFlagError* err) { return flag__UnknownFlagError_msg(*err); } static inline int flag__ArgsCountError_code_Interface_IError_method_wrapper(flag__ArgsCountError* err) { return Error_code(err->Error); } static inline string flag__ArgsCountError_msg_Interface_IError_method_wrapper(flag__ArgsCountError* err) { return flag__ArgsCountError_msg(*err); } static inline int semver__InvalidComparatorFormatError_code_Interface_IError_method_wrapper(semver__InvalidComparatorFormatError* err) { return MessageError_code(err->MessageError); } static inline string semver__InvalidComparatorFormatError_msg_Interface_IError_method_wrapper(semver__InvalidComparatorFormatError* err) { return MessageError_msg(err->MessageError); } static inline int semver__EmptyInputError_code_Interface_IError_method_wrapper(semver__EmptyInputError* err) { return Error_code(err->Error); } static inline string semver__EmptyInputError_msg_Interface_IError_method_wrapper(semver__EmptyInputError* err) { return semver__EmptyInputError_msg(*err); } static inline int semver__InvalidVersionFormatError_code_Interface_IError_method_wrapper(semver__InvalidVersionFormatError* err) { return Error_code(err->Error); } static inline string semver__InvalidVersionFormatError_msg_Interface_IError_method_wrapper(semver__InvalidVersionFormatError* err) { return semver__InvalidVersionFormatError_msg(*err); } static inline int os__Eof_code_Interface_IError_method_wrapper(os__Eof* err) { return Error_code(err->Error); } static inline string os__Eof_msg_Interface_IError_method_wrapper(os__Eof* err) { return Error_msg(err->Error); } static inline int os__NotExpected_code_Interface_IError_method_wrapper(os__NotExpected* err) { return os__NotExpected_code(*err); } static inline string os__NotExpected_msg_Interface_IError_method_wrapper(os__NotExpected* err) { return os__NotExpected_msg(*err); } static inline int os__FileNotOpenedError_code_Interface_IError_method_wrapper(os__FileNotOpenedError* err) { return Error_code(err->Error); } static inline string os__FileNotOpenedError_msg_Interface_IError_method_wrapper(os__FileNotOpenedError* err) { return os__FileNotOpenedError_msg(*err); } static inline int os__SizeOfTypeIs0Error_code_Interface_IError_method_wrapper(os__SizeOfTypeIs0Error* err) { return Error_code(err->Error); } static inline string os__SizeOfTypeIs0Error_msg_Interface_IError_method_wrapper(os__SizeOfTypeIs0Error* err) { return os__SizeOfTypeIs0Error_msg(*err); } static inline int os__ExecutableNotFoundError_code_Interface_IError_method_wrapper(os__ExecutableNotFoundError* err) { return Error_code(err->Error); } static inline string os__ExecutableNotFoundError_msg_Interface_IError_method_wrapper(os__ExecutableNotFoundError* err) { return os__ExecutableNotFoundError_msg(*err); } static inline int v__parser__IncludeError_code_Interface_IError_method_wrapper(v__parser__IncludeError* err) { return Error_code(err->Error); } static inline string v__parser__IncludeError_msg_Interface_IError_method_wrapper(v__parser__IncludeError* err) { return v__parser__IncludeError_msg(*err); } static inline int v__gen__c__UnsupportedAssertCtempTransform_code_Interface_IError_method_wrapper(v__gen__c__UnsupportedAssertCtempTransform* err) { return Error_code(err->Error); } static inline string v__gen__c__UnsupportedAssertCtempTransform_msg_Interface_IError_method_wrapper(v__gen__c__UnsupportedAssertCtempTransform* err) { return Error_msg(err->Error); } struct _IError_interface_methods { int (*_method_code)(void* _); string (*_method_msg)(void* _); }; struct _IError_interface_methods IError_name_table[17] = { { ._method_code = (void*) None___code_Interface_IError_method_wrapper, ._method_msg = (void*) None___msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) 0, ._method_msg = (void*) 0, }, { ._method_code = (void*) Error_code_Interface_IError_method_wrapper, ._method_msg = (void*) Error_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) MessageError_code_Interface_IError_method_wrapper, ._method_msg = (void*) MessageError_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) time__TimeParseError_code_Interface_IError_method_wrapper, ._method_msg = (void*) time__TimeParseError_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) flag__UnknownFlagError_code_Interface_IError_method_wrapper, ._method_msg = (void*) flag__UnknownFlagError_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) flag__ArgsCountError_code_Interface_IError_method_wrapper, ._method_msg = (void*) flag__ArgsCountError_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) semver__InvalidComparatorFormatError_code_Interface_IError_method_wrapper, ._method_msg = (void*) semver__InvalidComparatorFormatError_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) semver__EmptyInputError_code_Interface_IError_method_wrapper, ._method_msg = (void*) semver__EmptyInputError_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) semver__InvalidVersionFormatError_code_Interface_IError_method_wrapper, ._method_msg = (void*) semver__InvalidVersionFormatError_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) os__Eof_code_Interface_IError_method_wrapper, ._method_msg = (void*) os__Eof_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) os__NotExpected_code_Interface_IError_method_wrapper, ._method_msg = (void*) os__NotExpected_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) os__FileNotOpenedError_code_Interface_IError_method_wrapper, ._method_msg = (void*) os__FileNotOpenedError_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) os__SizeOfTypeIs0Error_code_Interface_IError_method_wrapper, ._method_msg = (void*) os__SizeOfTypeIs0Error_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) os__ExecutableNotFoundError_code_Interface_IError_method_wrapper, ._method_msg = (void*) os__ExecutableNotFoundError_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) v__parser__IncludeError_code_Interface_IError_method_wrapper, ._method_msg = (void*) v__parser__IncludeError_msg_Interface_IError_method_wrapper, }, { ._method_code = (void*) v__gen__c__UnsupportedAssertCtempTransform_code_Interface_IError_method_wrapper, ._method_msg = (void*) v__gen__c__UnsupportedAssertCtempTransform_msg_Interface_IError_method_wrapper, }, }; // Casting functions for converting "None__" to interface "IError" static inline IError I_None___to_Interface_IError(None__* x) { return (IError) { ._None__ = x, ._typ = _IError_None___index, }; } // Casting functions for converting "voidptr" to interface "IError" static inline IError I_voidptr_to_Interface_IError(voidptr* x) { return (IError) { ._voidptr = x, ._typ = _IError_voidptr_index, }; } // Casting functions for converting "Error" to interface "IError" static inline IError I_Error_to_Interface_IError(Error* x) { return (IError) { ._Error = x, ._typ = _IError_Error_index, }; } // Casting functions for converting "MessageError" to interface "IError" static inline IError I_MessageError_to_Interface_IError(MessageError* x) { return (IError) { ._MessageError = x, ._typ = _IError_MessageError_index, }; } // Casting functions for converting "time__TimeParseError" to interface "IError" static inline IError I_time__TimeParseError_to_Interface_IError(time__TimeParseError* x) { return (IError) { ._time__TimeParseError = x, ._typ = _IError_time__TimeParseError_index, }; } // Casting functions for converting "flag__UnknownFlagError" to interface "IError" static inline IError I_flag__UnknownFlagError_to_Interface_IError(flag__UnknownFlagError* x) { return (IError) { ._flag__UnknownFlagError = x, ._typ = _IError_flag__UnknownFlagError_index, }; } // Casting functions for converting "flag__ArgsCountError" to interface "IError" static inline IError I_flag__ArgsCountError_to_Interface_IError(flag__ArgsCountError* x) { return (IError) { ._flag__ArgsCountError = x, ._typ = _IError_flag__ArgsCountError_index, }; } // Casting functions for converting "semver__InvalidComparatorFormatError" to interface "IError" static inline IError I_semver__InvalidComparatorFormatError_to_Interface_IError(semver__InvalidComparatorFormatError* x) { return (IError) { ._semver__InvalidComparatorFormatError = x, ._typ = _IError_semver__InvalidComparatorFormatError_index, }; } // Casting functions for converting "semver__EmptyInputError" to interface "IError" static inline IError I_semver__EmptyInputError_to_Interface_IError(semver__EmptyInputError* x) { return (IError) { ._semver__EmptyInputError = x, ._typ = _IError_semver__EmptyInputError_index, }; } // Casting functions for converting "semver__InvalidVersionFormatError" to interface "IError" static inline IError I_semver__InvalidVersionFormatError_to_Interface_IError(semver__InvalidVersionFormatError* x) { return (IError) { ._semver__InvalidVersionFormatError = x, ._typ = _IError_semver__InvalidVersionFormatError_index, }; } // Casting functions for converting "os__Eof" to interface "IError" static inline IError I_os__Eof_to_Interface_IError(os__Eof* x) { return (IError) { ._os__Eof = x, ._typ = _IError_os__Eof_index, }; } // Casting functions for converting "os__NotExpected" to interface "IError" static inline IError I_os__NotExpected_to_Interface_IError(os__NotExpected* x) { return (IError) { ._os__NotExpected = x, ._typ = _IError_os__NotExpected_index, }; } // Casting functions for converting "os__FileNotOpenedError" to interface "IError" static inline IError I_os__FileNotOpenedError_to_Interface_IError(os__FileNotOpenedError* x) { return (IError) { ._os__FileNotOpenedError = x, ._typ = _IError_os__FileNotOpenedError_index, }; } // Casting functions for converting "os__SizeOfTypeIs0Error" to interface "IError" static inline IError I_os__SizeOfTypeIs0Error_to_Interface_IError(os__SizeOfTypeIs0Error* x) { return (IError) { ._os__SizeOfTypeIs0Error = x, ._typ = _IError_os__SizeOfTypeIs0Error_index, }; } // Casting functions for converting "os__ExecutableNotFoundError" to interface "IError" static inline IError I_os__ExecutableNotFoundError_to_Interface_IError(os__ExecutableNotFoundError* x) { return (IError) { ._os__ExecutableNotFoundError = x, ._typ = _IError_os__ExecutableNotFoundError_index, }; } // Casting functions for converting "v__parser__IncludeError" to interface "IError" static inline IError I_v__parser__IncludeError_to_Interface_IError(v__parser__IncludeError* x) { return (IError) { ._v__parser__IncludeError = x, ._typ = _IError_v__parser__IncludeError_index, }; } // Casting functions for converting "v__gen__c__UnsupportedAssertCtempTransform" to interface "IError" static inline IError I_v__gen__c__UnsupportedAssertCtempTransform_to_Interface_IError(v__gen__c__UnsupportedAssertCtempTransform* x) { return (IError) { ._v__gen__c__UnsupportedAssertCtempTransform = x, ._typ = _IError_v__gen__c__UnsupportedAssertCtempTransform_index, }; } static rand__PRNG I_rand__wyrand__WyRandRNG_to_Interface_rand__PRNG(rand__wyrand__WyRandRNG* x); const int _rand__PRNG_rand__wyrand__WyRandRNG_index = 0; static rand__PRNG I_voidptr_to_Interface_rand__PRNG(voidptr* x); const int _rand__PRNG_voidptr_index = 1; // ^^^ number of types for interface rand__PRNG: 2 // Methods wrapper for interface "rand__PRNG" struct _rand__PRNG_interface_methods { int (*_method_block_size)(void* _); void (*_method__v_free)(void* _); void (*_method_seed)(void* _, Array_u32 seed_data); u16 (*_method_u16)(void* _); u32 (*_method_u32)(void* _); u64 (*_method_u64)(void* _); u8 (*_method_u8)(void* _); }; struct _rand__PRNG_interface_methods rand__PRNG_name_table[2] = { { ._method_block_size = (void*) rand__wyrand__WyRandRNG_block_size, ._method__v_free = (void*) rand__wyrand__WyRandRNG_free, ._method_seed = (void*) rand__wyrand__WyRandRNG_seed, ._method_u16 = (void*) rand__wyrand__WyRandRNG_u16, ._method_u32 = (void*) rand__wyrand__WyRandRNG_u32, ._method_u64 = (void*) rand__wyrand__WyRandRNG_u64, ._method_u8 = (void*) rand__wyrand__WyRandRNG_u8, }, { ._method_block_size = (void*) 0, ._method__v_free = (void*) 0, ._method_seed = (void*) 0, ._method_u16 = (void*) 0, ._method_u32 = (void*) 0, ._method_u64 = (void*) 0, ._method_u8 = (void*) 0, }, }; // Casting functions for converting "rand__wyrand__WyRandRNG" to interface "rand__PRNG" static inline rand__PRNG I_rand__wyrand__WyRandRNG_to_Interface_rand__PRNG(rand__wyrand__WyRandRNG* x) { return (rand__PRNG) { ._rand__wyrand__WyRandRNG = x, ._typ = _rand__PRNG_rand__wyrand__WyRandRNG_index, }; } // Casting functions for converting "voidptr" to interface "rand__PRNG" static inline rand__PRNG I_voidptr_to_Interface_rand__PRNG(voidptr* x) { return (rand__PRNG) { ._voidptr = x, ._typ = _rand__PRNG_voidptr_index, }; } static v__type_resolver__IResolverType I_v__type_resolver__DummyResolver_to_Interface_v__type_resolver__IResolverType(v__type_resolver__DummyResolver* x); const int _v__type_resolver__IResolverType_v__type_resolver__DummyResolver_index = 0; static v__type_resolver__IResolverType I_voidptr_to_Interface_v__type_resolver__IResolverType(voidptr* x); const int _v__type_resolver__IResolverType_voidptr_index = 1; static v__type_resolver__IResolverType I_v__checker__Checker_to_Interface_v__type_resolver__IResolverType(v__checker__Checker* x); const int _v__type_resolver__IResolverType_v__checker__Checker_index = 2; static v__type_resolver__IResolverType I_v__gen__c__Gen_to_Interface_v__type_resolver__IResolverType(v__gen__c__Gen* x); const int _v__type_resolver__IResolverType_v__gen__c__Gen_index = 3; // ^^^ number of types for interface v__type_resolver__IResolverType: 4 // Methods wrapper for interface "v__type_resolver__IResolverType" static inline v__ast__Type v__type_resolver__DummyResolver_unwrap_generic_Interface_v__type_resolver__IResolverType_method_wrapper(v__type_resolver__DummyResolver* d, v__ast__Type t) { return v__type_resolver__DummyResolver_unwrap_generic(*d, t); } struct _v__type_resolver__IResolverType_interface_methods { v__ast__Type (*_method_unwrap_generic)(void* _, v__ast__Type t); }; struct _v__type_resolver__IResolverType_interface_methods v__type_resolver__IResolverType_name_table[4] = { { ._method_unwrap_generic = (void*) v__type_resolver__DummyResolver_unwrap_generic_Interface_v__type_resolver__IResolverType_method_wrapper, }, { ._method_unwrap_generic = (void*) 0, }, { ._method_unwrap_generic = (void*) v__checker__Checker_unwrap_generic, }, { ._method_unwrap_generic = (void*) v__gen__c__Gen_unwrap_generic, }, }; // Casting functions for converting "v__type_resolver__DummyResolver" to interface "v__type_resolver__IResolverType" static inline v__type_resolver__IResolverType I_v__type_resolver__DummyResolver_to_Interface_v__type_resolver__IResolverType(v__type_resolver__DummyResolver* x) { return (v__type_resolver__IResolverType) { ._v__type_resolver__DummyResolver = x, ._typ = _v__type_resolver__IResolverType_v__type_resolver__DummyResolver_index, .file = (v__ast__File**)((char*)x + __offsetof_ptr(x, v__type_resolver__DummyResolver, file)), }; } // Casting functions for converting "voidptr" to interface "v__type_resolver__IResolverType" static inline v__type_resolver__IResolverType I_voidptr_to_Interface_v__type_resolver__IResolverType(voidptr* x) { return (v__type_resolver__IResolverType) { ._voidptr = x, ._typ = _v__type_resolver__IResolverType_voidptr_index, .file = (v__ast__File**)((char*)x), }; } // Casting functions for converting "v__checker__Checker" to interface "v__type_resolver__IResolverType" static inline v__type_resolver__IResolverType I_v__checker__Checker_to_Interface_v__type_resolver__IResolverType(v__checker__Checker* x) { return (v__type_resolver__IResolverType) { ._v__checker__Checker = x, ._typ = _v__type_resolver__IResolverType_v__checker__Checker_index, .file = (v__ast__File**)((char*)x + __offsetof_ptr(x, v__checker__Checker, file)), }; } // Casting functions for converting "v__gen__c__Gen" to interface "v__type_resolver__IResolverType" static inline v__type_resolver__IResolverType I_v__gen__c__Gen_to_Interface_v__type_resolver__IResolverType(v__gen__c__Gen* x) { return (v__type_resolver__IResolverType) { ._v__gen__c__Gen = x, ._typ = _v__type_resolver__IResolverType_v__gen__c__Gen_index, .file = (v__ast__File**)((char*)x + __offsetof_ptr(x, v__gen__c__Gen, file)), }; } static v__ast__walker__Visitor I_v__ast__walker__Inspector_to_Interface_v__ast__walker__Visitor(v__ast__walker__Inspector* x); const int _v__ast__walker__Visitor_v__ast__walker__Inspector_index = 0; static v__ast__walker__Visitor I_voidptr_to_Interface_v__ast__walker__Visitor(voidptr* x); const int _v__ast__walker__Visitor_voidptr_index = 1; static v__ast__walker__Visitor I_v__callgraph__Mapper_to_Interface_v__ast__walker__Visitor(v__callgraph__Mapper* x); const int _v__ast__walker__Visitor_v__callgraph__Mapper_index = 2; // ^^^ number of types for interface v__ast__walker__Visitor: 3 // Methods wrapper for interface "v__ast__walker__Visitor" struct _v__ast__walker__Visitor_interface_methods { _result_void (*_method_visit)(void* _, v__ast__Node* node); }; struct _v__ast__walker__Visitor_interface_methods v__ast__walker__Visitor_name_table[3] = { { ._method_visit = (void*) v__ast__walker__Inspector_visit, }, { ._method_visit = (void*) 0, }, { ._method_visit = (void*) v__callgraph__Mapper_visit, }, }; // Casting functions for converting "v__ast__walker__Inspector" to interface "v__ast__walker__Visitor" static inline v__ast__walker__Visitor I_v__ast__walker__Inspector_to_Interface_v__ast__walker__Visitor(v__ast__walker__Inspector* x) { return (v__ast__walker__Visitor) { ._v__ast__walker__Inspector = x, ._typ = _v__ast__walker__Visitor_v__ast__walker__Inspector_index, }; } // Casting functions for converting "voidptr" to interface "v__ast__walker__Visitor" static inline v__ast__walker__Visitor I_voidptr_to_Interface_v__ast__walker__Visitor(voidptr* x) { return (v__ast__walker__Visitor) { ._voidptr = x, ._typ = _v__ast__walker__Visitor_voidptr_index, }; } // Casting functions for converting "v__callgraph__Mapper" to interface "v__ast__walker__Visitor" static inline v__ast__walker__Visitor I_v__callgraph__Mapper_to_Interface_v__ast__walker__Visitor(v__callgraph__Mapper* x) { return (v__ast__walker__Visitor) { ._v__callgraph__Mapper = x, ._typ = _v__ast__walker__Visitor_v__callgraph__Mapper_index, }; } // V sort fn definitions: VV_LOC int compare_2018276881664952276_RepIndex_by_idx(RepIndex* a, RepIndex* b) { if (a->idx < b->idx) return -1; else return 1; } VV_LOC int compare_5856511986181937489_string(string* a, string* b) { if (string__lt(*a, *b)) return -1; else return 1; } VV_LOC int compare_6984583855671780374_string(string* a, string* b) { if (string__lt(*a, *b)) return -1; else return 1; } VV_LOC int compare_13857508711935328005_string(string* a, string* b) { if (string__lt(*a, *b)) return -1; else return 1; } VV_LOC int compare_16890712418519328305_string(string* a, string* b) { if (string__lt(*a, *b)) return -1; else return 1; } VV_LOC int compare_6081961377856465380_v__util__Possibility_by_similarity(v__util__Possibility* a, v__util__Possibility* b) { if (a->similarity < b->similarity) return -1; else return 1; } VV_LOC int compare_6081961377856465380_string(string* a, string* b) { if (string__lt(*a, *b)) return -1; else return 1; } VV_LOC int compare_13857757049580525278_v__ast__StringifyModReplacement_by_weight_reverse(v__ast__StringifyModReplacement* a, v__ast__StringifyModReplacement* b) { if (b->weight < a->weight) return -1; else return 1; } VV_LOC int compare_2358202099351622853_int(int* a, int* b) { if (*a < *b) return -1; else return 1; } VV_LOC int compare_11428131622760361090_v__checker__ACFieldMethod_by_name(v__checker__ACFieldMethod* a, v__checker__ACFieldMethod* b) { if (string__lt(a->name, b->name)) return -1; else return 1; } VV_LOC int compare_12155997196440863451_v__ast__StructField_by_i(v__ast__StructField* a, v__ast__StructField* b) { if (a->i < b->i) return -1; else return 1; } VV_LOC int compare_17767866704287204994_string(string* a, string* b) { if (string__lt(*a, *b)) return -1; else return 1; } VV_LOC int compare_17767866704287204994_v__ast__Fn_by_name(v__ast__Fn* a, v__ast__Fn* b) { if (string__lt(a->name, b->name)) return -1; else return 1; } VV_LOC int compare_10151352214168403551_string(string* a, string* b) { if (string__lt(*a, *b)) return -1; else return 1; } VV_LOC int compare_7642010017538462575_string(string* a, string* b) { if (string__lt(*a, *b)) return -1; else return 1; } // V shared type functions: static inline voidptr __dup__shared__Map_string_time__StopWatch(voidptr src, int sz) { __shared__Map_string_time__StopWatch* dest = memdup(src, sz); sync__RwMutex_init(&dest->mtx); return dest; } static inline voidptr __dup__shared__Map_u64_string(voidptr src, int sz) { __shared__Map_u64_string* dest = memdup(src, sz); sync__RwMutex_init(&dest->mtx); return dest; } static inline voidptr __dup__shared__Map_int_Array_v__ast__Type(voidptr src, int sz) { __shared__Map_int_Array_v__ast__Type* dest = memdup(src, sz); sync__RwMutex_init(&dest->mtx); return dest; } static inline voidptr __dup__shared__Array_voidptr(voidptr src, int sz) { __shared__Array_voidptr* dest = memdup(src, sz); sync__RwMutex_init(&dest->mtx); return dest; } static inline voidptr __dup__shared__Array_string(voidptr src, int sz) { __shared__Array_string* dest = memdup(src, sz); sync__RwMutex_init(&dest->mtx); return dest; } static inline voidptr __dup__shared__Map_string_bool(voidptr src, int sz) { __shared__Map_string_bool* dest = memdup(src, sz); sync__RwMutex_init(&dest->mtx); return dest; } typedef struct __shared_map __shared_map; struct __shared_map { sync__RwMutex mtx; map val; }; static inline voidptr __dup_shared_map(voidptr src, int sz) { __shared_map* dest = memdup(src, sz); sync__RwMutex_init(&dest->mtx); return dest; } typedef struct __shared_array __shared_array; struct __shared_array { sync__RwMutex mtx; array val; }; static inline voidptr __dup_shared_array(voidptr src, int sz) { __shared_array* dest = memdup(src, sz); sync__RwMutex_init(&dest->mtx); return dest; } static inline void __sort_ptr(uintptr_t a[], bool b[], int l) { for (int i=1; i0 && a[j-1] > ins) { a[j] = a[j-1]; b[j] = b[j-1]; j--; } a[j] = ins; b[j] = insb; } } // end of V out (header) // V gowrappers waiter fns: void* sync__pool__process_in_thread_thread_wrapper(thread_arg_sync__pool__process_in_thread *arg); // V auto str functions: static string time__FormatDate_str(time__FormatDate it) { /* gen_str_for_enum */ switch(it) { case time__FormatDate__ddmmyy: return _S("ddmmyy"); case time__FormatDate__ddmmyyyy: return _S("ddmmyyyy"); case time__FormatDate__mmddyy: return _S("mmddyy"); case time__FormatDate__mmddyyyy: return _S("mmddyyyy"); case time__FormatDate__mmmd: return _S("mmmd"); case time__FormatDate__mmmdd: return _S("mmmdd"); case time__FormatDate__mmmddyy: return _S("mmmddyy"); case time__FormatDate__mmmddyyyy: return _S("mmmddyyyy"); case time__FormatDate__no_date: return _S("no_date"); case time__FormatDate__yyyymmdd: return _S("yyyymmdd"); case time__FormatDate__yymmdd: return _S("yymmdd"); default: return _S("unknown enum value"); } } static string v__pref__Arch_str(v__pref__Arch it) { /* gen_str_for_enum */ switch(it) { case v__pref__Arch___auto: return _S("_auto"); case v__pref__Arch__amd64: return _S("amd64"); case v__pref__Arch__arm64: return _S("arm64"); case v__pref__Arch__arm32: return _S("arm32"); case v__pref__Arch__rv64: return _S("rv64"); case v__pref__Arch__rv32: return _S("rv32"); case v__pref__Arch__i386: return _S("i386"); case v__pref__Arch__s390x: return _S("s390x"); case v__pref__Arch__ppc64le: return _S("ppc64le"); case v__pref__Arch__loongarch64: return _S("loongarch64"); case v__pref__Arch__js_node: return _S("js_node"); case v__pref__Arch__js_browser: return _S("js_browser"); case v__pref__Arch__js_freestanding: return _S("js_freestanding"); case v__pref__Arch__wasm32: return _S("wasm32"); case v__pref__Arch___max: return _S("_max"); default: return _S("unknown enum value"); } } static string v__pref__Backend_str(v__pref__Backend it) { /* gen_str_for_enum */ switch(it) { case v__pref__Backend__c: return _S("c"); case v__pref__Backend__golang: return _S("golang"); case v__pref__Backend__interpret: return _S("interpret"); case v__pref__Backend__js_node: return _S("js_node"); case v__pref__Backend__js_browser: return _S("js_browser"); case v__pref__Backend__js_freestanding: return _S("js_freestanding"); case v__pref__Backend__native: return _S("native"); case v__pref__Backend__wasm: return _S("wasm"); default: return _S("unknown enum value"); } } static string Array_v__ast__Expr_str(Array_v__ast__Expr a) { return indent_Array_v__ast__Expr_str(a, 0);} static string indent_Array_v__ast__Expr_str(Array_v__ast__Expr a, int indent_count) { strings__Builder sb = strings__new_builder(2 + a.len * 10); strings__Builder_write_string(&sb, _S("[")); for (int i = 0; i < a.len; ++i) { v__ast__Expr it = *(v__ast__Expr*)array_get(a, i); strings__Builder_write_string(&sb, _S("")); string x = v__ast__Expr_str(&it); strings__Builder_write_string(&sb, x); if (i < a.len-1) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_string(&sb, _S("]")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string v__ast__CallExpr_str(v__ast__CallExpr it) { return indent_v__ast__CallExpr_str(it, 0);} static string v__ast__UsedFeatures_str(v__ast__UsedFeatures it) { return indent_v__ast__UsedFeatures_str(it, 0);} static string Array_int_str(Array_int a) { return indent_Array_int_str(a, 0);} static string indent_Array_int_str(Array_int a, int indent_count) { strings__Builder sb = strings__new_builder(2 + a.len * 10); strings__Builder_write_string(&sb, _S("[")); for (int i = 0; i < a.len; ++i) { int it = *(int*)array_get(a, i); strings__Builder_write_string(&sb, _S("")); string x = int_str(it); strings__Builder_write_string(&sb, x); if (i < a.len-1) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_string(&sb, _S("]")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string v__ast__IdentKind_str(v__ast__IdentKind it) { /* gen_str_for_enum */ switch(it) { case v__ast__IdentKind__unresolved: return _S("unresolved"); case v__ast__IdentKind__blank_ident: return _S("blank_ident"); case v__ast__IdentKind__variable: return _S("variable"); case v__ast__IdentKind__constant: return _S("constant"); case v__ast__IdentKind__global: return _S("global"); case v__ast__IdentKind__function: return _S("function"); default: return _S("unknown enum value"); } } static string v__token__Pos_str(v__token__Pos it) { return indent_v__token__Pos_str(it, 0);} static string Array_v__ast__Attr_str(Array_v__ast__Attr a) { return indent_Array_v__ast__Attr_str(a, 0);} static string indent_Array_v__ast__Attr_str(Array_v__ast__Attr a, int indent_count) { strings__Builder sb = strings__new_builder(2 + a.len * 10); strings__Builder_write_string(&sb, _S("[")); for (int i = 0; i < a.len; ++i) { v__ast__Attr it = *(v__ast__Attr*)array_get(a, i); strings__Builder_write_string(&sb, _S("")); string x = v__ast__Attr_str(&it); strings__Builder_write_string(&sb, x); if (i < a.len-1) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_string(&sb, _S("]")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string v__checker__ComptimeBranchSkipState_str(v__checker__ComptimeBranchSkipState it) { /* gen_str_for_enum */ switch(it) { case v__checker__ComptimeBranchSkipState__eval: return _S("eval"); case v__checker__ComptimeBranchSkipState__skip: return _S("skip"); case v__checker__ComptimeBranchSkipState__unknown: return _S("unknown"); default: return _S("unknown enum value"); } } static string Array_v__ast__Type_str(Array_v__ast__Type a) { return indent_Array_v__ast__Type_str(a, 0);} static string indent_Array_v__ast__Type_str(Array_v__ast__Type a, int indent_count) { strings__Builder sb = strings__new_builder(2 + a.len * 10); strings__Builder_write_string(&sb, _S("[")); for (int i = 0; i < a.len; ++i) { u32 it = *(u32*)array_get(a, i); strings__Builder_write_string(&sb, _S("")); string x = u32_str(it); strings__Builder_write_string(&sb, x); if (i < a.len-1) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_string(&sb, _S("]")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string Array_Array_v__ast__Type_str(Array_Array_v__ast__Type a) { return indent_Array_Array_v__ast__Type_str(a, 0);} static string indent_Array_Array_v__ast__Type_str(Array_Array_v__ast__Type a, int indent_count) { strings__Builder sb = strings__new_builder(2 + a.len * 10); strings__Builder_write_string(&sb, _S("[")); for (int i = 0; i < a.len; ++i) { Array_v__ast__Type it = *(Array_v__ast__Type*)array_get(a, i); string x = indent_Array_v__ast__Type_str(it, indent_count); strings__Builder_write_string(&sb, x); if (i < a.len-1) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_string(&sb, _S("]")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string v__ast__Ident_str(v__ast__Ident it) { return indent_v__ast__Ident_str(it, 0);} static string v__ast__Language_str(v__ast__Language it) { /* gen_str_for_enum */ switch(it) { case v__ast__Language__v: return _S("v"); case v__ast__Language__c: return _S("c"); case v__ast__Language__js: return _S("js"); case v__ast__Language__wasm: return _S("wasm"); case v__ast__Language__amd64: return _S("amd64"); case v__ast__Language__i386: return _S("i386"); case v__ast__Language__arm64: return _S("arm64"); case v__ast__Language__arm32: return _S("arm32"); case v__ast__Language__rv64: return _S("rv64"); case v__ast__Language__rv32: return _S("rv32"); case v__ast__Language__s390x: return _S("s390x"); case v__ast__Language__ppc64le: return _S("ppc64le"); case v__ast__Language__loongarch64: return _S("loongarch64"); case v__ast__Language__wasm32: return _S("wasm32"); default: return _S("unknown enum value"); } } static string v__scanner__CommentsMode_str(v__scanner__CommentsMode it) { /* gen_str_for_enum */ switch(it) { case v__scanner__CommentsMode__skip_comments: return _S("skip_comments"); case v__scanner__CommentsMode__parse_comments: return _S("parse_comments"); case v__scanner__CommentsMode__toplevel_comments: return _S("toplevel_comments"); default: return _S("unknown enum value"); } } static string v__parser__State_str(v__parser__State it) { /* gen_str_for_enum */ switch(it) { case v__parser__State__simple: return _S("simple"); case v__parser__State__html: return _S("html"); case v__parser__State__css: return _S("css"); case v__parser__State__js: return _S("js"); default: return _S("unknown enum value"); } } static string v__gen__c__StrType_str(v__gen__c__StrType it) { return indent_v__gen__c__StrType_str(it, 0);} static string v__ast__Enum_str(v__ast__Enum it) { return indent_v__ast__Enum_str(it, 0);} static string v__ast__AttrKind_str(v__ast__AttrKind it) { /* gen_str_for_enum */ switch(it) { case v__ast__AttrKind__plain: return _S("plain"); case v__ast__AttrKind__string: return _S("string"); case v__ast__AttrKind__number: return _S("number"); case v__ast__AttrKind__bool: return _S("bool"); case v__ast__AttrKind__comptime_define: return _S("comptime_define"); default: return _S("unknown enum value"); } } static string v__ast__ComptTimeConstValue_str(v__ast__ComptTimeConstValue x) { return indent_v__ast__ComptTimeConstValue_str(x, 0); } static string v__errors__Reporter_str(v__errors__Reporter it) { /* gen_str_for_enum */ switch(it) { case v__errors__Reporter__scanner: return _S("scanner"); case v__errors__Reporter__parser: return _S("parser"); case v__errors__Reporter__checker: return _S("checker"); case v__errors__Reporter__builder: return _S("builder"); case v__errors__Reporter__gen: return _S("gen"); default: return _S("unknown enum value"); } } static string v__builder__CcompilerOptions_str(v__builder__CcompilerOptions it) { return indent_v__builder__CcompilerOptions_str(it, 0);} static string Array_v__cflag__CFlag_str(Array_v__cflag__CFlag a) { return indent_Array_v__cflag__CFlag_str(a, 0);} static string indent_Array_v__cflag__CFlag_str(Array_v__cflag__CFlag a, int indent_count) { strings__Builder sb = strings__new_builder(2 + a.len * 10); strings__Builder_write_string(&sb, _S("[")); for (int i = 0; i < a.len; ++i) { v__cflag__CFlag it = *(v__cflag__CFlag*)array_get(a, i); strings__Builder_write_string(&sb, _S("")); string x = v__cflag__CFlag_str(&it); strings__Builder_write_string(&sb, x); if (i < a.len-1) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_string(&sb, _S("]")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string Map_string_int_str(Map_string_int m) { return indent_Map_string_int_str(m, 0);} static string indent_Map_string_int_str(Map_string_int m, int indent_count) { /* gen_str_for_map */ strings__Builder sb = strings__new_builder(2 + m.key_values.len * 10); strings__Builder_write_string(&sb, _S("{")); bool is_first = true; for (int i = 0; i < m.key_values.len; ++i) { if (!DenseArray_has_index(&m.key_values, i)) { continue; } else if (!is_first) { strings__Builder_write_string(&sb, _S(", ")); } string key = *(string*)DenseArray_key(&m.key_values, i); strings__Builder_write_string(&sb, str_intp(2, _MOV((StrIntpData[]){{_S("'"), 0xfe10, {.d_s = key}},{_S("'"), 0, {.d_c = 0 }}}))); strings__Builder_write_string(&sb, _S(": ")); strings__Builder_write_string(&sb, int_str(*(int*)DenseArray_value(&m.key_values, i))); is_first = false; } strings__Builder_write_string(&sb, _S("}")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string v__pref__CompilerType_str(v__pref__CompilerType it) { /* gen_str_for_enum */ switch(it) { case v__pref__CompilerType__gcc: return _S("gcc"); case v__pref__CompilerType__tinyc: return _S("tinyc"); case v__pref__CompilerType__clang: return _S("clang"); case v__pref__CompilerType__emcc: return _S("emcc"); case v__pref__CompilerType__mingw: return _S("mingw"); case v__pref__CompilerType__msvc: return _S("msvc"); case v__pref__CompilerType__cplusplus: return _S("cplusplus"); default: return _S("unknown enum value"); } } static string Array_v__ast__CallArg_str(Array_v__ast__CallArg a) { return indent_Array_v__ast__CallArg_str(a, 0);} static string indent_Array_v__ast__CallArg_str(Array_v__ast__CallArg a, int indent_count) { strings__Builder sb = strings__new_builder(2 + a.len * 10); strings__Builder_write_string(&sb, _S("[")); for (int i = 0; i < a.len; ++i) { v__ast__CallArg it = *(v__ast__CallArg*)array_get(a, i); strings__Builder_write_string(&sb, _S("")); string x = v__ast__CallArg_str(it); strings__Builder_write_string(&sb, x); if (i < a.len-1) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_string(&sb, _S("]")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string v__ast__OrExpr_str(v__ast__OrExpr it) { return indent_v__ast__OrExpr_str(it, 0);} static string Array_v__ast__Comment_str(Array_v__ast__Comment a) { return indent_Array_v__ast__Comment_str(a, 0);} static string indent_Array_v__ast__Comment_str(Array_v__ast__Comment a, int indent_count) { strings__Builder sb = strings__new_builder(2 + a.len * 10); strings__Builder_write_string(&sb, _S("[")); for (int i = 0; i < a.len; ++i) { v__ast__Comment it = *(v__ast__Comment*)array_get(a, i); string x = indent_v__ast__Comment_str(it, indent_count); strings__Builder_write_string(&sb, x); if (i < a.len-1) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_string(&sb, _S("]")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string Map_int_bool_str(Map_int_bool m) { return indent_Map_int_bool_str(m, 0);} static string indent_Map_int_bool_str(Map_int_bool m, int indent_count) { /* gen_str_for_map */ strings__Builder sb = strings__new_builder(2 + m.key_values.len * 10); strings__Builder_write_string(&sb, _S("{")); bool is_first = true; for (int i = 0; i < m.key_values.len; ++i) { if (!DenseArray_has_index(&m.key_values, i)) { continue; } else if (!is_first) { strings__Builder_write_string(&sb, _S(", ")); } int key = *(int*)DenseArray_key(&m.key_values, i); strings__Builder_write_string(&sb, int_str(key)); strings__Builder_write_string(&sb, _S(": ")); strings__Builder_write_string(&sb, bool_str(*(bool*)DenseArray_value(&m.key_values, i))); is_first = false; } strings__Builder_write_string(&sb, _S("}")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string Map_string_bool_str(Map_string_bool m) { return indent_Map_string_bool_str(m, 0);} static string indent_Map_string_bool_str(Map_string_bool m, int indent_count) { /* gen_str_for_map */ strings__Builder sb = strings__new_builder(2 + m.key_values.len * 10); strings__Builder_write_string(&sb, _S("{")); bool is_first = true; for (int i = 0; i < m.key_values.len; ++i) { if (!DenseArray_has_index(&m.key_values, i)) { continue; } else if (!is_first) { strings__Builder_write_string(&sb, _S(", ")); } string key = *(string*)DenseArray_key(&m.key_values, i); strings__Builder_write_string(&sb, str_intp(2, _MOV((StrIntpData[]){{_S("'"), 0xfe10, {.d_s = key}},{_S("'"), 0, {.d_c = 0 }}}))); strings__Builder_write_string(&sb, _S(": ")); strings__Builder_write_string(&sb, bool_str(*(bool*)DenseArray_value(&m.key_values, i))); is_first = false; } strings__Builder_write_string(&sb, _S("}")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string Map_v__ast__Type_bool_str(Map_v__ast__Type_bool m) { return indent_Map_v__ast__Type_bool_str(m, 0);} static string indent_Map_v__ast__Type_bool_str(Map_v__ast__Type_bool m, int indent_count) { /* gen_str_for_map */ strings__Builder sb = strings__new_builder(2 + m.key_values.len * 10); strings__Builder_write_string(&sb, _S("{")); bool is_first = true; for (int i = 0; i < m.key_values.len; ++i) { if (!DenseArray_has_index(&m.key_values, i)) { continue; } else if (!is_first) { strings__Builder_write_string(&sb, _S(", ")); } u32 key = *(u32*)DenseArray_key(&m.key_values, i); strings__Builder_write_string(&sb, u32_str(key)); strings__Builder_write_string(&sb, _S(": ")); strings__Builder_write_string(&sb, bool_str(*(bool*)DenseArray_value(&m.key_values, i))); is_first = false; } strings__Builder_write_string(&sb, _S("}")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string v__ast__ScopeObject_str(v__ast__ScopeObject x) { return indent_v__ast__ScopeObject_str(x, 0); } static string v__ast__IdentInfo_str(v__ast__IdentInfo x) { return indent_v__ast__IdentInfo_str(x, 0); } static string Map_string_Array_v__ast__Attr_str(Map_string_Array_v__ast__Attr m) { return indent_Map_string_Array_v__ast__Attr_str(m, 0);} static string indent_Map_string_Array_v__ast__Attr_str(Map_string_Array_v__ast__Attr m, int indent_count) { /* gen_str_for_map */ strings__Builder sb = strings__new_builder(2 + m.key_values.len * 10); strings__Builder_write_string(&sb, _S("{")); bool is_first = true; for (int i = 0; i < m.key_values.len; ++i) { if (!DenseArray_has_index(&m.key_values, i)) { continue; } else if (!is_first) { strings__Builder_write_string(&sb, _S(", ")); } string key = *(string*)DenseArray_key(&m.key_values, i); strings__Builder_write_string(&sb, str_intp(2, _MOV((StrIntpData[]){{_S("'"), 0xfe10, {.d_s = key}},{_S("'"), 0, {.d_c = 0 }}}))); strings__Builder_write_string(&sb, _S(": ")); strings__Builder_write_string(&sb, indent_Array_v__ast__Attr_str(*(Array_v__ast__Attr*)DenseArray_value(&m.key_values, i), indent_count)); is_first = false; } strings__Builder_write_string(&sb, _S("}")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string v__ast__EmptyExpr_str(v__ast__EmptyExpr it) { return indent_v__ast__EmptyExpr_str(it, 0); } static string indent_v__ast__EmptyExpr_str(v__ast__EmptyExpr it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string tmp_ds = u8_str(it); string res = str_intp(3, _MOV((StrIntpData[]){ {_SLIT0, 0xfe10, {.d_s = indents }}, {_S("v.ast.EmptyExpr("), 0xfe10, {.d_s = tmp_ds }}, {_S(")"), 0, {.d_c = 0 }} })); string_free(&indents); string_free(&tmp_ds); return res; } static string v__builder__CC_str(v__builder__CC it) { /* gen_str_for_enum */ switch(it) { case v__builder__CC__tcc: return _S("tcc"); case v__builder__CC__gcc: return _S("gcc"); case v__builder__CC__icc: return _S("icc"); case v__builder__CC__msvc: return _S("msvc"); case v__builder__CC__clang: return _S("clang"); case v__builder__CC__emcc: return _S("emcc"); case v__builder__CC__unknown: return _S("unknown"); default: return _S("unknown enum value"); } } static string v__ast__OrKind_str(v__ast__OrKind it) { /* gen_str_for_enum */ switch(it) { case v__ast__OrKind__absent: return _S("absent"); case v__ast__OrKind__block: return _S("block"); case v__ast__OrKind__propagate_option: return _S("propagate_option"); case v__ast__OrKind__propagate_result: return _S("propagate_result"); default: return _S("unknown enum value"); } } static string Array_v__ast__Stmt_str(Array_v__ast__Stmt a) { return indent_Array_v__ast__Stmt_str(a, 0);} static string indent_Array_v__ast__Stmt_str(Array_v__ast__Stmt a, int indent_count) { strings__Builder sb = strings__new_builder(2 + a.len * 10); strings__Builder_write_string(&sb, _S("[")); for (int i = 0; i < a.len; ++i) { v__ast__Stmt it = *(v__ast__Stmt*)array_get(a, i); strings__Builder_write_string(&sb, _S("")); string x = v__ast__Stmt_str(it); strings__Builder_write_string(&sb, x); if (i < a.len-1) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_string(&sb, _S("]")); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } static string v__ast__Comment_str(v__ast__Comment it) { return indent_v__ast__Comment_str(it, 0);} static string v__ast__EmptyScopeObject_str(v__ast__EmptyScopeObject it) { return indent_v__ast__EmptyScopeObject_str(it, 0);} static string v__ast__AsmRegister_str(v__ast__AsmRegister it) { return indent_v__ast__AsmRegister_str(it, 0);} static string v__ast__ConstField_str(v__ast__ConstField it) { return indent_v__ast__ConstField_str(it, 0);} static string v__ast__GlobalField_str(v__ast__GlobalField it) { return indent_v__ast__GlobalField_str(it, 0);} static string v__ast__Var_str(v__ast__Var it) { return indent_v__ast__Var_str(it, 0);} static string v__ast__IdentFn_str(v__ast__IdentFn it) { return indent_v__ast__IdentFn_str(it, 0);} static string v__ast__IdentVar_str(v__ast__IdentVar it) { return indent_v__ast__IdentVar_str(it, 0);} static string v__ast__ComptimeVarKind_str(v__ast__ComptimeVarKind it) { /* gen_str_for_enum */ switch(it) { case v__ast__ComptimeVarKind__no_comptime: return _S("no_comptime"); case v__ast__ComptimeVarKind__key_var: return _S("key_var"); case v__ast__ComptimeVarKind__value_var: return _S("value_var"); case v__ast__ComptimeVarKind__field_var: return _S("field_var"); case v__ast__ComptimeVarKind__generic_param: return _S("generic_param"); case v__ast__ComptimeVarKind__generic_var: return _S("generic_var"); case v__ast__ComptimeVarKind__smartcast: return _S("smartcast"); case v__ast__ComptimeVarKind__aggregate: return _S("aggregate"); default: return _S("unknown enum value"); } } // V auto functions: string indent_v__ast__CallExpr_str(v__ast__CallExpr it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = indent_v__token__Pos_str(it.pos, indent_count + 1); string _t2 = indent_v__token__Pos_str(it.name_pos, indent_count + 1); string _t3 = indent_Array_v__ast__CallArg_str(it.args, indent_count + 1); string _t4 = indent_Array_v__ast__Type_str(it.expected_arg_types, indent_count + 1); string _t5 = v__ast__Language_str((it.language)); string _t6 = indent_v__ast__OrExpr_str(it.or_block, indent_count + 1); string _t7 = v__ast__Expr_str(&it.left); string _t8 = v__ast__Type_str(it.left_type); string _t9 = v__ast__Type_str(it.receiver_type); string _t10 = v__ast__Type_str(it.receiver_concrete_type); string _t11 = v__ast__Type_str(it.return_type); string _t12 = v__ast__Type_str(it.return_type_generic); string _t13 = v__ast__Type_str(it.fn_var_type); string _t14 = indent_Array_v__ast__Type_str(it.concrete_types, indent_count + 1); string _t15 = indent_v__token__Pos_str(it.concrete_list_pos, indent_count + 1); string _t16 = indent_Array_v__ast__Type_str(it.raw_concrete_types, indent_count + 1); string _t17 = isnil(it.scope) ? _S("nil") : (indent_count > 25)? _S("") : v__ast__Scope_str(it.scope); string _t18 = indent_Array_v__ast__Type_str(it.from_embed_types, indent_count + 1); string _t19 = indent_Array_v__ast__Comment_str(it.comments, indent_count + 1); string res = str_intp( 155, _MOV((StrIntpData[]){ {_S("ast.CallExpr{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" pos: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" name_pos: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t2}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" mod: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.mod}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" name: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.name}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_method: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_method ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_field: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_field ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_fn_var: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_fn_var ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_fn_a_const: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_fn_a_const ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_keep_alive: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_keep_alive ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_noreturn: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_noreturn ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_ctor_new: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_ctor_new ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_file_translated: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_file_translated ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_static_method: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_static_method ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" args: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t3}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" expected_arg_types: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t4}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" comptime_ret_val: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.comptime_ret_val ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" language: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t5}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" or_block: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t6}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" left: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t7}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" left_type: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t8}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" receiver_type: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t9}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" receiver_concrete_type: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t10}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" return_type: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t11}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" return_type_generic: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t12}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" nr_ret_values: "), 0, {.d_c=0}}, {_S(""), 7, {.d_i32=it.nr_ret_values}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" fn_var_type: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t13}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" const_name: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.const_name}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" should_be_skipped: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.should_be_skipped ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" concrete_types: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t14}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" concrete_list_pos: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t15}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" raw_concrete_types: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t16}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" free_receiver: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.free_receiver ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" scope: &"), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t17}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" from_embed_types: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t18}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" comments: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t19}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_return_used: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_return_used ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_expand_simple_interpolation: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_expand_simple_interpolation ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_unwrapped_fn_selector: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_unwrapped_fn_selector ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t19); string_free(&_t18); string_free(&_t17); string_free(&_t16); string_free(&_t15); string_free(&_t14); string_free(&_t13); string_free(&_t12); string_free(&_t11); string_free(&_t10); string_free(&_t9); string_free(&_t8); string_free(&_t7); string_free(&_t6); string_free(&_t5); string_free(&_t4); string_free(&_t3); string_free(&_t2); string_free(&_t1); string_free(&indents); return res; } string indent_v__ast__UsedFeatures_str(v__ast__UsedFeatures it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = indent_Map_int_bool_str(it.print_types, indent_count + 1); string _t2 = indent_Map_string_bool_str(it.used_fns, indent_count + 1); string _t3 = indent_Map_string_bool_str(it.used_consts, indent_count + 1); string _t4 = indent_Map_string_bool_str(it.used_globals, indent_count + 1); string _t5 = indent_Map_int_bool_str(it.used_syms, indent_count + 1); string _t6 = indent_Array_v__ast__Type_str(it.used_veb_types, indent_count + 1); string _t7 = indent_Map_string_bool_str(it.comptime_calls, indent_count + 1); string _t8 = indent_Map_v__ast__Type_bool_str(it.comptime_syms, indent_count + 1); string res = str_intp( 111, _MOV((StrIntpData[]){ {_S("ast.UsedFeatures{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" dump: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.dump ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" index: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.index ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" range_index: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.range_index ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" cast_ptr: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.cast_ptr ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" anon_fn: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.anon_fn ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" auto_str: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.auto_str ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" auto_str_ptr: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.auto_str_ptr ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" arr_prepend: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.arr_prepend ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" arr_insert: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.arr_insert ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" arr_first: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.arr_first ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" arr_last: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.arr_last ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" arr_pop: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.arr_pop ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" arr_delete: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.arr_delete ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" arr_reverse: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.arr_reverse ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" arr_map: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.arr_map ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" type_name: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.type_name ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" print_options: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.print_options ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" print_types: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" used_fns: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t2}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" used_consts: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t3}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" used_globals: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t4}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" used_syms: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t5}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" used_veb_types: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t6}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" used_maps: "), 0, {.d_c=0}}, {_S(""), 7, {.d_i32=it.used_maps}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" used_none: "), 0, {.d_c=0}}, {_S(""), 7, {.d_i32=it.used_none}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" comptime_calls: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t7}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" comptime_syms: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t8}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t8); string_free(&_t7); string_free(&_t6); string_free(&_t5); string_free(&_t4); string_free(&_t3); string_free(&_t2); string_free(&_t1); string_free(&indents); return res; } string indent_v__token__Pos_str(v__token__Pos it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string res = str_intp( 23, _MOV((StrIntpData[]){ {_S("token.Pos{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" len: "), 0, {.d_c=0}}, {_S(""), 7, {.d_i32=it.len}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" line_nr: "), 0, {.d_c=0}}, {_S(""), 7, {.d_i32=it.line_nr}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" pos: "), 0, {.d_c=0}}, {_S(""), 7, {.d_i32=it.pos}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" col: "), 0, {.d_c=0}}, {_S(""), 7, {.d_i32=it.col}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" last_line: "), 0, {.d_c=0}}, {_S(""), 7, {.d_i32=it.last_line}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&indents); return res; } string indent_v__ast__Ident_str(v__ast__Ident it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = v__ast__Language_str((it.language)); string _t2 = v__token__Kind_str((it.tok_kind)); string _t3 = indent_v__token__Pos_str(it.pos, indent_count + 1); string _t4 = indent_v__token__Pos_str(it.mut_pos, indent_count + 1); string _t5 = isnil(it.scope) ? _S("nil") : (indent_count > 25)? _S("") : v__ast__Scope_str(it.scope); string _t6 = indent_v__ast__ScopeObject_str(it.obj, indent_count + 1); string _t7 = v__ast__IdentKind_str((it.kind)); string _t8 = indent_v__ast__IdentInfo_str(it.info, indent_count + 1); string _t9 = indent_v__ast__OrExpr_str(it.or_expr, indent_count + 1); string _t10 = indent_Array_v__ast__Type_str(it.concrete_types, indent_count + 1); string res = str_intp( 71, _MOV((StrIntpData[]){ {_S("ast.Ident{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" language: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" tok_kind: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t2}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" pos: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t3}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" mut_pos: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t4}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" comptime: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.comptime ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" scope: &"), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t5}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" obj: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t6}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" mod: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.mod}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" name: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.name}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" full_name: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.full_name}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" cached_name: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.cached_name}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" kind: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t7}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" info: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t8}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_mut: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_mut ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" or_expr: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t9}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" concrete_types: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t10}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" ct_expr: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.ct_expr ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t10); string_free(&_t9); string_free(&_t8); string_free(&_t7); string_free(&_t6); string_free(&_t5); string_free(&_t4); string_free(&_t3); string_free(&_t2); string_free(&_t1); string_free(&indents); return res; } string indent_v__gen__c__StrType_str(v__gen__c__StrType it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = v__ast__Type_str(it.typ); string res = str_intp( 11, _MOV((StrIntpData[]){ {_S("c.StrType{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" styp: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.styp}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" typ: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t1); string_free(&indents); return res; } string indent_v__ast__Enum_str(v__ast__Enum it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = Array_string_str(it.vals); string _t2 = v__ast__Type_str(it.typ); string _t3 = indent_Map_string_Array_v__ast__Attr_str(it.attrs, indent_count + 1); string res = str_intp( 27, _MOV((StrIntpData[]){ {_S("ast.Enum{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" vals: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_flag: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_flag ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_multi_allowed: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_multi_allowed ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" uses_exprs: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.uses_exprs ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" typ: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t2}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" attrs: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t3}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t3); string_free(&_t2); string_free(&_t1); string_free(&indents); return res; } static string indent_v__ast__ComptTimeConstValue_str(v__ast__ComptTimeConstValue x, int indent_count) { switch(x._typ) { case 354: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = indent_v__ast__EmptyExpr_str(*(v__ast__EmptyExpr*)x._v__ast__EmptyExpr, indent_count)}}, {_S(")"), 0, {.d_c = 0 }} })); case 16: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = f32_str(*(f32*)x._f32)}}, {_S(")"), 0, {.d_c = 0 }} })); case 17: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = f64_str(*(f64*)x._f64)}}, {_S(")"), 0, {.d_c = 0 }} })); case 6: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = i16_str(*(i16*)x._i16)}}, {_S(")"), 0, {.d_c = 0 }} })); case 7: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = i32_str(*(i32*)x._i32)}}, {_S(")"), 0, {.d_c = 0 }} })); case 9: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = i64_str(*(i64*)x._i64)}}, {_S(")"), 0, {.d_c = 0 }} })); case 5: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = i8_str(*(i8*)x._i8)}}, {_S(")"), 0, {.d_c = 0 }} })); case 22: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = rune_str(*(rune*)x._rune)}}, {_S(")"), 0, {.d_c = 0 }} })); case 21: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue('"), 0xfe10, {.d_s = string_str(*(string*)x._string)}}, {_S("')"), 0, {.d_c = 0 }} })); case 12: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = u16_str(*(u16*)x._u16)}}, {_S(")"), 0, {.d_c = 0 }} })); case 13: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = u32_str(*(u32*)x._u32)}}, {_S(")"), 0, {.d_c = 0 }} })); case 14: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = u64_str(*(u64*)x._u64)}}, {_S(")"), 0, {.d_c = 0 }} })); case 11: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = u8_str(*(u8*)x._u8)}}, {_S(")"), 0, {.d_c = 0 }} })); case 2: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ComptTimeConstValue("), 0xfe10, {.d_s = voidptr_str(*(voidptr*)x._voidptr)}}, {_S(")"), 0, {.d_c = 0 }} })); default: return _S("unknown sum type value"); } } string indent_v__builder__CcompilerOptions_str(v__builder__CcompilerOptions it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = v__builder__CC_str((it.cc)); string _t2 = Array_string_str(it.args); string _t3 = Array_string_str(it.wargs); string _t4 = Array_string_str(it.pre_args); string _t5 = Array_string_str(it.o_args); string _t6 = Array_string_str(it.source_args); string _t7 = Array_string_str(it.post_args); string _t8 = Array_string_str(it.linker_flags); string _t9 = Array_string_str(it.ldflags); string res = str_intp( 59, _MOV((StrIntpData[]){ {_S("builder.CcompilerOptions{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" guessed_compiler: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.guessed_compiler}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" shared_postfix: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.shared_postfix}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" debug_mode: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.debug_mode ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" cc: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" env_cflags: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.env_cflags}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" env_ldflags: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.env_ldflags}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" args: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t2}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" wargs: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t3}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" pre_args: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t4}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" o_args: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t5}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" source_args: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t6}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" post_args: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t7}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" linker_flags: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t8}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" ldflags: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t9}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t9); string_free(&_t8); string_free(&_t7); string_free(&_t6); string_free(&_t5); string_free(&_t4); string_free(&_t3); string_free(&_t2); string_free(&_t1); string_free(&indents); return res; } string indent_v__ast__OrExpr_str(v__ast__OrExpr it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = v__ast__OrKind_str((it.kind)); string _t2 = indent_v__token__Pos_str(it.pos, indent_count + 1); string _t3 = indent_Array_v__ast__Stmt_str(it.stmts, indent_count + 1); string res = str_intp( 15, _MOV((StrIntpData[]){ {_S("ast.OrExpr{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" kind: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" pos: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t2}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" stmts: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t3}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t3); string_free(&_t2); string_free(&_t1); string_free(&indents); return res; } static string indent_v__ast__ScopeObject_str(v__ast__ScopeObject x, int indent_count) { switch(x._typ) { case 418: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ScopeObject("), 0xfe10, {.d_s = indent_v__ast__EmptyScopeObject_str(*(v__ast__EmptyScopeObject*)x._v__ast__EmptyScopeObject, indent_count)}}, {_S(")"), 0, {.d_c = 0 }} })); case 419: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ScopeObject("), 0xfe10, {.d_s = indent_v__ast__AsmRegister_str(*(v__ast__AsmRegister*)x._v__ast__AsmRegister, indent_count)}}, {_S(")"), 0, {.d_c = 0 }} })); case 420: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ScopeObject("), 0xfe10, {.d_s = indent_v__ast__ConstField_str(*(v__ast__ConstField*)x._v__ast__ConstField, indent_count)}}, {_S(")"), 0, {.d_c = 0 }} })); case 421: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ScopeObject("), 0xfe10, {.d_s = indent_v__ast__GlobalField_str(*(v__ast__GlobalField*)x._v__ast__GlobalField, indent_count)}}, {_S(")"), 0, {.d_c = 0 }} })); case 422: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.ScopeObject("), 0xfe10, {.d_s = indent_v__ast__Var_str(*(v__ast__Var*)x._v__ast__Var, indent_count)}}, {_S(")"), 0, {.d_c = 0 }} })); default: return _S("unknown sum type value"); } } static string indent_v__ast__IdentInfo_str(v__ast__IdentInfo x, int indent_count) { switch(x._typ) { case 476: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.IdentInfo("), 0xfe10, {.d_s = indent_v__ast__IdentFn_str(*(v__ast__IdentFn*)x._v__ast__IdentFn, indent_count)}}, {_S(")"), 0, {.d_c = 0 }} })); case 477: return str_intp(2, _MOV((StrIntpData[]){ {_S("ast.IdentInfo("), 0xfe10, {.d_s = indent_v__ast__IdentVar_str(*(v__ast__IdentVar*)x._v__ast__IdentVar, indent_count)}}, {_S(")"), 0, {.d_c = 0 }} })); default: return _S("unknown sum type value"); } } string indent_v__ast__Comment_str(v__ast__Comment it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = indent_v__token__Pos_str(it.pos, indent_count + 1); string res = str_intp( 15, _MOV((StrIntpData[]){ {_S("ast.Comment{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" text: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.text}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_multi: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_multi ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" pos: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t1); string_free(&indents); return res; } string indent_v__ast__EmptyScopeObject_str(v__ast__EmptyScopeObject it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = v__ast__Type_str(it.typ); string res = str_intp( 11, _MOV((StrIntpData[]){ {_S("ast.EmptyScopeObject{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" name: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.name}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" typ: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t1); string_free(&indents); return res; } string indent_v__ast__AsmRegister_str(v__ast__AsmRegister it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = v__ast__Type_str(it.typ); string res = str_intp( 15, _MOV((StrIntpData[]){ {_S("ast.AsmRegister{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" name: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.name}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" typ: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" size: "), 0, {.d_c=0}}, {_S(""), 7, {.d_i32=it.size}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t1); string_free(&indents); return res; } string indent_v__ast__ConstField_str(v__ast__ConstField it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = indent_v__token__Pos_str(it.pos, indent_count + 1); string _t2 = indent_Array_v__ast__Attr_str(it.attrs, indent_count + 1); string _t3 = v__ast__Expr_str(&it.expr); string _t4 = v__ast__Type_str(it.typ); string _t5 = indent_Array_v__ast__Comment_str(it.comments, indent_count + 1); string _t6 = indent_Array_v__ast__Comment_str(it.end_comments, indent_count + 1); string _t7 = indent_v__ast__ComptTimeConstValue_str(it.comptime_expr_value, indent_count + 1); string res = str_intp( 51, _MOV((StrIntpData[]){ {_S("ast.ConstField{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" mod: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.mod}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" name: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.name}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_pub: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_pub ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_markused: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_markused ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" pos: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" attrs: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t2}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_virtual_c: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_virtual_c ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" expr: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t3}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" typ: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t4}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" comments: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t5}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" end_comments: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t6}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" comptime_expr_value: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t7}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t7); string_free(&_t6); string_free(&_t5); string_free(&_t4); string_free(&_t3); string_free(&_t2); string_free(&_t1); string_free(&indents); return res; } string indent_v__ast__GlobalField_str(v__ast__GlobalField it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = indent_v__token__Pos_str(it.pos, indent_count + 1); string _t2 = indent_v__token__Pos_str(it.typ_pos, indent_count + 1); string _t3 = v__ast__Expr_str(&it.expr); string _t4 = v__ast__Type_str(it.typ); string _t5 = indent_Array_v__ast__Comment_str(it.comments, indent_count + 1); string res = str_intp( 43, _MOV((StrIntpData[]){ {_S("ast.GlobalField{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" name: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.name}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" has_expr: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.has_expr ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" pos: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" typ_pos: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t2}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_markused: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_markused ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_volatile: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_volatile ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_exported: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_exported ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" expr: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t3}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" typ: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t4}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" comments: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t5}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t5); string_free(&_t4); string_free(&_t3); string_free(&_t2); string_free(&_t1); string_free(&indents); return res; } string indent_v__ast__Var_str(v__ast__Var it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = v__ast__ShareType_str((it.share)); string _t2 = v__ast__Expr_str(&it.expr); string _t3 = v__ast__Type_str(it.typ); string _t4 = v__ast__Type_str(it.orig_type); string _t5 = indent_Array_v__ast__Type_str(it.smartcasts, indent_count + 1); string _t6 = indent_v__token__Pos_str(it.pos, indent_count + 1); string _t7 = v__ast__ComptimeVarKind_str((it.ct_type_var)); string res = str_intp( 103, _MOV((StrIntpData[]){ {_S("ast.Var{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" name: "), 0, {.d_c=0}}, {_S("'"), 16, {.d_s=it.name}}, {_S("'"), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" share: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_mut: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_mut ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_static: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_static ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_volatile: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_volatile ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_autofree_tmp: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_autofree_tmp ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_inherited: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_inherited ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" has_inherited: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.has_inherited ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_arg: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_arg ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_auto_deref: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_auto_deref ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_unwrapped: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_unwrapped ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_index_var: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_index_var ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" expr: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t2}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" typ: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t3}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" orig_type: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t4}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" smartcasts: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t5}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" pos: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t6}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_used: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_used ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_changed: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_changed ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" ct_type_var: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t7}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" ct_type_unwrapped: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.ct_type_unwrapped ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_or: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_or ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_tmp: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_tmp ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_auto_heap: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_auto_heap ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_stack_obj: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_stack_obj ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t7); string_free(&_t6); string_free(&_t5); string_free(&_t4); string_free(&_t3); string_free(&_t2); string_free(&_t1); string_free(&indents); return res; } string indent_v__ast__IdentFn_str(v__ast__IdentFn it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = v__ast__Type_str(it.typ); string res = str_intp( 7, _MOV((StrIntpData[]){ {_S("ast.IdentFn{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" typ: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t1); string_free(&indents); return res; } string indent_v__ast__IdentVar_str(v__ast__IdentVar it, int indent_count) { string indents = string_repeat(_S(" "), indent_count); string _t1 = v__ast__Type_str(it.typ); string _t2 = v__ast__ShareType_str((it.share)); string res = str_intp( 27, _MOV((StrIntpData[]){ {_S("ast.IdentVar{\n"), 0, {.d_c=0}}, {_SLIT0, 0xfe10, {.d_s=indents}}, {_S(" typ: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t1}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_mut: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_mut ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_static: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_static ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_volatile: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_volatile ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" is_option: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=it.is_option ? _S("true") : _S("false")}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S(" share: "), 0, {.d_c=0}}, {_S(""), 16, {.d_s=_t2}}, {_S(""), 0, {.d_c=0}}, {_S("\n"), 0xfe10, {.d_s=indents}}, {_S("}"), 0, {.d_c=0}}, })); string_free(&_t2); string_free(&_t1); string_free(&indents); return res; } v__ast__Expr v__ast__EmptyExpr_to_sumtype_v__ast__Expr(v__ast__EmptyExpr* x) { v__ast__EmptyExpr* ptr = memdup(x, sizeof(v__ast__EmptyExpr)); return (v__ast__Expr){ ._v__ast__EmptyExpr = ptr, ._typ = 354}; } v__ast__Stmt v__ast__EmptyStmt_to_sumtype_v__ast__Stmt(v__ast__EmptyStmt* x) { v__ast__EmptyStmt* ptr = memdup(x, sizeof(v__ast__EmptyStmt)); return (v__ast__Stmt){ ._v__ast__EmptyStmt = ptr, ._typ = 399, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__EmptyStmt, pos))}; } v__ast__ScopeObject v__ast__EmptyScopeObject_to_sumtype_v__ast__ScopeObject(v__ast__EmptyScopeObject* x) { v__ast__EmptyScopeObject* ptr = memdup(x, sizeof(v__ast__EmptyScopeObject)); return (v__ast__ScopeObject){ ._v__ast__EmptyScopeObject = ptr, ._typ = 418, .name = (string*)((char*)ptr + __offsetof_ptr(ptr, v__ast__EmptyScopeObject, name)), .typ = (v__ast__Type*)((char*)ptr + __offsetof_ptr(ptr, v__ast__EmptyScopeObject, typ))}; } v__ast__ComptTimeConstValue v__ast__EmptyExpr_to_sumtype_v__ast__ComptTimeConstValue(v__ast__EmptyExpr* x) { v__ast__EmptyExpr* ptr = memdup(x, sizeof(v__ast__EmptyExpr)); return (v__ast__ComptTimeConstValue){ ._v__ast__EmptyExpr = ptr, ._typ = 354}; } v__ast__Node v__ast__Expr_to_sumtype_v__ast__Node(v__ast__Expr* x) { v__ast__Expr* ptr = memdup(x, sizeof(v__ast__Expr)); return (v__ast__Node){ ._v__ast__Expr = ptr, ._typ = 389}; } v__ast__Expr v__ast__Ident_to_sumtype_v__ast__Expr(v__ast__Ident* x) { v__ast__Ident* ptr = memdup(x, sizeof(v__ast__Ident)); return (v__ast__Expr){ ._v__ast__Ident = ptr, ._typ = 358}; } v__ast__Node v__ast__Stmt_to_sumtype_v__ast__Node(v__ast__Stmt* x) { v__ast__Stmt* ptr = memdup(x, sizeof(v__ast__Stmt)); return (v__ast__Node){ ._v__ast__Stmt = ptr, ._typ = 416}; } v__ast__Node v__ast__StructInitField_to_sumtype_v__ast__Node(v__ast__StructInitField* x) { v__ast__StructInitField* ptr = memdup(x, sizeof(v__ast__StructInitField)); return (v__ast__Node){ ._v__ast__StructInitField = ptr, ._typ = 432}; } v__ast__Stmt v__ast__FnDecl_to_sumtype_v__ast__Stmt(v__ast__FnDecl* x) { v__ast__FnDecl* ptr = memdup(x, sizeof(v__ast__FnDecl)); return (v__ast__Stmt){ ._v__ast__FnDecl = ptr, ._typ = 237, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__FnDecl, pos))}; } v__ast__Node v__ast__CallArg_to_sumtype_v__ast__Node(v__ast__CallArg* x) { v__ast__CallArg* ptr = memdup(x, sizeof(v__ast__CallArg)); return (v__ast__Node){ ._v__ast__CallArg = ptr, ._typ = 424}; } v__ast__Expr v__ast__OrExpr_to_sumtype_v__ast__Expr(v__ast__OrExpr* x) { v__ast__OrExpr* ptr = memdup(x, sizeof(v__ast__OrExpr)); return (v__ast__Expr){ ._v__ast__OrExpr = ptr, ._typ = 373}; } v__ast__Node v__ast__IfBranch_to_sumtype_v__ast__Node(v__ast__IfBranch* x) { v__ast__IfBranch* ptr = memdup(x, sizeof(v__ast__IfBranch)); return (v__ast__Node){ ._v__ast__IfBranch = ptr, ._typ = 427}; } v__ast__Node v__ast__MatchBranch_to_sumtype_v__ast__Node(v__ast__MatchBranch* x) { v__ast__MatchBranch* ptr = memdup(x, sizeof(v__ast__MatchBranch)); return (v__ast__Node){ ._v__ast__MatchBranch = ptr, ._typ = 428}; } v__ast__Node v__ast__SelectBranch_to_sumtype_v__ast__Node(v__ast__SelectBranch* x) { v__ast__SelectBranch* ptr = memdup(x, sizeof(v__ast__SelectBranch)); return (v__ast__Node){ ._v__ast__SelectBranch = ptr, ._typ = 430}; } v__ast__Node v__ast__StructField_to_sumtype_v__ast__Node(v__ast__StructField* x) { v__ast__StructField* ptr = memdup(x, sizeof(v__ast__StructField)); return (v__ast__Node){ ._v__ast__StructField = ptr, ._typ = 431}; } v__ast__Node v__ast__GlobalField_to_sumtype_v__ast__Node(v__ast__GlobalField* x) { v__ast__GlobalField* ptr = memdup(x, sizeof(v__ast__GlobalField)); return (v__ast__Node){ ._v__ast__GlobalField = ptr, ._typ = 421}; } v__ast__Node v__ast__ConstField_to_sumtype_v__ast__Node(v__ast__ConstField* x) { v__ast__ConstField* ptr = memdup(x, sizeof(v__ast__ConstField)); return (v__ast__Node){ ._v__ast__ConstField = ptr, ._typ = 420}; } v__ast__Node v__ast__EnumField_to_sumtype_v__ast__Node(v__ast__EnumField* x) { v__ast__EnumField* ptr = memdup(x, sizeof(v__ast__EnumField)); return (v__ast__Node){ ._v__ast__EnumField = ptr, ._typ = 426}; } v__ast__Node v__ast__Param_to_sumtype_v__ast__Node(v__ast__Param* x) { v__ast__Param* ptr = memdup(x, sizeof(v__ast__Param)); return (v__ast__Node){ ._v__ast__Param = ptr, ._typ = 429}; } v__ast__Expr v__ast__TypeNode_to_sumtype_v__ast__Expr(v__ast__TypeNode* x) { v__ast__TypeNode* ptr = memdup(x, sizeof(v__ast__TypeNode)); return (v__ast__Expr){ ._v__ast__TypeNode = ptr, ._typ = 386}; } v__ast__ScopeObject v__ast__AsmRegister_to_sumtype_v__ast__ScopeObject(v__ast__AsmRegister* x) { v__ast__AsmRegister* ptr = memdup(x, sizeof(v__ast__AsmRegister)); return (v__ast__ScopeObject){ ._v__ast__AsmRegister = ptr, ._typ = 419, .name = (string*)((char*)ptr + __offsetof_ptr(ptr, v__ast__AsmRegister, name)), .typ = (v__ast__Type*)((char*)ptr + __offsetof_ptr(ptr, v__ast__AsmRegister, typ))}; } v__ast__Expr v__ast__ArrayInit_to_sumtype_v__ast__Expr(v__ast__ArrayInit* x) { v__ast__ArrayInit* ptr = memdup(x, sizeof(v__ast__ArrayInit)); return (v__ast__Expr){ ._v__ast__ArrayInit = ptr, ._typ = 338}; } v__ast__Expr v__ast__StringLiteral_to_sumtype_v__ast__Expr(v__ast__StringLiteral* x) { v__ast__StringLiteral* ptr = memdup(x, sizeof(v__ast__StringLiteral)); return (v__ast__Expr){ ._v__ast__StringLiteral = ptr, ._typ = 384}; } v__ast__Expr v__ast__MapInit_to_sumtype_v__ast__Expr(v__ast__MapInit* x) { v__ast__MapInit* ptr = memdup(x, sizeof(v__ast__MapInit)); return (v__ast__Expr){ ._v__ast__MapInit = ptr, ._typ = 368}; } v__ast__Expr v__ast__StructInit_to_sumtype_v__ast__Expr(v__ast__StructInit* x) { v__ast__StructInit* ptr = memdup(x, sizeof(v__ast__StructInit)); return (v__ast__Expr){ ._v__ast__StructInit = ptr, ._typ = 385}; } v__ast__TypeInfo v__ast__SumType_to_sumtype_v__ast__TypeInfo(v__ast__SumType* x) { v__ast__SumType* ptr = memdup(x, sizeof(v__ast__SumType)); return (v__ast__TypeInfo){ ._v__ast__SumType = ptr, ._typ = 544}; } v__ast__TypeInfo v__ast__Chan_to_sumtype_v__ast__TypeInfo(v__ast__Chan* x) { v__ast__Chan* ptr = memdup(x, sizeof(v__ast__Chan)); return (v__ast__TypeInfo){ ._v__ast__Chan = ptr, ._typ = 550}; } v__ast__TypeInfo v__ast__Map_to_sumtype_v__ast__TypeInfo(v__ast__Map* x) { v__ast__Map* ptr = memdup(x, sizeof(v__ast__Map)); return (v__ast__TypeInfo){ ._v__ast__Map = ptr, ._typ = 514}; } v__ast__TypeInfo v__ast__Thread_to_sumtype_v__ast__TypeInfo(v__ast__Thread* x) { v__ast__Thread* ptr = memdup(x, sizeof(v__ast__Thread)); return (v__ast__TypeInfo){ ._v__ast__Thread = ptr, ._typ = 551}; } v__ast__TypeInfo v__ast__Struct_to_sumtype_v__ast__TypeInfo(v__ast__Struct* x) { v__ast__Struct* ptr = memdup(x, sizeof(v__ast__Struct)); return (v__ast__TypeInfo){ ._v__ast__Struct = ptr, ._typ = 518}; } v__ast__TypeInfo v__ast__Array_to_sumtype_v__ast__TypeInfo(v__ast__Array* x) { v__ast__Array* ptr = memdup(x, sizeof(v__ast__Array)); return (v__ast__TypeInfo){ ._v__ast__Array = ptr, ._typ = 513}; } v__ast__TypeInfo v__ast__ArrayFixed_to_sumtype_v__ast__TypeInfo(v__ast__ArrayFixed* x) { v__ast__ArrayFixed* ptr = memdup(x, sizeof(v__ast__ArrayFixed)); return (v__ast__TypeInfo){ ._v__ast__ArrayFixed = ptr, ._typ = 549}; } v__ast__TypeInfo v__ast__MultiReturn_to_sumtype_v__ast__TypeInfo(v__ast__MultiReturn* x) { v__ast__MultiReturn* ptr = memdup(x, sizeof(v__ast__MultiReturn)); return (v__ast__TypeInfo){ ._v__ast__MultiReturn = ptr, ._typ = 552}; } v__ast__TypeInfo v__ast__FnType_to_sumtype_v__ast__TypeInfo(v__ast__FnType* x) { v__ast__FnType* ptr = memdup(x, sizeof(v__ast__FnType)); return (v__ast__TypeInfo){ ._v__ast__FnType = ptr, ._typ = 553}; } v__ast__Expr v__ast__None_to_sumtype_v__ast__Expr(v__ast__None* x) { v__ast__None* ptr = memdup(x, sizeof(v__ast__None)); return (v__ast__Expr){ ._v__ast__None = ptr, ._typ = 371}; } v__ast__TypeInfo v__ast__Interface_to_sumtype_v__ast__TypeInfo(v__ast__Interface* x) { v__ast__Interface* ptr = memdup(x, sizeof(v__ast__Interface)); return (v__ast__TypeInfo){ ._v__ast__Interface = ptr, ._typ = 542}; } v__ast__Stmt v__ast__AssertStmt_to_sumtype_v__ast__Stmt(v__ast__AssertStmt* x) { v__ast__AssertStmt* ptr = memdup(x, sizeof(v__ast__AssertStmt)); return (v__ast__Stmt){ ._v__ast__AssertStmt = ptr, ._typ = 391, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__AssertStmt, pos))}; } v__ast__Expr v__ast__IfExpr_to_sumtype_v__ast__Expr(v__ast__IfExpr* x) { v__ast__IfExpr* ptr = memdup(x, sizeof(v__ast__IfExpr)); return (v__ast__Expr){ ._v__ast__IfExpr = ptr, ._typ = 359}; } v__ast__Expr v__ast__BoolLiteral_to_sumtype_v__ast__Expr(v__ast__BoolLiteral* x) { v__ast__BoolLiteral* ptr = memdup(x, sizeof(v__ast__BoolLiteral)); return (v__ast__Expr){ ._v__ast__BoolLiteral = ptr, ._typ = 342}; } v__ast__Expr v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(v__ast__IntegerLiteral* x) { v__ast__IntegerLiteral* ptr = memdup(x, sizeof(v__ast__IntegerLiteral)); return (v__ast__Expr){ ._v__ast__IntegerLiteral = ptr, ._typ = 363}; } v__ast__Expr v__ast__FloatLiteral_to_sumtype_v__ast__Expr(v__ast__FloatLiteral* x) { v__ast__FloatLiteral* ptr = memdup(x, sizeof(v__ast__FloatLiteral)); return (v__ast__Expr){ ._v__ast__FloatLiteral = ptr, ._typ = 356}; } v__ast__Expr v__ast__MatchExpr_to_sumtype_v__ast__Expr(v__ast__MatchExpr* x) { v__ast__MatchExpr* ptr = memdup(x, sizeof(v__ast__MatchExpr)); return (v__ast__Expr){ ._v__ast__MatchExpr = ptr, ._typ = 369}; } v__ast__Stmt v__ast__ForCStmt_to_sumtype_v__ast__Stmt(v__ast__ForCStmt* x) { v__ast__ForCStmt* ptr = memdup(x, sizeof(v__ast__ForCStmt)); return (v__ast__Stmt){ ._v__ast__ForCStmt = ptr, ._typ = 402, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__ForCStmt, pos))}; } v__ast__Stmt v__ast__ForStmt_to_sumtype_v__ast__Stmt(v__ast__ForStmt* x) { v__ast__ForStmt* ptr = memdup(x, sizeof(v__ast__ForStmt)); return (v__ast__Stmt){ ._v__ast__ForStmt = ptr, ._typ = 404, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__ForStmt, pos))}; } v__ast__Stmt v__ast__InterfaceDecl_to_sumtype_v__ast__Stmt(v__ast__InterfaceDecl* x) { v__ast__InterfaceDecl* ptr = memdup(x, sizeof(v__ast__InterfaceDecl)); return (v__ast__Stmt){ ._v__ast__InterfaceDecl = ptr, ._typ = 410, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__InterfaceDecl, pos))}; } v__ast__Expr v__ast__CallExpr_to_sumtype_v__ast__Expr(v__ast__CallExpr* x) { v__ast__CallExpr* ptr = memdup(x, sizeof(v__ast__CallExpr)); return (v__ast__Expr){ ._v__ast__CallExpr = ptr, ._typ = 344}; } v__ast__Expr v__ast__InfixExpr_to_sumtype_v__ast__Expr(v__ast__InfixExpr* x) { v__ast__InfixExpr* ptr = memdup(x, sizeof(v__ast__InfixExpr)); return (v__ast__Expr){ ._v__ast__InfixExpr = ptr, ._typ = 362}; } v__ast__Expr v__ast__SqlExpr_to_sumtype_v__ast__Expr(v__ast__SqlExpr* x) { v__ast__SqlExpr* ptr = memdup(x, sizeof(v__ast__SqlExpr)); return (v__ast__Expr){ ._v__ast__SqlExpr = ptr, ._typ = 382}; } v__ast__Stmt v__ast__ExprStmt_to_sumtype_v__ast__Stmt(v__ast__ExprStmt* x) { v__ast__ExprStmt* ptr = memdup(x, sizeof(v__ast__ExprStmt)); return (v__ast__Stmt){ ._v__ast__ExprStmt = ptr, ._typ = 401, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__ExprStmt, pos))}; } v__ast__Stmt v__ast__Block_to_sumtype_v__ast__Stmt(v__ast__Block* x) { v__ast__Block* ptr = memdup(x, sizeof(v__ast__Block)); return (v__ast__Stmt){ ._v__ast__Block = ptr, ._typ = 393, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__Block, pos))}; } v__ast__Expr v__ast__AnonFn_to_sumtype_v__ast__Expr(v__ast__AnonFn* x) { v__ast__AnonFn* ptr = memdup(x, sizeof(v__ast__AnonFn)); return (v__ast__Expr){ ._v__ast__AnonFn = ptr, ._typ = 336}; } v__ast__Expr v__ast__IndexExpr_to_sumtype_v__ast__Expr(v__ast__IndexExpr* x) { v__ast__IndexExpr* ptr = memdup(x, sizeof(v__ast__IndexExpr)); return (v__ast__Expr){ ._v__ast__IndexExpr = ptr, ._typ = 361}; } v__ast__Expr v__ast__PrefixExpr_to_sumtype_v__ast__Expr(v__ast__PrefixExpr* x) { v__ast__PrefixExpr* ptr = memdup(x, sizeof(v__ast__PrefixExpr)); return (v__ast__Expr){ ._v__ast__PrefixExpr = ptr, ._typ = 376}; } v__ast__IdentInfo v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(v__ast__IdentVar* x) { v__ast__IdentVar* ptr = memdup(x, sizeof(v__ast__IdentVar)); return (v__ast__IdentInfo){ ._v__ast__IdentVar = ptr, ._typ = 477, .typ = (v__ast__Type*)((char*)ptr + __offsetof_ptr(ptr, v__ast__IdentVar, typ))}; } v__ast__Expr v__ast__CastExpr_to_sumtype_v__ast__Expr(v__ast__CastExpr* x) { v__ast__CastExpr* ptr = memdup(x, sizeof(v__ast__CastExpr)); return (v__ast__Expr){ ._v__ast__CastExpr = ptr, ._typ = 345}; } v__ast__Stmt v__ast__TypeDecl_to_sumtype_v__ast__Stmt(v__ast__TypeDecl* x) { v__ast__TypeDecl* ptr = memdup(x, sizeof(v__ast__TypeDecl)); return (v__ast__Stmt){ ._v__ast__TypeDecl = ptr, ._typ = 334, .pos = ptr->pos}; } v__ast__TypeDecl v__ast__AliasTypeDecl_to_sumtype_v__ast__TypeDecl(v__ast__AliasTypeDecl* x) { v__ast__AliasTypeDecl* ptr = memdup(x, sizeof(v__ast__AliasTypeDecl)); return (v__ast__TypeDecl){ ._v__ast__AliasTypeDecl = ptr, ._typ = 331, .name = (string*)((char*)ptr + __offsetof_ptr(ptr, v__ast__AliasTypeDecl, name)), .is_pub = (bool*)((char*)ptr + __offsetof_ptr(ptr, v__ast__AliasTypeDecl, is_pub)), .typ = (v__ast__Type*)((char*)ptr + __offsetof_ptr(ptr, v__ast__AliasTypeDecl, typ)), .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__AliasTypeDecl, pos)), .attrs = (Array_v__ast__Attr*)((char*)ptr + __offsetof_ptr(ptr, v__ast__AliasTypeDecl, attrs)), .is_markused = (bool*)((char*)ptr + __offsetof_ptr(ptr, v__ast__AliasTypeDecl, is_markused))}; } v__ast__Expr v__ast__SelectorExpr_to_sumtype_v__ast__Expr(v__ast__SelectorExpr* x) { v__ast__SelectorExpr* ptr = memdup(x, sizeof(v__ast__SelectorExpr)); return (v__ast__Expr){ ._v__ast__SelectorExpr = ptr, ._typ = 379}; } v__ast__AsmArg v__ast__AsmRegister_to_sumtype_v__ast__AsmArg(v__ast__AsmRegister* x) { v__ast__AsmRegister* ptr = memdup(x, sizeof(v__ast__AsmRegister)); return (v__ast__AsmArg){ ._v__ast__AsmRegister = ptr, ._typ = 419}; } v__ast__ScopeObject v__ast__Var_to_sumtype_v__ast__ScopeObject(v__ast__Var* x) { v__ast__Var* ptr = memdup(x, sizeof(v__ast__Var)); return (v__ast__ScopeObject){ ._v__ast__Var = ptr, ._typ = 422, .name = (string*)((char*)ptr + __offsetof_ptr(ptr, v__ast__Var, name)), .typ = (v__ast__Type*)((char*)ptr + __offsetof_ptr(ptr, v__ast__Var, typ))}; } v__ast__IdentInfo v__ast__IdentFn_to_sumtype_v__ast__IdentInfo(v__ast__IdentFn* x) { v__ast__IdentFn* ptr = memdup(x, sizeof(v__ast__IdentFn)); return (v__ast__IdentInfo){ ._v__ast__IdentFn = ptr, ._typ = 476, .typ = (v__ast__Type*)((char*)ptr + __offsetof_ptr(ptr, v__ast__IdentFn, typ))}; } v__ast__ScopeObject v__ast__ConstField_to_sumtype_v__ast__ScopeObject(v__ast__ConstField* x) { v__ast__ConstField* ptr = memdup(x, sizeof(v__ast__ConstField)); return (v__ast__ScopeObject){ ._v__ast__ConstField = ptr, ._typ = 420, .name = (string*)((char*)ptr + __offsetof_ptr(ptr, v__ast__ConstField, name)), .typ = (v__ast__Type*)((char*)ptr + __offsetof_ptr(ptr, v__ast__ConstField, typ))}; } v__ast__Expr v__ast__ComptimeCall_to_sumtype_v__ast__Expr(v__ast__ComptimeCall* x) { v__ast__ComptimeCall* ptr = memdup(x, sizeof(v__ast__ComptimeCall)); return (v__ast__Expr){ ._v__ast__ComptimeCall = ptr, ._typ = 349}; } v__ast__ComptTimeConstValue i64_to_sumtype_v__ast__ComptTimeConstValue(i64* x) { i64* ptr = memdup(x, sizeof(i64)); return (v__ast__ComptTimeConstValue){ ._i64 = ptr, ._typ = 9}; } v__ast__ComptTimeConstValue f64_to_sumtype_v__ast__ComptTimeConstValue(f64* x) { f64* ptr = memdup(x, sizeof(f64)); return (v__ast__ComptTimeConstValue){ ._f64 = ptr, ._typ = 17}; } v__ast__ComptTimeConstValue u64_to_sumtype_v__ast__ComptTimeConstValue(u64* x) { u64* ptr = memdup(x, sizeof(u64)); return (v__ast__ComptTimeConstValue){ ._u64 = ptr, ._typ = 14}; } v__ast__ComptTimeConstValue string_to_sumtype_v__ast__ComptTimeConstValue(string* x) { string* ptr = memdup(x, sizeof(string)); return (v__ast__ComptTimeConstValue){ ._string = ptr, ._typ = 21}; } v__ast__ComptTimeConstValue rune_to_sumtype_v__ast__ComptTimeConstValue(rune* x) { rune* ptr = memdup(x, sizeof(rune)); return (v__ast__ComptTimeConstValue){ ._rune = ptr, ._typ = 22}; } v__ast__ComptTimeConstValue i32_to_sumtype_v__ast__ComptTimeConstValue(i32* x) { i32* ptr = memdup(x, sizeof(i32)); return (v__ast__ComptTimeConstValue){ ._i32 = ptr, ._typ = 7}; } v__ast__ComptTimeConstValue i8_to_sumtype_v__ast__ComptTimeConstValue(i8* x) { i8* ptr = memdup(x, sizeof(i8)); return (v__ast__ComptTimeConstValue){ ._i8 = ptr, ._typ = 5}; } v__ast__ComptTimeConstValue i16_to_sumtype_v__ast__ComptTimeConstValue(i16* x) { i16* ptr = memdup(x, sizeof(i16)); return (v__ast__ComptTimeConstValue){ ._i16 = ptr, ._typ = 6}; } v__ast__ComptTimeConstValue u8_to_sumtype_v__ast__ComptTimeConstValue(u8* x) { u8* ptr = memdup(x, sizeof(u8)); return (v__ast__ComptTimeConstValue){ ._u8 = ptr, ._typ = 11}; } v__ast__ComptTimeConstValue u16_to_sumtype_v__ast__ComptTimeConstValue(u16* x) { u16* ptr = memdup(x, sizeof(u16)); return (v__ast__ComptTimeConstValue){ ._u16 = ptr, ._typ = 12}; } v__ast__ComptTimeConstValue u32_to_sumtype_v__ast__ComptTimeConstValue(u32* x) { u32* ptr = memdup(x, sizeof(u32)); return (v__ast__ComptTimeConstValue){ ._u32 = ptr, ._typ = 13}; } v__ast__ComptTimeConstValue f32_to_sumtype_v__ast__ComptTimeConstValue(f32* x) { f32* ptr = memdup(x, sizeof(f32)); return (v__ast__ComptTimeConstValue){ ._f32 = ptr, ._typ = 16}; } v__ast__ComptTimeConstValue voidptr_to_sumtype_v__ast__ComptTimeConstValue(voidptr* x) { voidptr* ptr = memdup(x, sizeof(voidptr)); return (v__ast__ComptTimeConstValue){ ._voidptr = ptr, ._typ = 2}; } v__ast__Stmt v__ast__Return_to_sumtype_v__ast__Stmt(v__ast__Return* x) { v__ast__Return* ptr = memdup(x, sizeof(v__ast__Return)); return (v__ast__Stmt){ ._v__ast__Return = ptr, ._typ = 412, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__Return, pos))}; } v__ast__Expr v__ast__AsCast_to_sumtype_v__ast__Expr(v__ast__AsCast* x) { v__ast__AsCast* ptr = memdup(x, sizeof(v__ast__AsCast)); return (v__ast__Expr){ ._v__ast__AsCast = ptr, ._typ = 339}; } v__ast__Expr v__ast__ParExpr_to_sumtype_v__ast__Expr(v__ast__ParExpr* x) { v__ast__ParExpr* ptr = memdup(x, sizeof(v__ast__ParExpr)); return (v__ast__Expr){ ._v__ast__ParExpr = ptr, ._typ = 374}; } v__ast__TypeInfo v__ast__Aggregate_to_sumtype_v__ast__TypeInfo(v__ast__Aggregate* x) { v__ast__Aggregate* ptr = memdup(x, sizeof(v__ast__Aggregate)); return (v__ast__TypeInfo){ ._v__ast__Aggregate = ptr, ._typ = 537}; } v__checker__ORMExpr v__ast__SqlExpr_to_sumtype_v__checker__ORMExpr(v__ast__SqlExpr* x) { v__ast__SqlExpr* ptr = memdup(x, sizeof(v__ast__SqlExpr)); return (v__checker__ORMExpr){ ._v__ast__SqlExpr = ptr, ._typ = 382, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SqlExpr, pos)), .db_expr = (v__ast__Expr*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SqlExpr, db_expr)), .or_expr = (v__ast__OrExpr*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SqlExpr, or_expr))}; } v__checker__ORMExpr v__ast__SqlStmt_to_sumtype_v__checker__ORMExpr(v__ast__SqlStmt* x) { v__ast__SqlStmt* ptr = memdup(x, sizeof(v__ast__SqlStmt)); return (v__checker__ORMExpr){ ._v__ast__SqlStmt = ptr, ._typ = 414, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SqlStmt, pos)), .db_expr = (v__ast__Expr*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SqlStmt, db_expr)), .or_expr = (v__ast__OrExpr*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SqlStmt, or_expr))}; } v__ast__Expr v__ast__PostfixExpr_to_sumtype_v__ast__Expr(v__ast__PostfixExpr* x) { v__ast__PostfixExpr* ptr = memdup(x, sizeof(v__ast__PostfixExpr)); return (v__ast__Expr){ ._v__ast__PostfixExpr = ptr, ._typ = 375}; } v__ast__AsmArg string_to_sumtype_v__ast__AsmArg(string* x) { string* ptr = memdup(x, sizeof(string)); return (v__ast__AsmArg){ ._string = ptr, ._typ = 21}; } v__ast__AsmArg v__ast__FloatLiteral_to_sumtype_v__ast__AsmArg(v__ast__FloatLiteral* x) { v__ast__FloatLiteral* ptr = memdup(x, sizeof(v__ast__FloatLiteral)); return (v__ast__AsmArg){ ._v__ast__FloatLiteral = ptr, ._typ = 356}; } v__ast__AsmArg v__ast__AsmDisp_to_sumtype_v__ast__AsmArg(v__ast__AsmDisp* x) { v__ast__AsmDisp* ptr = memdup(x, sizeof(v__ast__AsmDisp)); return (v__ast__AsmArg){ ._v__ast__AsmDisp = ptr, ._typ = 498}; } v__ast__AsmArg v__ast__IntegerLiteral_to_sumtype_v__ast__AsmArg(v__ast__IntegerLiteral* x) { v__ast__IntegerLiteral* ptr = memdup(x, sizeof(v__ast__IntegerLiteral)); return (v__ast__AsmArg){ ._v__ast__IntegerLiteral = ptr, ._typ = 363}; } v__ast__AsmArg v__ast__CharLiteral_to_sumtype_v__ast__AsmArg(v__ast__CharLiteral* x) { v__ast__CharLiteral* ptr = memdup(x, sizeof(v__ast__CharLiteral)); return (v__ast__AsmArg){ ._v__ast__CharLiteral = ptr, ._typ = 347}; } v__ast__AsmArg v__ast__AsmAddressing_to_sumtype_v__ast__AsmArg(v__ast__AsmAddressing* x) { v__ast__AsmAddressing* ptr = memdup(x, sizeof(v__ast__AsmAddressing)); return (v__ast__AsmArg){ ._v__ast__AsmAddressing = ptr, ._typ = 496}; } v__ast__AsmArg v__ast__AsmAlias_to_sumtype_v__ast__AsmArg(v__ast__AsmAlias* x) { v__ast__AsmAlias* ptr = memdup(x, sizeof(v__ast__AsmAlias)); return (v__ast__AsmArg){ ._v__ast__AsmAlias = ptr, ._typ = 497}; } v__ast__Stmt v__ast__NodeError_to_sumtype_v__ast__Stmt(v__ast__NodeError* x) { v__ast__NodeError* ptr = memdup(x, sizeof(v__ast__NodeError)); return (v__ast__Stmt){ ._v__ast__NodeError = ptr, ._typ = 335, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__NodeError, pos))}; } v__ast__Stmt v__ast__AssignStmt_to_sumtype_v__ast__Stmt(v__ast__AssignStmt* x) { v__ast__AssignStmt* ptr = memdup(x, sizeof(v__ast__AssignStmt)); return (v__ast__Stmt){ ._v__ast__AssignStmt = ptr, ._typ = 392, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__AssignStmt, pos))}; } v__ast__Expr v__ast__ComptimeSelector_to_sumtype_v__ast__Expr(v__ast__ComptimeSelector* x) { v__ast__ComptimeSelector* ptr = memdup(x, sizeof(v__ast__ComptimeSelector)); return (v__ast__Expr){ ._v__ast__ComptimeSelector = ptr, ._typ = 350}; } v__ast__TypeInfo v__ast__Enum_to_sumtype_v__ast__TypeInfo(v__ast__Enum* x) { v__ast__Enum* ptr = memdup(x, sizeof(v__ast__Enum)); return (v__ast__TypeInfo){ ._v__ast__Enum = ptr, ._typ = 548}; } v__ast__Expr v__ast__NodeError_to_sumtype_v__ast__Expr(v__ast__NodeError* x) { v__ast__NodeError* ptr = memdup(x, sizeof(v__ast__NodeError)); return (v__ast__Expr){ ._v__ast__NodeError = ptr, ._typ = 335}; } v__ast__Expr v__ast__Comment_to_sumtype_v__ast__Expr(v__ast__Comment* x) { v__ast__Comment* ptr = memdup(x, sizeof(v__ast__Comment)); return (v__ast__Expr){ ._v__ast__Comment = ptr, ._typ = 348}; } v__ast__Expr v__ast__EnumVal_to_sumtype_v__ast__Expr(v__ast__EnumVal* x) { v__ast__EnumVal* ptr = memdup(x, sizeof(v__ast__EnumVal)); return (v__ast__Expr){ ._v__ast__EnumVal = ptr, ._typ = 355}; } v__ast__Expr v__ast__AtExpr_to_sumtype_v__ast__Expr(v__ast__AtExpr* x) { v__ast__AtExpr* ptr = memdup(x, sizeof(v__ast__AtExpr)); return (v__ast__Expr){ ._v__ast__AtExpr = ptr, ._typ = 341}; } v__ast__Expr v__ast__ComptimeType_to_sumtype_v__ast__Expr(v__ast__ComptimeType* x) { v__ast__ComptimeType* ptr = memdup(x, sizeof(v__ast__ComptimeType)); return (v__ast__Expr){ ._v__ast__ComptimeType = ptr, ._typ = 351}; } v__ast__Expr v__ast__CharLiteral_to_sumtype_v__ast__Expr(v__ast__CharLiteral* x) { v__ast__CharLiteral* ptr = memdup(x, sizeof(v__ast__CharLiteral)); return (v__ast__Expr){ ._v__ast__CharLiteral = ptr, ._typ = 347}; } v__ast__Expr v__ast__GoExpr_to_sumtype_v__ast__Expr(v__ast__GoExpr* x) { v__ast__GoExpr* ptr = memdup(x, sizeof(v__ast__GoExpr)); return (v__ast__Expr){ ._v__ast__GoExpr = ptr, ._typ = 357}; } v__ast__Expr v__ast__SpawnExpr_to_sumtype_v__ast__Expr(v__ast__SpawnExpr* x) { v__ast__SpawnExpr* ptr = memdup(x, sizeof(v__ast__SpawnExpr)); return (v__ast__Expr){ ._v__ast__SpawnExpr = ptr, ._typ = 381}; } v__ast__Expr v__ast__SelectExpr_to_sumtype_v__ast__Expr(v__ast__SelectExpr* x) { v__ast__SelectExpr* ptr = memdup(x, sizeof(v__ast__SelectExpr)); return (v__ast__Expr){ ._v__ast__SelectExpr = ptr, ._typ = 378}; } v__ast__Expr v__ast__Nil_to_sumtype_v__ast__Expr(v__ast__Nil* x) { v__ast__Nil* ptr = memdup(x, sizeof(v__ast__Nil)); return (v__ast__Expr){ ._v__ast__Nil = ptr, ._typ = 370}; } v__ast__Expr v__ast__UnsafeExpr_to_sumtype_v__ast__Expr(v__ast__UnsafeExpr* x) { v__ast__UnsafeExpr* ptr = memdup(x, sizeof(v__ast__UnsafeExpr)); return (v__ast__Expr){ ._v__ast__UnsafeExpr = ptr, ._typ = 388}; } v__ast__Expr v__ast__LambdaExpr_to_sumtype_v__ast__Expr(v__ast__LambdaExpr* x) { v__ast__LambdaExpr* ptr = memdup(x, sizeof(v__ast__LambdaExpr)); return (v__ast__Expr){ ._v__ast__LambdaExpr = ptr, ._typ = 365}; } v__ast__Expr v__ast__LockExpr_to_sumtype_v__ast__Expr(v__ast__LockExpr* x) { v__ast__LockExpr* ptr = memdup(x, sizeof(v__ast__LockExpr)); return (v__ast__Expr){ ._v__ast__LockExpr = ptr, ._typ = 367}; } v__ast__Expr v__ast__TypeOf_to_sumtype_v__ast__Expr(v__ast__TypeOf* x) { v__ast__TypeOf* ptr = memdup(x, sizeof(v__ast__TypeOf)); return (v__ast__Expr){ ._v__ast__TypeOf = ptr, ._typ = 387}; } v__ast__Expr v__ast__IsRefType_to_sumtype_v__ast__Expr(v__ast__IsRefType* x) { v__ast__IsRefType* ptr = memdup(x, sizeof(v__ast__IsRefType)); return (v__ast__Expr){ ._v__ast__IsRefType = ptr, ._typ = 364}; } v__ast__Expr v__ast__SizeOf_to_sumtype_v__ast__Expr(v__ast__SizeOf* x) { v__ast__SizeOf* ptr = memdup(x, sizeof(v__ast__SizeOf)); return (v__ast__Expr){ ._v__ast__SizeOf = ptr, ._typ = 380}; } v__ast__Expr v__ast__DumpExpr_to_sumtype_v__ast__Expr(v__ast__DumpExpr* x) { v__ast__DumpExpr* ptr = memdup(x, sizeof(v__ast__DumpExpr)); return (v__ast__Expr){ ._v__ast__DumpExpr = ptr, ._typ = 353}; } v__ast__Expr v__ast__OffsetOf_to_sumtype_v__ast__Expr(v__ast__OffsetOf* x) { v__ast__OffsetOf* ptr = memdup(x, sizeof(v__ast__OffsetOf)); return (v__ast__Expr){ ._v__ast__OffsetOf = ptr, ._typ = 372}; } v__ast__Expr v__ast__Likely_to_sumtype_v__ast__Expr(v__ast__Likely* x) { v__ast__Likely* ptr = memdup(x, sizeof(v__ast__Likely)); return (v__ast__Expr){ ._v__ast__Likely = ptr, ._typ = 366}; } v__ast__Stmt v__ast__StructDecl_to_sumtype_v__ast__Stmt(v__ast__StructDecl* x) { v__ast__StructDecl* ptr = memdup(x, sizeof(v__ast__StructDecl)); return (v__ast__Stmt){ ._v__ast__StructDecl = ptr, ._typ = 415, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__StructDecl, pos))}; } v__ast__Expr v__ast__RangeExpr_to_sumtype_v__ast__Expr(v__ast__RangeExpr* x) { v__ast__RangeExpr* ptr = memdup(x, sizeof(v__ast__RangeExpr)); return (v__ast__Expr){ ._v__ast__RangeExpr = ptr, ._typ = 377}; } v__ast__Expr v__ast__ArrayDecompose_to_sumtype_v__ast__Expr(v__ast__ArrayDecompose* x) { v__ast__ArrayDecompose* ptr = memdup(x, sizeof(v__ast__ArrayDecompose)); return (v__ast__Expr){ ._v__ast__ArrayDecompose = ptr, ._typ = 337}; } v__ast__Stmt v__ast__ForInStmt_to_sumtype_v__ast__Stmt(v__ast__ForInStmt* x) { v__ast__ForInStmt* ptr = memdup(x, sizeof(v__ast__ForInStmt)); return (v__ast__Stmt){ ._v__ast__ForInStmt = ptr, ._typ = 403, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__ForInStmt, pos))}; } v__ast__Expr v__ast__IfGuardExpr_to_sumtype_v__ast__Expr(v__ast__IfGuardExpr* x) { v__ast__IfGuardExpr* ptr = memdup(x, sizeof(v__ast__IfGuardExpr)); return (v__ast__Expr){ ._v__ast__IfGuardExpr = ptr, ._typ = 360}; } v__ast__TypeInfo v__ast__GenericInst_to_sumtype_v__ast__TypeInfo(v__ast__GenericInst* x) { v__ast__GenericInst* ptr = memdup(x, sizeof(v__ast__GenericInst)); return (v__ast__TypeInfo){ ._v__ast__GenericInst = ptr, ._typ = 555}; } v__ast__Stmt v__ast__Module_to_sumtype_v__ast__Stmt(v__ast__Module* x) { v__ast__Module* ptr = memdup(x, sizeof(v__ast__Module)); return (v__ast__Stmt){ ._v__ast__Module = ptr, ._typ = 411, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__Module, pos))}; } v__ast__Stmt v__ast__Import_to_sumtype_v__ast__Stmt(v__ast__Import* x) { v__ast__Import* ptr = memdup(x, sizeof(v__ast__Import)); return (v__ast__Stmt){ ._v__ast__Import = ptr, ._typ = 409, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__Import, pos))}; } v__ast__Stmt v__ast__ConstDecl_to_sumtype_v__ast__Stmt(v__ast__ConstDecl* x) { v__ast__ConstDecl* ptr = memdup(x, sizeof(v__ast__ConstDecl)); return (v__ast__Stmt){ ._v__ast__ConstDecl = ptr, ._typ = 396, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__ConstDecl, pos))}; } v__ast__Stmt v__ast__EnumDecl_to_sumtype_v__ast__Stmt(v__ast__EnumDecl* x) { v__ast__EnumDecl* ptr = memdup(x, sizeof(v__ast__EnumDecl)); return (v__ast__Stmt){ ._v__ast__EnumDecl = ptr, ._typ = 400, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__EnumDecl, pos))}; } v__ast__Stmt v__ast__GlobalDecl_to_sumtype_v__ast__Stmt(v__ast__GlobalDecl* x) { v__ast__GlobalDecl* ptr = memdup(x, sizeof(v__ast__GlobalDecl)); return (v__ast__Stmt){ ._v__ast__GlobalDecl = ptr, ._typ = 405, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__GlobalDecl, pos))}; } v__ast__Stmt v__ast__ComptimeFor_to_sumtype_v__ast__Stmt(v__ast__ComptimeFor* x) { v__ast__ComptimeFor* ptr = memdup(x, sizeof(v__ast__ComptimeFor)); return (v__ast__Stmt){ ._v__ast__ComptimeFor = ptr, ._typ = 395, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__ComptimeFor, pos))}; } v__ast__Stmt v__ast__HashStmt_to_sumtype_v__ast__Stmt(v__ast__HashStmt* x) { v__ast__HashStmt* ptr = memdup(x, sizeof(v__ast__HashStmt)); return (v__ast__Stmt){ ._v__ast__HashStmt = ptr, ._typ = 408, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__HashStmt, pos))}; } v__ast__Stmt v__ast__SemicolonStmt_to_sumtype_v__ast__Stmt(v__ast__SemicolonStmt* x) { v__ast__SemicolonStmt* ptr = memdup(x, sizeof(v__ast__SemicolonStmt)); return (v__ast__Stmt){ ._v__ast__SemicolonStmt = ptr, ._typ = 413, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SemicolonStmt, pos))}; } v__ast__Stmt v__ast__AsmStmt_to_sumtype_v__ast__Stmt(v__ast__AsmStmt* x) { v__ast__AsmStmt* ptr = memdup(x, sizeof(v__ast__AsmStmt)); return (v__ast__Stmt){ ._v__ast__AsmStmt = ptr, ._typ = 390, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__AsmStmt, pos))}; } v__ast__Stmt v__ast__SqlStmt_to_sumtype_v__ast__Stmt(v__ast__SqlStmt* x) { v__ast__SqlStmt* ptr = memdup(x, sizeof(v__ast__SqlStmt)); return (v__ast__Stmt){ ._v__ast__SqlStmt = ptr, ._typ = 414, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SqlStmt, pos))}; } v__ast__Stmt v__ast__GotoLabel_to_sumtype_v__ast__Stmt(v__ast__GotoLabel* x) { v__ast__GotoLabel* ptr = memdup(x, sizeof(v__ast__GotoLabel)); return (v__ast__Stmt){ ._v__ast__GotoLabel = ptr, ._typ = 406, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__GotoLabel, pos))}; } v__ast__Stmt v__ast__DebuggerStmt_to_sumtype_v__ast__Stmt(v__ast__DebuggerStmt* x) { v__ast__DebuggerStmt* ptr = memdup(x, sizeof(v__ast__DebuggerStmt)); return (v__ast__Stmt){ ._v__ast__DebuggerStmt = ptr, ._typ = 397, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__DebuggerStmt, pos))}; } v__ast__Stmt v__ast__BranchStmt_to_sumtype_v__ast__Stmt(v__ast__BranchStmt* x) { v__ast__BranchStmt* ptr = memdup(x, sizeof(v__ast__BranchStmt)); return (v__ast__Stmt){ ._v__ast__BranchStmt = ptr, ._typ = 394, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__BranchStmt, pos))}; } v__ast__Stmt v__ast__DeferStmt_to_sumtype_v__ast__Stmt(v__ast__DeferStmt* x) { v__ast__DeferStmt* ptr = memdup(x, sizeof(v__ast__DeferStmt)); return (v__ast__Stmt){ ._v__ast__DeferStmt = ptr, ._typ = 398, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__DeferStmt, pos))}; } v__ast__Stmt v__ast__GotoStmt_to_sumtype_v__ast__Stmt(v__ast__GotoStmt* x) { v__ast__GotoStmt* ptr = memdup(x, sizeof(v__ast__GotoStmt)); return (v__ast__Stmt){ ._v__ast__GotoStmt = ptr, ._typ = 407, .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__GotoStmt, pos))}; } v__ast__Expr v__ast__ConcatExpr_to_sumtype_v__ast__Expr(v__ast__ConcatExpr* x) { v__ast__ConcatExpr* ptr = memdup(x, sizeof(v__ast__ConcatExpr)); return (v__ast__Expr){ ._v__ast__ConcatExpr = ptr, ._typ = 352}; } v__ast__Expr v__ast__ChanInit_to_sumtype_v__ast__Expr(v__ast__ChanInit* x) { v__ast__ChanInit* ptr = memdup(x, sizeof(v__ast__ChanInit)); return (v__ast__Expr){ ._v__ast__ChanInit = ptr, ._typ = 346}; } v__ast__Expr v__ast__StringInterLiteral_to_sumtype_v__ast__Expr(v__ast__StringInterLiteral* x) { v__ast__StringInterLiteral* ptr = memdup(x, sizeof(v__ast__StringInterLiteral)); return (v__ast__Expr){ ._v__ast__StringInterLiteral = ptr, ._typ = 383}; } v__ast__ScopeObject v__ast__GlobalField_to_sumtype_v__ast__ScopeObject(v__ast__GlobalField* x) { v__ast__GlobalField* ptr = memdup(x, sizeof(v__ast__GlobalField)); return (v__ast__ScopeObject){ ._v__ast__GlobalField = ptr, ._typ = 421, .name = (string*)((char*)ptr + __offsetof_ptr(ptr, v__ast__GlobalField, name)), .typ = (v__ast__Type*)((char*)ptr + __offsetof_ptr(ptr, v__ast__GlobalField, typ))}; } v__ast__TypeDecl v__ast__SumTypeDecl_to_sumtype_v__ast__TypeDecl(v__ast__SumTypeDecl* x) { v__ast__SumTypeDecl* ptr = memdup(x, sizeof(v__ast__SumTypeDecl)); return (v__ast__TypeDecl){ ._v__ast__SumTypeDecl = ptr, ._typ = 333, .name = (string*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SumTypeDecl, name)), .is_pub = (bool*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SumTypeDecl, is_pub)), .typ = (v__ast__Type*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SumTypeDecl, typ)), .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SumTypeDecl, pos)), .attrs = (Array_v__ast__Attr*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SumTypeDecl, attrs)), .is_markused = (bool*)((char*)ptr + __offsetof_ptr(ptr, v__ast__SumTypeDecl, is_markused))}; } v__ast__TypeDecl v__ast__FnTypeDecl_to_sumtype_v__ast__TypeDecl(v__ast__FnTypeDecl* x) { v__ast__FnTypeDecl* ptr = memdup(x, sizeof(v__ast__FnTypeDecl)); return (v__ast__TypeDecl){ ._v__ast__FnTypeDecl = ptr, ._typ = 332, .name = (string*)((char*)ptr + __offsetof_ptr(ptr, v__ast__FnTypeDecl, name)), .is_pub = (bool*)((char*)ptr + __offsetof_ptr(ptr, v__ast__FnTypeDecl, is_pub)), .typ = (v__ast__Type*)((char*)ptr + __offsetof_ptr(ptr, v__ast__FnTypeDecl, typ)), .pos = (v__token__Pos*)((char*)ptr + __offsetof_ptr(ptr, v__ast__FnTypeDecl, pos)), .attrs = (Array_v__ast__Attr*)((char*)ptr + __offsetof_ptr(ptr, v__ast__FnTypeDecl, attrs)), .is_markused = (bool*)((char*)ptr + __offsetof_ptr(ptr, v__ast__FnTypeDecl, is_markused))}; } v__ast__TypeInfo v__ast__Alias_to_sumtype_v__ast__TypeInfo(v__ast__Alias* x) { v__ast__Alias* ptr = memdup(x, sizeof(v__ast__Alias)); return (v__ast__TypeInfo){ ._v__ast__Alias = ptr, ._typ = 539}; } v__ast__Node v__ast__File_to_sumtype_v__ast__Node(v__ast__File* x) { v__ast__File* ptr = memdup(x, sizeof(v__ast__File)); return (v__ast__Node){ ._v__ast__File = ptr, ._typ = 228}; } v__ast__Expr v__ast__CTempVar_to_sumtype_v__ast__Expr(v__ast__CTempVar* x) { v__ast__CTempVar* ptr = memdup(x, sizeof(v__ast__CTempVar)); return (v__ast__Expr){ ._v__ast__CTempVar = ptr, ._typ = 343}; } static bool Array_u8_contains(Array_u8 a, u8 v) { for (int i = 0; i < a.len; ++i) { if (((u8*)a.data)[i] == v) { return true; } } return false; } static bool Array_string_contains(Array_string a, string v) { for (int i = 0; i < a.len; ++i) { if (fast_string_eq(((string*)a.data)[i], v)) { return true; } } return false; } static bool Array_v__token__Kind_contains(Array_v__token__Kind a, v__token__Kind v) { for (int i = 0; i < a.len; ++i) { if (((v__token__Kind*)a.data)[i] == v) { return true; } } return false; } static bool Array_fixed_string_8_contains(Array_fixed_string_8 a, string v) { for (int i = 0; i < 8; ++i) { if (fast_string_eq(a[i], v)) { return true; } } return false; } static bool Array_Array_v__ast__Type_contains(Array_Array_v__ast__Type a, Array_v__ast__Type v) { for (int i = 0; i < a.len; ++i) { if (Array_v__ast__Type_arr_eq(((Array_v__ast__Type*)a.data)[i], v)) { return true; } } return false; } static bool Array_v__ast__Type_contains(Array_v__ast__Type a, v__ast__Type v) { for (int i = 0; i < a.len; ++i) { if (((v__ast__Type*)a.data)[i] == v) { return true; } } return false; } static bool Array_v__ast__Kind_contains(Array_v__ast__Kind a, v__ast__Kind v) { for (int i = 0; i < a.len; ++i) { if (((v__ast__Kind*)a.data)[i] == v) { return true; } } return false; } static bool Array_int_contains(Array_int a, int v) { for (int i = 0; i < a.len; ++i) { if (((int*)a.data)[i] == v) { return true; } } return false; } static bool Array_rune_contains(Array_rune a, rune v) { for (int i = 0; i < a.len; ++i) { if (((rune*)a.data)[i] == v) { return true; } } return false; } static bool Array_i64_contains(Array_i64 a, i64 v) { for (int i = 0; i < a.len; ++i) { if (((i64*)a.data)[i] == v) { return true; } } return false; } static bool Array_u64_contains(Array_u64 a, u64 v) { for (int i = 0; i < a.len; ++i) { if (((u64*)a.data)[i] == v) { return true; } } return false; } static bool Array_v__gen__c__StrType_contains(Array_v__gen__c__StrType a, v__gen__c__StrType v) { for (int i = 0; i < a.len; ++i) { if (v__gen__c__StrType_struct_eq(((v__gen__c__StrType*)a.data)[i], v)) { return true; } } return false; } static bool Array_v__gen__c__SumtypeCastingFn_contains(Array_v__gen__c__SumtypeCastingFn a, v__gen__c__SumtypeCastingFn v) { for (int i = 0; i < a.len; ++i) { if (v__gen__c__SumtypeCastingFn_struct_eq(((v__gen__c__SumtypeCastingFn*)a.data)[i], v)) { return true; } } return false; } static bool Array_v__ast__EmbeddedFile_contains(Array_v__ast__EmbeddedFile a, v__ast__EmbeddedFile v) { for (int i = 0; i < a.len; ++i) { if (v__ast__EmbeddedFile_struct_eq(((v__ast__EmbeddedFile*)a.data)[i], v)) { return true; } } return false; } static bool Array_v__ast__TypeSymbol_ptr_contains(Array_v__ast__TypeSymbol_ptr a, v__ast__TypeSymbol* v) { for (int i = 0; i < a.len; ++i) { if (((v__ast__TypeSymbol**)a.data)[i] == v) { return true; } } return false; } static int Array_string_index(Array_string a, string v) { string* pelem = a.data; for (int i = 0; i < a.len; ++i, ++pelem) { if (fast_string_eq(*pelem, v)) { return i; } } return -1; } static int Array_v__ast__StructField_index(Array_v__ast__StructField a, v__ast__StructField v) { v__ast__StructField* pelem = a.data; for (int i = 0; i < a.len; ++i, ++pelem) { if (v__ast__StructField_struct_eq(*pelem, v)) { return i; } } return -1; } static int Array_int_index(Array_int a, int v) { int* pelem = a.data; for (int i = 0; i < a.len; ++i, ++pelem) { if (*pelem == v) { return i; } } return -1; } inline bool Array_string_arr_eq(Array_string a, Array_string b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!string__eq(*((string*)((byte*)a.data+(i*a.element_size))), *((string*)((byte*)b.data+(i*b.element_size))))) { return false; } } return true; } inline bool v__ast__Type_alias_eq(v__ast__Type a, v__ast__Type b) { return a == b; } inline bool Array_v__ast__Type_arr_eq(Array_v__ast__Type a, Array_v__ast__Type b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (((v__ast__Type*)a.data)[i] != ((v__ast__Type*)b.data)[i]) { return false; } } return true; } inline bool v__token__Pos_struct_eq(v__token__Pos a, v__token__Pos b) { return a.len == b.len && a.line_nr == b.line_nr && a.pos == b.pos && a.col == b.col && a.last_line == b.last_line; } inline bool v__ast__AsmRegister_struct_eq(v__ast__AsmRegister a, v__ast__AsmRegister b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.typ == b.typ && a.size == b.size; } inline bool v__ast__Comment_struct_eq(v__ast__Comment a, v__ast__Comment b) { return ((a.text.len == b.text.len && a.text.len == 0) || fast_string_eq(a.text, b.text)) && a.is_multi == b.is_multi && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool Array_v__ast__Comment_arr_eq(Array_v__ast__Comment a, Array_v__ast__Comment b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__Comment_struct_eq(((v__ast__Comment*)a.data)[i], ((v__ast__Comment*)b.data)[i])) { return false; } } return true; } inline bool v__ast__AsmClobbered_struct_eq(v__ast__AsmClobbered a, v__ast__AsmClobbered b) { return v__ast__AsmRegister_struct_eq(a.reg, b.reg) && Array_v__ast__Comment_arr_eq(a.comments, b.comments); } inline bool Array_v__ast__AsmClobbered_arr_eq(Array_v__ast__AsmClobbered a, Array_v__ast__AsmClobbered b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__AsmClobbered_struct_eq(((v__ast__AsmClobbered*)a.data)[i], ((v__ast__AsmClobbered*)b.data)[i])) { return false; } } return true; } inline bool v__ast__AsmAddressing_struct_eq(v__ast__AsmAddressing a, v__ast__AsmAddressing b) { return a.scale == b.scale && a.mode == b.mode && v__token__Pos_struct_eq(a.pos, b.pos) && ((a.segment.len == b.segment.len && a.segment.len == 0) || fast_string_eq(a.segment, b.segment)) && v__ast__AsmArg_sumtype_eq(a.displacement, b.displacement) && v__ast__AsmArg_sumtype_eq(a.base, b.base) && v__ast__AsmArg_sumtype_eq(a.index, b.index); } inline bool v__ast__AsmAlias_struct_eq(v__ast__AsmAlias a, v__ast__AsmAlias b) { return v__token__Pos_struct_eq(a.pos, b.pos) && ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)); } inline bool v__ast__AsmDisp_struct_eq(v__ast__AsmDisp a, v__ast__AsmDisp b) { return ((a.val.len == b.val.len && a.val.len == 0) || fast_string_eq(a.val, b.val)) && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__BoolLiteral_struct_eq(v__ast__BoolLiteral a, v__ast__BoolLiteral b) { return a.val == b.val && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__CharLiteral_struct_eq(v__ast__CharLiteral a, v__ast__CharLiteral b) { return ((a.val.len == b.val.len && a.val.len == 0) || fast_string_eq(a.val, b.val)) && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__FloatLiteral_struct_eq(v__ast__FloatLiteral a, v__ast__FloatLiteral b) { return ((a.val.len == b.val.len && a.val.len == 0) || fast_string_eq(a.val, b.val)) && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__IntegerLiteral_struct_eq(v__ast__IntegerLiteral a, v__ast__IntegerLiteral b) { return ((a.val.len == b.val.len && a.val.len == 0) || fast_string_eq(a.val, b.val)) && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__AsmArg_sumtype_eq(v__ast__AsmArg a, v__ast__AsmArg b) { if (a._typ != b._typ) { return false; } if (a._typ == b._typ && b._typ == 0) { return true; } // uninitialized if (a._typ == 496) { return v__ast__AsmAddressing_struct_eq(*a._v__ast__AsmAddressing, *b._v__ast__AsmAddressing); } if (a._typ == 497) { return v__ast__AsmAlias_struct_eq(*a._v__ast__AsmAlias, *b._v__ast__AsmAlias); } if (a._typ == 498) { return v__ast__AsmDisp_struct_eq(*a._v__ast__AsmDisp, *b._v__ast__AsmDisp); } if (a._typ == 419) { return v__ast__AsmRegister_struct_eq(*a._v__ast__AsmRegister, *b._v__ast__AsmRegister); } if (a._typ == 342) { return v__ast__BoolLiteral_struct_eq(*a._v__ast__BoolLiteral, *b._v__ast__BoolLiteral); } if (a._typ == 347) { return v__ast__CharLiteral_struct_eq(*a._v__ast__CharLiteral, *b._v__ast__CharLiteral); } if (a._typ == 356) { return v__ast__FloatLiteral_struct_eq(*a._v__ast__FloatLiteral, *b._v__ast__FloatLiteral); } if (a._typ == 363) { return v__ast__IntegerLiteral_struct_eq(*a._v__ast__IntegerLiteral, *b._v__ast__IntegerLiteral); } if (a._typ == 21) { return string__eq(*a._string, *b._string); } return false; } inline bool Array_v__ast__AsmArg_arr_eq(Array_v__ast__AsmArg a, Array_v__ast__AsmArg b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__AsmArg_sumtype_eq(((v__ast__AsmArg*)a.data)[i], ((v__ast__AsmArg*)b.data)[i])) { return false; } } return true; } inline bool v__ast__AsmTemplate_struct_eq(v__ast__AsmTemplate a, v__ast__AsmTemplate b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.is_label == b.is_label && a.is_directive == b.is_directive && Array_v__ast__AsmArg_arr_eq(a.args, b.args) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool Array_v__ast__AsmTemplate_arr_eq(Array_v__ast__AsmTemplate a, Array_v__ast__AsmTemplate b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__AsmTemplate_struct_eq(((v__ast__AsmTemplate*)a.data)[i], ((v__ast__AsmTemplate*)b.data)[i])) { return false; } } return true; } inline bool v__ast__NodeError_struct_eq(v__ast__NodeError a, v__ast__NodeError b) { return a.idx == b.idx && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__Attr_struct_eq(v__ast__Attr a, v__ast__Attr b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.has_arg == b.has_arg && ((a.arg.len == b.arg.len && a.arg.len == 0) || fast_string_eq(a.arg, b.arg)) && a.kind == b.kind && a.ct_opt == b.ct_opt && v__token__Pos_struct_eq(a.pos, b.pos) && a.has_at == b.has_at && v__ast__Expr_sumtype_eq(a.ct_expr, b.ct_expr) && a.ct_evaled == b.ct_evaled && a.ct_skip == b.ct_skip; } inline bool Array_v__ast__Attr_arr_eq(Array_v__ast__Attr a, Array_v__ast__Attr b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__Attr_struct_eq(((v__ast__Attr*)a.data)[i], ((v__ast__Attr*)b.data)[i])) { return false; } } return true; } inline bool v__ast__Embed_struct_eq(v__ast__Embed a, v__ast__Embed b) { return a.typ == b.typ && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Comment_arr_eq(a.comments, b.comments); } inline bool Array_v__ast__Embed_arr_eq(Array_v__ast__Embed a, Array_v__ast__Embed b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__Embed_struct_eq(((v__ast__Embed*)a.data)[i], ((v__ast__Embed*)b.data)[i])) { return false; } } return true; } inline bool v__ast__TypeNode_struct_eq(v__ast__TypeNode a, v__ast__TypeNode b) { return v__token__Pos_struct_eq(a.pos, b.pos) && a.typ == b.typ && v__ast__Stmt_sumtype_eq(a.stmt, b.stmt) && Array_v__ast__Comment_arr_eq(a.end_comments, b.end_comments); } inline bool Array_v__ast__TypeNode_arr_eq(Array_v__ast__TypeNode a, Array_v__ast__TypeNode b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__TypeNode_struct_eq(((v__ast__TypeNode*)a.data)[i], ((v__ast__TypeNode*)b.data)[i])) { return false; } } return true; } inline bool Array_v__ast__StructField_arr_eq(Array_v__ast__StructField a, Array_v__ast__StructField b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__StructField_struct_eq(((v__ast__StructField*)a.data)[i], ((v__ast__StructField*)b.data)[i])) { return false; } } return true; } inline bool v__ast__StructDecl_struct_eq(v__ast__StructDecl a, v__ast__StructDecl b) { return v__token__Pos_struct_eq(a.pos, b.pos) && ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && ((a.scoped_name.len == b.scoped_name.len && a.scoped_name.len == 0) || fast_string_eq(a.scoped_name, b.scoped_name)) && Array_v__ast__Type_arr_eq(a.generic_types, b.generic_types) && a.is_pub == b.is_pub && a.mut_pos == b.mut_pos && a.pub_pos == b.pub_pos && a.pub_mut_pos == b.pub_mut_pos && a.global_pos == b.global_pos && a.module_pos == b.module_pos && a.is_union == b.is_union && a.is_option == b.is_option && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && Array_v__ast__Comment_arr_eq(a.pre_comments, b.pre_comments) && Array_v__ast__Comment_arr_eq(a.end_comments, b.end_comments) && Array_v__ast__Embed_arr_eq(a.embeds, b.embeds) && a.is_implements == b.is_implements && Array_v__ast__TypeNode_arr_eq(a.implements_types, b.implements_types) && a.language == b.language && Array_v__ast__StructField_arr_eq(a.fields, b.fields) && a.idx == b.idx; } inline bool v__ast__StructField_struct_eq(v__ast__StructField a, v__ast__StructField b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.type_pos, b.type_pos) && v__token__Pos_struct_eq(a.option_pos, b.option_pos) && Array_v__ast__Comment_arr_eq(a.pre_comments, b.pre_comments) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && a.i == b.i && a.has_default_expr == b.has_default_expr && a.has_prev_newline == b.has_prev_newline && a.has_break_line == b.has_break_line && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && a.is_pub == b.is_pub && ((a.default_val.len == b.default_val.len && a.default_val.len == 0) || fast_string_eq(a.default_val, b.default_val)) && a.is_mut == b.is_mut && a.is_global == b.is_global && a.is_volatile == b.is_volatile && a.is_deprecated == b.is_deprecated && a.is_embed == b.is_embed && Array_v__ast__Comment_arr_eq(a.next_comments, b.next_comments) && a.is_recursive == b.is_recursive && a.is_part_of_union == b.is_part_of_union && a.container_typ == b.container_typ && v__ast__Expr_sumtype_eq(a.default_expr, b.default_expr) && a.default_expr_typ == b.default_expr_typ && ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.typ == b.typ && a.unaliased_typ == b.unaliased_typ && v__ast__StructDecl_struct_eq(a.anon_struct_decl, b.anon_struct_decl); } inline bool v__ast__Param_struct_eq(v__ast__Param a, v__ast__Param b) { return v__token__Pos_struct_eq(a.pos, b.pos) && ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.is_mut == b.is_mut && a.is_shared == b.is_shared && a.is_atomic == b.is_atomic && v__token__Pos_struct_eq(a.type_pos, b.type_pos) && a.is_hidden == b.is_hidden && a.on_newline == b.on_newline && a.typ == b.typ; } inline bool Array_v__ast__Param_arr_eq(Array_v__ast__Param a, Array_v__ast__Param b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__Param_struct_eq(((v__ast__Param*)a.data)[i], ((v__ast__Param*)b.data)[i])) { return false; } } return true; } inline bool Array_v__ast__Stmt_arr_eq(Array_v__ast__Stmt a, Array_v__ast__Stmt b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__Stmt_sumtype_eq(((v__ast__Stmt*)a.data)[i], ((v__ast__Stmt*)b.data)[i])) { return false; } } return true; } inline bool v__ast__EmptyScopeObject_struct_eq(v__ast__EmptyScopeObject a, v__ast__EmptyScopeObject b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.typ == b.typ; } inline bool v__ast__EmptyExpr_alias_eq(v__ast__EmptyExpr a, v__ast__EmptyExpr b) { return a == b; } inline bool v__ast__ComptTimeConstValue_sumtype_eq(v__ast__ComptTimeConstValue a, v__ast__ComptTimeConstValue b) { if (a._typ != b._typ) { return false; } if (a._typ == b._typ && b._typ == 0) { return true; } // uninitialized if (a._typ == 354) { return v__ast__EmptyExpr_alias_eq(*a._v__ast__EmptyExpr, *b._v__ast__EmptyExpr); } if (a._typ == 16) { return *a._f32 == *b._f32; } if (a._typ == 17) { return *a._f64 == *b._f64; } if (a._typ == 6) { return *a._i16 == *b._i16; } if (a._typ == 7) { return *a._i32 == *b._i32; } if (a._typ == 9) { return *a._i64 == *b._i64; } if (a._typ == 5) { return *a._i8 == *b._i8; } if (a._typ == 22) { return *a._rune == *b._rune; } if (a._typ == 21) { return string__eq(*a._string, *b._string); } if (a._typ == 12) { return *a._u16 == *b._u16; } if (a._typ == 13) { return *a._u32 == *b._u32; } if (a._typ == 14) { return *a._u64 == *b._u64; } if (a._typ == 11) { return *a._u8 == *b._u8; } if (a._typ == 2) { return *a._voidptr == *b._voidptr; } return false; } inline bool v__ast__ConstField_struct_eq(v__ast__ConstField a, v__ast__ConstField b) { return ((a.mod.len == b.mod.len && a.mod.len == 0) || fast_string_eq(a.mod, b.mod)) && ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.is_pub == b.is_pub && a.is_markused == b.is_markused && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && a.is_virtual_c == b.is_virtual_c && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.typ == b.typ && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && Array_v__ast__Comment_arr_eq(a.end_comments, b.end_comments) && v__ast__ComptTimeConstValue_sumtype_eq(a.comptime_expr_value, b.comptime_expr_value); } inline bool v__ast__GlobalField_struct_eq(v__ast__GlobalField a, v__ast__GlobalField b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.has_expr == b.has_expr && v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.typ_pos, b.typ_pos) && a.is_markused == b.is_markused && a.is_volatile == b.is_volatile && a.is_exported == b.is_exported && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.typ == b.typ && Array_v__ast__Comment_arr_eq(a.comments, b.comments); } inline bool v__ast__Var_struct_eq(v__ast__Var a, v__ast__Var b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.share == b.share && a.is_mut == b.is_mut && a.is_static == b.is_static && a.is_volatile == b.is_volatile && a.is_autofree_tmp == b.is_autofree_tmp && a.is_inherited == b.is_inherited && a.has_inherited == b.has_inherited && a.is_arg == b.is_arg && a.is_auto_deref == b.is_auto_deref && a.is_unwrapped == b.is_unwrapped && a.is_index_var == b.is_index_var && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.typ == b.typ && a.orig_type == b.orig_type && Array_v__ast__Type_arr_eq(a.smartcasts, b.smartcasts) && v__token__Pos_struct_eq(a.pos, b.pos) && a.is_used == b.is_used && a.is_changed == b.is_changed && a.ct_type_var == b.ct_type_var && a.ct_type_unwrapped == b.ct_type_unwrapped && a.is_or == b.is_or && a.is_tmp == b.is_tmp && a.is_auto_heap == b.is_auto_heap && a.is_stack_obj == b.is_stack_obj; } inline bool v__ast__ScopeObject_sumtype_eq(v__ast__ScopeObject a, v__ast__ScopeObject b) { if (a._typ != b._typ) { return false; } if (a._typ == b._typ && b._typ == 0) { return true; } // uninitialized if (a._typ == 418) { return v__ast__EmptyScopeObject_struct_eq(*a._v__ast__EmptyScopeObject, *b._v__ast__EmptyScopeObject); } if (a._typ == 419) { return v__ast__AsmRegister_struct_eq(*a._v__ast__AsmRegister, *b._v__ast__AsmRegister); } if (a._typ == 420) { return v__ast__ConstField_struct_eq(*a._v__ast__ConstField, *b._v__ast__ConstField); } if (a._typ == 421) { return v__ast__GlobalField_struct_eq(*a._v__ast__GlobalField, *b._v__ast__GlobalField); } if (a._typ == 422) { return v__ast__Var_struct_eq(*a._v__ast__Var, *b._v__ast__Var); } return false; } inline bool v__ast__IdentFn_struct_eq(v__ast__IdentFn a, v__ast__IdentFn b) { return a.typ == b.typ; } inline bool v__ast__IdentVar_struct_eq(v__ast__IdentVar a, v__ast__IdentVar b) { return a.typ == b.typ && a.is_mut == b.is_mut && a.is_static == b.is_static && a.is_volatile == b.is_volatile && a.is_option == b.is_option && a.share == b.share; } inline bool v__ast__IdentInfo_sumtype_eq(v__ast__IdentInfo a, v__ast__IdentInfo b) { if (a._typ != b._typ) { return false; } if (a._typ == b._typ && b._typ == 0) { return true; } // uninitialized if (a._typ == 476) { return v__ast__IdentFn_struct_eq(*a._v__ast__IdentFn, *b._v__ast__IdentFn); } if (a._typ == 477) { return v__ast__IdentVar_struct_eq(*a._v__ast__IdentVar, *b._v__ast__IdentVar); } return false; } inline bool v__ast__OrExpr_struct_eq(v__ast__OrExpr a, v__ast__OrExpr b) { return a.kind == b.kind && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts); } inline bool v__ast__Ident_struct_eq(v__ast__Ident a, v__ast__Ident b) { return a.language == b.language && a.tok_kind == b.tok_kind && v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.mut_pos, b.mut_pos) && a.comptime == b.comptime && a.scope == b.scope && v__ast__ScopeObject_sumtype_eq(a.obj, b.obj) && ((a.mod.len == b.mod.len && a.mod.len == 0) || fast_string_eq(a.mod, b.mod)) && ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && ((a.full_name.len == b.full_name.len && a.full_name.len == 0) || fast_string_eq(a.full_name, b.full_name)) && ((a.cached_name.len == b.cached_name.len && a.cached_name.len == 0) || fast_string_eq(a.cached_name, b.cached_name)) && a.kind == b.kind && v__ast__IdentInfo_sumtype_eq(a.info, b.info) && a.is_mut == b.is_mut && v__ast__OrExpr_struct_eq(a.or_expr, b.or_expr) && Array_v__ast__Type_arr_eq(a.concrete_types, b.concrete_types) && a.ct_expr == b.ct_expr; } inline bool Array_v__ast__Ident_arr_eq(Array_v__ast__Ident a, Array_v__ast__Ident b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__Ident_struct_eq(((v__ast__Ident*)a.data)[i], ((v__ast__Ident*)b.data)[i])) { return false; } } return true; } inline bool v__ast__DeferStmt_struct_eq(v__ast__DeferStmt a, v__ast__DeferStmt b) { return v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts) && Array_v__ast__Ident_arr_eq(a.defer_vars, b.defer_vars) && ((a.ifdef.len == b.ifdef.len && a.ifdef.len == 0) || fast_string_eq(a.ifdef, b.ifdef)) && a.idx_in_fn == b.idx_in_fn; } inline bool Array_v__ast__DeferStmt_arr_eq(Array_v__ast__DeferStmt a, Array_v__ast__DeferStmt b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__DeferStmt_struct_eq(((v__ast__DeferStmt*)a.data)[i], ((v__ast__DeferStmt*)b.data)[i])) { return false; } } return true; } inline bool v__ast__FnTrace_struct_eq(v__ast__FnTrace a, v__ast__FnTrace b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && ((a.file.len == b.file.len && a.file.len == 0) || fast_string_eq(a.file, b.file)) && a.line == b.line && a.return_type == b.return_type && a.func == b.func && a.is_fn_var == b.is_fn_var; } inline bool Map_string_v__ast__FnTrace_map_eq(Map_string_v__ast__FnTrace a, Map_string_v__ast__FnTrace b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.key_values.len; ++i) { if (!DenseArray_has_index(&a.key_values, i)) continue; voidptr k = DenseArray_key(&a.key_values, i); if (!map_exists(&b, k)) return false; v__ast__FnTrace v = *(v__ast__FnTrace*)map_get(&a, k, &(v__ast__FnTrace[]){ 0 }); if (!v__ast__FnTrace_struct_eq(*(v__ast__FnTrace*)map_get(&b, k, &(v__ast__FnTrace[]){ 0 }), v)) { return false; } } return true; } inline bool v__ast__FnDecl_struct_eq(v__ast__FnDecl a, v__ast__FnDecl b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && ((a.short_name.len == b.short_name.len && a.short_name.len == 0) || fast_string_eq(a.short_name, b.short_name)) && ((a.mod.len == b.mod.len && a.mod.len == 0) || fast_string_eq(a.mod, b.mod)) && a.is_deprecated == b.is_deprecated && a.is_pub == b.is_pub && a.is_c_variadic == b.is_c_variadic && a.is_c_extern == b.is_c_extern && a.is_variadic == b.is_variadic && a.is_anon == b.is_anon && a.is_noreturn == b.is_noreturn && a.is_manualfree == b.is_manualfree && a.is_main == b.is_main && a.is_test == b.is_test && a.is_conditional == b.is_conditional && a.is_exported == b.is_exported && a.is_keep_alive == b.is_keep_alive && a.is_unsafe == b.is_unsafe && a.is_must_use == b.is_must_use && a.is_markused == b.is_markused && a.is_file_translated == b.is_file_translated && v__ast__StructField_struct_eq(a.receiver, b.receiver) && v__token__Pos_struct_eq(a.receiver_pos, b.receiver_pos) && a.is_method == b.is_method && a.is_static_type_method == b.is_static_type_method && v__token__Pos_struct_eq(a.static_type_pos, b.static_type_pos) && v__token__Pos_struct_eq(a.method_type_pos, b.method_type_pos) && a.method_idx == b.method_idx && a.rec_mut == b.rec_mut && a.has_prev_newline == b.has_prev_newline && a.has_break_line == b.has_break_line && a.rec_share == b.rec_share && a.language == b.language && a.file_mode == b.file_mode && a.no_body == b.no_body && a.is_builtin == b.is_builtin && v__token__Pos_struct_eq(a.name_pos, b.name_pos) && v__token__Pos_struct_eq(a.body_pos, b.body_pos) && ((a.file.len == b.file.len && a.file.len == 0) || fast_string_eq(a.file, b.file)) && Array_string_arr_eq(a.generic_names, b.generic_names) && a.is_direct_arr == b.is_direct_arr && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && a.ctdefine_idx == b.ctdefine_idx && a.idx == b.idx && Array_v__ast__Param_arr_eq(a.params, b.params) && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts) && Array_v__ast__DeferStmt_arr_eq(a.defer_stmts, b.defer_stmts) && Map_string_v__ast__FnTrace_map_eq(a.trace_fns, b.trace_fns) && a.return_type == b.return_type && v__token__Pos_struct_eq(a.return_type_pos, b.return_type_pos) && a.has_return == b.has_return && a.should_be_skipped == b.should_be_skipped && a.ninstances == b.ninstances && a.has_await == b.has_await && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && Array_v__ast__Comment_arr_eq(a.end_comments, b.end_comments) && Array_v__ast__Comment_arr_eq(a.next_comments, b.next_comments) && a.source_file == b.source_file && a.scope == b.scope && Array_string_arr_eq(a.label_names, b.label_names) && v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.end_pos, b.end_pos) && a.is_expand_simple_interpolation == b.is_expand_simple_interpolation; } inline bool Map_string_bool_map_eq(Map_string_bool a, Map_string_bool b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.key_values.len; ++i) { if (!DenseArray_has_index(&a.key_values, i)) continue; voidptr k = DenseArray_key(&a.key_values, i); if (!map_exists(&b, k)) return false; bool v = *(bool*)map_get(&a, k, &(bool[]){ 0 }); if (*(bool*)map_get(&b, k, &(bool[]){ 0 }) != v) { return false; } } return true; } inline bool v__ast__AnonFn_struct_eq(v__ast__AnonFn a, v__ast__AnonFn b) { return v__ast__FnDecl_struct_eq(a.decl, b.decl) && Array_v__ast__Param_arr_eq(a.inherited_vars, b.inherited_vars) && a.typ == b.typ && Map_string_bool_map_eq(a.has_gen, b.has_gen); } inline bool v__ast__ArrayDecompose_struct_eq(v__ast__ArrayDecompose a, v__ast__ArrayDecompose b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.expr_type == b.expr_type && a.arg_type == b.arg_type; } inline bool Array_Array_v__ast__Comment_arr_eq(Array_Array_v__ast__Comment a, Array_Array_v__ast__Comment b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!Array_v__ast__Comment_arr_eq(((Array_v__ast__Comment*)a.data)[i], ((Array_v__ast__Comment*)b.data)[i])) { return false; } } return true; } inline bool Array_v__ast__Expr_arr_eq(Array_v__ast__Expr a, Array_v__ast__Expr b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__Expr_sumtype_eq(((v__ast__Expr*)a.data)[i], ((v__ast__Expr*)b.data)[i])) { return false; } } return true; } inline bool v__ast__ArrayInit_struct_eq(v__ast__ArrayInit a, v__ast__ArrayInit b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.elem_type_pos, b.elem_type_pos) && Array_Array_v__ast__Comment_arr_eq(a.ecmnts, b.ecmnts) && Array_v__ast__Comment_arr_eq(a.pre_cmnts, b.pre_cmnts) && a.is_fixed == b.is_fixed && a.is_option == b.is_option && a.has_val == b.has_val && ((a.mod.len == b.mod.len && a.mod.len == 0) || fast_string_eq(a.mod, b.mod)) && a.has_len == b.has_len && a.has_cap == b.has_cap && a.has_init == b.has_init && a.has_index == b.has_index && Array_v__ast__Expr_arr_eq(a.exprs, b.exprs) && v__ast__Expr_sumtype_eq(a.len_expr, b.len_expr) && v__ast__Expr_sumtype_eq(a.cap_expr, b.cap_expr) && v__ast__Expr_sumtype_eq(a.init_expr, b.init_expr) && Array_v__ast__Type_arr_eq(a.expr_types, b.expr_types) && a.elem_type == b.elem_type && a.init_type == b.init_type && a.typ == b.typ && a.alias_type == b.alias_type && a.has_callexpr == b.has_callexpr; } inline bool v__ast__AsCast_struct_eq(v__ast__AsCast a, v__ast__AsCast b) { return a.typ == b.typ && v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.expr_type == b.expr_type; } inline bool v__ast__Assoc_struct_eq(v__ast__Assoc a, v__ast__Assoc b) { return ((a.var_name.len == b.var_name.len && a.var_name.len == 0) || fast_string_eq(a.var_name, b.var_name)) && Array_string_arr_eq(a.fields, b.fields) && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Expr_arr_eq(a.exprs, b.exprs) && a.typ == b.typ && a.scope == b.scope; } inline bool v__ast__AtExpr_struct_eq(v__ast__AtExpr a, v__ast__AtExpr b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && v__token__Pos_struct_eq(a.pos, b.pos) && a.kind == b.kind && ((a.val.len == b.val.len && a.val.len == 0) || fast_string_eq(a.val, b.val)); } inline bool v__ast__CTempVar_struct_eq(v__ast__CTempVar a, v__ast__CTempVar b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.typ == b.typ && a.is_ptr == b.is_ptr && v__ast__Expr_sumtype_eq(a.orig, b.orig) && a.is_fixed_ret == b.is_fixed_ret; } inline bool v__ast__CallArg_struct_eq(v__ast__CallArg a, v__ast__CallArg b) { return a.is_mut == b.is_mut && a.share == b.share && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.typ == b.typ && a.is_tmp_autofree == b.is_tmp_autofree && v__token__Pos_struct_eq(a.pos, b.pos) && a.should_be_ptr == b.should_be_ptr && a.ct_expr == b.ct_expr; } inline bool Array_v__ast__CallArg_arr_eq(Array_v__ast__CallArg a, Array_v__ast__CallArg b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__CallArg_struct_eq(((v__ast__CallArg*)a.data)[i], ((v__ast__CallArg*)b.data)[i])) { return false; } } return true; } inline bool v__ast__CallExpr_struct_eq(v__ast__CallExpr a, v__ast__CallExpr b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.name_pos, b.name_pos) && ((a.mod.len == b.mod.len && a.mod.len == 0) || fast_string_eq(a.mod, b.mod)) && ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.is_method == b.is_method && a.is_field == b.is_field && a.is_fn_var == b.is_fn_var && a.is_fn_a_const == b.is_fn_a_const && a.is_keep_alive == b.is_keep_alive && a.is_noreturn == b.is_noreturn && a.is_ctor_new == b.is_ctor_new && a.is_file_translated == b.is_file_translated && a.is_static_method == b.is_static_method && Array_v__ast__CallArg_arr_eq(a.args, b.args) && Array_v__ast__Type_arr_eq(a.expected_arg_types, b.expected_arg_types) && a.comptime_ret_val == b.comptime_ret_val && a.language == b.language && v__ast__OrExpr_struct_eq(a.or_block, b.or_block) && v__ast__Expr_sumtype_eq(a.left, b.left) && a.left_type == b.left_type && a.receiver_type == b.receiver_type && a.receiver_concrete_type == b.receiver_concrete_type && a.return_type == b.return_type && a.return_type_generic == b.return_type_generic && a.nr_ret_values == b.nr_ret_values && a.fn_var_type == b.fn_var_type && ((a.const_name.len == b.const_name.len && a.const_name.len == 0) || fast_string_eq(a.const_name, b.const_name)) && a.should_be_skipped == b.should_be_skipped && Array_v__ast__Type_arr_eq(a.concrete_types, b.concrete_types) && v__token__Pos_struct_eq(a.concrete_list_pos, b.concrete_list_pos) && Array_v__ast__Type_arr_eq(a.raw_concrete_types, b.raw_concrete_types) && a.free_receiver == b.free_receiver && a.scope == b.scope && Array_v__ast__Type_arr_eq(a.from_embed_types, b.from_embed_types) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && a.is_return_used == b.is_return_used && a.is_expand_simple_interpolation == b.is_expand_simple_interpolation && a.is_unwrapped_fn_selector == b.is_unwrapped_fn_selector; } inline bool v__ast__CastExpr_struct_eq(v__ast__CastExpr a, v__ast__CastExpr b) { return v__ast__Expr_sumtype_eq(a.arg, b.arg) && a.typ == b.typ && v__ast__Expr_sumtype_eq(a.expr, b.expr) && ((a.typname.len == b.typname.len && a.typname.len == 0) || fast_string_eq(a.typname, b.typname)) && a.expr_type == b.expr_type && a.has_arg == b.has_arg && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__ChanInit_struct_eq(v__ast__ChanInit a, v__ast__ChanInit b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.elem_type_pos, b.elem_type_pos) && a.has_cap == b.has_cap && v__ast__Expr_sumtype_eq(a.cap_expr, b.cap_expr) && a.typ == b.typ && a.elem_type == b.elem_type; } inline bool v__ast__Module_struct_eq(v__ast__Module a, v__ast__Module b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && ((a.short_name.len == b.short_name.len && a.short_name.len == 0) || fast_string_eq(a.short_name, b.short_name)) && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.name_pos, b.name_pos) && a.is_skipped == b.is_skipped; } inline bool v__ast__ImportSymbol_struct_eq(v__ast__ImportSymbol a, v__ast__ImportSymbol b) { return v__token__Pos_struct_eq(a.pos, b.pos) && ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)); } inline bool Array_v__ast__ImportSymbol_arr_eq(Array_v__ast__ImportSymbol a, Array_v__ast__ImportSymbol b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__ImportSymbol_struct_eq(((v__ast__ImportSymbol*)a.data)[i], ((v__ast__ImportSymbol*)b.data)[i])) { return false; } } return true; } inline bool v__ast__Import_struct_eq(v__ast__Import a, v__ast__Import b) { return ((a.source_name.len == b.source_name.len && a.source_name.len == 0) || fast_string_eq(a.source_name, b.source_name)) && ((a.mod.len == b.mod.len && a.mod.len == 0) || fast_string_eq(a.mod, b.mod)) && ((a.alias.len == b.alias.len && a.alias.len == 0) || fast_string_eq(a.alias, b.alias)) && v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.mod_pos, b.mod_pos) && v__token__Pos_struct_eq(a.alias_pos, b.alias_pos) && v__token__Pos_struct_eq(a.syms_pos, b.syms_pos) && Array_v__ast__ImportSymbol_arr_eq(a.syms, b.syms) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && Array_v__ast__Comment_arr_eq(a.next_comments, b.next_comments); } inline bool Array_v__ast__Import_arr_eq(Array_v__ast__Import a, Array_v__ast__Import b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__Import_struct_eq(((v__ast__Import*)a.data)[i], ((v__ast__Import*)b.data)[i])) { return false; } } return true; } inline bool Array_u8_arr_eq(Array_u8 a, Array_u8 b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (*((u8*)((byte*)a.data+(i*a.element_size))) != *((u8*)((byte*)b.data+(i*b.element_size)))) { return false; } } return true; } inline bool v__ast__EmbeddedFile_struct_eq(v__ast__EmbeddedFile a, v__ast__EmbeddedFile b) { return ((a.compression_type.len == b.compression_type.len && a.compression_type.len == 0) || fast_string_eq(a.compression_type, b.compression_type)) && ((a.rpath.len == b.rpath.len && a.rpath.len == 0) || fast_string_eq(a.rpath, b.rpath)) && ((a.apath.len == b.apath.len && a.apath.len == 0) || fast_string_eq(a.apath, b.apath)) && a.is_compressed == b.is_compressed && Array_u8_arr_eq(a.bytes, b.bytes) && a.len == b.len; } inline bool Array_v__ast__EmbeddedFile_arr_eq(Array_v__ast__EmbeddedFile a, Array_v__ast__EmbeddedFile b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__EmbeddedFile_struct_eq(((v__ast__EmbeddedFile*)a.data)[i], ((v__ast__EmbeddedFile*)b.data)[i])) { return false; } } return true; } inline bool Map_string_string_map_eq(Map_string_string a, Map_string_string b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.key_values.len; ++i) { if (!DenseArray_has_index(&a.key_values, i)) continue; voidptr k = DenseArray_key(&a.key_values, i); if (!map_exists(&b, k)) return false; string v = *(string*)map_get(&a, k, &(string[]){ 0 }); if (!fast_string_eq(*(string*)map_get(&b, k, &(string[]){_S("")}), v)) { return false; } } return true; } inline bool v__errors__CompilerMessage_struct_eq(v__errors__CompilerMessage a, v__errors__CompilerMessage b) { return ((a.message.len == b.message.len && a.message.len == 0) || fast_string_eq(a.message, b.message)) && ((a.details.len == b.details.len && a.details.len == 0) || fast_string_eq(a.details, b.details)) && ((a.file_path.len == b.file_path.len && a.file_path.len == 0) || fast_string_eq(a.file_path, b.file_path)) && v__token__Pos_struct_eq(a.pos, b.pos) && a.reporter == b.reporter; } inline bool v__errors__Error_struct_eq(v__errors__Error a, v__errors__Error b) { return v__errors__CompilerMessage_struct_eq(a.CompilerMessage, b.CompilerMessage); } inline bool Array_v__errors__Error_arr_eq(Array_v__errors__Error a, Array_v__errors__Error b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__errors__Error_struct_eq(((v__errors__Error*)a.data)[i], ((v__errors__Error*)b.data)[i])) { return false; } } return true; } inline bool v__errors__Warning_struct_eq(v__errors__Warning a, v__errors__Warning b) { return v__errors__CompilerMessage_struct_eq(a.CompilerMessage, b.CompilerMessage); } inline bool Array_v__errors__Warning_arr_eq(Array_v__errors__Warning a, Array_v__errors__Warning b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__errors__Warning_struct_eq(((v__errors__Warning*)a.data)[i], ((v__errors__Warning*)b.data)[i])) { return false; } } return true; } inline bool v__errors__Notice_struct_eq(v__errors__Notice a, v__errors__Notice b) { return v__errors__CompilerMessage_struct_eq(a.CompilerMessage, b.CompilerMessage); } inline bool Array_v__errors__Notice_arr_eq(Array_v__errors__Notice a, Array_v__errors__Notice b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__errors__Notice_struct_eq(((v__errors__Notice*)a.data)[i], ((v__errors__Notice*)b.data)[i])) { return false; } } return true; } inline bool Array_v__ast__FnDecl_ptr_arr_eq(Array_v__ast__FnDecl_ptr a, Array_v__ast__FnDecl_ptr b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (*((v__ast__FnDecl**)((byte*)a.data+(i*a.element_size))) != *((v__ast__FnDecl**)((byte*)b.data+(i*b.element_size)))) { return false; } } return true; } inline bool v__ast__File_struct_eq(v__ast__File a, v__ast__File b) { return a.nr_lines == b.nr_lines && a.nr_bytes == b.nr_bytes && a.nr_tokens == b.nr_tokens && v__ast__Module_struct_eq(a.mod, b.mod) && a.global_scope == b.global_scope && a.is_test == b.is_test && a.is_generated == b.is_generated && a.is_translated == b.is_translated && a.language == b.language && a.idx == b.idx && ((a.path.len == b.path.len && a.path.len == 0) || fast_string_eq(a.path, b.path)) && ((a.path_base.len == b.path_base.len && a.path_base.len == 0) || fast_string_eq(a.path_base, b.path_base)) && a.scope == b.scope && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts) && Array_v__ast__Import_arr_eq(a.imports, b.imports) && Array_string_arr_eq(a.auto_imports, b.auto_imports) && Array_v__ast__EmbeddedFile_arr_eq(a.embedded_files, b.embedded_files) && Map_string_string_map_eq(a.imported_symbols, b.imported_symbols) && Array_v__errors__Error_arr_eq(a.errors, b.errors) && Array_v__errors__Warning_arr_eq(a.warnings, b.warnings) && Array_v__errors__Notice_arr_eq(a.notices, b.notices) && Array_v__ast__FnDecl_ptr_arr_eq(a.generic_fns, b.generic_fns) && Array_string_arr_eq(a.global_labels, b.global_labels) && Array_string_arr_eq(a.template_paths, b.template_paths) && ((a.unique_prefix.len == b.unique_prefix.len && a.unique_prefix.len == 0) || fast_string_eq(a.unique_prefix, b.unique_prefix)) && a.is_parse_text == b.is_parse_text && a.is_template_text == b.is_template_text; } inline bool v__ast__ComptimeCall_struct_eq(v__ast__ComptimeCall a, v__ast__ComptimeCall b) { return v__token__Pos_struct_eq(a.pos, b.pos) && a.has_parens == b.has_parens && ((a.method_name.len == b.method_name.len && a.method_name.len == 0) || fast_string_eq(a.method_name, b.method_name)) && a.kind == b.kind && v__token__Pos_struct_eq(a.method_pos, b.method_pos) && a.scope == b.scope && a.is_vweb == b.is_vweb && a.is_veb == b.is_veb && v__token__Pos_struct_eq(a.env_pos, b.env_pos) && a.is_d_resolved == b.is_d_resolved && v__ast__File_struct_eq(a.veb_tmpl, b.veb_tmpl) && v__ast__Expr_sumtype_eq(a.left, b.left) && a.left_type == b.left_type && a.result_type == b.result_type && ((a.env_value.len == b.env_value.len && a.env_value.len == 0) || fast_string_eq(a.env_value, b.env_value)) && ((a.compile_value.len == b.compile_value.len && a.compile_value.len == 0) || fast_string_eq(a.compile_value, b.compile_value)) && ((a.args_var.len == b.args_var.len && a.args_var.len == 0) || fast_string_eq(a.args_var, b.args_var)) && Array_v__ast__CallArg_arr_eq(a.args, b.args) && v__ast__EmbeddedFile_struct_eq(a.embed_file, b.embed_file) && v__ast__OrExpr_struct_eq(a.or_block, b.or_block); } inline bool v__ast__ComptimeSelector_struct_eq(v__ast__ComptimeSelector a, v__ast__ComptimeSelector b) { return a.has_parens == b.has_parens && v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__OrExpr_struct_eq(a.or_block, b.or_block) && v__ast__Expr_sumtype_eq(a.left, b.left) && a.left_type == b.left_type && v__ast__Expr_sumtype_eq(a.field_expr, b.field_expr) && a.typ == b.typ && a.is_name == b.is_name && ((a.typ_key.len == b.typ_key.len && a.typ_key.len == 0) || fast_string_eq(a.typ_key, b.typ_key)); } inline bool v__ast__ComptimeType_struct_eq(v__ast__ComptimeType a, v__ast__ComptimeType b) { return a.kind == b.kind && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__ConcatExpr_struct_eq(v__ast__ConcatExpr a, v__ast__ConcatExpr b) { return Array_v__ast__Expr_arr_eq(a.vals, b.vals) && v__token__Pos_struct_eq(a.pos, b.pos) && a.return_type == b.return_type; } inline bool v__ast__DumpExpr_struct_eq(v__ast__DumpExpr a, v__ast__DumpExpr b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.expr_type == b.expr_type && ((a.cname.len == b.cname.len && a.cname.len == 0) || fast_string_eq(a.cname, b.cname)); } inline bool v__ast__EnumVal_struct_eq(v__ast__EnumVal a, v__ast__EnumVal b) { return ((a.enum_name.len == b.enum_name.len && a.enum_name.len == 0) || fast_string_eq(a.enum_name, b.enum_name)) && ((a.val.len == b.val.len && a.val.len == 0) || fast_string_eq(a.val, b.val)) && ((a.mod.len == b.mod.len && a.mod.len == 0) || fast_string_eq(a.mod, b.mod)) && v__token__Pos_struct_eq(a.pos, b.pos) && a.typ == b.typ; } inline bool v__ast__GoExpr_struct_eq(v__ast__GoExpr a, v__ast__GoExpr b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__CallExpr_struct_eq(a.call_expr, b.call_expr) && a.is_expr == b.is_expr; } inline bool v__ast__IfBranch_struct_eq(v__ast__IfBranch a, v__ast__IfBranch b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.body_pos, b.body_pos) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && v__ast__Expr_sumtype_eq(a.cond, b.cond) && a.pkg_exist == b.pkg_exist && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts) && a.scope == b.scope; } inline bool Array_v__ast__IfBranch_arr_eq(Array_v__ast__IfBranch a, Array_v__ast__IfBranch b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__IfBranch_struct_eq(((v__ast__IfBranch*)a.data)[i], ((v__ast__IfBranch*)b.data)[i])) { return false; } } return true; } inline bool v__ast__IfExpr_struct_eq(v__ast__IfExpr a, v__ast__IfExpr b) { return a.is_comptime == b.is_comptime && a.tok_kind == b.tok_kind && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Comment_arr_eq(a.post_comments, b.post_comments) && v__ast__Expr_sumtype_eq(a.left, b.left) && Array_v__ast__IfBranch_arr_eq(a.branches, b.branches) && a.is_expr == b.is_expr && a.typ == b.typ && a.has_else == b.has_else; } inline bool v__ast__IfGuardVar_struct_eq(v__ast__IfGuardVar a, v__ast__IfGuardVar b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.is_mut == b.is_mut && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool Array_v__ast__IfGuardVar_arr_eq(Array_v__ast__IfGuardVar a, Array_v__ast__IfGuardVar b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__IfGuardVar_struct_eq(((v__ast__IfGuardVar*)a.data)[i], ((v__ast__IfGuardVar*)b.data)[i])) { return false; } } return true; } inline bool v__ast__IfGuardExpr_struct_eq(v__ast__IfGuardExpr a, v__ast__IfGuardExpr b) { return Array_v__ast__IfGuardVar_arr_eq(a.vars, b.vars) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.expr_type == b.expr_type; } inline bool v__ast__IndexExpr_struct_eq(v__ast__IndexExpr a, v__ast__IndexExpr b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__Expr_sumtype_eq(a.index, b.index) && v__ast__OrExpr_struct_eq(a.or_expr, b.or_expr) && v__ast__Expr_sumtype_eq(a.left, b.left) && a.left_type == b.left_type && a.is_setter == b.is_setter && a.is_map == b.is_map && a.is_array == b.is_array && a.is_farray == b.is_farray && a.is_option == b.is_option && a.is_direct == b.is_direct && a.is_gated == b.is_gated && a.typ == b.typ; } inline bool v__ast__InfixExpr_struct_eq(v__ast__InfixExpr a, v__ast__InfixExpr b) { return a.op == b.op && v__token__Pos_struct_eq(a.pos, b.pos) && a.is_stmt == b.is_stmt && v__ast__Expr_sumtype_eq(a.left, b.left) && v__ast__Expr_sumtype_eq(a.right, b.right) && a.left_type == b.left_type && a.right_type == b.right_type && a.promoted_type == b.promoted_type && ((a.auto_locked.len == b.auto_locked.len && a.auto_locked.len == 0) || fast_string_eq(a.auto_locked, b.auto_locked)) && v__ast__OrExpr_struct_eq(a.or_block, b.or_block) && a.ct_left_value_evaled == b.ct_left_value_evaled && v__ast__ComptTimeConstValue_sumtype_eq(a.ct_left_value, b.ct_left_value) && a.left_ct_expr == b.left_ct_expr && a.ct_right_value_evaled == b.ct_right_value_evaled && v__ast__ComptTimeConstValue_sumtype_eq(a.ct_right_value, b.ct_right_value) && a.right_ct_expr == b.right_ct_expr && Array_v__ast__Comment_arr_eq(a.before_op_comments, b.before_op_comments) && Array_v__ast__Comment_arr_eq(a.after_op_comments, b.after_op_comments); } inline bool v__ast__IsRefType_struct_eq(v__ast__IsRefType a, v__ast__IsRefType b) { return a.guessed_type == b.guessed_type && a.is_type == b.is_type && v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.typ == b.typ; } inline bool v__ast__LambdaExpr_struct_eq(v__ast__LambdaExpr a, v__ast__LambdaExpr b) { return v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Ident_arr_eq(a.params, b.params) && v__token__Pos_struct_eq(a.pos_expr, b.pos_expr) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && v__token__Pos_struct_eq(a.pos_end, b.pos_end) && a.scope == b.scope && a.func == b.func && a.is_checked == b.is_checked && a.typ == b.typ && a.call_ctx == b.call_ctx; } inline bool v__ast__Likely_struct_eq(v__ast__Likely a, v__ast__Likely b) { return v__token__Pos_struct_eq(a.pos, b.pos) && a.is_likely == b.is_likely && v__ast__Expr_sumtype_eq(a.expr, b.expr); } inline bool Array_bool_arr_eq(Array_bool a, Array_bool b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (*((bool*)((byte*)a.data+(i*a.element_size))) != *((bool*)((byte*)b.data+(i*b.element_size)))) { return false; } } return true; } inline bool v__ast__LockExpr_struct_eq(v__ast__LockExpr a, v__ast__LockExpr b) { return Array_bool_arr_eq(a.is_rlock, b.is_rlock) && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts) && Array_v__ast__Expr_arr_eq(a.lockeds, b.lockeds) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && a.is_expr == b.is_expr && a.typ == b.typ && a.scope == b.scope; } inline bool v__ast__MapInit_struct_eq(v__ast__MapInit a, v__ast__MapInit b) { return v__token__Pos_struct_eq(a.pos, b.pos) && Array_Array_v__ast__Comment_arr_eq(a.comments, b.comments) && Array_v__ast__Comment_arr_eq(a.pre_cmnts, b.pre_cmnts) && Array_v__ast__Expr_arr_eq(a.keys, b.keys) && Array_v__ast__Expr_arr_eq(a.vals, b.vals) && Array_v__ast__Type_arr_eq(a.val_types, b.val_types) && a.typ == b.typ && a.key_type == b.key_type && a.value_type == b.value_type && a.has_update_expr == b.has_update_expr && v__ast__Expr_sumtype_eq(a.update_expr, b.update_expr) && v__token__Pos_struct_eq(a.update_expr_pos, b.update_expr_pos) && Array_v__ast__Comment_arr_eq(a.update_expr_comments, b.update_expr_comments); } inline bool v__ast__MatchBranch_struct_eq(v__ast__MatchBranch a, v__ast__MatchBranch b) { return Array_Array_v__ast__Comment_arr_eq(a.ecmnts, b.ecmnts) && v__token__Pos_struct_eq(a.pos, b.pos) && a.is_else == b.is_else && Array_v__ast__Comment_arr_eq(a.post_comments, b.post_comments) && v__token__Pos_struct_eq(a.branch_pos, b.branch_pos) && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts) && Array_v__ast__Expr_arr_eq(a.exprs, b.exprs) && a.scope == b.scope; } inline bool Array_v__ast__MatchBranch_arr_eq(Array_v__ast__MatchBranch a, Array_v__ast__MatchBranch b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__MatchBranch_struct_eq(((v__ast__MatchBranch*)a.data)[i], ((v__ast__MatchBranch*)b.data)[i])) { return false; } } return true; } inline bool v__ast__MatchExpr_struct_eq(v__ast__MatchExpr a, v__ast__MatchExpr b) { return a.tok_kind == b.tok_kind && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && v__ast__Expr_sumtype_eq(a.cond, b.cond) && Array_v__ast__MatchBranch_arr_eq(a.branches, b.branches) && a.is_expr == b.is_expr && a.return_type == b.return_type && a.cond_type == b.cond_type && a.expected_type == b.expected_type && a.is_sum_type == b.is_sum_type; } inline bool v__ast__Nil_struct_eq(v__ast__Nil a, v__ast__Nil b) { return v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__None_struct_eq(v__ast__None a, v__ast__None b) { return v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__OffsetOf_struct_eq(v__ast__OffsetOf a, v__ast__OffsetOf b) { return a.struct_type == b.struct_type && ((a.field.len == b.field.len && a.field.len == 0) || fast_string_eq(a.field, b.field)) && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__ParExpr_struct_eq(v__ast__ParExpr a, v__ast__ParExpr b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && Array_v__ast__Comment_arr_eq(a.comments, b.comments); } inline bool v__ast__PostfixExpr_struct_eq(v__ast__PostfixExpr a, v__ast__PostfixExpr b) { return a.op == b.op && v__token__Pos_struct_eq(a.pos, b.pos) && a.is_c2v_prefix == b.is_c2v_prefix && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.typ == b.typ && ((a.auto_locked.len == b.auto_locked.len && a.auto_locked.len == 0) || fast_string_eq(a.auto_locked, b.auto_locked)); } inline bool v__ast__PrefixExpr_struct_eq(v__ast__PrefixExpr a, v__ast__PrefixExpr b) { return a.op == b.op && v__token__Pos_struct_eq(a.pos, b.pos) && a.right_type == b.right_type && v__ast__Expr_sumtype_eq(a.right, b.right) && v__ast__OrExpr_struct_eq(a.or_block, b.or_block) && a.is_option == b.is_option; } inline bool v__ast__RangeExpr_struct_eq(v__ast__RangeExpr a, v__ast__RangeExpr b) { return a.has_high == b.has_high && a.has_low == b.has_low && v__token__Pos_struct_eq(a.pos, b.pos) && a.is_gated == b.is_gated && v__ast__Expr_sumtype_eq(a.low, b.low) && v__ast__Expr_sumtype_eq(a.high, b.high) && a.typ == b.typ; } inline bool v__ast__SelectBranch_struct_eq(v__ast__SelectBranch a, v__ast__SelectBranch b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__Comment_struct_eq(a.comment, b.comment) && a.is_else == b.is_else && a.is_timeout == b.is_timeout && Array_v__ast__Comment_arr_eq(a.post_comments, b.post_comments) && v__ast__Stmt_sumtype_eq(a.stmt, b.stmt) && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts); } inline bool Array_v__ast__SelectBranch_arr_eq(Array_v__ast__SelectBranch a, Array_v__ast__SelectBranch b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__SelectBranch_struct_eq(((v__ast__SelectBranch*)a.data)[i], ((v__ast__SelectBranch*)b.data)[i])) { return false; } } return true; } inline bool v__ast__SelectExpr_struct_eq(v__ast__SelectExpr a, v__ast__SelectExpr b) { return Array_v__ast__SelectBranch_arr_eq(a.branches, b.branches) && v__token__Pos_struct_eq(a.pos, b.pos) && a.has_exception == b.has_exception && a.is_expr == b.is_expr && a.expected_type == b.expected_type; } inline bool Array_Array_v__ast__Type_arr_eq(Array_Array_v__ast__Type a, Array_Array_v__ast__Type b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!Array_v__ast__Type_arr_eq(((Array_v__ast__Type*)a.data)[i], ((Array_v__ast__Type*)b.data)[i])) { return false; } } return true; } inline bool v__ast__SelectorExpr_struct_eq(v__ast__SelectorExpr a, v__ast__SelectorExpr b) { return v__token__Pos_struct_eq(a.pos, b.pos) && ((a.field_name.len == b.field_name.len && a.field_name.len == 0) || fast_string_eq(a.field_name, b.field_name)) && a.is_mut == b.is_mut && v__token__Pos_struct_eq(a.mut_pos, b.mut_pos) && a.next_token == b.next_token && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.expr_type == b.expr_type && a.typ == b.typ && a.name_type == b.name_type && v__ast__OrExpr_struct_eq(a.or_block, b.or_block) && a.gkind_field == b.gkind_field && a.scope == b.scope && Array_v__ast__Type_arr_eq(a.from_embed_types, b.from_embed_types) && Array_Array_v__ast__Type_arr_eq(a.generic_from_embed_types, b.generic_from_embed_types) && a.has_hidden_receiver == b.has_hidden_receiver && a.is_field_typ == b.is_field_typ; } inline bool v__ast__SizeOf_struct_eq(v__ast__SizeOf a, v__ast__SizeOf b) { return a.guessed_type == b.guessed_type && a.is_type == b.is_type && v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.typ == b.typ; } inline bool v__ast__SpawnExpr_struct_eq(v__ast__SpawnExpr a, v__ast__SpawnExpr b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__CallExpr_struct_eq(a.call_expr, b.call_expr) && a.is_expr == b.is_expr; } inline bool Map_int_v__ast__SqlExpr_map_eq(Map_int_v__ast__SqlExpr a, Map_int_v__ast__SqlExpr b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.key_values.len; ++i) { if (!DenseArray_has_index(&a.key_values, i)) continue; voidptr k = DenseArray_key(&a.key_values, i); if (!map_exists(&b, k)) return false; v__ast__SqlExpr v = *(v__ast__SqlExpr*)map_get(&a, k, &(v__ast__SqlExpr[]){ 0 }); if (!v__ast__SqlExpr_struct_eq(*(v__ast__SqlExpr*)map_get(&b, k, &(v__ast__SqlExpr[]){ 0 }), v)) { return false; } } return true; } inline bool v__ast__SqlExpr_struct_eq(v__ast__SqlExpr a, v__ast__SqlExpr b) { return a.is_count == b.is_count && a.is_insert == b.is_insert && ((a.inserted_var.len == b.inserted_var.len && a.inserted_var.len == 0) || fast_string_eq(a.inserted_var, b.inserted_var)) && a.has_where == b.has_where && a.has_order == b.has_order && a.has_limit == b.has_limit && a.has_offset == b.has_offset && a.has_desc == b.has_desc && a.is_array == b.is_array && a.is_generated == b.is_generated && v__token__Pos_struct_eq(a.pos, b.pos) && a.typ == b.typ && v__ast__Expr_sumtype_eq(a.db_expr, b.db_expr) && v__ast__Expr_sumtype_eq(a.where_expr, b.where_expr) && v__ast__Expr_sumtype_eq(a.order_expr, b.order_expr) && v__ast__Expr_sumtype_eq(a.limit_expr, b.limit_expr) && v__ast__Expr_sumtype_eq(a.offset_expr, b.offset_expr) && v__ast__TypeNode_struct_eq(a.table_expr, b.table_expr) && Array_v__ast__StructField_arr_eq(a.fields, b.fields) && Map_int_v__ast__SqlExpr_map_eq(a.sub_structs, b.sub_structs) && v__ast__OrExpr_struct_eq(a.or_expr, b.or_expr); } inline bool Array_int_arr_eq(Array_int a, Array_int b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (*((int*)((byte*)a.data+(i*a.element_size))) != *((int*)((byte*)b.data+(i*b.element_size)))) { return false; } } return true; } inline bool Array_v__token__Pos_arr_eq(Array_v__token__Pos a, Array_v__token__Pos b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__token__Pos_struct_eq(((v__token__Pos*)a.data)[i], ((v__token__Pos*)b.data)[i])) { return false; } } return true; } inline bool v__ast__StringInterLiteral_struct_eq(v__ast__StringInterLiteral a, v__ast__StringInterLiteral b) { return Array_string_arr_eq(a.vals, b.vals) && Array_int_arr_eq(a.fwidths, b.fwidths) && Array_int_arr_eq(a.precisions, b.precisions) && Array_bool_arr_eq(a.pluss, b.pluss) && Array_bool_arr_eq(a.fills, b.fills) && Array_v__token__Pos_arr_eq(a.fmt_poss, b.fmt_poss) && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Expr_arr_eq(a.exprs, b.exprs) && Array_v__ast__Type_arr_eq(a.expr_types, b.expr_types) && Array_u8_arr_eq(a.fmts, b.fmts) && Array_bool_arr_eq(a.need_fmts, b.need_fmts); } inline bool v__ast__StringLiteral_struct_eq(v__ast__StringLiteral a, v__ast__StringLiteral b) { return ((a.val.len == b.val.len && a.val.len == 0) || fast_string_eq(a.val, b.val)) && a.is_raw == b.is_raw && a.language == b.language && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__StructInitField_struct_eq(v__ast__StructInitField a, v__ast__StructInitField b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.name_pos, b.name_pos) && Array_v__ast__Comment_arr_eq(a.pre_comments, b.pre_comments) && Array_v__ast__Comment_arr_eq(a.end_comments, b.end_comments) && Array_v__ast__Comment_arr_eq(a.next_comments, b.next_comments) && a.has_prev_newline == b.has_prev_newline && a.has_break_line == b.has_break_line && a.is_embed == b.is_embed && v__ast__Expr_sumtype_eq(a.expr, b.expr) && ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.typ == b.typ && a.expected_type == b.expected_type && a.parent_type == b.parent_type; } inline bool Array_v__ast__StructInitField_arr_eq(Array_v__ast__StructInitField a, Array_v__ast__StructInitField b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__StructInitField_struct_eq(((v__ast__StructInitField*)a.data)[i], ((v__ast__StructInitField*)b.data)[i])) { return false; } } return true; } inline bool v__ast__StructInit_struct_eq(v__ast__StructInit a, v__ast__StructInit b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.name_pos, b.name_pos) && a.no_keys == b.no_keys && a.is_short_syntax == b.is_short_syntax && a.is_anon == b.is_anon && a.unresolved == b.unresolved && Array_v__ast__Comment_arr_eq(a.pre_comments, b.pre_comments) && ((a.typ_str.len == b.typ_str.len && a.typ_str.len == 0) || fast_string_eq(a.typ_str, b.typ_str)) && a.typ == b.typ && v__ast__Expr_sumtype_eq(a.update_expr, b.update_expr) && a.update_expr_type == b.update_expr_type && v__token__Pos_struct_eq(a.update_expr_pos, b.update_expr_pos) && Array_v__ast__Comment_arr_eq(a.update_expr_comments, b.update_expr_comments) && a.is_update_embed == b.is_update_embed && a.has_update_expr == b.has_update_expr && Array_v__ast__StructInitField_arr_eq(a.init_fields, b.init_fields) && Array_v__ast__Type_arr_eq(a.generic_types, b.generic_types) && a.language == b.language; } inline bool v__ast__TypeOf_struct_eq(v__ast__TypeOf a, v__ast__TypeOf b) { return a.is_type == b.is_type && v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.typ == b.typ; } inline bool v__ast__UnsafeExpr_struct_eq(v__ast__UnsafeExpr a, v__ast__UnsafeExpr b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__Expr_sumtype_eq(a.expr, b.expr); } inline bool v__ast__Expr_sumtype_eq(v__ast__Expr a, v__ast__Expr b) { if (a._typ != b._typ) { return false; } if (a._typ == b._typ && b._typ == 0) { return true; } // uninitialized if (a._typ == 335) { return v__ast__NodeError_struct_eq(*a._v__ast__NodeError, *b._v__ast__NodeError); } if (a._typ == 336) { return v__ast__AnonFn_struct_eq(*a._v__ast__AnonFn, *b._v__ast__AnonFn); } if (a._typ == 337) { return v__ast__ArrayDecompose_struct_eq(*a._v__ast__ArrayDecompose, *b._v__ast__ArrayDecompose); } if (a._typ == 338) { return v__ast__ArrayInit_struct_eq(*a._v__ast__ArrayInit, *b._v__ast__ArrayInit); } if (a._typ == 339) { return v__ast__AsCast_struct_eq(*a._v__ast__AsCast, *b._v__ast__AsCast); } if (a._typ == 340) { return v__ast__Assoc_struct_eq(*a._v__ast__Assoc, *b._v__ast__Assoc); } if (a._typ == 341) { return v__ast__AtExpr_struct_eq(*a._v__ast__AtExpr, *b._v__ast__AtExpr); } if (a._typ == 342) { return v__ast__BoolLiteral_struct_eq(*a._v__ast__BoolLiteral, *b._v__ast__BoolLiteral); } if (a._typ == 343) { return v__ast__CTempVar_struct_eq(*a._v__ast__CTempVar, *b._v__ast__CTempVar); } if (a._typ == 344) { return v__ast__CallExpr_struct_eq(*a._v__ast__CallExpr, *b._v__ast__CallExpr); } if (a._typ == 345) { return v__ast__CastExpr_struct_eq(*a._v__ast__CastExpr, *b._v__ast__CastExpr); } if (a._typ == 346) { return v__ast__ChanInit_struct_eq(*a._v__ast__ChanInit, *b._v__ast__ChanInit); } if (a._typ == 347) { return v__ast__CharLiteral_struct_eq(*a._v__ast__CharLiteral, *b._v__ast__CharLiteral); } if (a._typ == 348) { return v__ast__Comment_struct_eq(*a._v__ast__Comment, *b._v__ast__Comment); } if (a._typ == 349) { return v__ast__ComptimeCall_struct_eq(*a._v__ast__ComptimeCall, *b._v__ast__ComptimeCall); } if (a._typ == 350) { return v__ast__ComptimeSelector_struct_eq(*a._v__ast__ComptimeSelector, *b._v__ast__ComptimeSelector); } if (a._typ == 351) { return v__ast__ComptimeType_struct_eq(*a._v__ast__ComptimeType, *b._v__ast__ComptimeType); } if (a._typ == 352) { return v__ast__ConcatExpr_struct_eq(*a._v__ast__ConcatExpr, *b._v__ast__ConcatExpr); } if (a._typ == 353) { return v__ast__DumpExpr_struct_eq(*a._v__ast__DumpExpr, *b._v__ast__DumpExpr); } if (a._typ == 354) { return v__ast__EmptyExpr_alias_eq(*a._v__ast__EmptyExpr, *b._v__ast__EmptyExpr); } if (a._typ == 355) { return v__ast__EnumVal_struct_eq(*a._v__ast__EnumVal, *b._v__ast__EnumVal); } if (a._typ == 356) { return v__ast__FloatLiteral_struct_eq(*a._v__ast__FloatLiteral, *b._v__ast__FloatLiteral); } if (a._typ == 357) { return v__ast__GoExpr_struct_eq(*a._v__ast__GoExpr, *b._v__ast__GoExpr); } if (a._typ == 358) { return v__ast__Ident_struct_eq(*a._v__ast__Ident, *b._v__ast__Ident); } if (a._typ == 359) { return v__ast__IfExpr_struct_eq(*a._v__ast__IfExpr, *b._v__ast__IfExpr); } if (a._typ == 360) { return v__ast__IfGuardExpr_struct_eq(*a._v__ast__IfGuardExpr, *b._v__ast__IfGuardExpr); } if (a._typ == 361) { return v__ast__IndexExpr_struct_eq(*a._v__ast__IndexExpr, *b._v__ast__IndexExpr); } if (a._typ == 362) { return v__ast__InfixExpr_struct_eq(*a._v__ast__InfixExpr, *b._v__ast__InfixExpr); } if (a._typ == 363) { return v__ast__IntegerLiteral_struct_eq(*a._v__ast__IntegerLiteral, *b._v__ast__IntegerLiteral); } if (a._typ == 364) { return v__ast__IsRefType_struct_eq(*a._v__ast__IsRefType, *b._v__ast__IsRefType); } if (a._typ == 365) { return v__ast__LambdaExpr_struct_eq(*a._v__ast__LambdaExpr, *b._v__ast__LambdaExpr); } if (a._typ == 366) { return v__ast__Likely_struct_eq(*a._v__ast__Likely, *b._v__ast__Likely); } if (a._typ == 367) { return v__ast__LockExpr_struct_eq(*a._v__ast__LockExpr, *b._v__ast__LockExpr); } if (a._typ == 368) { return v__ast__MapInit_struct_eq(*a._v__ast__MapInit, *b._v__ast__MapInit); } if (a._typ == 369) { return v__ast__MatchExpr_struct_eq(*a._v__ast__MatchExpr, *b._v__ast__MatchExpr); } if (a._typ == 370) { return v__ast__Nil_struct_eq(*a._v__ast__Nil, *b._v__ast__Nil); } if (a._typ == 371) { return v__ast__None_struct_eq(*a._v__ast__None, *b._v__ast__None); } if (a._typ == 372) { return v__ast__OffsetOf_struct_eq(*a._v__ast__OffsetOf, *b._v__ast__OffsetOf); } if (a._typ == 373) { return v__ast__OrExpr_struct_eq(*a._v__ast__OrExpr, *b._v__ast__OrExpr); } if (a._typ == 374) { return v__ast__ParExpr_struct_eq(*a._v__ast__ParExpr, *b._v__ast__ParExpr); } if (a._typ == 375) { return v__ast__PostfixExpr_struct_eq(*a._v__ast__PostfixExpr, *b._v__ast__PostfixExpr); } if (a._typ == 376) { return v__ast__PrefixExpr_struct_eq(*a._v__ast__PrefixExpr, *b._v__ast__PrefixExpr); } if (a._typ == 377) { return v__ast__RangeExpr_struct_eq(*a._v__ast__RangeExpr, *b._v__ast__RangeExpr); } if (a._typ == 378) { return v__ast__SelectExpr_struct_eq(*a._v__ast__SelectExpr, *b._v__ast__SelectExpr); } if (a._typ == 379) { return v__ast__SelectorExpr_struct_eq(*a._v__ast__SelectorExpr, *b._v__ast__SelectorExpr); } if (a._typ == 380) { return v__ast__SizeOf_struct_eq(*a._v__ast__SizeOf, *b._v__ast__SizeOf); } if (a._typ == 381) { return v__ast__SpawnExpr_struct_eq(*a._v__ast__SpawnExpr, *b._v__ast__SpawnExpr); } if (a._typ == 382) { return v__ast__SqlExpr_struct_eq(*a._v__ast__SqlExpr, *b._v__ast__SqlExpr); } if (a._typ == 383) { return v__ast__StringInterLiteral_struct_eq(*a._v__ast__StringInterLiteral, *b._v__ast__StringInterLiteral); } if (a._typ == 384) { return v__ast__StringLiteral_struct_eq(*a._v__ast__StringLiteral, *b._v__ast__StringLiteral); } if (a._typ == 385) { return v__ast__StructInit_struct_eq(*a._v__ast__StructInit, *b._v__ast__StructInit); } if (a._typ == 386) { return v__ast__TypeNode_struct_eq(*a._v__ast__TypeNode, *b._v__ast__TypeNode); } if (a._typ == 387) { return v__ast__TypeOf_struct_eq(*a._v__ast__TypeOf, *b._v__ast__TypeOf); } if (a._typ == 388) { return v__ast__UnsafeExpr_struct_eq(*a._v__ast__UnsafeExpr, *b._v__ast__UnsafeExpr); } return false; } inline bool v__ast__AsmIO_struct_eq(v__ast__AsmIO a, v__ast__AsmIO b) { return ((a.alias.len == b.alias.len && a.alias.len == 0) || fast_string_eq(a.alias, b.alias)) && ((a.constraint.len == b.constraint.len && a.constraint.len == 0) || fast_string_eq(a.constraint, b.constraint)) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && a.typ == b.typ && v__token__Pos_struct_eq(a.pos, b.pos) && v__ast__Expr_sumtype_eq(a.expr, b.expr); } inline bool Array_v__ast__AsmIO_arr_eq(Array_v__ast__AsmIO a, Array_v__ast__AsmIO b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__AsmIO_struct_eq(((v__ast__AsmIO*)a.data)[i], ((v__ast__AsmIO*)b.data)[i])) { return false; } } return true; } inline bool v__ast__AsmStmt_struct_eq(v__ast__AsmStmt a, v__ast__AsmStmt b) { return a.arch == b.arch && a.is_basic == b.is_basic && a.is_volatile == b.is_volatile && a.is_goto == b.is_goto && Array_v__ast__AsmClobbered_arr_eq(a.clobbered, b.clobbered) && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__AsmTemplate_arr_eq(a.templates, b.templates) && a.scope == b.scope && Array_v__ast__AsmIO_arr_eq(a.output, b.output) && Array_v__ast__AsmIO_arr_eq(a.input, b.input) && Array_string_arr_eq(a.global_labels, b.global_labels) && Array_string_arr_eq(a.local_labels, b.local_labels); } inline bool v__ast__AssertStmt_struct_eq(v__ast__AssertStmt a, v__ast__AssertStmt b) { return v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.extra_pos, b.extra_pos) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && v__ast__Expr_sumtype_eq(a.extra, b.extra) && a.is_used == b.is_used; } inline bool v__ast__AssignStmt_struct_eq(v__ast__AssignStmt a, v__ast__AssignStmt b) { return a.op == b.op && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Comment_arr_eq(a.end_comments, b.end_comments) && Array_v__ast__Expr_arr_eq(a.right, b.right) && Array_v__ast__Expr_arr_eq(a.left, b.left) && Array_v__ast__Type_arr_eq(a.left_types, b.left_types) && Array_v__ast__Type_arr_eq(a.right_types, b.right_types) && a.is_static == b.is_static && a.is_volatile == b.is_volatile && a.is_simple == b.is_simple && a.has_cross_var == b.has_cross_var && v__ast__Attr_struct_eq(a.attr, b.attr); } inline bool v__ast__Block_struct_eq(v__ast__Block a, v__ast__Block b) { return a.is_unsafe == b.is_unsafe && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts); } inline bool v__ast__BranchStmt_struct_eq(v__ast__BranchStmt a, v__ast__BranchStmt b) { return a.kind == b.kind && ((a.label.len == b.label.len && a.label.len == 0) || fast_string_eq(a.label, b.label)) && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__ComptimeFor_struct_eq(v__ast__ComptimeFor a, v__ast__ComptimeFor b) { return ((a.val_var.len == b.val_var.len && a.val_var.len == 0) || fast_string_eq(a.val_var, b.val_var)) && a.kind == b.kind && v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.typ_pos, b.typ_pos) && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts) && a.typ == b.typ && v__ast__Expr_sumtype_eq(a.expr, b.expr); } inline bool Array_v__ast__ConstField_arr_eq(Array_v__ast__ConstField a, Array_v__ast__ConstField b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__ConstField_struct_eq(((v__ast__ConstField*)a.data)[i], ((v__ast__ConstField*)b.data)[i])) { return false; } } return true; } inline bool v__ast__ConstDecl_struct_eq(v__ast__ConstDecl a, v__ast__ConstDecl b) { return a.is_pub == b.is_pub && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && Array_v__ast__ConstField_arr_eq(a.fields, b.fields) && Array_v__ast__Comment_arr_eq(a.end_comments, b.end_comments) && a.is_block == b.is_block; } inline bool v__ast__DebuggerStmt_struct_eq(v__ast__DebuggerStmt a, v__ast__DebuggerStmt b) { return v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__EmptyStmt_struct_eq(v__ast__EmptyStmt a, v__ast__EmptyStmt b) { return v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__EnumField_struct_eq(v__ast__EnumField a, v__ast__EnumField b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && ((a.source_name.len == b.source_name.len && a.source_name.len == 0) || fast_string_eq(a.source_name, b.source_name)) && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Comment_arr_eq(a.pre_comments, b.pre_comments) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && Array_v__ast__Comment_arr_eq(a.next_comments, b.next_comments) && a.has_expr == b.has_expr && a.has_prev_newline == b.has_prev_newline && a.has_break_line == b.has_break_line && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && v__ast__Expr_sumtype_eq(a.expr, b.expr); } inline bool Array_v__ast__EnumField_arr_eq(Array_v__ast__EnumField a, Array_v__ast__EnumField b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__EnumField_struct_eq(((v__ast__EnumField*)a.data)[i], ((v__ast__EnumField*)b.data)[i])) { return false; } } return true; } inline bool v__ast__EnumDecl_struct_eq(v__ast__EnumDecl a, v__ast__EnumDecl b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.is_pub == b.is_pub && a.is_flag == b.is_flag && a.is_multi_allowed == b.is_multi_allowed && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && Array_v__ast__EnumField_arr_eq(a.fields, b.fields) && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && a.typ == b.typ && v__token__Pos_struct_eq(a.typ_pos, b.typ_pos) && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__ExprStmt_struct_eq(v__ast__ExprStmt a, v__ast__ExprStmt b) { return v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && v__ast__Expr_sumtype_eq(a.expr, b.expr) && a.is_expr == b.is_expr && a.typ == b.typ; } inline bool v__ast__ForCStmt_struct_eq(v__ast__ForCStmt a, v__ast__ForCStmt b) { return a.has_init == b.has_init && a.has_cond == b.has_cond && a.has_inc == b.has_inc && a.is_multi == b.is_multi && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && v__ast__Stmt_sumtype_eq(a.init, b.init) && v__ast__Expr_sumtype_eq(a.cond, b.cond) && v__ast__Stmt_sumtype_eq(a.inc, b.inc) && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts) && ((a.label.len == b.label.len && a.label.len == 0) || fast_string_eq(a.label, b.label)) && a.scope == b.scope; } inline bool v__ast__ForInStmt_struct_eq(v__ast__ForInStmt a, v__ast__ForInStmt b) { return ((a.key_var.len == b.key_var.len && a.key_var.len == 0) || fast_string_eq(a.key_var, b.key_var)) && ((a.val_var.len == b.val_var.len && a.val_var.len == 0) || fast_string_eq(a.val_var, b.val_var)) && a.is_range == b.is_range && v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.kv_pos, b.kv_pos) && v__token__Pos_struct_eq(a.vv_pos, b.vv_pos) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && a.val_is_mut == b.val_is_mut && a.val_is_ref == b.val_is_ref && v__ast__Expr_sumtype_eq(a.cond, b.cond) && a.key_type == b.key_type && a.val_type == b.val_type && a.cond_type == b.cond_type && v__ast__Expr_sumtype_eq(a.high, b.high) && a.high_type == b.high_type && a.kind == b.kind && ((a.label.len == b.label.len && a.label.len == 0) || fast_string_eq(a.label, b.label)) && a.scope == b.scope && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts); } inline bool v__ast__ForStmt_struct_eq(v__ast__ForStmt a, v__ast__ForStmt b) { return a.is_inf == b.is_inf && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && v__ast__Expr_sumtype_eq(a.cond, b.cond) && Array_v__ast__Stmt_arr_eq(a.stmts, b.stmts) && ((a.label.len == b.label.len && a.label.len == 0) || fast_string_eq(a.label, b.label)) && a.scope == b.scope; } inline bool Array_v__ast__GlobalField_arr_eq(Array_v__ast__GlobalField a, Array_v__ast__GlobalField b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__GlobalField_struct_eq(((v__ast__GlobalField*)a.data)[i], ((v__ast__GlobalField*)b.data)[i])) { return false; } } return true; } inline bool v__ast__GlobalDecl_struct_eq(v__ast__GlobalDecl a, v__ast__GlobalDecl b) { return ((a.mod.len == b.mod.len && a.mod.len == 0) || fast_string_eq(a.mod, b.mod)) && v__token__Pos_struct_eq(a.pos, b.pos) && a.is_block == b.is_block && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && Array_v__ast__GlobalField_arr_eq(a.fields, b.fields) && Array_v__ast__Comment_arr_eq(a.end_comments, b.end_comments); } inline bool v__ast__GotoLabel_struct_eq(v__ast__GotoLabel a, v__ast__GotoLabel b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && v__token__Pos_struct_eq(a.pos, b.pos) && a.is_used == b.is_used; } inline bool v__ast__GotoStmt_struct_eq(v__ast__GotoStmt a, v__ast__GotoStmt b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && v__token__Pos_struct_eq(a.pos, b.pos); } inline bool v__ast__HashStmt_struct_eq(v__ast__HashStmt a, v__ast__HashStmt b) { return ((a.mod.len == b.mod.len && a.mod.len == 0) || fast_string_eq(a.mod, b.mod)) && v__token__Pos_struct_eq(a.pos, b.pos) && ((a.source_file.len == b.source_file.len && a.source_file.len == 0) || fast_string_eq(a.source_file, b.source_file)) && a.is_use_once == b.is_use_once && ((a.val.len == b.val.len && a.val.len == 0) || fast_string_eq(a.val, b.val)) && ((a.kind.len == b.kind.len && a.kind.len == 0) || fast_string_eq(a.kind, b.kind)) && ((a.main.len == b.main.len && a.main.len == 0) || fast_string_eq(a.main, b.main)) && ((a.msg.len == b.msg.len && a.msg.len == 0) || fast_string_eq(a.msg, b.msg)) && Array_v__ast__Expr_arr_eq(a.ct_conds, b.ct_conds) && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs); } inline bool Array_v__ast__FnDecl_arr_eq(Array_v__ast__FnDecl a, Array_v__ast__FnDecl b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__FnDecl_struct_eq(((v__ast__FnDecl*)a.data)[i], ((v__ast__FnDecl*)b.data)[i])) { return false; } } return true; } inline bool v__ast__InterfaceEmbedding_struct_eq(v__ast__InterfaceEmbedding a, v__ast__InterfaceEmbedding b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.typ == b.typ && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Comment_arr_eq(a.comments, b.comments); } inline bool Array_v__ast__InterfaceEmbedding_arr_eq(Array_v__ast__InterfaceEmbedding a, Array_v__ast__InterfaceEmbedding b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__InterfaceEmbedding_struct_eq(((v__ast__InterfaceEmbedding*)a.data)[i], ((v__ast__InterfaceEmbedding*)b.data)[i])) { return false; } } return true; } inline bool v__ast__InterfaceDecl_struct_eq(v__ast__InterfaceDecl a, v__ast__InterfaceDecl b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.typ == b.typ && v__token__Pos_struct_eq(a.name_pos, b.name_pos) && a.language == b.language && Array_string_arr_eq(a.field_names, b.field_names) && a.is_pub == b.is_pub && a.mut_pos == b.mut_pos && v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Comment_arr_eq(a.pre_comments, b.pre_comments) && Array_v__ast__Type_arr_eq(a.generic_types, b.generic_types) && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && Array_v__ast__FnDecl_arr_eq(a.methods, b.methods) && Array_v__ast__StructField_arr_eq(a.fields, b.fields) && Array_v__ast__InterfaceEmbedding_arr_eq(a.embeds, b.embeds) && a.are_embeds_expanded == b.are_embeds_expanded; } inline bool v__ast__Return_struct_eq(v__ast__Return a, v__ast__Return b) { return v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && Array_v__ast__Expr_arr_eq(a.exprs, b.exprs) && Array_v__ast__Type_arr_eq(a.types, b.types); } inline bool v__ast__SemicolonStmt_struct_eq(v__ast__SemicolonStmt a, v__ast__SemicolonStmt b) { return v__token__Pos_struct_eq(a.pos, b.pos); } inline bool Map_int_v__ast__SqlStmtLine_map_eq(Map_int_v__ast__SqlStmtLine a, Map_int_v__ast__SqlStmtLine b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.key_values.len; ++i) { if (!DenseArray_has_index(&a.key_values, i)) continue; voidptr k = DenseArray_key(&a.key_values, i); if (!map_exists(&b, k)) return false; v__ast__SqlStmtLine v = *(v__ast__SqlStmtLine*)map_get(&a, k, &(v__ast__SqlStmtLine[]){ 0 }); if (!v__ast__SqlStmtLine_struct_eq(*(v__ast__SqlStmtLine*)map_get(&b, k, &(v__ast__SqlStmtLine[]){ 0 }), v)) { return false; } } return true; } inline bool v__ast__SqlStmtLine_struct_eq(v__ast__SqlStmtLine a, v__ast__SqlStmtLine b) { return a.kind == b.kind && v__token__Pos_struct_eq(a.pos, b.pos) && a.is_generated == b.is_generated && a.scope == b.scope && ((a.object_var.len == b.object_var.len && a.object_var.len == 0) || fast_string_eq(a.object_var, b.object_var)) && Array_string_arr_eq(a.updated_columns, b.updated_columns) && v__ast__TypeNode_struct_eq(a.table_expr, b.table_expr) && Array_v__ast__StructField_arr_eq(a.fields, b.fields) && Map_int_v__ast__SqlStmtLine_map_eq(a.sub_structs, b.sub_structs) && v__ast__Expr_sumtype_eq(a.where_expr, b.where_expr) && Array_v__ast__Expr_arr_eq(a.update_exprs, b.update_exprs) && Array_v__ast__Comment_arr_eq(a.pre_comments, b.pre_comments) && Array_v__ast__Comment_arr_eq(a.end_comments, b.end_comments); } inline bool Array_v__ast__SqlStmtLine_arr_eq(Array_v__ast__SqlStmtLine a, Array_v__ast__SqlStmtLine b) { if (a.len != b.len) { return false; } for (int i = 0; i < a.len; ++i) { if (!v__ast__SqlStmtLine_struct_eq(((v__ast__SqlStmtLine*)a.data)[i], ((v__ast__SqlStmtLine*)b.data)[i])) { return false; } } return true; } inline bool v__ast__SqlStmt_struct_eq(v__ast__SqlStmt a, v__ast__SqlStmt b) { return v__token__Pos_struct_eq(a.pos, b.pos) && Array_v__ast__SqlStmtLine_arr_eq(a.lines, b.lines) && v__ast__Expr_sumtype_eq(a.db_expr, b.db_expr) && v__ast__OrExpr_struct_eq(a.or_expr, b.or_expr) && a.db_expr_type == b.db_expr_type; } inline bool v__ast__AliasTypeDecl_struct_eq(v__ast__AliasTypeDecl a, v__ast__AliasTypeDecl b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.is_pub == b.is_pub && a.typ == b.typ && v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.type_pos, b.type_pos) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && a.parent_type == b.parent_type && a.is_markused == b.is_markused; } inline bool v__ast__FnTypeDecl_struct_eq(v__ast__FnTypeDecl a, v__ast__FnTypeDecl b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.is_pub == b.is_pub && a.typ == b.typ && v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.type_pos, b.type_pos) && Array_v__ast__Comment_arr_eq(a.comments, b.comments) && Array_v__ast__Type_arr_eq(a.generic_types, b.generic_types) && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && a.is_markused == b.is_markused; } inline bool v__ast__SumTypeDecl_struct_eq(v__ast__SumTypeDecl a, v__ast__SumTypeDecl b) { return ((a.name.len == b.name.len && a.name.len == 0) || fast_string_eq(a.name, b.name)) && a.is_pub == b.is_pub && v__token__Pos_struct_eq(a.pos, b.pos) && v__token__Pos_struct_eq(a.name_pos, b.name_pos) && a.typ == b.typ && Array_v__ast__Type_arr_eq(a.generic_types, b.generic_types) && Array_v__ast__Attr_arr_eq(a.attrs, b.attrs) && Array_v__ast__TypeNode_arr_eq(a.variants, b.variants) && a.is_markused == b.is_markused; } inline bool v__ast__TypeDecl_sumtype_eq(v__ast__TypeDecl a, v__ast__TypeDecl b) { if (a._typ != b._typ) { return false; } if (a._typ == b._typ && b._typ == 0) { return true; } // uninitialized if (a._typ == 331) { return v__ast__AliasTypeDecl_struct_eq(*a._v__ast__AliasTypeDecl, *b._v__ast__AliasTypeDecl); } if (a._typ == 332) { return v__ast__FnTypeDecl_struct_eq(*a._v__ast__FnTypeDecl, *b._v__ast__FnTypeDecl); } if (a._typ == 333) { return v__ast__SumTypeDecl_struct_eq(*a._v__ast__SumTypeDecl, *b._v__ast__SumTypeDecl); } return false; } inline bool v__ast__Stmt_sumtype_eq(v__ast__Stmt a, v__ast__Stmt b) { if (a._typ != b._typ) { return false; } if (a._typ == b._typ && b._typ == 0) { return true; } // uninitialized if (a._typ == 390) { return v__ast__AsmStmt_struct_eq(*a._v__ast__AsmStmt, *b._v__ast__AsmStmt); } if (a._typ == 391) { return v__ast__AssertStmt_struct_eq(*a._v__ast__AssertStmt, *b._v__ast__AssertStmt); } if (a._typ == 392) { return v__ast__AssignStmt_struct_eq(*a._v__ast__AssignStmt, *b._v__ast__AssignStmt); } if (a._typ == 393) { return v__ast__Block_struct_eq(*a._v__ast__Block, *b._v__ast__Block); } if (a._typ == 394) { return v__ast__BranchStmt_struct_eq(*a._v__ast__BranchStmt, *b._v__ast__BranchStmt); } if (a._typ == 395) { return v__ast__ComptimeFor_struct_eq(*a._v__ast__ComptimeFor, *b._v__ast__ComptimeFor); } if (a._typ == 396) { return v__ast__ConstDecl_struct_eq(*a._v__ast__ConstDecl, *b._v__ast__ConstDecl); } if (a._typ == 397) { return v__ast__DebuggerStmt_struct_eq(*a._v__ast__DebuggerStmt, *b._v__ast__DebuggerStmt); } if (a._typ == 398) { return v__ast__DeferStmt_struct_eq(*a._v__ast__DeferStmt, *b._v__ast__DeferStmt); } if (a._typ == 399) { return v__ast__EmptyStmt_struct_eq(*a._v__ast__EmptyStmt, *b._v__ast__EmptyStmt); } if (a._typ == 400) { return v__ast__EnumDecl_struct_eq(*a._v__ast__EnumDecl, *b._v__ast__EnumDecl); } if (a._typ == 401) { return v__ast__ExprStmt_struct_eq(*a._v__ast__ExprStmt, *b._v__ast__ExprStmt); } if (a._typ == 237) { return v__ast__FnDecl_struct_eq(*a._v__ast__FnDecl, *b._v__ast__FnDecl); } if (a._typ == 402) { return v__ast__ForCStmt_struct_eq(*a._v__ast__ForCStmt, *b._v__ast__ForCStmt); } if (a._typ == 403) { return v__ast__ForInStmt_struct_eq(*a._v__ast__ForInStmt, *b._v__ast__ForInStmt); } if (a._typ == 404) { return v__ast__ForStmt_struct_eq(*a._v__ast__ForStmt, *b._v__ast__ForStmt); } if (a._typ == 405) { return v__ast__GlobalDecl_struct_eq(*a._v__ast__GlobalDecl, *b._v__ast__GlobalDecl); } if (a._typ == 406) { return v__ast__GotoLabel_struct_eq(*a._v__ast__GotoLabel, *b._v__ast__GotoLabel); } if (a._typ == 407) { return v__ast__GotoStmt_struct_eq(*a._v__ast__GotoStmt, *b._v__ast__GotoStmt); } if (a._typ == 408) { return v__ast__HashStmt_struct_eq(*a._v__ast__HashStmt, *b._v__ast__HashStmt); } if (a._typ == 409) { return v__ast__Import_struct_eq(*a._v__ast__Import, *b._v__ast__Import); } if (a._typ == 410) { return v__ast__InterfaceDecl_struct_eq(*a._v__ast__InterfaceDecl, *b._v__ast__InterfaceDecl); } if (a._typ == 411) { return v__ast__Module_struct_eq(*a._v__ast__Module, *b._v__ast__Module); } if (a._typ == 335) { return v__ast__NodeError_struct_eq(*a._v__ast__NodeError, *b._v__ast__NodeError); } if (a._typ == 412) { return v__ast__Return_struct_eq(*a._v__ast__Return, *b._v__ast__Return); } if (a._typ == 413) { return v__ast__SemicolonStmt_struct_eq(*a._v__ast__SemicolonStmt, *b._v__ast__SemicolonStmt); } if (a._typ == 414) { return v__ast__SqlStmt_struct_eq(*a._v__ast__SqlStmt, *b._v__ast__SqlStmt); } if (a._typ == 415) { return v__ast__StructDecl_struct_eq(*a._v__ast__StructDecl, *b._v__ast__StructDecl); } if (a._typ == 334) { return v__ast__TypeDecl_sumtype_eq(*a._v__ast__TypeDecl, *b._v__ast__TypeDecl); } return false; } inline bool v__gen__c__StrType_struct_eq(v__gen__c__StrType a, v__gen__c__StrType b) { return ((a.styp.len == b.styp.len && a.styp.len == 0) || fast_string_eq(a.styp, b.styp)) && a.typ == b.typ; } inline bool v__gen__c__SumtypeCastingFn_struct_eq(v__gen__c__SumtypeCastingFn a, v__gen__c__SumtypeCastingFn b) { return ((a.fn_name.len == b.fn_name.len && a.fn_name.len == 0) || fast_string_eq(a.fn_name, b.fn_name)) && a.got == b.got && a.exp == b.exp; } static void v__ast__Param_free(v__ast__Param* it) { v__token__Pos_free(&(it->pos)); string_free(&(it->name)); v__token__Pos_free(&(it->type_pos)); } static void Array_v__ast__Param_free(Array_v__ast__Param* it) { for (int i = 0; i < it->len; i++) { v__ast__Param_free(&(((v__ast__Param*)it->data)[i])); } array_free(it); } static void v__ast__Attr_free(v__ast__Attr* it) { string_free(&(it->name)); string_free(&(it->arg)); v__token__Pos_free(&(it->pos)); } static void Array_v__ast__Attr_free(Array_v__ast__Attr* it) { for (int i = 0; i < it->len; i++) { v__ast__Attr_free(&(((v__ast__Attr*)it->data)[i])); } array_free(it); } static void v__ast__Fn_free(v__ast__Fn* it) { string_free(&(it->mod)); string_free(&(it->file)); v__token__Pos_free(&(it->pos)); v__token__Pos_free(&(it->name_pos)); v__token__Pos_free(&(it->return_type_pos)); string_free(&(it->name)); Array_v__ast__Param_free(&(it->params)); Array_string_free(&(it->generic_names)); Array_string_free(&(it->dep_names)); Array_v__ast__Attr_free(&(it->attrs)); } static void Array_v__ast__Fn_free(Array_v__ast__Fn* it) { for (int i = 0; i < it->len; i++) { v__ast__Fn_free(&(((v__ast__Fn*)it->data)[i])); } array_free(it); } static void Array_v__ast__Type_free(Array_v__ast__Type* it) { array_free(it); } static void v__ast__TypeSymbol_free(v__ast__TypeSymbol* it) { string_free(&(it->name)); string_free(&(it->cname)); string_free(&(it->rname)); Array_v__ast__Fn_free(&(it->methods)); Array_v__ast__Type_free(&(it->generic_types)); string_free(&(it->mod)); } // V gowrappers: void* sync__pool__process_in_thread_thread_wrapper(thread_arg_sync__pool__process_in_thread *arg) { arg->fn(arg->arg1, arg->arg2); _v_free(arg); return 0; } // V dump functions: string _v_dump_expr_string(string fpath, int line, string sexpr, string dump_arg) { string sline = int_str(line); string value = string_str(dump_arg); strings__Builder sb = strings__new_builder(64); strings__Builder_write_rune(&sb, '['); strings__Builder_write_string(&sb, fpath); strings__Builder_write_rune(&sb, ':'); strings__Builder_write_string(&sb, sline); strings__Builder_write_rune(&sb, ']'); strings__Builder_write_rune(&sb, ' '); strings__Builder_write_string(&sb, sexpr); strings__Builder_write_rune(&sb, ':'); strings__Builder_write_rune(&sb, ' '); strings__Builder_write_string(&sb, value); strings__Builder_write_rune(&sb, '\n'); string res; res = strings__Builder_str(&sb); eprint(res); string_free(&res); strings__Builder_free(&sb); string_free(&value); string_free(&sline); return dump_arg; } // V anon functions: VV_LOC void anon_fn_40181cb3d9c4559e__81(void) { println(_S("}")); } VV_LOC void anon_fn_6a0ddf9f315b536f__1865(void) { v__util__Timers* timers = main__timers_pointer(((void*)0)); v__util__Timers_show(timers, _S("TOTAL")); } // >> typeof() support for sum types / interfaces static char * v_typeof_interface_IError(int sidx) { if (sidx == _IError_None___index) return "None__"; if (sidx == _IError_voidptr_index) return "voidptr"; if (sidx == _IError_Error_index) return "Error"; if (sidx == _IError_MessageError_index) return "MessageError"; if (sidx == _IError_time__TimeParseError_index) return "time.TimeParseError"; if (sidx == _IError_flag__UnknownFlagError_index) return "flag.UnknownFlagError"; if (sidx == _IError_flag__ArgsCountError_index) return "flag.ArgsCountError"; if (sidx == _IError_semver__InvalidComparatorFormatError_index) return "semver.InvalidComparatorFormatError"; if (sidx == _IError_semver__EmptyInputError_index) return "semver.EmptyInputError"; if (sidx == _IError_semver__InvalidVersionFormatError_index) return "semver.InvalidVersionFormatError"; if (sidx == _IError_os__Eof_index) return "os.Eof"; if (sidx == _IError_os__NotExpected_index) return "os.NotExpected"; if (sidx == _IError_os__FileNotOpenedError_index) return "os.FileNotOpenedError"; if (sidx == _IError_os__SizeOfTypeIs0Error_index) return "os.SizeOfTypeIs0Error"; if (sidx == _IError_os__ExecutableNotFoundError_index) return "os.ExecutableNotFoundError"; if (sidx == _IError_v__parser__IncludeError_index) return "v.parser.IncludeError"; if (sidx == _IError_v__gen__c__UnsupportedAssertCtempTransform_index) return "v.gen.c.UnsupportedAssertCtempTransform"; return "unknown IError"; } int v_typeof_interface_idx_IError(int sidx) { if (sidx == _IError_None___index) return 82; if (sidx == _IError_voidptr_index) return 2; if (sidx == _IError_Error_index) return 83; if (sidx == _IError_MessageError_index) return 86; if (sidx == _IError_time__TimeParseError_index) return 266; if (sidx == _IError_flag__UnknownFlagError_index) return 680; if (sidx == _IError_flag__ArgsCountError_index) return 681; if (sidx == _IError_semver__InvalidComparatorFormatError_index) return 716; if (sidx == _IError_semver__EmptyInputError_index) return 718; if (sidx == _IError_semver__InvalidVersionFormatError_index) return 719; if (sidx == _IError_os__Eof_index) return 135; if (sidx == _IError_os__NotExpected_index) return 136; if (sidx == _IError_os__FileNotOpenedError_index) return 138; if (sidx == _IError_os__SizeOfTypeIs0Error_index) return 139; if (sidx == _IError_os__ExecutableNotFoundError_index) return 159; if (sidx == _IError_v__parser__IncludeError_index) return 599; if (sidx == _IError_v__gen__c__UnsupportedAssertCtempTransform_index) return 627; return 30; } static char * v_typeof_interface_rand__PRNG(int sidx) { if (sidx == _rand__PRNG_rand__wyrand__WyRandRNG_index) return "rand.wyrand.WyRandRNG"; if (sidx == _rand__PRNG_voidptr_index) return "voidptr"; return "unknown rand.PRNG"; } int v_typeof_interface_idx_rand__PRNG(int sidx) { if (sidx == _rand__PRNG_rand__wyrand__WyRandRNG_index) return 276; if (sidx == _rand__PRNG_voidptr_index) return 2; return 270; } char * v_typeof_sumtype_v__ast__TypeDecl(int sidx) { switch(sidx) { case 334: return "v.ast.TypeDecl"; case 331: return "v.ast.AliasTypeDecl"; case 332: return "v.ast.FnTypeDecl"; case 333: return "v.ast.SumTypeDecl"; default: return "unknown v.ast.TypeDecl"; } } int v_typeof_sumtype_idx_v__ast__TypeDecl(int sidx) { switch(sidx) { case 334: return 334; case 331: return 331; case 332: return 332; case 333: return 333; default: return 334; } } char * v_typeof_sumtype_v__ast__Expr(int sidx) { switch(sidx) { case 389: return "v.ast.Expr"; case 335: return "v.ast.NodeError"; case 336: return "v.ast.AnonFn"; case 337: return "v.ast.ArrayDecompose"; case 338: return "v.ast.ArrayInit"; case 339: return "v.ast.AsCast"; case 340: return "v.ast.Assoc"; case 341: return "v.ast.AtExpr"; case 342: return "v.ast.BoolLiteral"; case 343: return "v.ast.CTempVar"; case 344: return "v.ast.CallExpr"; case 345: return "v.ast.CastExpr"; case 346: return "v.ast.ChanInit"; case 347: return "v.ast.CharLiteral"; case 348: return "v.ast.Comment"; case 349: return "v.ast.ComptimeCall"; case 350: return "v.ast.ComptimeSelector"; case 351: return "v.ast.ComptimeType"; case 352: return "v.ast.ConcatExpr"; case 353: return "v.ast.DumpExpr"; case 354: return "v.ast.EmptyExpr"; case 355: return "v.ast.EnumVal"; case 356: return "v.ast.FloatLiteral"; case 357: return "v.ast.GoExpr"; case 358: return "v.ast.Ident"; case 359: return "v.ast.IfExpr"; case 360: return "v.ast.IfGuardExpr"; case 361: return "v.ast.IndexExpr"; case 362: return "v.ast.InfixExpr"; case 363: return "v.ast.IntegerLiteral"; case 364: return "v.ast.IsRefType"; case 365: return "v.ast.LambdaExpr"; case 366: return "v.ast.Likely"; case 367: return "v.ast.LockExpr"; case 368: return "v.ast.MapInit"; case 369: return "v.ast.MatchExpr"; case 370: return "v.ast.Nil"; case 371: return "v.ast.None"; case 372: return "v.ast.OffsetOf"; case 373: return "v.ast.OrExpr"; case 374: return "v.ast.ParExpr"; case 375: return "v.ast.PostfixExpr"; case 376: return "v.ast.PrefixExpr"; case 377: return "v.ast.RangeExpr"; case 378: return "v.ast.SelectExpr"; case 379: return "v.ast.SelectorExpr"; case 380: return "v.ast.SizeOf"; case 381: return "v.ast.SpawnExpr"; case 382: return "v.ast.SqlExpr"; case 383: return "v.ast.StringInterLiteral"; case 384: return "v.ast.StringLiteral"; case 385: return "v.ast.StructInit"; case 386: return "v.ast.TypeNode"; case 387: return "v.ast.TypeOf"; case 388: return "v.ast.UnsafeExpr"; default: return "unknown v.ast.Expr"; } } int v_typeof_sumtype_idx_v__ast__Expr(int sidx) { switch(sidx) { case 389: return 389; case 335: return 335; case 336: return 336; case 337: return 337; case 338: return 338; case 339: return 339; case 340: return 340; case 341: return 341; case 342: return 342; case 343: return 343; case 344: return 344; case 345: return 345; case 346: return 346; case 347: return 347; case 348: return 348; case 349: return 349; case 350: return 350; case 351: return 351; case 352: return 352; case 353: return 353; case 354: return 354; case 355: return 355; case 356: return 356; case 357: return 357; case 358: return 358; case 359: return 359; case 360: return 360; case 361: return 361; case 362: return 362; case 363: return 363; case 364: return 364; case 365: return 365; case 366: return 366; case 367: return 367; case 368: return 368; case 369: return 369; case 370: return 370; case 371: return 371; case 372: return 372; case 373: return 373; case 374: return 374; case 375: return 375; case 376: return 376; case 377: return 377; case 378: return 378; case 379: return 379; case 380: return 380; case 381: return 381; case 382: return 382; case 383: return 383; case 384: return 384; case 385: return 385; case 386: return 386; case 387: return 387; case 388: return 388; default: return 389; } } char * v_typeof_sumtype_v__ast__Stmt(int sidx) { switch(sidx) { case 416: return "v.ast.Stmt"; case 390: return "v.ast.AsmStmt"; case 391: return "v.ast.AssertStmt"; case 392: return "v.ast.AssignStmt"; case 393: return "v.ast.Block"; case 394: return "v.ast.BranchStmt"; case 395: return "v.ast.ComptimeFor"; case 396: return "v.ast.ConstDecl"; case 397: return "v.ast.DebuggerStmt"; case 398: return "v.ast.DeferStmt"; case 399: return "v.ast.EmptyStmt"; case 400: return "v.ast.EnumDecl"; case 401: return "v.ast.ExprStmt"; case 237: return "v.ast.FnDecl"; case 402: return "v.ast.ForCStmt"; case 403: return "v.ast.ForInStmt"; case 404: return "v.ast.ForStmt"; case 405: return "v.ast.GlobalDecl"; case 406: return "v.ast.GotoLabel"; case 407: return "v.ast.GotoStmt"; case 408: return "v.ast.HashStmt"; case 409: return "v.ast.Import"; case 410: return "v.ast.InterfaceDecl"; case 411: return "v.ast.Module"; case 335: return "v.ast.NodeError"; case 412: return "v.ast.Return"; case 413: return "v.ast.SemicolonStmt"; case 414: return "v.ast.SqlStmt"; case 415: return "v.ast.StructDecl"; case 334: return "v.ast.TypeDecl"; default: return "unknown v.ast.Stmt"; } } int v_typeof_sumtype_idx_v__ast__Stmt(int sidx) { switch(sidx) { case 416: return 416; case 390: return 390; case 391: return 391; case 392: return 392; case 393: return 393; case 394: return 394; case 395: return 395; case 396: return 396; case 397: return 397; case 398: return 398; case 399: return 399; case 400: return 400; case 401: return 401; case 237: return 237; case 402: return 402; case 403: return 403; case 404: return 404; case 405: return 405; case 406: return 406; case 407: return 407; case 408: return 408; case 409: return 409; case 410: return 410; case 411: return 411; case 335: return 335; case 412: return 412; case 413: return 413; case 414: return 414; case 415: return 415; case 334: return 334; default: return 416; } } char * v_typeof_sumtype_v__ast__ScopeObject(int sidx) { switch(sidx) { case 423: return "v.ast.ScopeObject"; case 418: return "v.ast.EmptyScopeObject"; case 419: return "v.ast.AsmRegister"; case 420: return "v.ast.ConstField"; case 421: return "v.ast.GlobalField"; case 422: return "v.ast.Var"; default: return "unknown v.ast.ScopeObject"; } } int v_typeof_sumtype_idx_v__ast__ScopeObject(int sidx) { switch(sidx) { case 423: return 423; case 418: return 418; case 419: return 419; case 420: return 420; case 421: return 421; case 422: return 422; default: return 423; } } char * v_typeof_sumtype_v__ast__Node(int sidx) { switch(sidx) { case 433: return "v.ast.Node"; case 424: return "v.ast.CallArg"; case 420: return "v.ast.ConstField"; case 425: return "v.ast.EmptyNode"; case 426: return "v.ast.EnumField"; case 389: return "v.ast.Expr"; case 228: return "v.ast.File"; case 421: return "v.ast.GlobalField"; case 427: return "v.ast.IfBranch"; case 428: return "v.ast.MatchBranch"; case 335: return "v.ast.NodeError"; case 429: return "v.ast.Param"; case 423: return "v.ast.ScopeObject"; case 430: return "v.ast.SelectBranch"; case 416: return "v.ast.Stmt"; case 431: return "v.ast.StructField"; case 432: return "v.ast.StructInitField"; default: return "unknown v.ast.Node"; } } int v_typeof_sumtype_idx_v__ast__Node(int sidx) { switch(sidx) { case 433: return 433; case 424: return 424; case 420: return 420; case 425: return 425; case 426: return 426; case 389: return 389; case 228: return 228; case 421: return 421; case 427: return 427; case 428: return 428; case 335: return 335; case 429: return 429; case 423: return 423; case 430: return 430; case 416: return 416; case 431: return 431; case 432: return 432; default: return 433; } } char * v_typeof_sumtype_v__ast__ComptTimeConstValue(int sidx) { switch(sidx) { case 436: return "v.ast.ComptTimeConstValue"; case 354: return "v.ast.EmptyExpr"; case 16: return "f32"; case 17: return "f64"; case 6: return "i16"; case 7: return "i32"; case 9: return "i64"; case 5: return "i8"; case 22: return "rune"; case 21: return "string"; case 12: return "u16"; case 13: return "u32"; case 14: return "u64"; case 11: return "u8"; case 2: return "voidptr"; default: return "unknown v.ast.ComptTimeConstValue"; } } int v_typeof_sumtype_idx_v__ast__ComptTimeConstValue(int sidx) { switch(sidx) { case 436: return 436; case 354: return 354; case 16: return 16; case 17: return 17; case 6: return 6; case 7: return 7; case 9: return 9; case 5: return 5; case 22: return 22; case 21: return 21; case 12: return 12; case 13: return 13; case 14: return 14; case 11: return 11; case 2: return 2; default: return 436; } } char * v_typeof_sumtype_v__ast__IdentInfo(int sidx) { switch(sidx) { case 478: return "v.ast.IdentInfo"; case 476: return "v.ast.IdentFn"; case 477: return "v.ast.IdentVar"; default: return "unknown v.ast.IdentInfo"; } } int v_typeof_sumtype_idx_v__ast__IdentInfo(int sidx) { switch(sidx) { case 478: return 478; case 476: return 476; case 477: return 477; default: return 478; } } char * v_typeof_sumtype_v__ast__AsmArg(int sidx) { switch(sidx) { case 494: return "v.ast.AsmArg"; case 496: return "v.ast.AsmAddressing"; case 497: return "v.ast.AsmAlias"; case 498: return "v.ast.AsmDisp"; case 419: return "v.ast.AsmRegister"; case 342: return "v.ast.BoolLiteral"; case 347: return "v.ast.CharLiteral"; case 356: return "v.ast.FloatLiteral"; case 363: return "v.ast.IntegerLiteral"; case 21: return "string"; default: return "unknown v.ast.AsmArg"; } } int v_typeof_sumtype_idx_v__ast__AsmArg(int sidx) { switch(sidx) { case 494: return 494; case 496: return 496; case 497: return 497; case 498: return 498; case 419: return 419; case 342: return 342; case 347: return 347; case 356: return 356; case 363: return 363; case 21: return 21; default: return 494; } } char * v_typeof_sumtype_v__ast__TypeInfo(int sidx) { switch(sidx) { case 558: return "v.ast.TypeInfo"; case 557: return "v.ast.UnknownTypeInfo"; case 537: return "v.ast.Aggregate"; case 539: return "v.ast.Alias"; case 513: return "v.ast.Array"; case 549: return "v.ast.ArrayFixed"; case 550: return "v.ast.Chan"; case 548: return "v.ast.Enum"; case 553: return "v.ast.FnType"; case 555: return "v.ast.GenericInst"; case 542: return "v.ast.Interface"; case 514: return "v.ast.Map"; case 552: return "v.ast.MultiReturn"; case 518: return "v.ast.Struct"; case 544: return "v.ast.SumType"; case 551: return "v.ast.Thread"; default: return "unknown v.ast.TypeInfo"; } } int v_typeof_sumtype_idx_v__ast__TypeInfo(int sidx) { switch(sidx) { case 558: return 558; case 557: return 557; case 537: return 537; case 539: return 539; case 513: return 513; case 549: return 549; case 550: return 550; case 548: return 548; case 553: return 553; case 555: return 555; case 542: return 542; case 514: return 514; case 552: return 552; case 518: return 518; case 544: return 544; case 551: return 551; default: return 558; } } char * v_typeof_sumtype_v__checker__ORMExpr(int sidx) { switch(sidx) { case 579: return "v.checker.ORMExpr"; case 382: return "v.ast.SqlExpr"; case 414: return "v.ast.SqlStmt"; default: return "unknown v.checker.ORMExpr"; } } int v_typeof_sumtype_idx_v__checker__ORMExpr(int sidx) { switch(sidx) { case 579: return 579; case 382: return 382; case 414: return 414; default: return 579; } } static char * v_typeof_interface_v__type_resolver__IResolverType(int sidx) { if (sidx == _v__type_resolver__IResolverType_v__type_resolver__DummyResolver_index) return "v.type_resolver.DummyResolver"; if (sidx == _v__type_resolver__IResolverType_voidptr_index) return "voidptr"; if (sidx == _v__type_resolver__IResolverType_v__checker__Checker_index) return "v.checker.Checker"; if (sidx == _v__type_resolver__IResolverType_v__gen__c__Gen_index) return "v.gen.c.Gen"; return "unknown v.type_resolver.IResolverType"; } int v_typeof_interface_idx_v__type_resolver__IResolverType(int sidx) { if (sidx == _v__type_resolver__IResolverType_v__type_resolver__DummyResolver_index) return 671; if (sidx == _v__type_resolver__IResolverType_voidptr_index) return 2; if (sidx == _v__type_resolver__IResolverType_v__checker__Checker_index) return 226; if (sidx == _v__type_resolver__IResolverType_v__gen__c__Gen_index) return 624; return 670; } static char * v_typeof_interface_v__ast__walker__Visitor(int sidx) { if (sidx == _v__ast__walker__Visitor_v__ast__walker__Inspector_index) return "v.ast.walker.Inspector"; if (sidx == _v__ast__walker__Visitor_voidptr_index) return "voidptr"; if (sidx == _v__ast__walker__Visitor_v__callgraph__Mapper_index) return "v.callgraph.Mapper"; return "unknown v.ast.walker.Visitor"; } int v_typeof_interface_idx_v__ast__walker__Visitor(int sidx) { if (sidx == _v__ast__walker__Visitor_v__ast__walker__Inspector_index) return 678; if (sidx == _v__ast__walker__Visitor_voidptr_index) return 2; if (sidx == _v__ast__walker__Visitor_v__callgraph__Mapper_index) return 613; return 676; } // << typeof() support for sum types // pointers to common sumtype fields // pointers to common sumtype fields // pointers to common sumtype fields // pointers to common sumtype fields // pointers to common sumtype fields strings__Builder strings__new_builder(int initial_size) { strings__Builder res = ((__new_array_with_default(0, initial_size, sizeof(u8), 0))); ArrayFlags_set(&res.flags, ArrayFlags__noslices); return res; } Array_u8 strings__Builder_reuse_as_plain_u8_array(strings__Builder* b) { ArrayFlags_clear(&b->flags, ArrayFlags__noslices); return *b; } void strings__Builder_write_ptr(strings__Builder* b, u8* ptr, int len) { if (len == 0) { return; } array_push_many(b, ptr, len); } void strings__Builder_write_rune(strings__Builder* b, rune r) { Array_fixed_u8_5 buffer = {0, 0, 0, 0, 0}; string res = utf32_to_str_no_malloc(((u32)(r)), &buffer[0]); if (res.len == 0) { return; } array_push_many(b, res.str, res.len); } void strings__Builder_write_runes(strings__Builder* b, Array_rune runes) { Array_fixed_u8_5 buffer = {0, 0, 0, 0, 0}; for (int _t1 = 0; _t1 < runes.len; ++_t1) { rune r = ((rune*)runes.data)[_t1]; string res = utf32_to_str_no_malloc(((u32)(r)), &buffer[0]); if (res.len == 0) { continue; } array_push_many(b, res.str, res.len); } } inline void strings__Builder_write_u8(strings__Builder* b, u8 data) { array_push((array*)b, _MOV((u8[]){ data })); } void strings__Builder_write_decimal(strings__Builder* b, i64 n) { if (n == 0) { strings__Builder_write_u8(b, 0x30); return; } Array_fixed_u8_25 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; i64 x = (n < 0 ? (-n) : (n)); int i = 24; for (;;) { if (!(x != 0)) break; i64 nextx = (i64)(x / 10); i64 r = (i64)(x % 10); buf[i] = (u8)(((u8)(r)) + 0x30); x = nextx; i--; } if (n < 0) { buf[i] = '-'; i--; } strings__Builder_write_ptr(b, &buf[(int)(i + 1)], (int)(24 - i)); } void strings__Builder_drain_builder(strings__Builder* b, strings__Builder* other, int other_new_cap) { if (other->len > 0) { _PUSH_MANY(b, (*other), _t1, strings__Builder); } strings__Builder_free(other); *other = strings__new_builder(other_new_cap); } inline void strings__Builder_write_string(strings__Builder* b, string s) { if (s.len == 0) { return; } array_push_many(b, s.str, s.len); } inline void strings__Builder_write_string2(strings__Builder* b, string s1, string s2) { if (s1.len != 0) { array_push_many(b, s1.str, s1.len); } if (s2.len != 0) { array_push_many(b, s2.str, s2.len); } } void strings__Builder_go_back(strings__Builder* b, int n) { array_trim(b, (int)(b->len - n)); } inline string strings__Builder_spart(strings__Builder* b, int start_pos, int n) { { // Unsafe block u8* x = malloc_noscan((int)(n + 1)); vmemcpy(x, ((u8*)(b->data)) + start_pos, n); x[n] = 0; return tos(x, n); } return (string){.str=(byteptr)"", .is_lit=1}; } string strings__Builder_cut_last(strings__Builder* b, int n) { int cut_pos = (int)(b->len - n); string res = strings__Builder_spart(b, cut_pos, n); array_trim(b, cut_pos); return res; } string strings__Builder_cut_to(strings__Builder* b, int pos) { if (pos > b->len) { return _S(""); } return strings__Builder_cut_last(b, (int)(b->len - pos)); } void strings__Builder_go_back_to(strings__Builder* b, int pos) { array_trim(b, pos); } inline void strings__Builder_writeln(strings__Builder* b, string s) { if ((s).len != 0) { array_push_many(b, s.str, s.len); } array_push((array*)b, _MOV((u8[]){ ((u8)('\n')) })); } inline void strings__Builder_writeln2(strings__Builder* b, string s1, string s2) { if ((s1).len != 0) { array_push_many(b, s1.str, s1.len); } array_push((array*)b, _MOV((u8[]){ ((u8)('\n')) })); if ((s2).len != 0) { array_push_many(b, s2.str, s2.len); } array_push((array*)b, _MOV((u8[]){ ((u8)('\n')) })); } string strings__Builder_last_n(strings__Builder* b, int n) { if (n > b->len) { return _S(""); } return strings__Builder_spart(b, (int)(b->len - n), n); } string strings__Builder_after(strings__Builder* b, int n) { if (n >= b->len) { return _S(""); } return strings__Builder_spart(b, n, (int)(b->len - n)); } string strings__Builder_str(strings__Builder* b) { array_push((array*)b, _MOV((u8[]){ ((u8)(0)) })); u8* bcopy = ((u8*)(memdup_noscan(b->data, b->len))); string s = u8_vstring_with_len(bcopy, (int)(b->len - 1)); array_clear(b); return s; } void strings__Builder_free(strings__Builder* b) { if (b->data != 0) { _v_free(b->data); { // Unsafe block b->data = ((void*)0); } } } f32 strings__dice_coefficient(string s1, string s2) { if (s1.len == 0 || s2.len == 0) { return 0.0; } if (string__eq(s1, s2)) { return 1.0; } if (s1.len < 2 || s2.len < 2) { return 0.0; } string a = (s1.len > s2.len ? (s1) : (s2)); string b = (string__eq(a, s1) ? (s2) : (s1)); Map_string_int first_bigrams = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int i = 0; i < (int)(a.len - 1); ++i) { string bigram = string_substr(a, i, (int_literal)(i + 2)); int q = (_IN_MAP(ADDR(string, bigram), ADDR(map, first_bigrams)) ? ((int)((*(int*)map_get(ADDR(map, first_bigrams), &(string[]){bigram}, &(int[]){ 0 })) + 1)) : (1)); map_set(&first_bigrams, &(string[]){bigram}, &(int[]) { q }); } int intersection_size = 0; for (int i = 0; i < (int)(b.len - 1); ++i) { string bigram = string_substr(b, i, (int_literal)(i + 2)); int count = (_IN_MAP(ADDR(string, bigram), ADDR(map, first_bigrams)) ? ((*(int*)map_get(ADDR(map, first_bigrams), &(string[]){bigram}, &(int[]){ 0 }))) : (0)); if (count > 0) { map_set(&first_bigrams, &(string[]){bigram}, &(int[]) { (int)(count - 1) }); intersection_size++; } } return (f32)(((f32)(((f32)(2.0)) * ((f32)(intersection_size)))) / ((f32)((f32)(((f32)(a.len)) + ((f32)(b.len))) - 2))); } string strings__repeat(u8 c, int n) { if (n <= 0) { return _S(""); } u8* bytes = malloc_noscan((int)(n + 1)); { // Unsafe block memset(bytes, c, n); bytes[n] = '0'; } return u8_vstring_with_len(bytes, n); } string strings__repeat_string(string s, int n) { if (n <= 0 || s.len == 0) { return _S(""); } int slen = s.len; int blen = (int)(slen * n); u8* bytes = malloc_noscan((int)(blen + 1)); for (int bi = 0; bi < n; ++bi) { int bislen = (int)(bi * slen); for (int si = 0; si < slen; ++si) { { // Unsafe block bytes[(int)(bislen + si)] = s.str[ si]; } } } { // Unsafe block bytes[blen] = '0'; } return u8_vstring_with_len(bytes, blen); } VV_LOC void builtin__closure__closure_alloc(void) { u8* p = builtin__closure__closure_alloc_platform(); if (isnil(p)) { return; } u8* x = p + g_closure.v_page_size; int remaining = (int)(g_closure.v_page_size / _const_builtin__closure__closure_size); g_closure.closure_ptr = x; g_closure.closure_cap = remaining; for (;;) { if (!(remaining > 0)) break; vmemcpy(x, _const_builtin__closure__closure_thunk.data, _const_builtin__closure__closure_thunk.len); remaining--; { // Unsafe block x += _const_builtin__closure__closure_size; } } builtin__closure__closure_memory_protect_platform(g_closure.closure_ptr, g_closure.v_page_size, builtin__closure__MemoryProtectAtrr__read_exec); } VV_LOC void builtin__closure__closure_init(void) { int page_size = builtin__closure__get_page_size_platform(); g_closure.v_page_size = page_size; builtin__closure__closure_mtx_lock_init_platform(); builtin__closure__closure_alloc(); { // Unsafe block builtin__closure__closure_memory_protect_platform(g_closure.closure_ptr, page_size, builtin__closure__MemoryProtectAtrr__read_write); vmemcpy(g_closure.closure_ptr, _const_builtin__closure__closure_get_data_bytes.data, _const_builtin__closure__closure_get_data_bytes.len); builtin__closure__closure_memory_protect_platform(g_closure.closure_ptr, page_size, builtin__closure__MemoryProtectAtrr__read_exec); } g_closure.closure_get_data = (voidptr)g_closure.closure_ptr; { // Unsafe block g_closure.closure_ptr = ((u8*)(g_closure.closure_ptr)) + _const_builtin__closure__closure_size; } g_closure.closure_cap--; } VV_LOC voidptr builtin__closure__closure_create(voidptr func, voidptr data) { builtin__closure__closure_mtx_lock_platform(); if (g_closure.closure_cap == 0) { builtin__closure__closure_alloc(); } g_closure.closure_cap--; voidptr curr_closure = g_closure.closure_ptr; { // Unsafe block g_closure.closure_ptr = ((u8*)(g_closure.closure_ptr)) + _const_builtin__closure__closure_size; voidptr* p = ((voidptr*)(((u8*)(curr_closure)) - _const_builtin__closure__assumed_page_size)); p[0] = data; p[1] = func; } builtin__closure__closure_mtx_unlock_platform(); return curr_closure; } #if !defined(_VFREESTANDING) && !defined(__vinix__) #endif inline VV_LOC u8* builtin__closure__closure_alloc_platform(void) { u8* p = ((u8*)(((void*)0))); #if defined(_VFREESTANDING) { } #else { p = mmap(0, (int)(g_closure.v_page_size * 2), (PROT_READ | PROT_WRITE), (MAP_ANONYMOUS | MAP_PRIVATE), -1, 0U); if (p == ((u8*)(MAP_FAILED))) { return ((void*)0); } } #endif return p; } inline VV_LOC void builtin__closure__closure_memory_protect_platform(voidptr ptr, isize size, builtin__closure__MemoryProtectAtrr attr) { #if defined(_VFREESTANDING) { } #else { if (attr == (builtin__closure__MemoryProtectAtrr__read_exec)) { mprotect(ptr, size, (PROT_READ | PROT_EXEC)); } else if (attr == (builtin__closure__MemoryProtectAtrr__read_write)) { mprotect(ptr, size, (PROT_READ | PROT_WRITE)); } } #endif } inline VV_LOC int builtin__closure__get_page_size_platform(void) { int page_size = 0x4000; #if !defined(_VFREESTANDING) { page_size = ((int)(sysconf(_SC_PAGESIZE))); } #endif page_size = (int)(page_size * ((int)(((int)(((int)(_const_builtin__closure__assumed_page_size - 1)) / page_size)) + 1))); return page_size; } inline VV_LOC void builtin__closure__closure_mtx_lock_init_platform(void) { #if !defined(_VFREESTANDING) || defined(__vinix__) { pthread_mutex_init(&g_closure.ClosureMutex.closure_mtx, 0); } #endif } inline VV_LOC void builtin__closure__closure_mtx_lock_platform(void) { #if !defined(_VFREESTANDING) || defined(__vinix__) { pthread_mutex_lock(&g_closure.ClosureMutex.closure_mtx); } #endif } inline VV_LOC void builtin__closure__closure_mtx_unlock_platform(void) { #if !defined(_VFREESTANDING) || defined(__vinix__) { pthread_mutex_unlock(&g_closure.ClosureMutex.closure_mtx); } #endif } int math__bits__trailing_zeros_32(u32 x) { if (x == 0U) { return 32; } return ((int)(_const_math__bits__de_bruijn32tab[((u32)(((x & -x)) * _const_math__bits__de_bruijn32) >> (27))])); } int math__bits__trailing_zeros_64(u64 x) { if (x == 0U) { return 64; } return ((int)(_const_math__bits__de_bruijn64tab[((u64)(((x & -x)) * _const_math__bits__de_bruijn64) >> (58))])); } int math__bits__len_32(u32 x) { u32 y = x; int n = 0; if (y >= (65536)) { y >>= 16U; n = 16; } if (y >= (256)) { y >>= 8U; n += 8; } return (int)(n + ((int)(_const_math__bits__len_8_tab[y]))); } multi_return_u64_u64 math__bits__mul_64(u64 x, u64 y) { u64 x0 = (x & _const_math__bits__mask32); u64 x1 = (x >> 32U); u64 y0 = (y & _const_math__bits__mask32); u64 y1 = (y >> 32U); u64 w0 = (u64)(x0 * y0); u64 t = (u64)((u64)(x1 * y0) + ((w0 >> 32U))); u64 w1 = (t & _const_math__bits__mask32); u64 w2 = (t >> 32U); w1 += (u64)(x0 * y1); u64 hi = (u64)((u64)((u64)(x1 * y1) + w2) + ((w1 >> 32U))); u64 lo = (u64)(x * y); return (multi_return_u64_u64){.arg0=hi, .arg1=lo}; } VV_LOC multi_return_u32_u32_u32 strconv__lsr96(u32 s2, u32 s1, u32 s0) { u32 r0 = ((u32)(0U)); u32 r1 = ((u32)(0U)); u32 r2 = ((u32)(0U)); r0 = (((s0 >> 1U)) | ((((s1 & ((u32)(1U)))) << 31U))); r1 = (((s1 >> 1U)) | ((((s2 & ((u32)(1U)))) << 31U))); r2 = (s2 >> 1U); return (multi_return_u32_u32_u32){.arg0=r2, .arg1=r1, .arg2=r0}; } VV_LOC multi_return_u32_u32_u32 strconv__lsl96(u32 s2, u32 s1, u32 s0) { u32 r0 = ((u32)(0U)); u32 r1 = ((u32)(0U)); u32 r2 = ((u32)(0U)); r2 = (((s2 << 1U)) | ((((s1 & ((((u32)(1U)) << 31U)))) >> 31U))); r1 = (((s1 << 1U)) | ((((s0 & ((((u32)(1U)) << 31U)))) >> 31U))); r0 = (s0 << 1U); return (multi_return_u32_u32_u32){.arg0=r2, .arg1=r1, .arg2=r0}; } VV_LOC multi_return_u32_u32_u32 strconv__add96(u32 s2, u32 s1, u32 s0, u32 d2, u32 d1, u32 d0) { u64 w = ((u64)(0U)); u32 r0 = ((u32)(0U)); u32 r1 = ((u32)(0U)); u32 r2 = ((u32)(0U)); w = (u64)(((u64)(s0)) + ((u64)(d0))); r0 = ((u32)(w)); w >>= 32U; w += (u64)(((u64)(s1)) + ((u64)(d1))); r1 = ((u32)(w)); w >>= 32U; w += (u64)(((u64)(s2)) + ((u64)(d2))); r2 = ((u32)(w)); return (multi_return_u32_u32_u32){.arg0=r2, .arg1=r1, .arg2=r0}; } VV_LOC multi_return_strconv__ParserState_strconv__PrepNumber strconv__parser(string s) { int digx = 0; strconv__ParserState result = strconv__ParserState__ok; bool expneg = false; int expexp = 0; int i = 0; strconv__PrepNumber pn = ((strconv__PrepNumber){.negative = 0,.exponent = 0,.mantissa = 0,}); for (;;) { if (!(i < s.len && u8_is_space(s.str[ i]))) break; i++; } if (s.str[ i] == '-') { pn.negative = true; i++; } if (s.str[ i] == '+') { i++; } for (;;) { if (!(i < s.len && u8_is_digit(s.str[ i]))) break; if (digx < 18) { pn.mantissa *= 10U; pn.mantissa += ((u64)((rune)(s.str[ i] - _const_strconv__c_zero))); digx++; } else if (pn.exponent < 2147483647) { pn.exponent++; } i++; } if (i < s.len && s.str[ i] == '.') { i++; for (;;) { if (!(i < s.len && u8_is_digit(s.str[ i]))) break; if (digx < 18) { pn.mantissa *= 10U; pn.mantissa += ((u64)((rune)(s.str[ i] - _const_strconv__c_zero))); pn.exponent--; digx++; } i++; } } if (i < s.len && (s.str[ i] == 'e' || s.str[ i] == 'E')) { i++; if (i < s.len) { if (s.str[ i] == _const_strconv__c_plus) { i++; } else if (s.str[ i] == _const_strconv__c_minus) { expneg = true; i++; } for (;;) { if (!(i < s.len && u8_is_digit(s.str[ i]))) break; if (expexp < 214748364) { expexp *= 10; expexp += ((int)((rune)(s.str[ i] - _const_strconv__c_zero))); } i++; } } } if (expneg) { expexp = -expexp; } pn.exponent += expexp; if (pn.mantissa == 0U) { if (pn.negative) { result = strconv__ParserState__mzero; } else { result = strconv__ParserState__pzero; } } else if (pn.exponent > 309) { if (pn.negative) { result = strconv__ParserState__minf; } else { result = strconv__ParserState__pinf; } } else if (pn.exponent < -328) { if (pn.negative) { result = strconv__ParserState__mzero; } else { result = strconv__ParserState__pzero; } } if (i == 0 && s.len > 0) { return (multi_return_strconv__ParserState_strconv__PrepNumber){.arg0=strconv__ParserState__invalid_number, .arg1=pn}; } if (i != s.len) { return (multi_return_strconv__ParserState_strconv__PrepNumber){.arg0=strconv__ParserState__extra_char, .arg1=pn}; } return (multi_return_strconv__ParserState_strconv__PrepNumber){.arg0=result, .arg1=pn}; } VV_LOC u64 strconv__converter(strconv__PrepNumber* pn) { int binexp = 92; u32 s2 = ((u32)(0U)); u32 s1 = ((u32)(0U)); u32 s0 = ((u32)(0U)); u32 q2 = ((u32)(0U)); u32 q1 = ((u32)(0U)); u32 q0 = ((u32)(0U)); u32 r2 = ((u32)(0U)); u32 r1 = ((u32)(0U)); u32 r0 = ((u32)(0U)); u32 mask28 = ((u32)((((u64)(0xFU)) << 28U))); u64 result = ((u64)(0U)); s0 = ((u32)((pn->mantissa & ((u64)(0x00000000FFFFFFFFU))))); s1 = ((u32)((pn->mantissa >> 32U))); s2 = ((u32)(0U)); for (;;) { if (!(pn->exponent > 0)) break; multi_return_u32_u32_u32 mr_5609 = strconv__lsl96(s2, s1, s0); q2 = mr_5609.arg0; q1 = mr_5609.arg1; q0 = mr_5609.arg2; multi_return_u32_u32_u32 mr_5655 = strconv__lsl96(q2, q1, q0); r2 = mr_5655.arg0; r1 = mr_5655.arg1; r0 = mr_5655.arg2; multi_return_u32_u32_u32 mr_5711 = strconv__lsl96(r2, r1, r0); s2 = mr_5711.arg0; s1 = mr_5711.arg1; s0 = mr_5711.arg2; multi_return_u32_u32_u32 mr_5767 = strconv__add96(s2, s1, s0, q2, q1, q0); s2 = mr_5767.arg0; s1 = mr_5767.arg1; s0 = mr_5767.arg2; pn->exponent--; for (;;) { if (!(((s2 & mask28)) != 0U)) break; multi_return_u32_u32_u32 mr_5890 = strconv__lsr96(s2, s1, s0); q2 = mr_5890.arg0; q1 = mr_5890.arg1; q0 = mr_5890.arg2; binexp++; s2 = q2; s1 = q1; s0 = q0; } } for (;;) { if (!(pn->exponent < 0)) break; for (;;) { if (!(!(((s2 & ((((u32)(1U)) << 31U)))) != 0U))) break; multi_return_u32_u32_u32 mr_6037 = strconv__lsl96(s2, s1, s0); q2 = mr_6037.arg0; q1 = mr_6037.arg1; q0 = mr_6037.arg2; binexp--; s2 = q2; s1 = q1; s0 = q0; } q2 = (u32)(s2 / _const_strconv__c_ten); r1 = (u32)(s2 % _const_strconv__c_ten); r2 = (((s1 >> 8U)) | ((r1 << 24U))); q1 = (u32)(r2 / _const_strconv__c_ten); r1 = (u32)(r2 % _const_strconv__c_ten); r2 = ((((((s1 & ((u32)(0xFFU)))) << 16U)) | ((s0 >> 16U))) | ((r1 << 24U))); r0 = (u32)(r2 / _const_strconv__c_ten); r1 = (u32)(r2 % _const_strconv__c_ten); q1 = (((q1 << 8U)) | ((((r0 & ((u32)(0x00FF0000U)))) >> 16U))); q0 = (r0 << 16U); r2 = (((s0 & ((u32)(0xFFFFU)))) | ((r1 << 16U))); q0 |= (u32)(r2 / _const_strconv__c_ten); s2 = q2; s1 = q1; s0 = q0; pn->exponent++; } if (s2 != 0U || s1 != 0U || s0 != 0U) { for (;;) { if (!(((s2 & mask28)) == 0U)) break; multi_return_u32_u32_u32 mr_6717 = strconv__lsl96(s2, s1, s0); q2 = mr_6717.arg0; q1 = mr_6717.arg1; q0 = mr_6717.arg2; binexp--; s2 = q2; s1 = q1; s0 = q0; } } int nbit = 7; u32 check_round_bit = (((u32)(1U)) << ((u32)(nbit))); u32 check_round_mask = (((u32)(0xFFFFFFFFU)) << ((u32)(nbit))); if (((s1 & check_round_bit)) != 0U) { if (((s1 & ~check_round_mask)) != 0U) { multi_return_u32_u32_u32 mr_7802 = strconv__add96(s2, s1, s0, 0U, check_round_bit, 0U); s2 = mr_7802.arg0; s1 = mr_7802.arg1; s0 = mr_7802.arg2; } else { if (((s1 & ((check_round_bit << ((u32)(1U)))))) != 0U) { multi_return_u32_u32_u32 mr_7996 = strconv__add96(s2, s1, s0, 0U, check_round_bit, 0U); s2 = mr_7996.arg0; s1 = mr_7996.arg1; s0 = mr_7996.arg2; } } s1 = (s1 & check_round_mask); s0 = ((u32)(0U)); if ((s2 & ((mask28 << ((u32)(1U))))) != 0U) { multi_return_u32_u32_u32 mr_8203 = strconv__lsr96(s2, s1, s0); q2 = mr_8203.arg0; q1 = mr_8203.arg1; q0 = mr_8203.arg2; binexp++; s2 = q2; s1 = q1; s0 = q0; } } binexp += 1023; if (binexp > 2046) { if (pn->negative) { result = _const_strconv__double_minus_infinity; } else { result = _const_strconv__double_plus_infinity; } } else if (binexp < 1) { if (pn->negative) { result = _const_strconv__double_minus_zero; } else { result = _const_strconv__double_plus_zero; } } else if (s2 != 0U) { u64 q = ((u64)(0U)); u64 binexs2 = (((u64)(binexp)) << 52U); q = ((((((u64)((s2 & ~mask28))) << 24U)) | ((((u64)(((u64)(s1)) + ((u64)(128U)))) >> 8U))) | binexs2); if (pn->negative) { q |= ((((u64)(1U)) << 63U)); } result = q; } return result; } _result_f64 strconv__atof64(string s, strconv__AtoF64Param param) { if (s.len == 0) { return (_result_f64){ .is_error=true, .err=_v_error(_S("expected a number found an empty string")), .data={E_STRUCT} }; } strconv__Float64u res = ((strconv__Float64u){0}); multi_return_strconv__ParserState_strconv__PrepNumber mr_9383 = strconv__parser(s); strconv__ParserState res_parsing = mr_9383.arg0; strconv__PrepNumber pn = mr_9383.arg1; switch (res_parsing) { case strconv__ParserState__ok: { res.u = strconv__converter((voidptr)&pn); break; } case strconv__ParserState__pzero: { res.u = _const_strconv__double_plus_zero; break; } case strconv__ParserState__mzero: { res.u = _const_strconv__double_minus_zero; break; } case strconv__ParserState__pinf: { res.u = _const_strconv__double_plus_infinity; break; } case strconv__ParserState__minf: { res.u = _const_strconv__double_minus_infinity; break; } case strconv__ParserState__extra_char: { if (param.allow_extra_chars) { res.u = strconv__converter((voidptr)&pn); } else { return (_result_f64){ .is_error=true, .err=_v_error(_S("extra char after number")), .data={E_STRUCT} }; } break; } case strconv__ParserState__invalid_number: { return (_result_f64){ .is_error=true, .err=_v_error(_S("not a number")), .data={E_STRUCT} }; } } _result_f64 _t4 = {0}; _result_ok(&(f64[]) { res.f }, (_result*)(&_t4), sizeof(f64)); return _t4; } _result_u64 strconv__common_parse_uint(string s, int _base, int _bit_size, bool error_on_non_digit, bool error_on_high_digit) { multi_return_u64_int mr_730 = strconv__common_parse_uint2(s, _base, _bit_size); u64 result = mr_730.arg0; int err = mr_730.arg1; if (err != 0 && (error_on_non_digit || error_on_high_digit)) { switch (err) { case -1: { return (_result_u64){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("common_parse_uint: wrong base "), 0xfe07, {.d_i32 = _base}}, {_S(" for "), 0xfe10, {.d_s = s}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } case -2: { return (_result_u64){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("common_parse_uint: wrong bit size "), 0xfe07, {.d_i32 = _bit_size}}, {_S(" for "), 0xfe10, {.d_s = s}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } case -3: { return (_result_u64){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("common_parse_uint: integer overflow "), 0xfe10, {.d_s = s}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } default: { { return (_result_u64){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("common_parse_uint: syntax error "), 0xfe10, {.d_s = s}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } } } _result_u64 _t5 = {0}; _result_ok(&(u64[]) { result }, (_result*)(&_t5), sizeof(u64)); return _t5; } multi_return_u64_int strconv__common_parse_uint2(string s, int _base, int _bit_size) { if ((s).len == 0) { return (multi_return_u64_int){.arg0=((u64)(0U)), .arg1=1}; } int bit_size = _bit_size; int base = _base; int start_index = 0; if (base == 0) { base = 10; if (s.str[ 0] == '0') { u8 ch = (s.len > 1 ? ((s.str[ 1] | 32)) : ('0')); if (s.len >= 3) { if (ch == 'b') { base = 2; start_index += 2; } else if (ch == 'o') { base = 8; start_index += 2; } else if (ch == 'x') { base = 16; start_index += 2; } if (s.str[ start_index] == '_') { start_index++; } } else if (s.len >= 2 && (s.str[ 1] >= '0' && s.str[ 1] <= '9')) { base = 10; start_index++; } else { base = 8; start_index++; } } } if (bit_size == 0) { bit_size = _const_strconv__int_size; } else if (bit_size < 0 || bit_size > 64) { return (multi_return_u64_int){.arg0=((u64)(0U)), .arg1=-2}; } u64 cutoff = (u64)((u64)(_const_max_u64 / ((u64)(base))) + ((u64)(1U))); u64 max_val = (bit_size == 64 ? (_const_max_u64) : ((u64)(((((u64)(1U)) << ((u64)(bit_size)))) - ((u64)(1U))))); int basem1 = (int)(base - 1); u64 n = ((u64)(0U)); for (int i = start_index; i < s.len; ++i) { u8 c = s.str[ i]; if (c == '_') { if (i == start_index || i >= ((int)(s.len - 1))) { return (multi_return_u64_int){.arg0=((u64)(0U)), .arg1=1}; } if (s.str[ (int)(i - 1)] == '_' || s.str[ (int)(i + 1)] == '_') { return (multi_return_u64_int){.arg0=((u64)(0U)), .arg1=1}; } continue; } int sub_count = 0; c -= 48; if (c >= 17) { sub_count++; c -= 7; if (c >= 42) { sub_count++; c -= 32; } } if (c > basem1 || (sub_count == 0 && c > 9)) { return (multi_return_u64_int){.arg0=n, .arg1=(int)(i + 1)}; } if (n >= cutoff) { return (multi_return_u64_int){.arg0=max_val, .arg1=-3}; } n *= ((u64)(base)); u64 n1 = (u64)(n + ((u64)(c))); if (n1 < n || n1 > max_val) { return (multi_return_u64_int){.arg0=max_val, .arg1=-3}; } n = n1; } return (multi_return_u64_int){.arg0=n, .arg1=0}; } _result_u64 strconv__parse_uint(string s, int _base, int _bit_size) { return strconv__common_parse_uint(s, _base, _bit_size, true, true); } _result_i64 strconv__common_parse_int(string _s, int base, int _bit_size, bool error_on_non_digit, bool error_on_high_digit) { if ((_s).len == 0) { _result_i64 _t1 = {0}; _result_ok(&(i64[]) { ((i64)(0)) }, (_result*)(&_t1), sizeof(i64)); return _t1; } int bit_size = _bit_size; if (bit_size == 0) { bit_size = _const_strconv__int_size; } string s = _s; bool neg = false; if (s.str[ 0] == '+') { { // Unsafe block s = tos(s.str + 1, (int)(s.len - 1)); } } else if (s.str[ 0] == '-') { neg = true; { // Unsafe block s = tos(s.str + 1, (int)(s.len - 1)); } } _result_u64 _t2 = strconv__common_parse_uint(s, base, bit_size, error_on_non_digit, error_on_high_digit); if (_t2.is_error) { _result_i64 _t3 = {0}; _t3.is_error = true; _t3.err = _t2.err; return _t3; } u64 un = (*(u64*)_t2.data); if (un == 0U) { _result_i64 _t4 = {0}; _result_ok(&(i64[]) { ((i64)(0)) }, (_result*)(&_t4), sizeof(i64)); return _t4; } u64 cutoff = (((u64)(1U)) << ((u64)((int)(bit_size - 1)))); if (!neg && un >= cutoff) { _result_i64 _t5 = {0}; _result_ok(&(i64[]) { ((i64)((u64)(cutoff - ((u64)(1U))))) }, (_result*)(&_t5), sizeof(i64)); return _t5; } if (neg && un > cutoff) { _result_i64 _t6 = {0}; _result_ok(&(i64[]) { -((i64)(cutoff)) }, (_result*)(&_t6), sizeof(i64)); return _t6; } _result_i64 _t8; /* if prepend */ if (neg) { _result_ok(&(i64[]) { -((i64)(un)) }, (_result*)(&_t8), sizeof(i64)); } else { _result_ok(&(i64[]) { ((i64)(un)) }, (_result*)(&_t8), sizeof(i64)); } return _t8; } string strconv__Dec32_get_string_32(strconv__Dec32 d, bool neg, int i_n_digit, int i_pad_digit) { int n_digit = (int)(i_n_digit + 1); int pad_digit = (int)(i_pad_digit + 1); u32 out = d.m; int out_len = strconv__dec_digits(out); int out_len_original = out_len; int fw_zeros = 0; if (pad_digit > out_len) { fw_zeros = (int)(pad_digit - out_len); } Array_u8 buf = __new_array_with_default(((int)((int)((int)((int)(out_len + 5) + 1) + 1))), 0, sizeof(u8), 0); int i = 0; if (neg) { if (buf.data != 0) { ((u8*)buf.data)[i] = '-'; } i++; } int disp = 0; if (out_len <= 1) { disp = 1; } if (n_digit < out_len) { out += (u32)(_const_strconv__ten_pow_table_32[(int)((int)(out_len - n_digit) - 1)] * 5U); out /= _const_strconv__ten_pow_table_32[(int)(out_len - n_digit)]; out_len = n_digit; } int y = (int)(i + out_len); int x = 0; for (;;) { if (!(x < ((int)((int)(out_len - disp) - 1)))) break; ((u8*)buf.data)[(int)(y - x)] = (rune)('0' + ((u8)((u32)(out % 10U)))); out /= 10U; i++; x++; } if (i_n_digit == 0) { { // Unsafe block ((u8*)buf.data)[i] = 0; return tos(((u8*)(&((u8*)buf.data)[0])), i); } } if (out_len >= 1) { ((u8*)buf.data)[(int)(y - x)] = '.'; x++; i++; } if ((int)(y - x) >= 0) { ((u8*)buf.data)[(int)(y - x)] = (rune)('0' + ((u8)((u32)(out % 10U)))); i++; } for (;;) { if (!(fw_zeros > 0)) break; ((u8*)buf.data)[i] = '0'; i++; fw_zeros--; } ((u8*)buf.data)[i] = 'e'; i++; int exp = (int)((int)(d.e + out_len_original) - 1); if (exp < 0) { ((u8*)buf.data)[i] = '-'; i++; exp = -exp; } else { ((u8*)buf.data)[i] = '+'; i++; } int d1 = (int)(exp % 10); int d0 = (int)(exp / 10); ((u8*)buf.data)[i] = (rune)('0' + ((u8)(d0))); i++; ((u8*)buf.data)[i] = (rune)('0' + ((u8)(d1))); i++; ((u8*)buf.data)[i] = 0; return tos(((u8*)(&((u8*)buf.data)[0])), i); } VV_LOC multi_return_strconv__Dec32_bool strconv__f32_to_decimal_exact_int(u32 i_mant, u32 exp) { strconv__Dec32 d = ((strconv__Dec32){.m = 0,.e = 0,}); u32 e = (u32)(exp - 127U); if (e > _const_strconv__mantbits32) { return (multi_return_strconv__Dec32_bool){.arg0=d, .arg1=false}; } u32 shift = (u32)(_const_strconv__mantbits32 - e); u32 mant = (i_mant | 0x00800000U); d.m = (mant >> shift); if (((d.m << shift)) != mant) { return (multi_return_strconv__Dec32_bool){.arg0=d, .arg1=false}; } for (;;) { if (!(((u32)(d.m % 10U)) == 0U)) break; d.m /= 10U; d.e++; } return (multi_return_strconv__Dec32_bool){.arg0=d, .arg1=true}; } VV_LOC strconv__Dec32 strconv__f32_to_decimal(u32 mant, u32 exp) { int e2 = 0; u32 m2 = ((u32)(0U)); if (exp == 0U) { e2 = (int)((int)(-126 - ((int)(_const_strconv__mantbits32))) - 2); m2 = mant; } else { e2 = (int)((int)((int)(((int)(exp)) - 127) - ((int)(_const_strconv__mantbits32))) - 2); m2 = (((((u32)(1U)) << _const_strconv__mantbits32)) | mant); } bool even = ((m2 & 1U)) == 0U; bool accept_bounds = even; u32 mv = ((u32)((u32)(4 * m2))); u32 mp = ((u32)((u32)((u32)(4 * m2) + 2U))); u32 mm_shift = strconv__bool_to_u32(mant != 0U || exp <= 1U); u32 mm = ((u32)((u32)((u32)((u32)(4 * m2) - 1U) - mm_shift))); u32 vr = ((u32)(0U)); u32 vp = ((u32)(0U)); u32 vm = ((u32)(0U)); int e10 = 0; bool vm_is_trailing_zeros = false; bool vr_is_trailing_zeros = false; u8 last_removed_digit = ((u8)(0)); if (e2 >= 0) { u32 q = strconv__log10_pow2(e2); e10 = ((int)(q)); int k = (int)((int)(59 + strconv__pow5_bits(((int)(q)))) - 1); int i = (int)((int)(-e2 + ((int)(q))) + k); vr = strconv__mul_pow5_invdiv_pow2(mv, q, i); vp = strconv__mul_pow5_invdiv_pow2(mp, q, i); vm = strconv__mul_pow5_invdiv_pow2(mm, q, i); if (q != 0U && (u32)(((u32)(vp - 1U)) / 10U) <= (u32)(vm / 10U)) { int l = (int)((int)(59 + strconv__pow5_bits(((int)((u32)(q - 1U))))) - 1); last_removed_digit = ((u8)((u32)(strconv__mul_pow5_invdiv_pow2(mv, (u32)(q - 1U), (int)((int)(-e2 + ((int)((u32)(q - 1U)))) + l)) % 10U))); } if (q <= 9U) { if ((u32)(mv % 5U) == 0U) { vr_is_trailing_zeros = strconv__multiple_of_power_of_five_32(mv, q); } else if (accept_bounds) { vm_is_trailing_zeros = strconv__multiple_of_power_of_five_32(mm, q); } else if (strconv__multiple_of_power_of_five_32(mp, q)) { vp--; } } } else { u32 q = strconv__log10_pow5(-e2); e10 = (int)(((int)(q)) + e2); int i = (int)(-e2 - ((int)(q))); int k = (int)(strconv__pow5_bits(i) - 61); int j = (int)(((int)(q)) - k); vr = strconv__mul_pow5_div_pow2(mv, ((u32)(i)), j); vp = strconv__mul_pow5_div_pow2(mp, ((u32)(i)), j); vm = strconv__mul_pow5_div_pow2(mm, ((u32)(i)), j); if (q != 0U && ((u32)(((u32)(vp - 1U)) / 10U)) <= (u32)(vm / 10U)) { j = (int)((int)(((int)(q)) - 1) - ((int)(strconv__pow5_bits((int)(i + 1)) - 61))); last_removed_digit = ((u8)((u32)(strconv__mul_pow5_div_pow2(mv, ((u32)((int)(i + 1))), j) % 10U))); } if (q <= 1U) { vr_is_trailing_zeros = true; if (accept_bounds) { vm_is_trailing_zeros = mm_shift == 1U; } else { vp--; } } else if (q < 31U) { vr_is_trailing_zeros = strconv__multiple_of_power_of_two_32(mv, (u32)(q - 1U)); } } int removed = 0; u32 out = ((u32)(0U)); if (vm_is_trailing_zeros || vr_is_trailing_zeros) { for (;;) { if (!((u32)(vp / 10U) > (u32)(vm / 10U))) break; vm_is_trailing_zeros = vm_is_trailing_zeros && ((u32)(vm % 10U)) == 0U; vr_is_trailing_zeros = vr_is_trailing_zeros && last_removed_digit == 0; last_removed_digit = ((u8)((u32)(vr % 10U))); vr /= 10U; vp /= 10U; vm /= 10U; removed++; } if (vm_is_trailing_zeros) { for (;;) { if (!((u32)(vm % 10U) == 0U)) break; vr_is_trailing_zeros = vr_is_trailing_zeros && last_removed_digit == 0; last_removed_digit = ((u8)((u32)(vr % 10U))); vr /= 10U; vp /= 10U; vm /= 10U; removed++; } } if (vr_is_trailing_zeros && last_removed_digit == 5 && ((u32)(vr % 2U)) == 0U) { last_removed_digit = 4; } out = vr; if ((vr == vm && (!accept_bounds || !vm_is_trailing_zeros)) || last_removed_digit >= 5) { out++; } } else { for (;;) { if (!((u32)(vp / 10U) > (u32)(vm / 10U))) break; last_removed_digit = ((u8)((u32)(vr % 10U))); vr /= 10U; vp /= 10U; vm /= 10U; removed++; } out = (u32)(vr + strconv__bool_to_u32(vr == vm || last_removed_digit >= 5)); } return ((strconv__Dec32){.m = out,.e = (int)(e10 + removed),}); } string strconv__f32_to_str(f32 f, int n_digit) { strconv__Uf32 u1 = ((strconv__Uf32){0}); u1.f = f; u32 u = u1.u; bool neg = ((u >> ((u32)(_const_strconv__mantbits32 + _const_strconv__expbits32)))) != 0U; u32 mant = (u & ((u32)(((((u32)(1U)) << _const_strconv__mantbits32)) - ((u32)(1U))))); u32 exp = (((u >> _const_strconv__mantbits32)) & ((u32)(((((u32)(1U)) << _const_strconv__expbits32)) - ((u32)(1U))))); if (exp == 255U || (exp == 0U && mant == 0U)) { return strconv__get_string_special(neg, exp == 0U, mant == 0U); } multi_return_strconv__Dec32_bool mr_8566 = strconv__f32_to_decimal_exact_int(mant, exp); strconv__Dec32 d = mr_8566.arg0; bool ok = mr_8566.arg1; if (!ok) { d = strconv__f32_to_decimal(mant, exp); } return strconv__Dec32_get_string_32(d, neg, n_digit, 0); } VV_LOC string strconv__Dec64_get_string_64(strconv__Dec64 d, bool neg, int i_n_digit, int i_pad_digit) { int n_digit = (i_n_digit < 1 ? (1) : ((int)(i_n_digit + 1))); int pad_digit = (int)(i_pad_digit + 1); u64 out = d.m; int d_exp = d.e; int out_len = strconv__dec_digits(out); int out_len_original = out_len; int fw_zeros = 0; if (pad_digit > out_len) { fw_zeros = (int)(pad_digit - out_len); } Array_u8 buf = __new_array_with_default(((int)((int)((int)((int)(out_len + 6) + 1) + 1) + fw_zeros)), 0, sizeof(u8), 0); int i = 0; if (neg) { ((u8*)buf.data)[i] = '-'; i++; } int disp = 0; if (out_len <= 1) { disp = 1; } if (n_digit < out_len) { out += (u64)(_const_strconv__ten_pow_table_64[(int)((int)(out_len - n_digit) - 1)] * 5U); out /= _const_strconv__ten_pow_table_64[(int)(out_len - n_digit)]; u64 out_div = (u64)(d.m / _const_strconv__ten_pow_table_64[(int)(out_len - n_digit)]); if (out_div < out && strconv__dec_digits(out_div) < strconv__dec_digits(out)) { d_exp++; n_digit++; } out_len = n_digit; } int y = (int)(i + out_len); int x = 0; for (;;) { if (!(x < ((int)((int)(out_len - disp) - 1)))) break; ((u8*)buf.data)[(int)(y - x)] = (rune)('0' + ((u8)((u64)(out % 10U)))); out /= 10U; i++; x++; } if (out_len >= 1) { ((u8*)buf.data)[(int)(y - x)] = '.'; x++; i++; } if ((int)(y - x) >= 0) { ((u8*)buf.data)[(int)(y - x)] = (rune)('0' + ((u8)((u64)(out % 10U)))); i++; } for (;;) { if (!(fw_zeros > 0)) break; ((u8*)buf.data)[i] = '0'; i++; fw_zeros--; } ((u8*)buf.data)[i] = 'e'; i++; int exp = (int)((int)(d_exp + out_len_original) - 1); if (exp < 0) { ((u8*)buf.data)[i] = '-'; i++; exp = -exp; } else { ((u8*)buf.data)[i] = '+'; i++; } int d2 = (int)(exp % 10); exp /= 10; int d1 = (int)(exp % 10); int d0 = (int)(exp / 10); if (d0 > 0) { ((u8*)buf.data)[i] = (rune)('0' + ((u8)(d0))); i++; } ((u8*)buf.data)[i] = (rune)('0' + ((u8)(d1))); i++; ((u8*)buf.data)[i] = (rune)('0' + ((u8)(d2))); i++; ((u8*)buf.data)[i] = 0; return tos(((u8*)(&((u8*)buf.data)[0])), i); } VV_LOC multi_return_strconv__Dec64_bool strconv__f64_to_decimal_exact_int(u64 i_mant, u64 exp) { strconv__Dec64 d = ((strconv__Dec64){.m = 0,.e = 0,}); u64 e = (u64)(exp - 1023U); if (e > _const_strconv__mantbits64) { return (multi_return_strconv__Dec64_bool){.arg0=d, .arg1=false}; } u64 shift = (u64)(_const_strconv__mantbits64 - e); u64 mant = (i_mant | ((u64)(0x0010000000000000U))); d.m = (mant >> shift); if (((d.m << shift)) != mant) { return (multi_return_strconv__Dec64_bool){.arg0=d, .arg1=false}; } for (;;) { if (!(((u64)(d.m % 10U)) == 0U)) break; d.m /= 10U; d.e++; } return (multi_return_strconv__Dec64_bool){.arg0=d, .arg1=true}; } VV_LOC strconv__Dec64 strconv__f64_to_decimal(u64 mant, u64 exp) { int e2 = 0; u64 m2 = ((u64)(0U)); if (exp == 0U) { e2 = (int)((int)(-1022 - ((int)(_const_strconv__mantbits64))) - 2); m2 = mant; } else { e2 = (int)((int)((int)(((int)(exp)) - 1023) - ((int)(_const_strconv__mantbits64))) - 2); m2 = (((((u64)(1U)) << _const_strconv__mantbits64)) | mant); } bool even = ((m2 & 1U)) == 0U; bool accept_bounds = even; u64 mv = ((u64)((u64)(4 * m2))); u64 mm_shift = strconv__bool_to_u64(mant != 0U || exp <= 1U); u64 vr = ((u64)(0U)); u64 vp = ((u64)(0U)); u64 vm = ((u64)(0U)); int e10 = 0; bool vm_is_trailing_zeros = false; bool vr_is_trailing_zeros = false; if (e2 >= 0) { u32 q = (u32)(strconv__log10_pow2(e2) - strconv__bool_to_u32(e2 > 3)); e10 = ((int)(q)); int k = (int)((int)(122 + strconv__pow5_bits(((int)(q)))) - 1); int i = (int)((int)(-e2 + ((int)(q))) + k); strconv__Uint128 mul = *(((strconv__Uint128*)(&_const_strconv__pow5_inv_split_64_x[v_fixed_index((u32)(q * 2U), 584)]))); vr = strconv__mul_shift_64((u64)(((u64)(4U)) * m2), mul, i); vp = strconv__mul_shift_64((u64)((u64)(((u64)(4U)) * m2) + ((u64)(2U))), mul, i); vm = strconv__mul_shift_64((u64)((u64)((u64)(((u64)(4U)) * m2) - ((u64)(1U))) - mm_shift), mul, i); if (q <= 21U) { if ((u64)(mv % 5U) == 0U) { vr_is_trailing_zeros = strconv__multiple_of_power_of_five_64(mv, q); } else if (accept_bounds) { vm_is_trailing_zeros = strconv__multiple_of_power_of_five_64((u64)((u64)(mv - 1U) - mm_shift), q); } else if (strconv__multiple_of_power_of_five_64((u64)(mv + 2U), q)) { vp--; } } } else { u32 q = (u32)(strconv__log10_pow5(-e2) - strconv__bool_to_u32(-e2 > 1)); e10 = (int)(((int)(q)) + e2); int i = (int)(-e2 - ((int)(q))); int k = (int)(strconv__pow5_bits(i) - 121); int j = (int)(((int)(q)) - k); strconv__Uint128 mul = *(((strconv__Uint128*)(&_const_strconv__pow5_split_64_x[v_fixed_index((int)(i * 2), 652)]))); vr = strconv__mul_shift_64((u64)(((u64)(4U)) * m2), mul, j); vp = strconv__mul_shift_64((u64)((u64)(((u64)(4U)) * m2) + ((u64)(2U))), mul, j); vm = strconv__mul_shift_64((u64)((u64)((u64)(((u64)(4U)) * m2) - ((u64)(1U))) - mm_shift), mul, j); if (q <= 1U) { vr_is_trailing_zeros = true; if (accept_bounds) { vm_is_trailing_zeros = (mm_shift == 1U); } else { vp--; } } else if (q < 63U) { vr_is_trailing_zeros = strconv__multiple_of_power_of_two_64(mv, (u32)(q - 1U)); } } int removed = 0; u8 last_removed_digit = ((u8)(0)); u64 out = ((u64)(0U)); if (vm_is_trailing_zeros || vr_is_trailing_zeros) { for (;;) { u64 vp_div_10 = (u64)(vp / 10U); u64 vm_div_10 = (u64)(vm / 10U); if (vp_div_10 <= vm_div_10) { break; } u64 vm_mod_10 = (u64)(vm % 10U); u64 vr_div_10 = (u64)(vr / 10U); u64 vr_mod_10 = (u64)(vr % 10U); vm_is_trailing_zeros = vm_is_trailing_zeros && vm_mod_10 == 0U; vr_is_trailing_zeros = vr_is_trailing_zeros && last_removed_digit == 0; last_removed_digit = ((u8)(vr_mod_10)); vr = vr_div_10; vp = vp_div_10; vm = vm_div_10; removed++; } if (vm_is_trailing_zeros) { for (;;) { u64 vm_div_10 = (u64)(vm / 10U); u64 vm_mod_10 = (u64)(vm % 10U); if (vm_mod_10 != 0U) { break; } u64 vp_div_10 = (u64)(vp / 10U); u64 vr_div_10 = (u64)(vr / 10U); u64 vr_mod_10 = (u64)(vr % 10U); vr_is_trailing_zeros = vr_is_trailing_zeros && last_removed_digit == 0; last_removed_digit = ((u8)(vr_mod_10)); vr = vr_div_10; vp = vp_div_10; vm = vm_div_10; removed++; } } if (vr_is_trailing_zeros && last_removed_digit == 5 && ((u64)(vr % 2U)) == 0U) { last_removed_digit = 4; } out = vr; if ((vr == vm && (!accept_bounds || !vm_is_trailing_zeros)) || last_removed_digit >= 5) { out++; } } else { bool round_up = false; for (;;) { if (!((u64)(vp / 100U) > (u64)(vm / 100U))) break; round_up = ((u64)(vr % 100U)) >= 50U; vr /= 100U; vp /= 100U; vm /= 100U; removed += 2; } for (;;) { if (!((u64)(vp / 10U) > (u64)(vm / 10U))) break; round_up = ((u64)(vr % 10U)) >= 5U; vr /= 10U; vp /= 10U; vm /= 10U; removed++; } out = (u64)(vr + strconv__bool_to_u64(vr == vm || round_up)); } return ((strconv__Dec64){.m = out,.e = (int)(e10 + removed),}); } string strconv__f64_to_str(f64 f, int n_digit) { strconv__Uf64 u1 = ((strconv__Uf64){0}); u1.f = f; u64 u = u1.u; bool neg = ((u >> ((u32)(_const_strconv__mantbits64 + _const_strconv__expbits64)))) != 0U; u64 mant = (u & ((u64)(((((u64)(1U)) << _const_strconv__mantbits64)) - ((u64)(1U))))); u64 exp = (((u >> _const_strconv__mantbits64)) & ((u64)(((((u64)(1U)) << _const_strconv__expbits64)) - ((u64)(1U))))); if (exp == 2047U || (exp == 0U && mant == 0U)) { return strconv__get_string_special(neg, exp == 0U, mant == 0U); } multi_return_strconv__Dec64_bool mr_9551 = strconv__f64_to_decimal_exact_int(mant, exp); strconv__Dec64 d = mr_9551.arg0; bool ok = mr_9551.arg1; if (!ok) { d = strconv__f64_to_decimal(mant, exp); } return strconv__Dec64_get_string_64(d, neg, n_digit, 0); } string strconv__f64_to_str_pad(f64 f, int n_digit) { strconv__Uf64 u1 = ((strconv__Uf64){0}); u1.f = f; u64 u = u1.u; bool neg = ((u >> ((u32)(_const_strconv__mantbits64 + _const_strconv__expbits64)))) != 0U; u64 mant = (u & ((u64)(((((u64)(1U)) << _const_strconv__mantbits64)) - ((u64)(1U))))); u64 exp = (((u >> _const_strconv__mantbits64)) & ((u64)(((((u64)(1U)) << _const_strconv__expbits64)) - ((u64)(1U))))); if (exp == 2047U || (exp == 0U && mant == 0U)) { return strconv__get_string_special(neg, exp == 0U, mant == 0U); } multi_return_strconv__Dec64_bool mr_10332 = strconv__f64_to_decimal_exact_int(mant, exp); strconv__Dec64 d = mr_10332.arg0; bool ok = mr_10332.arg1; if (!ok) { d = strconv__f64_to_decimal(mant, exp); } return strconv__Dec64_get_string_64(d, neg, n_digit, n_digit); } void strconv__format_str_sb(string s, strconv__BF_param p, strings__Builder* sb) { if (p.len0 <= 0) { strings__Builder_write_string(sb, s); return; } int dif = (int)(p.len0 - utf8_str_visible_length(s)); if (dif <= 0) { strings__Builder_write_string(sb, s); return; } if (p.align == strconv__Align_text__right) { for (int i1 = 0; i1 < dif; i1++) { strings__Builder_write_u8(sb, p.pad_ch); } } strings__Builder_write_string(sb, s); if (p.align == strconv__Align_text__left) { for (int i1 = 0; i1 < dif; i1++) { strings__Builder_write_u8(sb, p.pad_ch); } } } void strconv__format_dec_sb(u64 d, strconv__BF_param p, strings__Builder* res) { int n_char = strconv__dec_digits(d); int sign_len = (!p.positive || p.sign_flag ? (1) : (0)); int number_len = (int)(sign_len + n_char); int dif = (int)(p.len0 - number_len); bool sign_written = false; if (p.align == strconv__Align_text__right) { if (p.pad_ch == '0') { if (p.positive) { if (p.sign_flag) { strings__Builder_write_u8(res, '+'); sign_written = true; } } else { strings__Builder_write_u8(res, '-'); sign_written = true; } } for (int i1 = 0; i1 < dif; i1++) { strings__Builder_write_u8(res, p.pad_ch); } } if (!sign_written) { if (p.positive) { if (p.sign_flag) { strings__Builder_write_u8(res, '+'); } } else { strings__Builder_write_u8(res, '-'); } } Array_fixed_u8_32 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int i = 20; u64 n = d; u64 d_i = ((u64)(0U)); if (n > 0U) { for (;;) { if (!(n > 0U)) break; u64 n1 = (u64)(n / 100U); d_i = (((u64)(n - ((u64)(n1 * 100U)))) << 1U); n = n1; { // Unsafe block buf[i] = _const_strconv__digit_pairs.str[d_i]; } i--; d_i++; { // Unsafe block buf[i] = _const_strconv__digit_pairs.str[d_i]; } i--; } i++; if (d_i < 20U) { i++; } strings__Builder_write_ptr(res, &buf[i], n_char); } else { strings__Builder_write_u8(res, '0'); } if (p.align == strconv__Align_text__left) { for (int i1 = 0; i1 < dif; i1++) { strings__Builder_write_u8(res, p.pad_ch); } } return; } string strconv__f64_to_str_lnd1(f64 f, int dec_digit) { { // Unsafe block string s = strconv__f64_to_str((f64)(f + _const_strconv__dec_round[dec_digit]), 18); if (s.len > 2 && (s.str[ 0] == 'n' || s.str[ 1] == 'i')) { return s; } bool m_sgn_flag = false; int sgn = 1; Array_fixed_u8_26 b = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int d_pos = 1; int i = 0; int i1 = 0; int exp = 0; int exp_sgn = 1; int dot_res_sp = -1; for (int _t2 = 0; _t2 < s.len; ++_t2) { u8 c = s.str[_t2]; if (c == ('-')) { sgn = -1; i++; } else if (c == ('+')) { sgn = 1; i++; } else if ((c >= '0' && c <= '9')) { b[i1] = c; i1++; i++; } else if (c == ('.')) { if (sgn > 0) { d_pos = i; } else { d_pos = (int)(i - 1); } i++; } else if (c == ('e')) { i++; break; } else { string_free(&s); return _S("[Float conversion error!!]"); } } b[i1] = 0; if (s.str[ i] == '-') { exp_sgn = -1; i++; } else if (s.str[ i] == '+') { exp_sgn = 1; i++; } int c = i; for (;;) { if (!(c < s.len)) break; exp = (int)((int)(exp * 10) + ((int)((rune)(s.str[ c] - '0')))); c++; } Array_u8 res = __new_array_with_default((int)(exp + 40), 0, sizeof(u8), &(u8[]){0}); int r_i = 0; string_free(&s); if (sgn == 1) { if (m_sgn_flag) { ((u8*)res.data)[r_i] = '+'; r_i++; } } else { ((u8*)res.data)[r_i] = '-'; r_i++; } i = 0; if (exp_sgn >= 0) { for (;;) { if (!(b[i] != 0)) break; ((u8*)res.data)[r_i] = b[i]; r_i++; i++; if (i >= d_pos && exp >= 0) { if (exp == 0) { dot_res_sp = r_i; ((u8*)res.data)[r_i] = '.'; r_i++; } exp--; } } for (;;) { if (!(exp >= 0)) break; ((u8*)res.data)[r_i] = '0'; r_i++; exp--; } } else { bool dot_p = true; for (;;) { if (!(exp > 0)) break; ((u8*)res.data)[r_i] = '0'; r_i++; exp--; if (dot_p) { dot_res_sp = r_i; ((u8*)res.data)[r_i] = '.'; r_i++; dot_p = false; } } for (;;) { if (!(b[i] != 0)) break; ((u8*)res.data)[r_i] = b[i]; r_i++; i++; } } if (dec_digit <= 0) { if (dot_res_sp < 0) { dot_res_sp = (int)(i + 1); } string tmp_res = string_clone(tos(res.data, dot_res_sp)); array_free(&res); return tmp_res; } if (dot_res_sp >= 0) { r_i = (int)((int)(dot_res_sp + dec_digit) + 1); ((u8*)res.data)[r_i] = 0; for (int c1 = 1; c1 < (int)(dec_digit + 1); ++c1) { if (((u8*)res.data)[(int)(r_i - c1)] == 0) { ((u8*)res.data)[(int)(r_i - c1)] = '0'; } } string tmp_res = string_clone(tos(res.data, r_i)); array_free(&res); return tmp_res; } else { if (dec_digit > 0) { int c1 = 0; ((u8*)res.data)[r_i] = '.'; r_i++; for (;;) { if (!(c1 < dec_digit)) break; ((u8*)res.data)[r_i] = '0'; r_i++; c1++; } ((u8*)res.data)[r_i] = 0; } string tmp_res = string_clone(tos(res.data, r_i)); array_free(&res); return tmp_res; } } return (string){.str=(byteptr)"", .is_lit=1}; } string strconv__format_fl(f64 f, strconv__BF_param p) { { // Unsafe block string fs = strconv__f64_to_str_lnd1((f >= ((f64)(0.0)) ? (f) : (-f)), p.len1); if (fs.str[ 0] == '[') { return fs; } if (p.rm_tail_zero) { string tmp = fs; fs = strconv__remove_tail_zeros(fs); string_free(&tmp); } Array_fixed_u8_512 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; Array_fixed_u8_512 out = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int buf_i = 0; int out_i = 0; int sign_len_diff = 0; if (p.pad_ch == '0') { if (p.positive) { if (p.sign_flag) { out[out_i] = '+'; out_i++; sign_len_diff = -1; } } else { out[out_i] = '-'; out_i++; sign_len_diff = -1; } } else { if (p.positive) { if (p.sign_flag) { buf[buf_i] = '+'; buf_i++; } } else { buf[buf_i] = '-'; buf_i++; } } vmemcpy(&buf[buf_i], fs.str, fs.len); buf_i += fs.len; int dif = (int)((int)(p.len0 - buf_i) + sign_len_diff); if (p.align == strconv__Align_text__right) { for (int i1 = 0; i1 < dif; i1++) { out[out_i] = p.pad_ch; out_i++; } } vmemcpy(&out[out_i], &buf[0], buf_i); out_i += buf_i; if (p.align == strconv__Align_text__left) { for (int i1 = 0; i1 < dif; i1++) { out[out_i] = p.pad_ch; out_i++; } } out[out_i] = 0; string tmp = fs; fs = tos_clone(&out[0]); string_free(&tmp); return fs; } return (string){.str=(byteptr)"", .is_lit=1}; } string strconv__format_es(f64 f, strconv__BF_param p) { { // Unsafe block string fs = strconv__f64_to_str_pad((f > 0 ? (f) : (-f)), p.len1); if (p.rm_tail_zero) { string tmp = fs; fs = strconv__remove_tail_zeros(fs); string_free(&tmp); } Array_fixed_u8_512 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; Array_fixed_u8_512 out = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int buf_i = 0; int out_i = 0; int sign_len_diff = 0; if (p.pad_ch == '0') { if (p.positive) { if (p.sign_flag) { out[out_i] = '+'; out_i++; sign_len_diff = -1; } } else { out[out_i] = '-'; out_i++; sign_len_diff = -1; } } else { if (p.positive) { if (p.sign_flag) { buf[buf_i] = '+'; buf_i++; } } else { buf[buf_i] = '-'; buf_i++; } } vmemcpy(&buf[buf_i], fs.str, fs.len); buf_i += fs.len; int dif = (int)((int)(p.len0 - buf_i) + sign_len_diff); if (p.align == strconv__Align_text__right) { for (int i1 = 0; i1 < dif; i1++) { out[out_i] = p.pad_ch; out_i++; } } vmemcpy(&out[out_i], &buf[0], buf_i); out_i += buf_i; if (p.align == strconv__Align_text__left) { for (int i1 = 0; i1 < dif; i1++) { out[out_i] = p.pad_ch; out_i++; } } out[out_i] = 0; string tmp = fs; fs = tos_clone(&out[0]); string_free(&tmp); return fs; } return (string){.str=(byteptr)"", .is_lit=1}; } string strconv__remove_tail_zeros(string s) { { // Unsafe block u8* buf = malloc_noscan((int)(s.len + 1)); int i_d = 0; int i_s = 0; for (;;) { if (!(i_s < s.len && !(s.str[ i_s] == '-' || s.str[ i_s] == '+') && (s.str[ i_s] > '9' || s.str[ i_s] < '0'))) break; buf[i_d] = s.str[ i_s]; i_s++; i_d++; } if (i_s < s.len && (s.str[ i_s] == '-' || s.str[ i_s] == '+')) { buf[i_d] = s.str[ i_s]; i_s++; i_d++; } for (;;) { if (!(i_s < s.len && s.str[ i_s] >= '0' && s.str[ i_s] <= '9')) break; buf[i_d] = s.str[ i_s]; i_s++; i_d++; } if (i_s < s.len && s.str[ i_s] == '.') { int i_s1 = (int)(i_s + 1); int sum = 0; int i_s2 = i_s1; for (;;) { if (!(i_s1 < s.len && s.str[ i_s1] >= '0' && s.str[ i_s1] <= '9')) break; sum += (u8)(s.str[ i_s1] - ((u8)('0'))); if (s.str[ i_s1] != '0') { i_s2 = i_s1; } i_s1++; } if (sum > 0) { for (int c_i = i_s; c_i < (int)(i_s2 + 1); ++c_i) { buf[i_d] = s.str[ c_i]; i_d++; } } i_s = i_s1; } if (i_s < s.len && s.str[ i_s] != '.') { for (;;) { buf[i_d] = s.str[ i_s]; i_s++; i_d++; if (i_s >= s.len) { break; } } } buf[i_d] = 0; return tos(buf, i_d); } return (string){.str=(byteptr)"", .is_lit=1}; } inline string strconv__ftoa_64(f64 f) { return strconv__f64_to_str(f, 17); } inline string strconv__ftoa_32(f32 f) { return strconv__f32_to_str(f, 8); } string strconv__format_int(i64 n, int radix) { { // Unsafe block if (radix < 2 || radix > 36) { panic_n(_S("invalid radix, it should be => 2 and <= 36, actual:"), radix); VUNREACHABLE(); } if (n == 0) { return _S("0"); } i64 n_copy = n; bool have_minus = false; if (n < 0) { have_minus = true; n_copy = -n_copy; } string res = _S(""); for (;;) { if (!(n_copy != 0)) break; string tmp_0 = res; int bdx = ((int)((i64)(n_copy % radix))); string tmp_1 = u8_ascii_str(_const_strconv__base_digits.str[ bdx]); res = string__plus(tmp_1, res); string_free(&tmp_0); string_free(&tmp_1); n_copy /= radix; } if (have_minus) { string final_res = string__plus(_S("-"), res); string_free(&res); return final_res; } return res; } return (string){.str=(byteptr)"", .is_lit=1}; } string strconv__format_uint(u64 n, int radix) { { // Unsafe block if (radix < 2 || radix > 36) { panic_n(_S("invalid radix, it should be => 2 and <= 36, actual:"), radix); VUNREACHABLE(); } if (n == 0U) { return _S("0"); } u64 n_copy = n; string res = _S(""); u64 uradix = ((u64)(radix)); for (;;) { if (!(n_copy != 0U)) break; string tmp_0 = res; string tmp_1 = u8_ascii_str(_const_strconv__base_digits.str[ (u64)(n_copy % uradix)]); res = string__plus(tmp_1, res); string_free(&tmp_0); string_free(&tmp_1); n_copy /= uradix; } return res; } return (string){.str=(byteptr)"", .is_lit=1}; } string strconv__f32_to_str_l(f32 f) { string s = strconv__f32_to_str(f, 6); string res = strconv__fxx_to_str_l_parse(s); string_free(&s); return res; } string strconv__f32_to_str_l_with_dot(f32 f) { string s = strconv__f32_to_str(f, 6); string res = strconv__fxx_to_str_l_parse_with_dot(s); string_free(&s); return res; } string strconv__f64_to_str_l(f64 f) { string s = strconv__f64_to_str(f, 18); string res = strconv__fxx_to_str_l_parse(s); string_free(&s); return res; } string strconv__f64_to_str_l_with_dot(f64 f) { string s = strconv__f64_to_str(f, 18); string res = strconv__fxx_to_str_l_parse_with_dot(s); string_free(&s); return res; } string strconv__fxx_to_str_l_parse(string s) { if (s.len > 2 && (s.str[ 0] == 'n' || s.str[ 1] == 'i')) { return string_clone(s); } bool m_sgn_flag = false; int sgn = 1; Array_fixed_u8_26 b = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int d_pos = 1; int i = 0; int i1 = 0; int exp = 0; int exp_sgn = 1; for (int _t2 = 0; _t2 < s.len; ++_t2) { u8 c = s.str[_t2]; if (c == '-') { sgn = -1; i++; } else if (c == '+') { sgn = 1; i++; } else if (c >= '0' && c <= '9') { b[i1] = c; i1++; i++; } else if (c == '.') { if (sgn > 0) { d_pos = i; } else { d_pos = (int)(i - 1); } i++; } else if (c == 'e') { i++; break; } else { return _S("Float conversion error!!"); } } b[i1] = 0; if (s.str[ i] == '-') { exp_sgn = -1; i++; } else if (s.str[ i] == '+') { exp_sgn = 1; i++; } int c = i; for (;;) { if (!(c < s.len)) break; exp = (int)((int)(exp * 10) + ((int)((rune)(s.str[ c] - '0')))); c++; } Array_u8 res = __new_array_with_default((int)(exp + 32), 0, sizeof(u8), &(u8[]){0}); int r_i = 0; if (sgn == 1) { if (m_sgn_flag) { ((u8*)res.data)[r_i] = '+'; r_i++; } } else { ((u8*)res.data)[r_i] = '-'; r_i++; } i = 0; if (exp_sgn >= 0) { for (;;) { if (!(b[i] != 0)) break; ((u8*)res.data)[r_i] = b[i]; r_i++; i++; if (i >= d_pos && exp >= 0) { if (exp == 0) { ((u8*)res.data)[r_i] = '.'; r_i++; } exp--; } } for (;;) { if (!(exp >= 0)) break; ((u8*)res.data)[r_i] = '0'; r_i++; exp--; } } else { bool dot_p = true; for (;;) { if (!(exp > 0)) break; ((u8*)res.data)[r_i] = '0'; r_i++; exp--; if (dot_p) { ((u8*)res.data)[r_i] = '.'; r_i++; dot_p = false; } } for (;;) { if (!(b[i] != 0)) break; ((u8*)res.data)[r_i] = b[i]; r_i++; i++; } } if (r_i > 1 && ((u8*)res.data)[(int)(r_i - 1)] == '.') { ((u8*)res.data)[r_i] = '0'; r_i++; } else if (!(Array_u8_contains(res, '.'))) { ((u8*)res.data)[r_i] = '.'; r_i++; ((u8*)res.data)[r_i] = '0'; r_i++; } ((u8*)res.data)[r_i] = 0; return tos(res.data, r_i); } string strconv__fxx_to_str_l_parse_with_dot(string s) { if (s.len > 2 && (s.str[ 0] == 'n' || s.str[ 1] == 'i')) { return string_clone(s); } bool m_sgn_flag = false; int sgn = 1; Array_fixed_u8_26 b = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int d_pos = 1; int i = 0; int i1 = 0; int exp = 0; int exp_sgn = 1; for (int _t2 = 0; _t2 < s.len; ++_t2) { u8 c = s.str[_t2]; if (c == '-') { sgn = -1; i++; } else if (c == '+') { sgn = 1; i++; } else if (c >= '0' && c <= '9') { b[i1] = c; i1++; i++; } else if (c == '.') { if (sgn > 0) { d_pos = i; } else { d_pos = (int)(i - 1); } i++; } else if (c == 'e') { i++; break; } else { return _S("Float conversion error!!"); } } b[i1] = 0; if (s.str[ i] == '-') { exp_sgn = -1; i++; } else if (s.str[ i] == '+') { exp_sgn = 1; i++; } int c = i; for (;;) { if (!(c < s.len)) break; exp = (int)((int)(exp * 10) + ((int)((rune)(s.str[ c] - '0')))); c++; } Array_u8 res = __new_array_with_default((int)(exp + 32), 0, sizeof(u8), &(u8[]){0}); int r_i = 0; if (sgn == 1) { if (m_sgn_flag) { ((u8*)res.data)[r_i] = '+'; r_i++; } } else { ((u8*)res.data)[r_i] = '-'; r_i++; } i = 0; if (exp_sgn >= 0) { for (;;) { if (!(b[i] != 0)) break; ((u8*)res.data)[r_i] = b[i]; r_i++; i++; if (i >= d_pos && exp >= 0) { if (exp == 0) { ((u8*)res.data)[r_i] = '.'; r_i++; } exp--; } } for (;;) { if (!(exp >= 0)) break; ((u8*)res.data)[r_i] = '0'; r_i++; exp--; } } else { bool dot_p = true; for (;;) { if (!(exp > 0)) break; ((u8*)res.data)[r_i] = '0'; r_i++; exp--; if (dot_p) { ((u8*)res.data)[r_i] = '.'; r_i++; dot_p = false; } } for (;;) { if (!(b[i] != 0)) break; ((u8*)res.data)[r_i] = b[i]; r_i++; i++; } } if (r_i > 1 && ((u8*)res.data)[(int)(r_i - 1)] == '.') { ((u8*)res.data)[r_i] = '0'; r_i++; } else if (!(Array_u8_contains(res, '.'))) { ((u8*)res.data)[r_i] = '.'; r_i++; ((u8*)res.data)[r_i] = '0'; r_i++; } ((u8*)res.data)[r_i] = 0; return tos(res.data, r_i); } inline VV_LOC u32 strconv__bool_to_u32(bool b) { if (b) { return ((u32)(1U)); } return ((u32)(0U)); } inline VV_LOC u64 strconv__bool_to_u64(bool b) { if (b) { return ((u64)(1U)); } return ((u64)(0U)); } VV_LOC string strconv__get_string_special(bool neg, bool expZero, bool mantZero) { if (!mantZero) { return _S("nan"); } if (!expZero) { if (neg) { return _S("-inf"); } else { return _S("+inf"); } } if (neg) { return _S("-0e+00"); } return _S("0e+00"); } VV_LOC u32 strconv__mul_shift_32(u32 m, u64 mul, int ishift) { multi_return_u64_u64 mr_750 = math__bits__mul_64(((u64)(m)), mul); u64 hi = mr_750.arg0; u64 lo = mr_750.arg1; u64 shifted_sum = (u64)(((lo >> ((u64)(ishift)))) + ((hi << ((u64)((int)(64 - ishift)))))); ; return ((u32)(shifted_sum)); } inline VV_LOC u32 strconv__mul_pow5_invdiv_pow2(u32 m, u32 q, int j) { ; return strconv__mul_shift_32(m, _const_strconv__pow5_inv_split_32[q], j); } inline VV_LOC u32 strconv__mul_pow5_div_pow2(u32 m, u32 i, int j) { ; return strconv__mul_shift_32(m, _const_strconv__pow5_split_32[i], j); } VV_LOC u32 strconv__pow5_factor_32(u32 i_v) { u32 v = i_v; for (u32 n = ((u32)(0U)); true; n++) { u32 q = (u32)(v / 5U); u32 r = (u32)(v % 5U); if (r != 0U) { return n; } v = q; } return v; } VV_LOC bool strconv__multiple_of_power_of_five_32(u32 v, u32 p) { return strconv__pow5_factor_32(v) >= p; } VV_LOC bool strconv__multiple_of_power_of_two_32(u32 v, u32 p) { return ((u32)(math__bits__trailing_zeros_32(v))) >= p; } VV_LOC u32 strconv__log10_pow2(int e) { ; ; return (((u32)(((u32)(e)) * 78913U)) >> 18U); } VV_LOC u32 strconv__log10_pow5(int e) { ; ; return (((u32)(((u32)(e)) * 732923U)) >> 20U); } VV_LOC int strconv__pow5_bits(int e) { ; ; return ((int)((u32)(((((u32)(((u32)(e)) * 1217359U)) >> 19U)) + 1U))); } VV_LOC u64 strconv__shift_right_128(strconv__Uint128 v, int shift) { ; return (((v.hi << ((u64)((int)(64 - shift))))) | ((v.lo >> ((u32)(shift))))); } VV_LOC u64 strconv__mul_shift_64(u64 m, strconv__Uint128 mul, int shift) { multi_return_u64_u64 mr_3253 = math__bits__mul_64(m, mul.hi); u64 hihi = mr_3253.arg0; u64 hilo = mr_3253.arg1; multi_return_u64_u64 mr_3288 = math__bits__mul_64(m, mul.lo); u64 lohi = mr_3288.arg0; strconv__Uint128 sum = ((strconv__Uint128){.lo = (u64)(lohi + hilo),.hi = hihi,}); if (sum.lo < lohi) { sum.hi++; } return strconv__shift_right_128(sum, (int)(shift - 64)); } VV_LOC u32 strconv__pow5_factor_64(u64 v_i) { u64 v = v_i; for (u32 n = ((u32)(0U)); true; n++) { u64 q = (u64)(v / 5U); u64 r = (u64)(v % 5U); if (r != 0U) { return n; } v = q; } return ((u32)(0U)); } VV_LOC bool strconv__multiple_of_power_of_five_64(u64 v, u32 p) { return strconv__pow5_factor_64(v) >= p; } VV_LOC bool strconv__multiple_of_power_of_two_64(u64 v, u32 p) { return ((u32)(math__bits__trailing_zeros_64(v))) >= p; } int strconv__dec_digits(u64 n) { if (n <= 9999999999U) { if (n <= 99999U) { if (n <= 99U) { if (n <= 9U) { return 1; } else { return 2; } } else { if (n <= 999U) { return 3; } else { if (n <= 9999U) { return 4; } else { return 5; } } } } else { if (n <= 9999999U) { if (n <= 999999U) { return 6; } else { return 7; } } else { if (n <= 99999999U) { return 8; } else { if (n <= 999999999U) { return 9; } return 10; } } } } else { if (n <= 999999999999999U) { if (n <= 999999999999U) { if (n <= 99999999999U) { return 11; } else { return 12; } } else { if (n <= 9999999999999U) { return 13; } else { if (n <= 99999999999999U) { return 14; } else { return 15; } } } } else { if (n <= 99999999999999999U) { if (n <= 9999999999999999U) { return 16; } else { return 17; } } else { if (n <= 999999999999999999U) { return 18; } else { if (n <= 9999999999999999999U) { return 19; } return 20; } } } } return 0; } VV_LOC array __new_array(int mylen, int cap, int elm_size) { panic_on_negative_len(mylen); panic_on_negative_cap(cap); int cap_ = (cap < mylen ? (mylen) : (cap)); array arr = ((array){.data = (voidptr)vcalloc((u64)(((u64)(cap_)) * ((u64)(elm_size)))),.offset = 0,.len = mylen,.cap = cap_,.flags = 0,.element_size = elm_size,}); return arr; } VV_LOC array __new_array_with_default(int mylen, int cap, int elm_size, voidptr val) { panic_on_negative_len(mylen); panic_on_negative_cap(cap); int cap_ = (cap < mylen ? (mylen) : (cap)); array arr = ((array){.data = 0,.offset = 0,.len = mylen,.cap = cap_,.flags = 0,.element_size = elm_size,}); u64 total_size = (u64)(((u64)(cap_)) * ((u64)(elm_size))); if (cap_ > 0 && mylen == 0) { arr.data = _v_malloc(__at_least_one(total_size)); } else { arr.data = vcalloc(total_size); } if (val != 0) { u8* eptr = ((u8*)(arr.data)); { // Unsafe block if (eptr != ((void*)0)) { if (arr.element_size == 1) { u8 byte_value = *(((u8*)(val))); for (int i = 0; i < arr.len; ++i) { eptr[i] = byte_value; } } else { for (int _t1 = 0; _t1 < arr.len; ++_t1) { vmemcpy(eptr, val, arr.element_size); eptr += arr.element_size; } } } } } return arr; } VV_LOC array __new_array_with_multi_default(int mylen, int cap, int elm_size, voidptr val) { panic_on_negative_len(mylen); panic_on_negative_cap(cap); int cap_ = (cap < mylen ? (mylen) : (cap)); array arr = ((array){.data = 0,.offset = 0,.len = mylen,.cap = cap_,.flags = 0,.element_size = elm_size,}); u64 total_size = (u64)(((u64)(cap_)) * ((u64)(elm_size))); arr.data = vcalloc(__at_least_one(total_size)); if (val != 0) { u8* eptr = ((u8*)(arr.data)); { // Unsafe block if (eptr != ((void*)0)) { for (int i = 0; i < arr.len; ++i) { vmemcpy(eptr, ((charptr)(val)) + (int)(i * arr.element_size), arr.element_size); eptr += arr.element_size; } } } } return arr; } VV_LOC array __new_array_with_array_default(int mylen, int cap, int elm_size, array val, int depth) { panic_on_negative_len(mylen); panic_on_negative_cap(cap); int cap_ = (cap < mylen ? (mylen) : (cap)); array arr = ((array){.data = (voidptr)_v_malloc(__at_least_one((u64)(((u64)(cap_)) * ((u64)(elm_size))))),.offset = 0,.len = mylen,.cap = cap_,.flags = 0,.element_size = elm_size,}); u8* eptr = ((u8*)(arr.data)); { // Unsafe block if (eptr != ((void*)0)) { for (int _t1 = 0; _t1 < arr.len; ++_t1) { array val_clone = array_clone_to_depth(&val, depth); vmemcpy(eptr, &val_clone, arr.element_size); eptr += arr.element_size; } } } return arr; } VV_LOC array new_array_from_c_array(int len, int cap, int elm_size, voidptr c_array) { panic_on_negative_len(len); panic_on_negative_cap(cap); int cap_ = (cap < len ? (len) : (cap)); array arr = ((array){.data = (voidptr)vcalloc((u64)(((u64)(cap_)) * ((u64)(elm_size)))),.offset = 0,.len = len,.cap = cap_,.flags = 0,.element_size = elm_size,}); vmemcpy(arr.data, c_array, (u64)(((u64)(len)) * ((u64)(elm_size)))); return arr; } void array_ensure_cap(array* a, int required) { if (required <= a->cap) { return; } if (ArrayFlags_has(&a->flags, ArrayFlags__nogrow)) { panic_n(_S("array.ensure_cap: array with the flag `.nogrow` cannot grow in size, array required new size:"), required); VUNREACHABLE(); } i64 cap = (a->cap > 0 ? (((i64)(a->cap))) : (((i64)(2)))); for (;;) { if (!(required > cap)) break; cap *= 2; } if (cap > _const_max_int) { if (a->cap < _const_max_int) { cap = _const_max_int; } else { panic_n(_S("array.ensure_cap: array needs to grow to cap (which is > 2^31):"), cap); VUNREACHABLE(); } } u64 new_size = (u64)(((u64)(cap)) * ((u64)(a->element_size))); u8* new_data = _v_malloc(__at_least_one(new_size)); if (a->data != ((void*)0)) { vmemcpy(new_data, a->data, (u64)(((u64)(a->len)) * ((u64)(a->element_size)))); if (ArrayFlags_has(&a->flags, ArrayFlags__noslices)) { _v_free(a->data); } } a->data = new_data; a->offset = 0; a->cap = ((int)(cap)); } void array_insert(array* a, int i, voidptr val) { if (i < 0 || i > a->len) { panic_n2(_S("array.insert: index out of range (i,a.len):"), i, a->len); VUNREACHABLE(); } if (a->len == _const_max_int) { _v_panic(_S("array.insert: a.len reached max_int")); VUNREACHABLE(); } if (a->len >= a->cap) { array_ensure_cap(a, (int)(a->len + 1)); } { // Unsafe block vmemmove(array_get_unsafe(*a, (int)(i + 1)), array_get_unsafe(*a, i), (u64)(((u64)(((int)(a->len - i)))) * ((u64)(a->element_size)))); array_set_unsafe(a, i, val); } a->len++; } VV_LOC void array_insert_many(array* a, int i, voidptr val, int size) { if (i < 0 || i > a->len) { panic_n2(_S("array.insert_many: index out of range (i,a.len):"), i, a->len); VUNREACHABLE(); } i64 new_len = (i64)(((i64)(a->len)) + ((i64)(size))); if (new_len > _const_max_int) { panic_n(_S("array.insert_many: max_int will be exceeded by a.len:"), new_len); VUNREACHABLE(); } array_ensure_cap(a, ((int)(new_len))); int elem_size = a->element_size; { // Unsafe block voidptr iptr = array_get_unsafe(*a, i); vmemmove(array_get_unsafe(*a, (int)(i + size)), iptr, (u64)(((u64)((int)(a->len - i))) * ((u64)(elem_size)))); vmemcpy(iptr, val, (u64)(((u64)(size)) * ((u64)(elem_size)))); } a->len = ((int)(new_len)); } void array_prepend(array* a, voidptr val) { array_insert(a, 0, val); } VV_LOC void array_prepend_many(array* a, voidptr val, int size) { array_insert_many(a, 0, val, size); } void array_delete(array* a, int i) { array_delete_many(a, i, 1); } void array_delete_many(array* a, int i, int size) { if (i < 0 || (i64)(((i64)(i)) + ((i64)(size))) > ((i64)(a->len))) { if (size > 1) { panic_n3(_S("array.delete: index out of range (i,i+size,a.len):"), i, (int)(i + size), a->len); VUNREACHABLE(); } else { panic_n2(_S("array.delete: index out of range (i,a.len):"), i, a->len); VUNREACHABLE(); } } if (ArrayFlags_all(&a->flags, (ArrayFlags__noshrink | ArrayFlags__noslices))) { vmemmove(((u8*)(a->data)) + (u64)(((u64)(i)) * ((u64)(a->element_size))), ((u8*)(a->data)) + (u64)(((u64)((int)(i + size))) * ((u64)(a->element_size))), (u64)(((u64)((int)((int)(a->len - i) - size))) * ((u64)(a->element_size)))); a->len -= size; return; } voidptr old_data = a->data; int new_size = (int)(a->len - size); int new_cap = (new_size == 0 ? (1) : (new_size)); a->data = vcalloc((u64)(((u64)(new_cap)) * ((u64)(a->element_size)))); vmemcpy(a->data, old_data, (u64)(((u64)(i)) * ((u64)(a->element_size)))); vmemcpy(((u8*)(a->data)) + (u64)(((u64)(i)) * ((u64)(a->element_size))), ((u8*)(old_data)) + (u64)(((u64)((int)(i + size))) * ((u64)(a->element_size))), (u64)(((u64)((int)((int)(a->len - i) - size))) * ((u64)(a->element_size)))); if (ArrayFlags_has(&a->flags, ArrayFlags__noslices)) { _v_free(old_data); } a->len = new_size; a->cap = new_cap; } void array_clear(array* a) { a->len = 0; } void array_trim(array* a, int index) { if (index < a->len) { a->len = index; } } inline VV_LOC voidptr array_get_unsafe(array a, int i) { { // Unsafe block return ((u8*)(a.data)) + (u64)(((u64)(i)) * ((u64)(a.element_size))); } return 0; } VV_LOC voidptr array_get(array a, int i) { #if !defined(CUSTOM_DEFINE_no_bounds_checking) { if (i < 0 || i >= a.len) { panic_n2(_S("array.get: index out of range (i,a.len):"), i, a.len); VUNREACHABLE(); } } #endif { // Unsafe block return ((u8*)(a.data)) + (u64)(((u64)(i)) * ((u64)(a.element_size))); } return 0; } VV_LOC voidptr array_get_with_check(array a, int i) { if (i < 0 || i >= a.len) { return 0; } { // Unsafe block return ((u8*)(a.data)) + (u64)(((u64)(i)) * ((u64)(a.element_size))); } return 0; } voidptr array_first(array a) { if (a.len == 0) { _v_panic(_S("array.first: array is empty")); VUNREACHABLE(); } return a.data; } voidptr array_last(array a) { if (a.len == 0) { _v_panic(_S("array.last: array is empty")); VUNREACHABLE(); } { // Unsafe block return ((u8*)(a.data)) + (u64)(((u64)((int)(a.len - 1))) * ((u64)(a.element_size))); } return 0; } voidptr array_pop(array* a) { if (a->len == 0) { _v_panic(_S("array.pop: array is empty")); VUNREACHABLE(); } int new_len = (int)(a->len - 1); u8* last_elem = ((u8*)(a->data)) + (u64)(((u64)(new_len)) * ((u64)(a->element_size))); a->len = new_len; return last_elem; } void array_delete_last(array* a) { if (a->len == 0) { _v_panic(_S("array.delete_last: array is empty")); VUNREACHABLE(); } a->len--; } VV_LOC array array_slice(array a, int start, int _end) { int end = (_end == _const_max_int ? (a.len) : (_end)); #if !defined(CUSTOM_DEFINE_no_bounds_checking) { if (start > end) { _v_panic(string__plus(string__plus(string__plus(_S("array.slice: invalid slice index (start>end):"), impl_i64_to_string(((i64)(start)))), _S(", ")), impl_i64_to_string(end))); VUNREACHABLE(); } if (end > a.len) { _v_panic(string__plus(string__plus(string__plus(string__plus(_S("array.slice: slice bounds out of range ("), impl_i64_to_string(end)), _S(" >= ")), impl_i64_to_string(a.len)), _S(")"))); VUNREACHABLE(); } if (start < 0) { _v_panic(string__plus(_S("array.slice: slice bounds out of range (start<0):"), impl_i64_to_string(start))); VUNREACHABLE(); } } #endif u64 offset = (u64)(((u64)(start)) * ((u64)(a.element_size))); u8* data = ((u8*)(a.data)) + offset; int l = (int)(end - start); array res = ((array){.data = (voidptr)data,.offset = (int)(a.offset + ((int)(offset))),.len = l,.cap = l,.flags = 0,.element_size = a.element_size,}); return res; } VV_LOC array array_slice_ni(array a, int _start, int _end) { int end = (_end == _const_max_int ? (a.len) : (_end)); int start = _start; if (start < 0) { start = (int)(a.len + start); if (start < 0) { start = 0; } } if (end < 0) { end = (int)(a.len + end); if (end < 0) { end = 0; } } if (end >= a.len) { end = a.len; } if (start >= a.len || start > end) { array res = ((array){.data = a.data,.offset = 0,.len = 0,.cap = 0,.flags = 0,.element_size = a.element_size,}); return res; } u64 offset = (u64)(((u64)(start)) * ((u64)(a.element_size))); u8* data = ((u8*)(a.data)) + offset; int l = (int)(end - start); array res = ((array){.data = (voidptr)data,.offset = (int)(a.offset + ((int)(offset))),.len = l,.cap = l,.flags = 0,.element_size = a.element_size,}); return res; } VV_LOC array array_clone_static_to_depth(array a, int depth) { return array_clone_to_depth(&a, depth); } array array_clone(array* a) { return array_clone_to_depth(a, 0); } array array_clone_to_depth(array* a, int depth) { u64 source_capacity_in_bytes = (u64)(((u64)(a->cap)) * ((u64)(a->element_size))); array arr = ((array){.data = (voidptr)vcalloc(source_capacity_in_bytes),.offset = 0,.len = a->len,.cap = a->cap,.flags = 0,.element_size = a->element_size,}); if (depth > 0 && _us32_eq(sizeof(array),a->element_size) && a->len >= 0 && a->cap >= a->len) { array ar = ((array){.data = 0,.offset = 0,.len = 0,.cap = 0,.flags = 0,.element_size = 0,}); int asize = ((int)(sizeof(array))); for (int i = 0; i < a->len; ++i) { vmemcpy(&ar, array_get_unsafe(*a, i), asize); array ar_clone = array_clone_to_depth(&ar, (int)(depth - 1)); array_set_unsafe(&arr, i, &ar_clone); } return arr; } else { if (a->data != 0 && source_capacity_in_bytes > 0U) { vmemcpy(((u8*)(arr.data)), a->data, source_capacity_in_bytes); } return arr; } return (array){.data = 0,.offset = 0,.len = 0,.cap = 0,.flags = 0,.element_size = 0,}; } inline VV_LOC void array_set_unsafe(array* a, int i, voidptr val) { vmemcpy(((u8*)(a->data)) + (u64)(((u64)(a->element_size)) * ((u64)(i))), val, a->element_size); } VV_LOC void array_set(array* a, int i, voidptr val) { #if !defined(CUSTOM_DEFINE_no_bounds_checking) { if (i < 0 || i >= a->len) { panic_n2(_S("array.set: index out of range (i,a.len):"), i, a->len); VUNREACHABLE(); } } #endif vmemcpy(((u8*)(a->data)) + (u64)(((u64)(a->element_size)) * ((u64)(i))), val, a->element_size); } VV_LOC void array_push(array* a, voidptr val) { if (a->len < 0) { _v_panic(_S("array.push: negative len")); VUNREACHABLE(); } if (a->len >= _const_max_int) { _v_panic(_S("array.push: len bigger than max_int")); VUNREACHABLE(); } if (a->len >= a->cap) { array_ensure_cap(a, (int)(a->len + 1)); } vmemcpy(((u8*)(a->data)) + (u64)(((u64)(a->element_size)) * ((u64)(a->len))), val, a->element_size); a->len++; } void array_push_many(array* a, voidptr val, int size) { if (size <= 0 || val == ((void*)0)) { return; } i64 new_len = (i64)(((i64)(a->len)) + ((i64)(size))); if (new_len > _const_max_int) { _v_panic(_S("array.push_many: new len exceeds max_int")); VUNREACHABLE(); } if (new_len >= a->cap) { array_ensure_cap(a, ((int)(new_len))); } if (a->data == val && a->data != 0) { array copy = array_clone(a); vmemcpy(((u8*)(a->data)) + (u64)(((u64)(a->element_size)) * ((u64)(a->len))), copy.data, (u64)(((u64)(a->element_size)) * ((u64)(size)))); } else { if (a->data != 0 && val != 0) { vmemcpy(((u8*)(a->data)) + (u64)(((u64)(a->element_size)) * ((u64)(a->len))), val, (u64)(((u64)(a->element_size)) * ((u64)(size)))); } } a->len = ((int)(new_len)); } array array_reverse(array a) { if (a.len < 2) { return a; } array arr = ((array){.data = (voidptr)vcalloc((u64)(((u64)(a.cap)) * ((u64)(a.element_size)))),.offset = 0,.len = a.len,.cap = a.cap,.flags = 0,.element_size = a.element_size,}); for (int i = 0; i < a.len; ++i) { array_set_unsafe(&arr, i, array_get_unsafe(a, (int)((int)(a.len - 1) - i))); } return arr; } void array_free(array* a) { #if defined(_VPREALLOC) { return; } #endif if (ArrayFlags_has(&a->flags, ArrayFlags__nofree)) { return; } u8* mblock_ptr = ((u8*)((u64)(((u64)(a->data)) - ((u64)(a->offset))))); if (mblock_ptr != ((void*)0)) { _v_free(mblock_ptr); } { // Unsafe block a->data = ((void*)0); a->offset = 0; } } array array_filter(array a, bool (*predicate)(voidptr )); bool array_any(array a, bool (*predicate)(voidptr )); bool array_all(array a, bool (*predicate)(voidptr )); array array_map(array a, voidptr (*callback)(voidptr )); void array_sort(array* a, int (*callback)(voidptr , voidptr )); array array_sorted(array* a, int (*callback)(voidptr , voidptr )); void array_sort_with_compare(array* a, int (*callback)(voidptr , voidptr )) { #if defined(_VFREESTANDING) { } #else { vqsort(a->data, ((usize)(a->len)), ((usize)(a->element_size)), (voidptr)callback); } #endif } bool array_contains(array a, voidptr value); int array_index(array a, voidptr value); void Array_string_free(Array_string* a) { #if defined(_VPREALLOC) { return; } #endif for (int _t2 = 0; _t2 < a->len; ++_t2) { string* s = ((string*)a->data) + _t2; string_free(s); } array_free((((array*)(a)))); } string Array_string_str(Array_string a) { int sb_len = 4; if (a.len > 0) { sb_len += ((string*)a.data)[0].len; sb_len *= a.len; } sb_len += 2; strings__Builder sb = strings__new_builder(sb_len); strings__Builder_write_u8(&sb, '['); for (int i = 0; i < a.len; ++i) { string val = ((string*)a.data)[i]; strings__Builder_write_u8(&sb, '\''); strings__Builder_write_string(&sb, val); strings__Builder_write_u8(&sb, '\''); if (i < (int)(a.len - 1)) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_u8(&sb, ']'); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } int copy(Array_u8* dst, Array_u8 src) { int min = (dst->len < src.len ? (dst->len) : (src.len)); if (min > 0) { vmemmove(((u8*)(dst->data)), src.data, min); } return min; } Array_voidptr array_pointers(array a) { Array_voidptr res = __new_array_with_default(0, 0, sizeof(voidptr), 0); for (int i = 0; i < a.len; ++i) { array_push((array*)&res, _MOV((voidptr[]){ array_get_unsafe(a, i) })); } return res; } void u8_free(u8* data) { _v_free(data); } inline VV_LOC void panic_on_negative_len(int len) { if (len < 0) { panic_n(_S("negative .len:"), len); VUNREACHABLE(); } } inline VV_LOC void panic_on_negative_cap(int cap) { if (cap < 0) { panic_n(_S("negative .cap:"), cap); VUNREACHABLE(); } } VV_LOC array __new_array_noscan(int mylen, int cap, int elm_size) { return __new_array(mylen, cap, elm_size); } VV_LOC array __new_array_with_multi_default_noscan(int mylen, int cap, int elm_size, voidptr val) { return __new_array_with_multi_default(mylen, cap, elm_size, val); } VV_LOC array __new_array_with_array_default_noscan(int mylen, int cap, int elm_size, array val, int depth) { return __new_array_with_array_default(mylen, cap, elm_size, val, depth); } void print_backtrace(void) { #if !defined(CUSTOM_DEFINE_no_backtrace) { #if defined(_VFREESTANDING) { } #elif defined(_VNATIVE) { } #elif defined(__TINYC__) { tcc_backtrace("Backtrace"); } #elif defined(CUSTOM_DEFINE_use_libbacktrace) { print_libbacktrace(1); } #else { print_backtrace_skipping_top_frames(2); } #endif } #endif } VV_LOC void eprint_space_padding(string output, int max_len) { int padding_len = (int)(max_len - output.len); if (padding_len > 0) { for (int _t1 = 0; _t1 < padding_len; ++_t1) { eprint(_S(" ")); } } } bool print_backtrace_skipping_top_frames(int xskipframes) { #if defined(CUSTOM_DEFINE_no_backtrace) { return false; } #else { int skipframes = (int)(xskipframes + 2); #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) { return print_backtrace_skipping_top_frames_bsd(skipframes); } #elif defined(__linux__) { return print_backtrace_skipping_top_frames_linux(skipframes); } #else { println(str_intp(2, _MOV((StrIntpData[]){{_S("print_backtrace_skipping_top_frames is not implemented. skipframes: "), 0xfe07, {.d_i32 = skipframes}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif } #endif return false; } VV_LOC bool print_backtrace_skipping_top_frames_bsd(int skipframes) { #if defined(CUSTOM_DEFINE_no_backtrace) { return false; } #else { #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) { Array_fixed_voidptr_100 buffer = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int nr_ptrs = backtrace(&buffer[0], 100); if (nr_ptrs < 2) { eprintln(_S("C.backtrace returned less than 2 frames")); return false; } backtrace_symbols_fd(&buffer[skipframes], (int)(nr_ptrs - skipframes), 2); } #endif return true; } #endif return 0; } VV_LOC bool print_backtrace_skipping_top_frames_linux(int skipframes) { #if defined(__ANDROID__) { eprintln(_S("On Android no backtrace is available.")); return false; } #endif #if !defined(__GLIBC__) { eprintln(_S("backtrace_symbols is missing => printing backtraces is not available.")); eprintln(_S("Some libc implementations like musl simply do not provide it.")); return false; } #endif #if defined(_VNATIVE) { eprintln(_S("native backend does not support backtraces yet.")); return false; } #elif defined(CUSTOM_DEFINE_no_backtrace) { return false; } #else { #if defined(__linux__) && !defined(_VFREESTANDING) { #if defined(__TINYC__) { tcc_backtrace("Backtrace"); return false; } #else { Array_fixed_voidptr_100 buffer = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int nr_ptrs = backtrace(&buffer[0], 100); if (nr_ptrs < 2) { eprintln(_S("C.backtrace returned less than 2 frames")); return false; } int nr_actual_frames = (int)(nr_ptrs - skipframes); char** csymbols = backtrace_symbols(((voidptr)(&buffer[skipframes])), nr_actual_frames); for (int i = 0; i < nr_actual_frames; ++i) { string sframe = tos2(((u8*)(csymbols[i]))); string executable = string_all_before(sframe, _S("(")); string addr = string_all_before(string_all_after(sframe, _S("[")), _S("]")); string beforeaddr = string_all_before(sframe, _S("[")); string cmd = string__plus(string__plus(string__plus(_S("addr2line -e "), executable), _S(" ")), addr); voidptr f = popen(((char*)(cmd.str)), "r"); if (f == ((void*)0)) { eprintln(sframe); continue; } Array_fixed_u8_1000 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; string output = _S(""); { // Unsafe block u8* bp = &buf[0]; for (;;) { if (!(fgets(((char*)(bp)), 1000, f) != 0)) break; output = string__plus(output, tos(bp, vstrlen(bp))); } } output = string__plus(string_trim_chars(output, _S(" \t\n"), TrimMode__trim_both), _S(":")); if (pclose(f) != 0) { eprintln(sframe); continue; } if (_SLIT_EQ(output.str, output.len, "??:0:") || _SLIT_EQ(output.str, output.len, "??:?:")) { output = _S(""); } output = string_replace(output, _S(" (discriminator"), _S(": (d.")); eprint(output); eprint_space_padding(output, 55); eprint(_S(" | ")); eprint(addr); eprint(_S(" | ")); eprintln(beforeaddr); } if (nr_actual_frames > 0) { free(csymbols); } } #endif } #endif } #endif return true; } VV_LOC void v_segmentation_fault_handler(i32 signal_number) { #if defined(_VFREESTANDING) { } #else { fprintf(stderr, "signal %d: segmentation fault\n", signal_number); } #endif #if defined(CUSTOM_DEFINE_use_libbacktrace) { eprint_libbacktrace(1); } #else { print_backtrace(); } #endif _v_exit((i32)(128 + signal_number)); VUNREACHABLE(); } VNORETURN void _v_exit(int code) { exit(code); VUNREACHABLE(); while(1); } _result_void at_exit(void (*cb)(void)) { #if defined(_VFREESTANDING) { } #else { int res = atexit((voidptr)cb); if (res != 0) { return (_result_void){ .is_error=true, .err=error_with_code(_S("at_exit failed"), res), .data={E_STRUCT} }; } } #endif return (_result_void){0}; } VNORETURN void panic_option_not_set(string s) { _v_panic(string__plus(string__plus(_S("option not set ("), s), _S(")"))); VUNREACHABLE(); while(1); } VNORETURN void panic_result_not_set(string s) { _v_panic(string__plus(string__plus(_S("result not set ("), s), _S(")"))); VUNREACHABLE(); while(1); } string vcurrent_hash(void) { return _S("b876644"); } VNORETURN void _v_panic(string s) { #if defined(_VFREESTANDING) { } #else { eprint(_S("V panic: ")); eprintln(s); eprint(_S("v hash: ")); eprintln(vcurrent_hash()); flush_stdout(); #if defined(_VNATIVE) { exit(1); VUNREACHABLE(); } #elif defined(CUSTOM_DEFINE_exit_after_panic_message) { exit(1); VUNREACHABLE(); } #elif defined(CUSTOM_DEFINE_no_backtrace) { exit(1); VUNREACHABLE(); } #else { #if defined(__TINYC__) { #if defined(CUSTOM_DEFINE_panics_break_into_debugger) { break_if_debugger_attached(); } #else { tcc_backtrace("Backtrace"); } #endif exit(1); VUNREACHABLE(); } #endif #if defined(CUSTOM_DEFINE_use_libbacktrace) { eprint_libbacktrace(1); } #else { print_backtrace_skipping_top_frames(1); } #endif #if defined(CUSTOM_DEFINE_panics_break_into_debugger) { break_if_debugger_attached(); } #endif exit(1); VUNREACHABLE(); } #endif } #endif exit(1); VUNREACHABLE(); while(1); } string c_error_number_str(int errnum) { string err_msg = _S(""); #if defined(_VFREESTANDING) { } #else { #if !defined(__vinix__) { char* c_msg = strerror(errnum); err_msg = ((string){.str = ((u8*)(c_msg)), .len = strlen(c_msg), .is_lit = 1}); } #endif } #endif return err_msg; } VNORETURN void panic_n(string s, i64 number1) { _v_panic(string__plus(s, impl_i64_to_string(number1))); VUNREACHABLE(); while(1); } VNORETURN void panic_n2(string s, i64 number1, i64 number2) { _v_panic(string__plus(string__plus(string__plus(s, impl_i64_to_string(number1)), _S(", ")), impl_i64_to_string(number2))); VUNREACHABLE(); while(1); } VNORETURN VV_LOC void panic_n3(string s, i64 number1, i64 number2, i64 number3) { _v_panic(string__plus(string__plus(string__plus(string__plus(string__plus(s, impl_i64_to_string(number1)), _S(", ")), impl_i64_to_string(number2)), _S(", ")), impl_i64_to_string(number2))); VUNREACHABLE(); while(1); } VNORETURN void panic_error_number(string basestr, int errnum) { _v_panic(string__plus(basestr, c_error_number_str(errnum))); VUNREACHABLE(); while(1); } void eprintln(string s) { if (s.str == 0) { eprintln(_S("eprintln(NIL)")); return; } #if defined(CUSTOM_DEFINE_builtin_print_use_fprintf) { fprintf(stderr, "%.*s\n", s.len, s.str); return; } #endif #if defined(_VFREESTANDING) { } #elif defined(__TARGET_IOS__) { WrappedNSLog(s.str); } #else { flush_stdout(); flush_stderr(); #if defined(__ANDROID__) && !defined(__TERMUX__) { android_print(stderr, "%.*s\n", s.len, s.str); } #endif _writeln_to_fd(2, s); flush_stderr(); } #endif } void eprint(string s) { if (s.str == 0) { eprint(_S("eprint(NIL)")); return; } #if defined(CUSTOM_DEFINE_builtin_print_use_fprintf) { fprintf(stderr, "%.*s", s.len, s.str); return; } #endif #if defined(_VFREESTANDING) { } #elif defined(__TARGET_IOS__) { WrappedNSLog(s.str); } #else { flush_stdout(); flush_stderr(); #if defined(__ANDROID__) && !defined(__TERMUX__) { android_print(stderr, "%.*s", s.len, s.str); } #endif _write_buf_to_fd(2, s.str, s.len); flush_stderr(); } #endif } void flush_stdout(void) { #if defined(_VFREESTANDING) { } #else { fflush(stdout); } #endif } void flush_stderr(void) { #if defined(_VFREESTANDING) { } #else { fflush(stderr); } #endif } void unbuffer_stdout(void) { #if defined(_VFREESTANDING) { } #else { setbuf(stdout, 0); } #endif } void print(string s) { #if defined(CUSTOM_DEFINE_builtin_print_use_fprintf) { fprintf(stdout, "%.*s", s.len, s.str); return; } #endif #if defined(__ANDROID__) && !defined(__TERMUX__) { android_print(stdout, "%.*s\n", s.len, s.str); } #elif defined(__TARGET_IOS__) { WrappedNSLog(s.str); } #elif defined(_VFREESTANDING) { } #else { _write_buf_to_fd(1, s.str, s.len); } #endif } void println(string s) { if (s.str == 0) { println(_S("println(NIL)")); return; } #if defined(CUSTOM_DEFINE_noprintln) { return; } #endif #if defined(CUSTOM_DEFINE_builtin_print_use_fprintf) { fprintf(stdout, "%.*s\n", s.len, s.str); return; } #endif #if defined(__ANDROID__) && !defined(__TERMUX__) { android_print(stdout, "%.*s\n", s.len, s.str); return; } #elif defined(__TARGET_IOS__) { WrappedNSLog(s.str); return; } #elif defined(_VFREESTANDING) { } #else { _writeln_to_fd(1, s); } #endif } VV_LOC void _writeln_to_fd(int fd, string s) { #if defined(CUSTOM_DEFINE_builtin_writeln_should_write_at_once) { { // Unsafe block int buf_len = (int)(s.len + 1); u8* buf = _v_malloc(buf_len); memcpy(buf, s.str, s.len); buf[s.len] = '\n'; _write_buf_to_fd(fd, buf, buf_len); _v_free(buf); } } #else { u8 lf = ((u8)('\n')); _write_buf_to_fd(fd, s.str, s.len); _write_buf_to_fd(fd, &lf, 1); } #endif } VV_LOC void _write_buf_to_fd(int fd, u8* buf, int buf_len) { if (buf_len <= 0) { return; } u8* ptr = buf; isize remaining_bytes = ((isize)(buf_len)); isize x = ((isize)(0)); #if defined(_VFREESTANDING) || defined(__vinix__) || defined(CUSTOM_DEFINE_builtin_write_buf_to_fd_should_use_c_write) { { // Unsafe block for (;;) { if (!(remaining_bytes > 0)) break; x = write(fd, ptr, remaining_bytes); ptr += x; remaining_bytes -= x; } } } #else { voidptr stream = ((voidptr)(stdout)); if (fd == 2) { stream = ((voidptr)(stderr)); } { // Unsafe block for (;;) { if (!(remaining_bytes > 0)) break; x = ((isize)(fwrite(ptr, 1, remaining_bytes, stream))); ptr += x; remaining_bytes -= x; } } } #endif } VNORETURN VV_LOC void _memory_panic(string fname, isize size) { v_memory_panic = true; eprint(fname); eprint(_S("(")); #if defined(_VFREESTANDING) || defined(__vinix__) { eprint(_S("size")); } #else { fprintf(stderr, "%p", ((voidptr)(size))); } #endif if (size < 0) { eprint(_S(" < 0")); } eprintln(_S(")")); _v_panic(_S("memory allocation failure")); VUNREACHABLE(); while(1); } u8* _v_malloc(isize n) { #if defined(CUSTOM_DEFINE_trace_malloc) { total_m += n; fprintf(stderr, "_v_malloc %6d total %10d\n", n, total_m); } #endif if (n < 0) { _memory_panic(_S("malloc"), n); VUNREACHABLE(); } else if (n == 0) { return ((u8*)(((void*)0))); } u8* res = ((u8*)(((void*)0))); #if defined(_VPREALLOC) { return prealloc_malloc(n); } #elif defined(_VGCBOEHM) { { // Unsafe block res = GC_MALLOC(n); } } #elif defined(_VFREESTANDING) { } #else { #if defined(_WIN32) { res = _aligned_malloc(n, 1); } #else { res = malloc(n); } #endif } #endif if (res == 0) { _memory_panic(_S("malloc"), n); VUNREACHABLE(); } #if defined(CUSTOM_DEFINE_debug_malloc) { memset(res, 0x4D, n); } #endif return res; } u8* malloc_noscan(isize n) { #if defined(CUSTOM_DEFINE_trace_malloc) { total_m += n; fprintf(stderr, "malloc_noscan %6d total %10d\n", n, total_m); } #endif if (n < 0) { _memory_panic(_S("malloc_noscan"), n); VUNREACHABLE(); } u8* res = ((u8*)(((void*)0))); #if defined(_VPREALLOC) { return prealloc_malloc(n); } #elif defined(_VGCBOEHM) { #if defined(CUSTOM_DEFINE_gcboehm_opt) { { // Unsafe block res = GC_MALLOC_ATOMIC(n); } } #else { { // Unsafe block res = GC_MALLOC(n); } } #endif } #elif defined(_VFREESTANDING) { } #else { #if defined(_WIN32) { res = _aligned_malloc(n, 1); } #else { res = malloc(n); } #endif } #endif if (res == 0) { _memory_panic(_S("malloc_noscan"), n); VUNREACHABLE(); } #if defined(CUSTOM_DEFINE_debug_malloc) { memset(res, 0x4D, n); } #endif return res; } inline VV_LOC u64 __at_least_one(u64 how_many) { if (how_many == 0U) { return 1U; } return how_many; } u8* malloc_uncollectable(isize n) { #if defined(CUSTOM_DEFINE_trace_malloc) { total_m += n; fprintf(stderr, "malloc_uncollectable %6d total %10d\n", n, total_m); } #endif if (n < 0) { _memory_panic(_S("malloc_uncollectable"), n); VUNREACHABLE(); } u8* res = ((u8*)(((void*)0))); #if defined(_VPREALLOC) { return prealloc_malloc(n); } #elif defined(_VGCBOEHM) { { // Unsafe block res = GC_MALLOC_UNCOLLECTABLE(n); } } #elif defined(_VFREESTANDING) { } #else { #if defined(_WIN32) { res = _aligned_malloc(n, 1); } #else { res = malloc(n); } #endif } #endif if (res == 0) { _memory_panic(_S("malloc_uncollectable"), n); VUNREACHABLE(); } #if defined(CUSTOM_DEFINE_debug_malloc) { memset(res, 0x4D, n); } #endif return res; } u8* v_realloc(u8* b, isize n) { #if defined(CUSTOM_DEFINE_trace_realloc) { fprintf(stderr, "v_realloc %6d\n", n); } #endif u8* new_ptr = ((u8*)(((void*)0))); #if defined(_VPREALLOC) { { // Unsafe block new_ptr = _v_malloc(n); memcpy(new_ptr, b, n); } return new_ptr; } #elif defined(_VGCBOEHM) { new_ptr = GC_REALLOC(b, n); } #else { #if defined(_WIN32) { new_ptr = _aligned_realloc(b, n, 1); } #else { new_ptr = realloc(b, n); } #endif } #endif if (new_ptr == 0) { _memory_panic(_S("v_realloc"), n); VUNREACHABLE(); } return new_ptr; } u8* realloc_data(u8* old_data, int old_size, int new_size) { #if defined(CUSTOM_DEFINE_trace_realloc) { fprintf(stderr, "realloc_data old_size: %6d new_size: %6d\n", old_size, new_size); } #endif #if defined(_VPREALLOC) { return prealloc_realloc(old_data, old_size, new_size); } #endif #if defined(CUSTOM_DEFINE_debug_realloc) { { // Unsafe block u8* new_ptr = _v_malloc(new_size); int min_size = (old_size < new_size ? (old_size) : (new_size)); memcpy(new_ptr, old_data, min_size); memset(old_data, 0x57, old_size); _v_free(old_data); return new_ptr; } } #endif u8* nptr = ((u8*)(((void*)0))); #if defined(_VGCBOEHM) { nptr = GC_REALLOC(old_data, new_size); } #else { #if defined(_WIN32) { nptr = _aligned_realloc(old_data, new_size, 1); } #else { nptr = realloc(old_data, new_size); } #endif } #endif if (nptr == 0) { _memory_panic(_S("realloc_data"), ((isize)(new_size))); VUNREACHABLE(); } return nptr; } u8* vcalloc(isize n) { #if defined(CUSTOM_DEFINE_trace_vcalloc) { total_m += n; fprintf(stderr, "vcalloc %6d total %10d\n", n, total_m); } #endif if (n < 0) { _memory_panic(_S("vcalloc"), n); VUNREACHABLE(); } else if (n == 0) { return ((u8*)(((void*)0))); } #if defined(_VPREALLOC) { return prealloc_calloc(n); } #elif defined(_VGCBOEHM) { return ((u8*)(GC_MALLOC(n))); } #else { #if defined(_WIN32) { voidptr ptr = _aligned_malloc(n, 1); if (ptr != ((u8*)(((void*)0)))) { memset(ptr, 0, n); } return ptr; } #else { return calloc(1, n); } #endif } #endif return ((u8*)(((void*)0))); } u8* vcalloc_noscan(isize n) { #if defined(CUSTOM_DEFINE_trace_vcalloc) { total_m += n; fprintf(stderr, "vcalloc_noscan %6d total %10d\n", n, total_m); } #endif #if defined(_VPREALLOC) { return prealloc_calloc(n); } #elif defined(_VGCBOEHM) { if (n < 0) { _memory_panic(_S("vcalloc_noscan"), n); VUNREACHABLE(); } #if defined(CUSTOM_DEFINE_gcboehm_opt) { voidptr res = GC_MALLOC_ATOMIC(n); memset(res, 0, n); return ((u8*)(res)); } #else { voidptr res = GC_MALLOC(n); return ((u8*)(res)); } #endif } #else { return vcalloc(n); } #endif return ((u8*)(((void*)0))); } void _v_free(voidptr ptr) { #if defined(CUSTOM_DEFINE_trace_free) { fprintf(stderr, "free ptr: %p\n", ptr); } #endif #if defined(CUSTOM_DEFINE_builtin_free_nop) { return; } #endif if (ptr == 0) { #if defined(CUSTOM_DEFINE_trace_free_nulls) { fprintf(stderr, "free null ptr\n", ptr); } #endif #if defined(CUSTOM_DEFINE_trace_free_nulls_break) { break_if_debugger_attached(); } #endif return; } #if defined(_VPREALLOC) { return; } #elif defined(_VGCBOEHM) { #if defined(CUSTOM_DEFINE_gcboehm_leak) { GC_FREE(ptr); } #endif } #else { #if defined(_WIN32) { _aligned_free(ptr); } #else { free(ptr); } #endif } #endif } voidptr memdup(voidptr src, isize sz) { #if defined(CUSTOM_DEFINE_trace_memdup) { fprintf(stderr, "memdup size: %10d\n", sz); } #endif if (sz == 0) { return vcalloc(1); } { // Unsafe block u8* mem = _v_malloc(sz); return memcpy(mem, src, sz); } return 0; } voidptr memdup_noscan(voidptr src, isize sz) { #if defined(CUSTOM_DEFINE_trace_memdup) { fprintf(stderr, "memdup_noscan size: %10d\n", sz); } #endif if (sz == 0) { return vcalloc_noscan(1); } { // Unsafe block u8* mem = malloc_noscan(sz); return memcpy(mem, src, sz); } return 0; } voidptr memdup_uncollectable(voidptr src, isize sz) { #if defined(CUSTOM_DEFINE_trace_memdup) { fprintf(stderr, "memdup_uncollectable size: %10d\n", sz); } #endif if (sz == 0) { return vcalloc(1); } { // Unsafe block u8* mem = malloc_uncollectable(sz); return memcpy(mem, src, sz); } return 0; } inline VV_LOC int v_fixed_index(int i, int len) { #if !defined(CUSTOM_DEFINE_no_bounds_checking) { if (i < 0 || i >= len) { _v_panic(string__plus(string__plus(string__plus(string__plus(_S("fixed array index out of range (index: "), i64_str(((i64)(i)))), _S(", len: ")), i64_str(((i64)(len)))), _S(")"))); VUNREACHABLE(); } } #endif return i; } Array_string arguments(void) { u8** argv = ((u8**)(g_main_argv)); Array_string res = __new_array_with_default(0, g_main_argc, sizeof(string), 0); for (int i = 0; i < g_main_argc; ++i) { #if defined(_WIN32) { array_push((array*)&res, _MOV((string[]){ string_from_wide(((u16*)(argv[i]))) })); } #else { array_push((array*)&res, _MOV((string[]){ tos_clone(argv[i]) })); } #endif } return res; } inline bool isnil(voidptr v) { return v == 0; } VV_LOC voidptr __as_cast(voidptr obj, int obj_type, int expected_type) { if (obj_type != expected_type) { string obj_name = string_clone(((VCastTypeIndexName*)as_cast_type_indexes.data)[0].tname); string expected_name = string_clone(((VCastTypeIndexName*)as_cast_type_indexes.data)[0].tname); for (int _t1 = 0; _t1 < as_cast_type_indexes.len; ++_t1) { VCastTypeIndexName x = ((VCastTypeIndexName*)as_cast_type_indexes.data)[_t1]; if (x.tindex == obj_type) { obj_name = string_clone(x.tname); } if (x.tindex == expected_type) { expected_name = string_clone(x.tname); } } _v_panic(string__plus(string__plus(string__plus(string__plus(_S("as cast: cannot cast `"), obj_name), _S("` to `")), expected_name), _S("`"))); VUNREACHABLE(); } return obj; } VV_LOC void builtin_init(void) { #if defined(_VGCBOEHM) { #if !defined(CUSTOM_DEFINE_gc_warn_on_stderr) { gc_set_warn_proc((voidptr)internal_gc_warn_proc_none); } #endif } #endif } VV_LOC void break_if_debugger_attached(void) { { // Unsafe block voidptr* ptr = ((voidptr*)(0)); *ptr = ((void*)0); } } void gc_set_warn_proc(void (*cb)(char* msg, usize arg)) { } VV_LOC void internal_gc_warn_proc_none(char* msg, usize arg) { } VV_LOC void print_libbacktrace(int frames_to_skip) { } __NOINLINE VV_LOC void eprint_libbacktrace(int frames_to_skip) { } int proc_pidpath(int , voidptr , int ); inline int vstrlen(u8* s) { return strlen(((char*)(s))); } inline int vstrlen_char(char* s) { return strlen(s); } inline voidptr vmemcpy(voidptr dest, const voidptr const_src, isize n) { #if defined(CUSTOM_DEFINE_trace_vmemcpy) { fprintf(stderr, "vmemcpy dest: %p src: %p n: %6ld\n", dest, const_src, n); } #endif #if defined(CUSTOM_DEFINE_trace_vmemcpy_nulls) { if (dest == 0 || const_src == 0) { fprintf(stderr, "vmemcpy null pointers passed, dest: %p src: %p n: %6ld\n", dest, const_src, n); print_backtrace(); } } #endif if (n == 0) { return dest; } { // Unsafe block return memcpy(dest, const_src, n); } return 0; } inline voidptr vmemmove(voidptr dest, const voidptr const_src, isize n) { #if defined(CUSTOM_DEFINE_trace_vmemmove) { fprintf(stderr, "vmemmove dest: %p src: %p n: %6ld\n", dest, const_src, n); } #endif if (n == 0) { return dest; } { // Unsafe block return memmove(dest, const_src, n); } return 0; } inline int vmemcmp(const voidptr const_s1, const voidptr const_s2, isize n) { #if defined(CUSTOM_DEFINE_trace_vmemcmp) { fprintf(stderr, "vmemcmp s1: %p s2: %p n: %6ld\n", const_s1, const_s2, n); } #endif if (n == 0) { return 0; } { // Unsafe block return memcmp(const_s1, const_s2, n); } return 0; } inline voidptr vmemset(voidptr s, int c, isize n) { #if defined(CUSTOM_DEFINE_trace_vmemset) { fprintf(stderr, "vmemset s: %p c: %d n: %6ld\n", s, c, n); } #endif #if defined(CUSTOM_DEFINE_trace_vmemset_nulls) { if (s == 0) { fprintf(stderr, "vmemset null pointers passed s: %p, c: %6d, n: %6ld\n", s, c, n); print_backtrace(); } } #endif if (n == 0) { return s; } { // Unsafe block return memset(s, c, n); } return 0; } inline VV_LOC void vqsort(voidptr base, usize nmemb, usize size, int (*sort_cb)(const voidptr const_a, const voidptr const_b)) { #if defined(CUSTOM_DEFINE_trace_vqsort) { fprintf(stderr, "vqsort base: %p, nmemb: %6uld, size: %6uld, sort_cb: %p\n", base, nmemb, size, sort_cb); } #endif if (nmemb == 0) { return; } #if defined(CUSTOM_DEFINE_trace_vqsort_nulls) { if (base == 0 || ((u64)(sort_cb)) == 0U) { fprintf(stderr, "vqsort null pointers passed base: %p, nmemb: %6uld, size: %6uld, sort_cb: %p\n", base, nmemb, size, sort_cb); print_backtrace(); } } #endif qsort(base, nmemb, size, ((voidptr)(sort_cb))); } #if !defined(_VNATIVE) #endif inline string f64_str(f64 x) { { // Unsafe block strconv__Float64u f = ((strconv__Float64u){.f = x,}); if (f.u == _const_strconv__double_minus_zero) { return _S("-0.0"); } if (f.u == _const_strconv__double_plus_zero) { return _S("0.0"); } } f64 abs_x = f64_abs(x); if (abs_x >= ((f64)(0.0001)) && abs_x < ((f64)(1.0e6))) { return strconv__f64_to_str_l(x); } else { return strconv__ftoa_64(x); } return (string){.str=(byteptr)"", .is_lit=1}; } inline string f64_strg(f64 x) { if (x == 0) { return _S("0.0"); } f64 abs_x = f64_abs(x); if (abs_x >= ((f64)(0.0001)) && abs_x < ((f64)(1.0e6))) { return strconv__f64_to_str_l_with_dot(x); } else { return strconv__ftoa_64(x); } return (string){.str=(byteptr)"", .is_lit=1}; } inline string f32_str(f32 x) { { // Unsafe block strconv__Float32u f = ((strconv__Float32u){.f = x,}); if (f.u == _const_strconv__single_minus_zero) { return _S("-0.0"); } if (f.u == _const_strconv__single_plus_zero) { return _S("0.0"); } } f32 abs_x = f32_abs(x); if (abs_x >= ((f32)(0.0001)) && abs_x < ((f32)(1.0e6))) { return strconv__f32_to_str_l(x); } else { return strconv__ftoa_32(x); } return (string){.str=(byteptr)"", .is_lit=1}; } inline string f32_strg(f32 x) { if (x == 0) { return _S("0.0"); } f32 abs_x = f32_abs(x); if (abs_x >= ((f32)(0.0001)) && abs_x < ((f32)(1.0e6))) { return strconv__f32_to_str_l_with_dot(x); } else { return strconv__ftoa_32(x); } return (string){.str=(byteptr)"", .is_lit=1}; } inline f32 f32_abs(f32 a) { return (a < 0 ? (-a) : (a)); } inline f64 f64_abs(f64 a) { return (a < 0 ? (-a) : (a)); } string ptr_str(voidptr ptr) { string buf1 = u64_to_hex_no_leading_zeros(((u64)(ptr)), 16); return buf1; } string isize_str(isize x) { return i64_str(((i64)(x))); } string usize_str(usize x) { return u64_str(((u64)(x))); } string char_str(char* cptr) { return u64_hex(((u64)(cptr))); } inline VV_LOC string int_str_l(int nn, int max) { { // Unsafe block i64 n = ((i64)(nn)); int d = 0; if (n == 0) { return _S("0"); } bool is_neg = false; if (n < 0) { n = -n; is_neg = true; } int index = max; u8* buf = malloc_noscan((int)(max + 1)); buf[index] = 0; index--; for (;;) { if (!(n > 0)) break; int n1 = ((int)((i64)(n / 100))); d = ((int)((((u32)((int)(((int)(n)) - ((int)(n1 * 100))))) << 1U))); n = n1; buf[index] = _const_digit_pairs.str[d]; index--; d++; buf[index] = _const_digit_pairs.str[d]; index--; } index++; if (d < 20) { index++; } if (is_neg) { index--; buf[index] = '-'; } int diff = (int)(max - index); vmemmove(buf, ((voidptr)(buf + index)), (int)(diff + 1)); return tos(buf, diff); } return (string){.str=(byteptr)"", .is_lit=1}; } string i8_str(i8 n) { return int_str_l(((int)(n)), 5); } string i16_str(i16 n) { return int_str_l(((int)(n)), 7); } string u16_str(u16 n) { return int_str_l(((int)(n)), 7); } string i32_str(i32 n) { return int_str_l(((int)(n)), 12); } string int_str(int n) { return int_str_l(n, 12); } inline string u32_str(u32 nn) { { // Unsafe block u32 n = nn; u32 d = ((u32)(0U)); if (n == 0U) { return _S("0"); } int max = 12; u8* buf = malloc_noscan((int)(max + 1)); int index = max; buf[index] = 0; index--; for (;;) { if (!(n > 0U)) break; u32 n1 = (u32)(n / ((u32)(100U))); d = ((((u32)(n - ((u32)(n1 * ((u32)(100U)))))) << ((u32)(1U)))); n = n1; buf[index] = _const_digit_pairs.str[ d]; index--; d++; buf[index] = _const_digit_pairs.str[ d]; index--; } index++; if (d < ((u32)(20U))) { index++; } int diff = (int)(max - index); vmemmove(buf, ((voidptr)(buf + index)), (int)(diff + 1)); return tos(buf, diff); } return (string){.str=(byteptr)"", .is_lit=1}; } inline string int_literal_str(int_literal n) { return impl_i64_to_string(n); } inline string i64_str(i64 nn) { return impl_i64_to_string(nn); } VV_LOC string impl_i64_to_string(i64 nn) { { // Unsafe block i64 n = nn; i64 d = ((i64)(0)); if (n == 0) { return _S("0"); } else if (n == _const_min_i64) { return _S("-9223372036854775808"); } int max = 20; u8* buf = malloc_noscan((int)(max + 1)); bool is_neg = false; if (n < 0) { n = -n; is_neg = true; } int index = max; buf[index] = 0; index--; for (;;) { if (!(n > 0)) break; i64 n1 = (i64)(n / ((i64)(100))); d = ((((u32)((i64)(n - ((i64)(n1 * ((i64)(100))))))) << ((i64)(1)))); n = n1; buf[index] = _const_digit_pairs.str[ d]; index--; d++; buf[index] = _const_digit_pairs.str[ d]; index--; } index++; if (d < ((i64)(20))) { index++; } if (is_neg) { index--; buf[index] = '-'; } int diff = (int)(max - index); vmemmove(buf, ((voidptr)(buf + index)), (int)(diff + 1)); return tos(buf, diff); } return (string){.str=(byteptr)"", .is_lit=1}; } inline string u64_str(u64 nn) { { // Unsafe block u64 n = nn; u64 d = ((u64)(0U)); if (n == 0U) { return _S("0"); } int max = 20; u8* buf = malloc_noscan((int)(max + 1)); int index = max; buf[index] = 0; index--; for (;;) { if (!(n > 0U)) break; u64 n1 = (u64)(n / 100U); d = ((((u64)(n - ((u64)(n1 * 100U)))) << 1U)); n = n1; buf[index] = _const_digit_pairs.str[ d]; index--; d++; buf[index] = _const_digit_pairs.str[ d]; index--; } index++; if (d < 20U) { index++; } int diff = (int)(max - index); vmemmove(buf, ((voidptr)(buf + index)), (int)(diff + 1)); return tos(buf, diff); } return (string){.str=(byteptr)"", .is_lit=1}; } string bool_str(bool b) { if (b) { return _S("true"); } return _S("false"); } inline VV_LOC string u64_to_hex(u64 nn, u8 len) { u64 n = nn; Array_fixed_u8_17 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; buf[len] = 0; int i = 0; for (i = (u8)(len - 1); i >= 0; i--) { u8 d = ((u8)((n & 0xFU))); buf[i] = (d < 10 ? ((rune)(d + '0')) : ((u8)(d + 87))); n = (n >> 4U); } return tos(memdup(&buf[0], (u8)(len + 1)), len); } inline VV_LOC string u64_to_hex_no_leading_zeros(u64 nn, u8 len) { u64 n = nn; Array_fixed_u8_17 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; buf[len] = 0; int i = 0; for (i = (u8)(len - 1); i >= 0; i--) { u8 d = ((u8)((n & 0xFU))); buf[i] = (d < 10 ? ((rune)(d + '0')) : ((u8)(d + 87))); n = (n >> 4U); if (n == 0U) { break; } } int res_len = (int)(len - i); return tos(memdup(&buf[i], (int)(res_len + 1)), res_len); } string u8_hex(u8 nn) { if (nn == 0) { return _S("00"); } return u64_to_hex(nn, 2); } string u32_hex(u32 nn) { if (nn == 0U) { return _S("0"); } return u64_to_hex_no_leading_zeros(nn, 8); } string int_hex(int nn) { return u32_hex(((u32)(nn))); } string u64_hex(u64 nn) { if (nn == 0U) { return _S("0"); } return u64_to_hex_no_leading_zeros(nn, 16); } string voidptr_str(voidptr nn) { return string__plus(_S("0x"), u64_hex(((u64)(nn)))); } string byteptr_str(byteptr nn) { return string__plus(_S("0x"), u64_hex(((u64)(nn)))); } string charptr_str(charptr nn) { return string__plus(_S("0x"), u64_hex(((u64)(nn)))); } string u64_hex_full(u64 nn) { return u64_to_hex(nn, 16); } string u8_str(u8 b) { return int_str_l(((int)(b)), 7); } string u8_ascii_str(u8 b) { string str = ((string){.str = malloc_noscan(2), .len = 1}); { // Unsafe block str.str[0] = b; str.str[1] = 0; } return str; } inline bool u8_is_capital(u8 c) { return c >= 'A' && c <= 'Z'; } string Array_u8_bytestr(Array_u8 b) { { // Unsafe block u8* buf = malloc_noscan((int)(b.len + 1)); vmemcpy(buf, b.data, b.len); buf[b.len] = 0; return tos(buf, b.len); } return (string){.str=(byteptr)"", .is_lit=1}; } inline int int_min(int a, int b) { return (a < b ? (a) : (b)); } inline int int_max(int a, int b) { return (a > b ? (a) : (b)); } inline VV_LOC bool fast_string_eq(string a, string b) { if (a.len != b.len) { return false; } { // Unsafe block return memcmp(a.str, b.str, b.len) == 0; } return 0; } VV_LOC u64 map_hash_string(voidptr pkey) { string key = *((string*)(pkey)); return wyhash(key.str, ((u64)(key.len)), 0U, ((u64*)(((voidptr)(_wyp))))); } VV_LOC u64 map_hash_int_1(voidptr pkey) { return wyhash64(*((u8*)(pkey)), 0U); } VV_LOC u64 map_hash_int_2(voidptr pkey) { return wyhash64(*((u16*)(pkey)), 0U); } VV_LOC u64 map_hash_int_4(voidptr pkey) { return wyhash64(*((u32*)(pkey)), 0U); } VV_LOC u64 map_hash_int_8(voidptr pkey) { return wyhash64(*((u64*)(pkey)), 0U); } VV_LOC void DenseArray_zeros_to_end(DenseArray* d) { u8* tmp_value = _v_malloc(d->value_bytes); u8* tmp_key = _v_malloc(d->key_bytes); int count = 0; for (int i = 0; i < d->len; ++i) { if (DenseArray_has_index(d, i)) { { // Unsafe block if (count != i) { memcpy(tmp_key, DenseArray_key(d, count), d->key_bytes); memcpy(DenseArray_key(d, count), DenseArray_key(d, i), d->key_bytes); memcpy(DenseArray_key(d, i), tmp_key, d->key_bytes); memcpy(tmp_value, DenseArray_value(d, count), d->value_bytes); memcpy(DenseArray_value(d, count), DenseArray_value(d, i), d->value_bytes); memcpy(DenseArray_value(d, i), tmp_value, d->value_bytes); } } count++; } } { // Unsafe block _v_free(tmp_value); _v_free(tmp_key); d->deletes = 0U; _v_free(d->all_deleted); } d->len = count; int old_cap = d->cap; d->cap = (count < 8 ? (8) : (count)); { // Unsafe block d->values = realloc_data(d->values, (int)(d->value_bytes * old_cap), (int)(d->value_bytes * d->cap)); d->keys = realloc_data(d->keys, (int)(d->key_bytes * old_cap), (int)(d->key_bytes * d->cap)); } } inline VV_LOC DenseArray new_dense_array(int key_bytes, int value_bytes) { int cap = 8; return ((DenseArray){ .key_bytes = key_bytes, .value_bytes = value_bytes, .cap = cap, .len = 0, .deletes = 0U, .all_deleted = ((void*)0), .keys = _v_malloc(__at_least_one((u64)(((u64)(cap)) * ((u64)(key_bytes))))), .values = _v_malloc(__at_least_one((u64)(((u64)(cap)) * ((u64)(value_bytes))))), }); } inline VV_LOC voidptr DenseArray_key(DenseArray* d, int i) { return ((voidptr)(d->keys + (int)(i * d->key_bytes))); } inline VV_LOC voidptr DenseArray_value(DenseArray* d, int i) { return ((voidptr)(d->values + (int)(i * d->value_bytes))); } inline VV_LOC bool DenseArray_has_index(DenseArray* d, int i) { return d->deletes == 0U || d->all_deleted[i] == 0; } inline VV_LOC int DenseArray_expand(DenseArray* d) { int old_cap = d->cap; int old_key_size = (int)(d->key_bytes * old_cap); int old_value_size = (int)(d->value_bytes * old_cap); if (d->cap == d->len) { d->cap += (d->cap >> 3); { // Unsafe block d->keys = realloc_data(d->keys, old_key_size, (int)(d->key_bytes * d->cap)); d->values = realloc_data(d->values, old_value_size, (int)(d->value_bytes * d->cap)); if (d->deletes != 0U) { d->all_deleted = realloc_data(d->all_deleted, old_cap, d->cap); vmemset(((voidptr)(d->all_deleted + d->len)), 0, (int)(d->cap - d->len)); } } } int push_index = d->len; { // Unsafe block if (d->deletes != 0U) { d->all_deleted[push_index] = 0; } } d->len++; return push_index; } inline VV_LOC bool map_eq_string(voidptr a, voidptr b) { return fast_string_eq(*((string*)(a)), *((string*)(b))); } inline VV_LOC bool map_eq_int_1(voidptr a, voidptr b) { return *((u8*)(a)) == *((u8*)(b)); } inline VV_LOC bool map_eq_int_2(voidptr a, voidptr b) { return *((u16*)(a)) == *((u16*)(b)); } inline VV_LOC bool map_eq_int_4(voidptr a, voidptr b) { return *((u32*)(a)) == *((u32*)(b)); } inline VV_LOC bool map_eq_int_8(voidptr a, voidptr b) { return *((u64*)(a)) == *((u64*)(b)); } inline VV_LOC void map_clone_string(voidptr dest, voidptr pkey) { { // Unsafe block string s = *((string*)(pkey)); *((string*)(dest)) = string_clone(s); } } inline VV_LOC void map_clone_int_1(voidptr dest, voidptr pkey) { { // Unsafe block *((u8*)(dest)) = *((u8*)(pkey)); } } inline VV_LOC void map_clone_int_2(voidptr dest, voidptr pkey) { { // Unsafe block *((u16*)(dest)) = *((u16*)(pkey)); } } inline VV_LOC void map_clone_int_4(voidptr dest, voidptr pkey) { { // Unsafe block *((u32*)(dest)) = *((u32*)(pkey)); } } inline VV_LOC void map_clone_int_8(voidptr dest, voidptr pkey) { { // Unsafe block *((u64*)(dest)) = *((u64*)(pkey)); } } inline VV_LOC void map_free_string(voidptr pkey) { string_free(ADDR(string, (*((string*)(pkey))))); } inline VV_LOC void map_free_nop(voidptr _d1) { } VV_LOC map new_map(int key_bytes, int value_bytes, u64 (*hash_fn)(voidptr ), bool (*key_eq_fn)(voidptr , voidptr ), void (*clone_fn)(voidptr , voidptr ), void (*free_fn)(voidptr )) { int metasize = ((int)((u32)(sizeof(u32) * ((int_literal)(_const_init_capicity + _const_extra_metas_inc))))); bool has_string_keys = _us32_lt(sizeof(voidptr),key_bytes); return ((map){ .key_bytes = key_bytes, .value_bytes = value_bytes, .even_index = _const_init_even_index, .cached_hashbits = _const_max_cached_hashbits, .shift = _const_init_log_capicity, .key_values = new_dense_array(key_bytes, value_bytes), .metas = ((u32*)(vcalloc_noscan(metasize))), .extra_metas = _const_extra_metas_inc, .has_string_keys = has_string_keys, .hash_fn = (voidptr)hash_fn, .key_eq_fn = (voidptr)key_eq_fn, .clone_fn = (voidptr)clone_fn, .free_fn = (voidptr)free_fn, .len = 0, }); } VV_LOC map new_map_init(u64 (*hash_fn)(voidptr ), bool (*key_eq_fn)(voidptr , voidptr ), void (*clone_fn)(voidptr , voidptr ), void (*free_fn)(voidptr ), int n, int key_bytes, int value_bytes, voidptr keys, voidptr values) { map out = new_map(key_bytes, value_bytes, (voidptr)hash_fn, (voidptr)key_eq_fn, (voidptr)clone_fn, (voidptr)free_fn); u8* pkey = ((u8*)(keys)); u8* pval = ((u8*)(values)); for (int _t1 = 0; _t1 < n; ++_t1) { { // Unsafe block map_set(&out, pkey, pval); pkey = pkey + key_bytes; pval = pval + value_bytes; } } return out; } map map_move(map* m) { map r = *m; vmemset(m, 0, ((int)(sizeof(map)))); return r; } void map_clear(map* m) { { // Unsafe block if (m->key_values.all_deleted != 0) { _v_free(m->key_values.all_deleted); m->key_values.all_deleted = ((void*)0); } vmemset(m->key_values.keys, 0, (int)(m->key_values.key_bytes * m->key_values.cap)); vmemset(m->metas, 0, (u32)(sizeof(u32) * ((u32)((u32)(m->even_index + 2U) + m->extra_metas)))); } m->key_values.len = 0; m->key_values.deletes = 0U; m->even_index = _const_init_even_index; m->cached_hashbits = _const_max_cached_hashbits; m->shift = _const_init_log_capicity; m->len = 0; } inline VV_LOC multi_return_u32_u32 map_key_to_index(map* m, voidptr pkey) { u64 hash = m->hash_fn(pkey); u64 index = (hash & m->even_index); u64 meta = (((((hash >> m->shift)) & _const_hash_mask)) | _const_probe_inc); return (multi_return_u32_u32){.arg0=((u32)(index)), .arg1=((u32)(meta))}; } inline VV_LOC multi_return_u32_u32 map_meta_less(map* m, u32 _index, u32 _metas) { u32 index = _index; u32 meta = _metas; for (;;) { if (!(meta < m->metas[index])) break; index += 2U; meta += _const_probe_inc; } return (multi_return_u32_u32){.arg0=index, .arg1=meta}; } inline VV_LOC void map_meta_greater(map* m, u32 _index, u32 _metas, u32 kvi) { u32 meta = _metas; u32 index = _index; u32 kv_index = kvi; for (;;) { if (!(m->metas[index] != 0U)) break; if (meta > m->metas[index]) { { // Unsafe block u32 tmp_meta = m->metas[index]; m->metas[index] = meta; meta = tmp_meta; u32 tmp_index = m->metas[(u32)(index + 1U)]; m->metas[(u32)(index + 1U)] = kv_index; kv_index = tmp_index; } } index += 2U; meta += _const_probe_inc; } { // Unsafe block m->metas[index] = meta; m->metas[(u32)(index + 1U)] = kv_index; } u32 probe_count = (u32)(((meta >> _const_hashbits)) - 1U); map_ensure_extra_metas(m, probe_count); } inline VV_LOC void map_ensure_extra_metas(map* m, u32 probe_count) { if (((probe_count << 1U)) == m->extra_metas) { u32 size_of_u32 = sizeof(u32); u32 old_mem_size = ((u32)((u32)(m->even_index + 2U) + m->extra_metas)); m->extra_metas += _const_extra_metas_inc; u32 mem_size = ((u32)((u32)(m->even_index + 2U) + m->extra_metas)); { // Unsafe block u8* x = realloc_data(((u8*)(m->metas)), ((int)((u32)(size_of_u32 * old_mem_size))), ((int)((u32)(size_of_u32 * mem_size)))); m->metas = ((u32*)(x)); vmemset(m->metas + mem_size - _const_extra_metas_inc, 0, ((int)((u32)(sizeof(u32) * _const_extra_metas_inc)))); } if (probe_count == 252U) { _v_panic(_S("Probe overflow")); VUNREACHABLE(); } } } VV_LOC void map_set(map* m, voidptr key, voidptr value) { f32 load_factor = (f32)(((f32)((((u32)(m->len)) << 1U))) / ((f32)(m->even_index))); if (load_factor > ((f32)(_const_max_load_factor))) { map_expand(m); } multi_return_u32_u32 mr_12308 = map_key_to_index(m, key); u32 index = mr_12308.arg0; u32 meta = mr_12308.arg1; multi_return_u32_u32 mr_12344 = map_meta_less(m, index, meta); index = mr_12344.arg0; meta = mr_12344.arg1; for (;;) { if (!(meta == m->metas[index])) break; int kv_index = ((int)(m->metas[(u32)(index + 1U)])); voidptr pkey = DenseArray_key(&m->key_values, kv_index); if (m->key_eq_fn(key, pkey)) { { // Unsafe block voidptr pval = DenseArray_value(&m->key_values, kv_index); vmemcpy(pval, value, m->value_bytes); } return; } index += 2U; meta += _const_probe_inc; } int kv_index = DenseArray_expand(&m->key_values); { // Unsafe block voidptr pkey = DenseArray_key(&m->key_values, kv_index); voidptr pvalue = DenseArray_value(&m->key_values, kv_index); m->clone_fn(pkey, key); vmemcpy(((u8*)(pvalue)), value, m->value_bytes); } map_meta_greater(m, index, meta, ((u32)(kv_index))); m->len++; } VV_LOC void map_expand(map* m) { u32 old_cap = m->even_index; m->even_index = (u32)(((((u32)(m->even_index + 2U)) << 1U)) - 2U); if (m->cached_hashbits == 0) { m->shift += _const_max_cached_hashbits; m->cached_hashbits = _const_max_cached_hashbits; map_rehash(m); } else { map_cached_rehash(m, old_cap); m->cached_hashbits--; } } VV_LOC void map_rehash(map* m) { u32 meta_bytes = (u32)(sizeof(u32) * ((u32)((u32)(m->even_index + 2U) + m->extra_metas))); map_reserve(m, meta_bytes); } void map_reserve(map* m, u32 meta_bytes) { { // Unsafe block u8* x = v_realloc(((u8*)(m->metas)), ((int)(meta_bytes))); m->metas = ((u32*)(x)); vmemset(m->metas, 0, ((int)(meta_bytes))); } for (int i = 0; i < m->key_values.len; i++) { if (!DenseArray_has_index(&m->key_values, i)) { continue; } voidptr pkey = DenseArray_key(&m->key_values, i); multi_return_u32_u32 mr_14105 = map_key_to_index(m, pkey); u32 index = mr_14105.arg0; u32 meta = mr_14105.arg1; multi_return_u32_u32 mr_14143 = map_meta_less(m, index, meta); index = mr_14143.arg0; meta = mr_14143.arg1; map_meta_greater(m, index, meta, ((u32)(i))); } } VV_LOC void map_cached_rehash(map* m, u32 old_cap) { u32* old_metas = m->metas; int metasize = ((int)((u32)(sizeof(u32) * ((u32)((u32)(m->even_index + 2U) + m->extra_metas))))); m->metas = ((u32*)(vcalloc(metasize))); u32 old_extra_metas = m->extra_metas; for (u32 i = ((u32)(0U)); i <= (u32)(old_cap + old_extra_metas); i += 2U) { if (old_metas[i] == 0U) { continue; } u32 old_meta = old_metas[i]; u32 old_probe_count = (((u32)(((old_meta >> _const_hashbits)) - 1U)) << 1U); u32 old_index = (((u32)(i - old_probe_count)) & ((m->even_index >> 1U))); u32 index = (((old_index | ((old_meta << m->shift)))) & m->even_index); u32 meta = (((old_meta & _const_hash_mask)) | _const_probe_inc); multi_return_u32_u32 mr_14945 = map_meta_less(m, index, meta); index = mr_14945.arg0; meta = mr_14945.arg1; u32 kv_index = old_metas[(u32)(i + 1U)]; map_meta_greater(m, index, meta, kv_index); } _v_free(old_metas); } VV_LOC voidptr map_get_and_set(map* m, voidptr key, voidptr zero) { for (;;) { multi_return_u32_u32 mr_15393 = map_key_to_index(m, key); u32 index = mr_15393.arg0; u32 meta = mr_15393.arg1; for (;;) { if (meta == m->metas[index]) { int kv_index = ((int)(m->metas[(u32)(index + 1U)])); voidptr pkey = DenseArray_key(&m->key_values, kv_index); if (m->key_eq_fn(key, pkey)) { voidptr pval = DenseArray_value(&m->key_values, kv_index); return ((u8*)(pval)); } } index += 2U; meta += _const_probe_inc; if (meta > m->metas[index]) { break; } } map_set(m, key, zero); } return ((void*)0); } VV_LOC voidptr map_get(map* m, voidptr key, voidptr zero) { multi_return_u32_u32 mr_16120 = map_key_to_index(m, key); u32 index = mr_16120.arg0; u32 meta = mr_16120.arg1; for (;;) { if (meta == m->metas[index]) { int kv_index = ((int)(m->metas[(u32)(index + 1U)])); voidptr pkey = DenseArray_key(&m->key_values, kv_index); if (m->key_eq_fn(key, pkey)) { voidptr pval = DenseArray_value(&m->key_values, kv_index); return ((u8*)(pval)); } } index += 2U; meta += _const_probe_inc; if (meta > m->metas[index]) { break; } } return zero; } VV_LOC voidptr map_get_check(map* m, voidptr key) { multi_return_u32_u32 mr_16785 = map_key_to_index(m, key); u32 index = mr_16785.arg0; u32 meta = mr_16785.arg1; for (;;) { if (meta == m->metas[index]) { int kv_index = ((int)(m->metas[(u32)(index + 1U)])); voidptr pkey = DenseArray_key(&m->key_values, kv_index); if (m->key_eq_fn(key, pkey)) { voidptr pval = DenseArray_value(&m->key_values, kv_index); return ((u8*)(pval)); } } index += 2U; meta += _const_probe_inc; if (meta > m->metas[index]) { break; } } return 0; } VV_LOC bool map_exists(map* m, voidptr key) { multi_return_u32_u32 mr_17295 = map_key_to_index(m, key); u32 index = mr_17295.arg0; u32 meta = mr_17295.arg1; for (;;) { if (meta == m->metas[index]) { int kv_index = ((int)(m->metas[(u32)(index + 1U)])); voidptr pkey = DenseArray_key(&m->key_values, kv_index); if (m->key_eq_fn(key, pkey)) { return true; } } index += 2U; meta += _const_probe_inc; if (meta > m->metas[index]) { break; } } return false; } inline VV_LOC void DenseArray_delete(DenseArray* d, int i) { if (d->deletes == 0U) { d->all_deleted = vcalloc(d->cap); } d->deletes++; { // Unsafe block d->all_deleted[i] = 1; } } void map_delete(map* m, voidptr key) { multi_return_u32_u32 mr_17933 = map_key_to_index(m, key); u32 index = mr_17933.arg0; u32 meta = mr_17933.arg1; multi_return_u32_u32 mr_17969 = map_meta_less(m, index, meta); index = mr_17969.arg0; meta = mr_17969.arg1; for (;;) { if (!(meta == m->metas[index])) break; int kv_index = ((int)(m->metas[(u32)(index + 1U)])); voidptr pkey = DenseArray_key(&m->key_values, kv_index); if (m->key_eq_fn(key, pkey)) { for (;;) { if (!(((m->metas[(u32)(index + 2U)] >> _const_hashbits)) > 1U)) break; { // Unsafe block m->metas[index] = (u32)(m->metas[(u32)(index + 2U)] - _const_probe_inc); m->metas[(u32)(index + 1U)] = m->metas[(u32)(index + 3U)]; } index += 2U; } m->len--; DenseArray_delete(&m->key_values, kv_index); { // Unsafe block m->metas[index] = 0U; m->free_fn(pkey); vmemset(pkey, 0, m->key_bytes); } if (m->key_values.len <= 32) { return; } if (_us32_ge(m->key_values.deletes,((m->key_values.len >> 1)))) { DenseArray_zeros_to_end(&m->key_values); map_rehash(m); } return; } index += 2U; meta += _const_probe_inc; } } array map_keys(map* m) { array keys = __new_array(m->len, 0, m->key_bytes); u8* item = ((u8*)(keys.data)); if (m->key_values.deletes == 0U) { for (int i = 0; i < m->key_values.len; i++) { { // Unsafe block voidptr pkey = DenseArray_key(&m->key_values, i); m->clone_fn(item, pkey); item = item + m->key_bytes; } } return keys; } for (int i = 0; i < m->key_values.len; i++) { if (!DenseArray_has_index(&m->key_values, i)) { continue; } { // Unsafe block voidptr pkey = DenseArray_key(&m->key_values, i); m->clone_fn(item, pkey); item = item + m->key_bytes; } } return keys; } array map_values(map* m) { array values = __new_array(m->len, 0, m->value_bytes); u8* item = ((u8*)(values.data)); if (m->key_values.deletes == 0U) { vmemcpy(item, m->key_values.values, (int)(m->value_bytes * m->key_values.len)); return values; } for (int i = 0; i < m->key_values.len; i++) { if (!DenseArray_has_index(&m->key_values, i)) { continue; } { // Unsafe block voidptr pvalue = DenseArray_value(&m->key_values, i); vmemcpy(item, pvalue, m->value_bytes); item = item + m->value_bytes; } } return values; } VV_LOC DenseArray DenseArray_clone(DenseArray* d) { DenseArray res = ((DenseArray){ .key_bytes = d->key_bytes, .value_bytes = d->value_bytes, .cap = d->cap, .len = d->len, .deletes = d->deletes, .all_deleted = ((void*)0), .keys = ((void*)0), .values = ((void*)0), }); { // Unsafe block if (d->deletes != 0U) { res.all_deleted = memdup(d->all_deleted, d->cap); } res.keys = memdup(d->keys, (int)(d->cap * d->key_bytes)); res.values = memdup(d->values, (int)(d->cap * d->value_bytes)); } return res; } map map_clone(map* m) { int metasize = ((int)((u32)(sizeof(u32) * ((u32)((u32)(m->even_index + 2U) + m->extra_metas))))); map res = ((map){ .key_bytes = m->key_bytes, .value_bytes = m->value_bytes, .even_index = m->even_index, .cached_hashbits = m->cached_hashbits, .shift = m->shift, .key_values = DenseArray_clone(&m->key_values), .metas = ((u32*)(malloc_noscan(metasize))), .extra_metas = m->extra_metas, .has_string_keys = m->has_string_keys, .hash_fn = (voidptr)m->hash_fn, .key_eq_fn = (voidptr)m->key_eq_fn, .clone_fn = (voidptr)m->clone_fn, .free_fn = (voidptr)m->free_fn, .len = m->len, }); vmemcpy(res.metas, m->metas, metasize); if (!m->has_string_keys) { return res; } for (int i = 0; i < m->key_values.len; ++i) { if (!DenseArray_has_index(&m->key_values, i)) { continue; } m->clone_fn(DenseArray_key(&res.key_values, i), DenseArray_key(&m->key_values, i)); } return res; } void map_free(map* m) { _v_free(m->metas); { // Unsafe block m->metas = ((void*)0); } if (m->key_values.deletes == 0U) { for (int i = 0; i < m->key_values.len; i++) { { // Unsafe block voidptr pkey = DenseArray_key(&m->key_values, i); m->free_fn(pkey); vmemset(pkey, 0, m->key_bytes); } } } else { for (int i = 0; i < m->key_values.len; i++) { if (!DenseArray_has_index(&m->key_values, i)) { continue; } { // Unsafe block voidptr pkey = DenseArray_key(&m->key_values, i); m->free_fn(pkey); vmemset(pkey, 0, m->key_bytes); } } } { // Unsafe block if (m->key_values.all_deleted != ((void*)0)) { _v_free(m->key_values.all_deleted); m->key_values.all_deleted = ((void*)0); } if (m->key_values.keys != ((void*)0)) { _v_free(m->key_values.keys); m->key_values.keys = ((void*)0); } if (m->key_values.values != ((void*)0)) { _v_free(m->key_values.values); m->key_values.values = ((void*)0); } m->hash_fn = (voidptr)((void*)0); m->key_eq_fn = (voidptr)((void*)0); m->clone_fn = (voidptr)((void*)0); m->free_fn = (voidptr)((void*)0); } } void IError_free(IError* ie) { { // Unsafe block IError* cie = ((IError*)(ie)); _v_free(cie->_object); } } VV_LOC void _option_none(voidptr data, _option* option, int size) { { // Unsafe block *option = ((_option){.state = 2,.err = _const_none__,}); vmemcpy(((u8*)(&option->err)) + sizeof(IError), data, size); } } VV_LOC void _option_ok(voidptr data, _option* option, int size) { { // Unsafe block *option = ((_option){.state = 0,.err = _const_none__,}); vmemcpy(((u8*)(&option->err)) + sizeof(IError), data, size); } } VV_LOC void _option_clone(_option* current, _option* option, int size) { { // Unsafe block *option = ((_option){.state = current->state,.err = current->err,}); vmemcpy(((u8*)(&option->err)) + sizeof(IError), ((u8*)(¤t->err)) + sizeof(IError), size); } } VV_LOC string None___str(None__ _d1) { return _S("none"); } string none_str(none _d1) { return _S("none"); } VV_LOC void vmemory_abort_on_nil(voidptr p, isize bytes) { if (p == 0) { fprintf(stderr, "could not allocate %td bytes\n", bytes); _v_exit(1); VUNREACHABLE(); } } VV_LOC VMemoryBlock* vmemory_block_new(VMemoryBlock* prev, isize at_least, isize align) { u32 vmem_block_size = sizeof(VMemoryBlock); VMemoryBlock* v = ((VMemoryBlock*)(calloc(1, vmem_block_size))); vmemory_abort_on_nil(v, vmem_block_size); if (prev != 0) { v->id = (int)(prev->id + 1); } v->previous = prev; if (prev != 0) { prev->next = v; } isize base_block_size = (at_least < ((isize)(_const_prealloc_block_size)) ? (((isize)(_const_prealloc_block_size))) : (at_least)); isize block_size = (align > 0 ? (((isize)(base_block_size % align) == 0 ? (base_block_size) : ((isize)((isize)(base_block_size + align) - ((isize)(base_block_size % align)))))) : (base_block_size)); #if defined(CUSTOM_DEFINE_prealloc_trace_malloc) { fprintf(stderr, "vmemory_block_new id: %d, block_size: %lld, at_least: %lld, align: %lld\n", v->id, block_size, at_least, align); } #endif int fixed_align = (align <= 1 ? (1) : (align)); #if defined(_WIN32) { v->start = _aligned_malloc(block_size, fixed_align); } #else { if (fixed_align == 1) { v->start = malloc(block_size); } else { v->start = aligned_alloc(fixed_align, block_size); } } #endif vmemory_abort_on_nil(v->start, block_size); #if defined(CUSTOM_DEFINE_prealloc_memset) { memset(v->start, ((int)(0)), block_size); } #endif v->stop = ((u8*)((i64)(((i64)(v->start)) + block_size))); v->current = v->start; return v; } VV_LOC u8* vmemory_block_malloc(isize n, isize align) { #if defined(CUSTOM_DEFINE_prealloc_trace_malloc) { fprintf(stderr, "vmemory_block_malloc g_memory_block.id: %d, n: %lld align: %d\n", g_memory_block->id, n, align); } #endif { // Unsafe block i64 remaining = (i64)(((i64)(g_memory_block->stop)) - ((i64)(g_memory_block->current))); if (_unlikely_(remaining < n)) { g_memory_block = vmemory_block_new(g_memory_block, n, align); } u8* res = ((u8*)(g_memory_block->current)); g_memory_block->current += n; #if defined(CUSTOM_DEFINE_prealloc_stats) { g_memory_block->mallocs++; } #endif return res; } return 0; } VV_LOC u8* prealloc_malloc(isize n) { return vmemory_block_malloc(n, 0); } VV_LOC u8* prealloc_realloc(u8* old_data, isize old_size, isize new_size) { u8* new_ptr = vmemory_block_malloc(new_size, 0); isize min_size = (old_size < new_size ? (old_size) : (new_size)); memcpy(new_ptr, old_data, min_size); return new_ptr; } VV_LOC u8* prealloc_calloc(isize n) { u8* new_ptr = vmemory_block_malloc(n, 0); memset(new_ptr, 0, n); return new_ptr; } VV_LOC void _result_ok(voidptr data, _result* res, int size) { { // Unsafe block *res = ((_result){.is_error = 0,.err = _const_none__,}); vmemcpy(((u8*)(&res->err)) + sizeof(IError), data, size); } } string IError_str(IError err) { return ((err._typ == _IError_None___index)? (_S("none")) : (err._typ == _IError_Error_index)? (Error_msg(*(err._Error))) : (err._typ == _IError_MessageError_index)? (MessageError_str((*(err._MessageError)))) : (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_interface_IError( (err)._typ ))}}, {_S(": "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})))); } string Error_msg(Error err) { return _S(""); } int Error_code(Error err) { return 0; } string MessageError_str(MessageError err) { if (err.code > 0) { return str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = err.msg}}, {_S("; code: "), 0xfe07, {.d_i32 = err.code}}, {_SLIT0, 0, { .d_c = 0 }}})); } return err.msg; } string MessageError_msg(MessageError err) { return err.msg; } int MessageError_code(MessageError err) { return err.code; } void MessageError_free(MessageError* err) { string_free(&err->msg); } inline IError _v_error(string message) { ; return I_MessageError_to_Interface_IError(((MessageError*)memdup(&(MessageError){.msg = message,.code = 0,}, sizeof(MessageError)))); } inline IError error_with_code(string message, int code) { ; return I_MessageError_to_Interface_IError(((MessageError*)memdup(&(MessageError){.msg = message,.code = code,}, sizeof(MessageError)))); } string rune_str(rune c) { return utf32_to_str(((u32)(c))); } string Array_rune_string(Array_rune ra) { strings__Builder sb = strings__new_builder(ra.len); strings__Builder_write_runes(&sb, ra); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } int rune_length_in_bytes(rune c) { u32 code = ((u32)(c)); if (code <= 0x7FU) { return 1; } else if (code <= 0x7FFU) { return 2; } else if (0xD800 <= code && code <= 0xDFFFU) { return -1; } else if (code <= 0xFFFFU) { return 3; } else if (code <= 0x10FFFFU) { return 4; } return -1; } rune rune_to_upper(rune c) { if (c < 0x80) { if (c >= 'a' && c <= 'z') { return (rune)(c - 32); } return c; } return rune_map_to(c, MapMode__to_upper); } rune rune_to_lower(rune c) { if (c < 0x80) { if (c >= 'A' && c <= 'Z') { return (rune)(c + 32); } return c; } return rune_map_to(c, MapMode__to_lower); } VV_LOC rune rune_map_to(rune c, MapMode mode) { int start = 0; int end = (int)(1264 / _const_rune_maps_columns_in_row); for (;;) { if (!(start < end)) break; int middle = (int)(((int)(start + end)) / 2); i32* cur_map = &_const_rune_maps[(int)(middle * _const_rune_maps_columns_in_row)]; if (c >= ((u32)(*cur_map)) && c <= ((u32)(*(cur_map + 1)))) { i32 offset = ((mode == MapMode__to_upper || mode == MapMode__to_title) ? (*(cur_map + 2)) : (*(cur_map + 3))); if (offset == _const_rune_maps_ul) { rune cnt = (rune)(((rune)(c - *cur_map)) % 2); if (mode == MapMode__to_lower) { return (rune)((rune)(c + 1) - cnt); } return (rune)(c - cnt); } else if (offset == _const_rune_maps_utl) { rune cnt = (rune)(((rune)(c - *cur_map)) % 3); if (mode == MapMode__to_upper) { return (rune)(c - cnt); } else if (mode == MapMode__to_lower) { return (rune)((rune)(c + 2) - cnt); } return (rune)((rune)(c + 1) - cnt); } return (rune)(c + offset); } if (c < ((u32)(*cur_map))) { end = middle; } else { start = (int)(middle + 1); } } return c; } VV_LOC mapnode* new_node(void) { return ((mapnode*)memdup(&(mapnode){.children = ((void*)0),.len = 0,.keys = {(string){.str=(byteptr)"", .is_lit=1}, (string){.str=(byteptr)"", .is_lit=1}, (string){.str=(byteptr)"", .is_lit=1}, (string){.str=(byteptr)"", .is_lit=1}, (string){.str=(byteptr)"", .is_lit=1}, (string){.str=(byteptr)"", .is_lit=1}, (string){.str=(byteptr)"", .is_lit=1}, (string){.str=(byteptr)"", .is_lit=1}, (string){.str=(byteptr)"", .is_lit=1}, (string){.str=(byteptr)"", .is_lit=1}, (string){.str=(byteptr)"", .is_lit=1}},.values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},}, sizeof(mapnode))); } VV_LOC void mapnode_free(mapnode* n) { println(_S("TODO")); } Array_rune string_runes(string s) { Array_rune runes = __new_array_with_default(0, s.len, sizeof(rune), 0); for (int i = 0; i < s.len; i++) { int char_len = utf8_char_len(s.str[i]); if (char_len > 1) { int end = ((int)(s.len - 1) >= (int)(i + char_len) ? ((int)(i + char_len)) : (s.len)); string r = string_substr(s, i, end); array_push((array*)&runes, _MOV((rune[]){ string_utf32_code(r) })); i += (int)(char_len - 1); } else { array_push((array*)&runes, _MOV((rune[]){ s.str[i] })); } } return runes; } string cstring_to_vstring(const char* const_s) { return string_clone(tos2(((u8*)(const_s)))); } string tos_clone(const u8* const_s) { return string_clone(tos2(((u8*)(const_s)))); } string tos(u8* s, int len) { if (s == 0) { _v_panic(_S("tos(): nil string")); VUNREACHABLE(); } return ((string){.str = s, .len = len}); } string tos2(u8* s) { if (s == 0) { _v_panic(_S("tos2: nil string")); VUNREACHABLE(); } return ((string){.str = s, .len = vstrlen(s)}); } string tos3(char* s) { if (s == 0) { _v_panic(_S("tos3: nil string")); VUNREACHABLE(); } return ((string){.str = ((u8*)(s)), .len = vstrlen_char(s)}); } string tos4(u8* s) { if (s == 0) { return _S(""); } return ((string){.str = s, .len = vstrlen(s)}); } string u8_vstring(u8* bp) { return ((string){.str = bp, .len = vstrlen(bp)}); } string u8_vstring_with_len(u8* bp, int len) { return ((string){.str = bp, .len = len, .is_lit = 0}); } bool string_is_pure_ascii(string s) { for (int i = 0; i < s.len; ++i) { if (s.str[ i] >= 0x80) { return false; } } return true; } inline VV_LOC string string_clone_static(string a) { return string_clone(a); } string string_clone(string a) { if (a.len <= 0) { return _S(""); } string b = ((string){.str = malloc_noscan((int)(a.len + 1)), .len = a.len}); { // Unsafe block vmemcpy(b.str, a.str, a.len); b.str[a.len] = 0; } return b; } string string_replace_once(string s, string rep, string with) { int idx = string_index_(s, rep); if (idx == -1) { return string_clone(s); } return string_plus_two(string_substr_unsafe(s, 0, idx), with, string_substr_unsafe(s, (int)(idx + rep.len), s.len)); } string string_replace(string s, string rep, string with) { bool string_replace_defer_0 = false; int pidxs_cap; int* pidxs; if (s.len == 0 || rep.len == 0 || rep.len > s.len) { return string_clone(s); } if (!string_contains(s, rep)) { return string_clone(s); } int pidxs_len = 0; pidxs_cap = (int)(s.len / rep.len); Array_fixed_int_10 stack_idxs = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; pidxs = &stack_idxs[0]; if (pidxs_cap > _const_replace_stack_buffer_size) { pidxs = ((int*)(_v_malloc((int)(((int)(sizeof(int))) * pidxs_cap)))); } string_replace_defer_0 = true; int idx = 0; for (;;) { idx = string_index_after_(s, rep, idx); if (idx == -1) { break; } { // Unsafe block pidxs[pidxs_len] = idx; pidxs_len++; } idx += rep.len; } if (pidxs_len == 0) { string _t3 = string_clone(s); // Defer begin if (string_replace_defer_0) { if (pidxs_cap > _const_replace_stack_buffer_size) { _v_free(pidxs); } } // Defer end return _t3; } int new_len = (int)(s.len + (int)(pidxs_len * ((int)(with.len - rep.len)))); u8* b = malloc_noscan((int)(new_len + 1)); int b_i = 0; int s_idx = 0; for (int j = 0; j < pidxs_len; ++j) { int rep_pos = pidxs[j]; int before_len = (int)(rep_pos - s_idx); vmemcpy(&b[b_i], &s.str[s_idx], before_len); b_i += before_len; s_idx = (int)(rep_pos + rep.len); vmemcpy(&b[b_i], &with.str[0], with.len); b_i += with.len; } if (s_idx < s.len) { vmemcpy(&b[b_i], &s.str[s_idx], (int)(s.len - s_idx)); } { // Unsafe block b[new_len] = 0; string _t4 = tos(b, new_len); // Defer begin if (string_replace_defer_0) { if (pidxs_cap > _const_replace_stack_buffer_size) { _v_free(pidxs); } } // Defer end return _t4; } return (string){.str=(byteptr)"", .is_lit=1}; } string string_replace_each(string s, Array_string vals) { bool string_replace_each_defer_0 = false; Array_RepIndex idxs; if (s.len == 0 || vals.len == 0) { return string_clone(s); } if ((int)(vals.len % 2) != 0) { eprintln(_S("string.replace_each(): odd number of strings")); return string_clone(s); } int new_len = s.len; idxs = __new_array_with_default(0, 6, sizeof(RepIndex), 0); string_replace_each_defer_0 = true; int idx = 0; string s_ = string_clone(s); for (int rep_i = 0; rep_i < vals.len; rep_i += 2) { string rep = ((string*)vals.data)[rep_i]; string with = ((string*)vals.data)[(int)(rep_i + 1)]; for (;;) { idx = string_index_after_(s_, rep, idx); if (idx == -1) { break; } for (int i = 0; i < rep.len; ++i) { { // Unsafe block s_.str[(int)(idx + i)] = 0; } } array_push((array*)&idxs, _MOV((RepIndex[]){ ((RepIndex){.idx = idx,.val_idx = rep_i,}) })); idx += rep.len; new_len += (int)(with.len - rep.len); } } if (idxs.len == 0) { string _t4 = string_clone(s); // Defer begin if (string_replace_each_defer_0) { array_free(&idxs); } // Defer end return _t4; } if (idxs.len > 0) { qsort(idxs.data, idxs.len, idxs.element_size, (voidptr)compare_2018276881664952276_RepIndex_by_idx); } ; u8* b = malloc_noscan((int)(new_len + 1)); int idx_pos = 0; RepIndex cur_idx = ((RepIndex*)idxs.data)[idx_pos]; int b_i = 0; for (int i = 0; i < s.len; i++) { if (i == cur_idx.idx) { string rep = ((string*)vals.data)[cur_idx.val_idx]; string with = ((string*)vals.data)[(int)(cur_idx.val_idx + 1)]; for (int j = 0; j < with.len; ++j) { { // Unsafe block b[b_i] = with.str[ j]; } b_i++; } i += (int)(rep.len - 1); idx_pos++; if (idx_pos < idxs.len) { cur_idx = ((RepIndex*)idxs.data)[idx_pos]; } } else { { // Unsafe block b[b_i] = s.str[i]; } b_i++; } } { // Unsafe block b[new_len] = 0; string _t5 = tos(b, new_len); // Defer begin if (string_replace_each_defer_0) { array_free(&idxs); } // Defer end return _t5; } return (string){.str=(byteptr)"", .is_lit=1}; } inline bool string_bool(string s) { return _SLIT_EQ(s.str, s.len, "true") || _SLIT_EQ(s.str, s.len, "t"); } inline int string_int(string s) { _result_i64 _t2 = strconv__common_parse_int(s, 0, 32, false, false); if (_t2.is_error) { IError err = _t2.err; *(i64*) _t2.data = 0; } return ((int)((*(i64*)_t2.data))); } inline i64 string_i64(string s) { _result_i64 _t2 = strconv__common_parse_int(s, 0, 64, false, false); if (_t2.is_error) { IError err = _t2.err; *(i64*) _t2.data = 0; } return (*(i64*)_t2.data); } inline f32 string_f32(string s) { _result_f64 _t2 = strconv__atof64(s, ((strconv__AtoF64Param){.allow_extra_chars = true,})); if (_t2.is_error) { IError err = _t2.err; *(f64*) _t2.data = 0; } return ((f32)((*(f64*)_t2.data))); } inline f64 string_f64(string s) { _result_f64 _t2 = strconv__atof64(s, ((strconv__AtoF64Param){.allow_extra_chars = true,})); if (_t2.is_error) { IError err = _t2.err; *(f64*) _t2.data = 0; } return (*(f64*)_t2.data); } inline u64 string_u64(string s) { _result_u64 _t2 = strconv__common_parse_uint(s, 0, 64, false, false); if (_t2.is_error) { IError err = _t2.err; *(u64*) _t2.data = 0U; } return (*(u64*)_t2.data); } VV_LOC bool string__eq(string s, string a) { if (s.str == 0) { _v_panic(_S("string.eq(): nil string")); VUNREACHABLE(); } if (s.len != a.len) { return false; } { // Unsafe block return vmemcmp(s.str, a.str, a.len) == 0; } return 0; } VV_LOC bool string__lt(string s, string a) { for (int i = 0; i < s.len; ++i) { if (i >= a.len || s.str[ i] > a.str[ i]) { return false; } else if (s.str[ i] < a.str[ i]) { return true; } } if (s.len < a.len) { return true; } return false; } VV_LOC string string__plus(string s, string a) { int new_len = (int)(a.len + s.len); string res = ((string){.str = malloc_noscan((int)(new_len + 1)), .len = new_len}); { // Unsafe block vmemcpy(res.str, s.str, s.len); vmemcpy(res.str + s.len, a.str, a.len); } { // Unsafe block res.str[new_len] = 0; } return res; } VV_LOC string string_plus_two(string s, string a, string b) { int new_len = (int)((int)(a.len + b.len) + s.len); string res = ((string){.str = malloc_noscan((int)(new_len + 1)), .len = new_len}); { // Unsafe block vmemcpy(res.str, s.str, s.len); vmemcpy(res.str + s.len, a.str, a.len); vmemcpy(res.str + s.len + a.len, b.str, b.len); } { // Unsafe block res.str[new_len] = 0; } return res; } Array_string string_split_any(string s, string delim) { bool string_split_any_defer_0 = false; Array_string res; res = __new_array_with_default(0, 0, sizeof(string), 0); ArrayFlags_set(&res.flags, ArrayFlags__noslices); string_split_any_defer_0 = true; int i = 0; if (s.len > 0) { if (delim.len <= 0) { Array_string _t1 = string_split(s, _S("")); // Defer begin if (string_split_any_defer_0) { ArrayFlags_clear(&res.flags, ArrayFlags__noslices); } // Defer end return _t1; } for (int index = 0; index < s.len; ++index) { u8 ch = s.str[index]; for (int _t2 = 0; _t2 < delim.len; ++_t2) { u8 delim_ch = delim.str[_t2]; if (ch == delim_ch) { array_push((array*)&res, _MOV((string[]){ string_substr(s, i, index) })); i = (int)(index + 1); break; } } } if (i < s.len) { array_push((array*)&res, _MOV((string[]){ string_substr(s, i, 2147483647) })); } } Array_string _t5 = res; // Defer begin if (string_split_any_defer_0) { ArrayFlags_clear(&res.flags, ArrayFlags__noslices); } // Defer end return _t5; } inline Array_string string_split(string s, string delim) { return string_split_nth(s, delim, 0); } inline Array_string string_rsplit(string s, string delim) { return string_rsplit_nth(s, delim, 0); } _option_multi_return_string_string string_split_once(string s, string delim) { Array_string result = string_split_nth(s, delim, 2); if (result.len != 2) { _option_multi_return_string_string _t1 = (_option_multi_return_string_string){ .state=2, .err=_const_none__, .data={E_STRUCT} }; return _t1; } _option_multi_return_string_string _t2; _option_ok(&(multi_return_string_string[]) { (multi_return_string_string){.arg0=(*(string*)array_get(result, 0)), .arg1=(*(string*)array_get(result, 1))} }, (_option*)(&_t2), sizeof(multi_return_string_string)); return _t2; } _option_multi_return_string_string string_rsplit_once(string s, string delim) { Array_string result = string_rsplit_nth(s, delim, 2); if (result.len != 2) { _option_multi_return_string_string _t1 = (_option_multi_return_string_string){ .state=2, .err=_const_none__, .data={E_STRUCT} }; return _t1; } _option_multi_return_string_string _t2; _option_ok(&(multi_return_string_string[]) { (multi_return_string_string){.arg0=(*(string*)array_get(result, 1)), .arg1=(*(string*)array_get(result, 0))} }, (_option*)(&_t2), sizeof(multi_return_string_string)); return _t2; } Array_string string_split_nth(string s, string delim, int nth) { bool string_split_nth_defer_0 = false; Array_string res; res = __new_array_with_default(0, 0, sizeof(string), 0); ArrayFlags_set(&res.flags, ArrayFlags__noslices); string_split_nth_defer_0 = true; switch (delim.len) { case 0: { for (int i = 0; i < s.len; ++i) { u8 ch = s.str[i]; if (nth > 0 && res.len == (int)(nth - 1)) { array_push((array*)&res, _MOV((string[]){ string_substr(s, i, 2147483647) })); break; } array_push((array*)&res, _MOV((string[]){ u8_ascii_str(ch) })); } break; } case 1: { u8 delim_byte = delim.str[ 0]; int start = 0; for (int i = 0; i < s.len; ++i) { u8 ch = s.str[i]; if (ch == delim_byte) { if (nth > 0 && res.len == (int)(nth - 1)) { break; } array_push((array*)&res, _MOV((string[]){ string_substr(s, start, i) })); start = (int)(i + 1); } } if (nth < 1 || res.len < nth) { array_push((array*)&res, _MOV((string[]){ string_substr(s, start, 2147483647) })); } break; } default: { { int start = 0; for (int i = 0; (int)(i + delim.len) <= s.len; ) { if (string__eq(string_substr_unsafe(s, i, (int)(i + delim.len)), delim)) { if (nth > 0 && res.len == (int)(nth - 1)) { break; } array_push((array*)&res, _MOV((string[]){ string_substr(s, start, i) })); i += delim.len; start = i; } else { i++; } } if (nth < 1 || res.len < nth) { array_push((array*)&res, _MOV((string[]){ string_substr(s, start, 2147483647) })); } break; } } } Array_string _t7 = res; // Defer begin if (string_split_nth_defer_0) { ArrayFlags_clear(&res.flags, ArrayFlags__noslices); } // Defer end return _t7; } Array_string string_rsplit_nth(string s, string delim, int nth) { bool string_rsplit_nth_defer_0 = false; Array_string res; res = __new_array_with_default(0, 0, sizeof(string), 0); ArrayFlags_set(&res.flags, ArrayFlags__noslices); string_rsplit_nth_defer_0 = true; switch (delim.len) { case 0: { for (int i = (int)(s.len - 1); i >= 0; i--) { if (nth > 0 && res.len == (int)(nth - 1)) { array_push((array*)&res, _MOV((string[]){ string_substr(s, 0, (int)(i + 1)) })); break; } array_push((array*)&res, _MOV((string[]){ u8_ascii_str(s.str[ i]) })); } break; } case 1: { u8 delim_byte = delim.str[ 0]; int rbound = s.len; for (int i = (int)(s.len - 1); i >= 0; i--) { if (s.str[ i] == delim_byte) { if (nth > 0 && res.len == (int)(nth - 1)) { break; } array_push((array*)&res, _MOV((string[]){ string_substr(s, (int)(i + 1), rbound) })); rbound = i; } } if (nth < 1 || res.len < nth) { array_push((array*)&res, _MOV((string[]){ string_substr(s, 0, rbound) })); } break; } default: { { int rbound = s.len; for (int i = (int)(s.len - 1); i >= 0; i--) { bool is_delim = (int)(i - delim.len) >= 0 && string__eq(string_substr(s, (int)(i - delim.len), i), delim); if (is_delim) { if (nth > 0 && res.len == (int)(nth - 1)) { break; } array_push((array*)&res, _MOV((string[]){ string_substr(s, i, rbound) })); i -= delim.len; rbound = i; } } if (nth < 1 || res.len < nth) { array_push((array*)&res, _MOV((string[]){ string_substr(s, 0, rbound) })); } break; } } } Array_string _t7 = res; // Defer begin if (string_rsplit_nth_defer_0) { ArrayFlags_clear(&res.flags, ArrayFlags__noslices); } // Defer end return _t7; } Array_string string_split_into_lines(string s) { bool string_split_into_lines_defer_0 = false; Array_string res; res = __new_array_with_default(0, 0, sizeof(string), 0); if (s.len == 0) { return res; } ArrayFlags_set(&res.flags, ArrayFlags__noslices); string_split_into_lines_defer_0 = true; rune cr = '\r'; rune lf = '\n'; int line_start = 0; for (int i = 0; i < s.len; i++) { if (line_start <= i) { if (s.str[ i] == lf) { array_push((array*)&res, _MOV((string[]){ (line_start == i ? (_S("")) : (string_substr(s, line_start, i))) })); line_start = (int)(i + 1); } else if (s.str[ i] == cr) { array_push((array*)&res, _MOV((string[]){ (line_start == i ? (_S("")) : (string_substr(s, line_start, i))) })); if (((int)(i + 1)) < s.len && s.str[ (int)(i + 1)] == lf) { line_start = (int)(i + 2); } else { line_start = (int)(i + 1); } } } } if (line_start < s.len) { array_push((array*)&res, _MOV((string[]){ string_substr(s, line_start, 2147483647) })); } Array_string _t5 = res; // Defer begin if (string_split_into_lines_defer_0) { ArrayFlags_clear(&res.flags, ArrayFlags__noslices); } // Defer end return _t5; } string string_substr(string s, int start, int _end) { int end = (_end == _const_max_int ? (s.len) : (_end)); #if !defined(CUSTOM_DEFINE_no_bounds_checking) { if (start > end || start > s.len || end > s.len || start < 0 || end < 0) { _v_panic(string__plus(string__plus(string__plus(string__plus(string__plus(string__plus(string__plus(_S("substr("), impl_i64_to_string(start)), _S(", ")), impl_i64_to_string(end)), _S(") out of bounds (len=")), impl_i64_to_string(s.len)), _S(") s=")), s)); VUNREACHABLE(); } } #endif int len = (int)(end - start); if (len == s.len) { return string_clone(s); } string res = ((string){.str = malloc_noscan((int)(len + 1)), .len = len}); { // Unsafe block vmemcpy(res.str, s.str + start, len); res.str[len] = 0; } return res; } string string_substr_unsafe(string s, int start, int _end) { int end = (_end == 2147483647 ? (s.len) : (_end)); int len = (int)(end - start); if (len == s.len) { return s; } return ((string){.str = s.str + start, .len = len}); } _result_string string_substr_with_check(string s, int start, int _end) { int end = (_end == _const_max_int ? (s.len) : (_end)); if (start > end || start > s.len || end > s.len || start < 0 || end < 0) { return (_result_string){ .is_error=true, .err=_v_error(string__plus(string__plus(string__plus(string__plus(string__plus(string__plus(_S("substr("), impl_i64_to_string(start)), _S(", ")), impl_i64_to_string(end)), _S(") out of bounds (len=")), impl_i64_to_string(s.len)), _S(")"))), .data={E_STRUCT} }; } int len = (int)(end - start); if (len == s.len) { _result_string _t2 = {0}; _result_ok(&(string[]) { string_clone(s) }, (_result*)(&_t2), sizeof(string)); return _t2; } string res = ((string){.str = malloc_noscan((int)(len + 1)), .len = len}); { // Unsafe block vmemcpy(res.str, s.str + start, len); res.str[len] = 0; } _result_string _t3 = {0}; _result_ok(&(string[]) { res }, (_result*)(&_t3), sizeof(string)); return _t3; } string string_substr_ni(string s, int _start, int _end) { int start = _start; int end = (_end == _const_max_int ? (s.len) : (_end)); if (start < 0) { start = (int)(s.len + start); if (start < 0) { start = 0; } } if (end < 0) { end = (int)(s.len + end); if (end < 0) { end = 0; } } if (end >= s.len) { end = s.len; } if (start > s.len || end < start) { return _S(""); } int len = (int)(end - start); string res = ((string){.str = malloc_noscan((int)(len + 1)), .len = len}); { // Unsafe block vmemcpy(res.str, s.str + start, len); res.str[len] = 0; } return res; } VV_LOC int string_index_(string s, string p) { if (p.len > s.len || p.len == 0) { return -1; } if (p.len > 2) { return string_index_kmp(s, p); } int i = 0; for (;;) { if (!(i < s.len)) break; int j = 0; for (;;) { if (!(j < p.len && s.str[(int)(i + j)] == p.str[j])) break; j++; } if (j == p.len) { return i; } i++; } return -1; } _option_int string_index(string s, string p) { int idx = string_index_(s, p); if (idx == -1) { return (_option_int){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_int _t2; _option_ok(&(int[]) { idx }, (_option*)(&_t2), sizeof(int)); return _t2; } inline _option_int string_last_index(string s, string needle) { int idx = string_index_last_(s, needle); if (idx == -1) { return (_option_int){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_int _t2; _option_ok(&(int[]) { idx }, (_option*)(&_t2), sizeof(int)); return _t2; } VV_LOC int string_index_kmp(string s, string p) { bool string_index_kmp_defer_0 = false; int* p_prefixes; if (p.len > s.len) { return -1; } Array_fixed_int_20 stack_prefixes = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; p_prefixes = &stack_prefixes[0]; if (p.len > _const_kmp_stack_buffer_size) { p_prefixes = ((int*)(vcalloc((int)(p.len * ((int)(sizeof(int))))))); } string_index_kmp_defer_0 = true; int j = 0; for (int i = 1; i < p.len; i++) { for (;;) { if (!(p.str[j] != p.str[i] && j > 0)) break; j = p_prefixes[(int)(j - 1)]; } if (p.str[j] == p.str[i]) { j++; } { // Unsafe block p_prefixes[i] = j; } } j = 0; for (int i = 0; i < s.len; ++i) { for (;;) { if (!(p.str[j] != s.str[i] && j > 0)) break; j = p_prefixes[(int)(j - 1)]; } if (p.str[j] == s.str[i]) { j++; } if (j == p.len) { int _t2 = (int)((int)(i - p.len) + 1); // Defer begin if (string_index_kmp_defer_0) { if (p.len > _const_kmp_stack_buffer_size) { _v_free(p_prefixes); } } // Defer end return _t2; } } int _t3 = -1; // Defer begin if (string_index_kmp_defer_0) { if (p.len > _const_kmp_stack_buffer_size) { _v_free(p_prefixes); } } // Defer end return _t3; } int string_index_any(string s, string chars) { for (int i = 0; i < s.len; ++i) { u8 ss = s.str[i]; for (int _t1 = 0; _t1 < chars.len; ++_t1) { u8 c = chars.str[_t1]; if (c == ss) { return i; } } } return -1; } VV_LOC int string_index_last_(string s, string p) { if (p.len > s.len || p.len == 0) { return -1; } int i = (int)(s.len - p.len); for (;;) { if (!(i >= 0)) break; int j = 0; for (;;) { if (!(j < p.len && s.str[(int)(i + j)] == p.str[j])) break; j++; } if (j == p.len) { return i; } i--; } return -1; } _option_int string_index_after(string s, string p, int start) { if (p.len > s.len) { return (_option_int){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } int strt = start; if (start < 0) { strt = 0; } if (start >= s.len) { return (_option_int){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } int i = strt; for (;;) { if (!(i < s.len)) break; int j = 0; int ii = i; for (;;) { if (!(j < p.len && s.str[ii] == p.str[j])) break; j++; ii++; } if (j == p.len) { _option_int _t3; _option_ok(&(int[]) { i }, (_option*)(&_t3), sizeof(int)); return _t3; } i++; } return (_option_int){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } int string_index_after_(string s, string p, int start) { if (p.len > s.len) { return -1; } int strt = start; if (start < 0) { strt = 0; } if (start >= s.len) { return -1; } int i = strt; for (;;) { if (!(i < s.len)) break; int j = 0; int ii = i; for (;;) { if (!(j < p.len && s.str[ii] == p.str[j])) break; j++; ii++; } if (j == p.len) { return i; } i++; } return -1; } int string_index_u8(string s, u8 c) { for (int i = 0; i < s.len; ++i) { u8 b = s.str[i]; if (b == c) { return i; } } return -1; } inline int string_last_index_u8(string s, u8 c) { for (int i = (int)(s.len - 1); i >= 0; i--) { if (s.str[ i] == c) { return i; } } return -1; } int string_count(string s, string substr) { if (s.len == 0 || substr.len == 0) { return 0; } if (substr.len > s.len) { return 0; } int n = 0; if (substr.len == 1) { u8 target = substr.str[ 0]; for (int _t3 = 0; _t3 < s.len; ++_t3) { u8 letter = s.str[_t3]; if (letter == target) { n++; } } return n; } int i = 0; for (;;) { i = string_index_after_(s, substr, i); if (i == -1) { return n; } i += substr.len; n++; } return 0; } bool string_contains_u8(string s, u8 x) { for (int _t1 = 0; _t1 < s.len; ++_t1) { u8 c = s.str[_t1]; if (x == c) { return true; } } return false; } bool string_contains(string s, string substr) { if (substr.len == 0) { return true; } if (substr.len == 1) { return string_contains_u8(s, substr.str[0]); } return string_index_(s, substr) != -1; } bool string_contains_any(string s, string chars) { for (int _t1 = 0; _t1 < chars.len; ++_t1) { u8 c = chars.str[_t1]; if (string_contains_u8(s, c)) { return true; } } return false; } bool string_starts_with(string s, string p) { if (p.len > s.len) { return false; } else if (vmemcmp(s.str, p.str, p.len) == 0) { return true; } return false; } bool string_ends_with(string s, string p) { if (p.len > s.len) { return false; } else if (vmemcmp(s.str + s.len - p.len, p.str, p.len) == 0) { return true; } return false; } string string_to_lower_ascii(string s) { { // Unsafe block u8* b = malloc_noscan((int)(s.len + 1)); for (int i = 0; i < s.len; ++i) { if (s.str[i] >= 'A' && s.str[i] <= 'Z') { b[i] = (u8)(s.str[i] + 32); } else { b[i] = s.str[i]; } } b[s.len] = 0; return tos(b, s.len); } return (string){.str=(byteptr)"", .is_lit=1}; } string string_to_lower(string s) { if (string_is_pure_ascii(s)) { return string_to_lower_ascii(s); } Array_rune runes = string_runes(s); for (int i = 0; i < runes.len; ++i) { ((rune*)runes.data)[i] = rune_to_lower(((rune*)runes.data)[i]); } return Array_rune_string(runes); } bool string_is_lower(string s) { if ((s).len == 0 || u8_is_digit(s.str[ 0])) { return false; } for (int i = 0; i < s.len; ++i) { if (s.str[ i] >= 'A' && s.str[ i] <= 'Z') { return false; } } return true; } string string_to_upper_ascii(string s) { { // Unsafe block u8* b = malloc_noscan((int)(s.len + 1)); for (int i = 0; i < s.len; ++i) { if (s.str[i] >= 'a' && s.str[i] <= 'z') { b[i] = (u8)(s.str[i] - 32); } else { b[i] = s.str[i]; } } b[s.len] = 0; return tos(b, s.len); } return (string){.str=(byteptr)"", .is_lit=1}; } string string_to_upper(string s) { if (string_is_pure_ascii(s)) { return string_to_upper_ascii(s); } Array_rune runes = string_runes(s); for (int i = 0; i < runes.len; ++i) { ((rune*)runes.data)[i] = rune_to_upper(((rune*)runes.data)[i]); } return Array_rune_string(runes); } bool string_is_upper(string s) { if ((s).len == 0 || u8_is_digit(s.str[ 0])) { return false; } for (int i = 0; i < s.len; ++i) { if (s.str[ i] >= 'a' && s.str[ i] <= 'z') { return false; } } return true; } bool string_is_capital(string s) { if (s.len == 0 || !(s.str[ 0] >= 'A' && s.str[ 0] <= 'Z')) { return false; } for (int i = 1; i < s.len; ++i) { if (s.str[ i] >= 'A' && s.str[ i] <= 'Z') { return false; } } return true; } bool string_starts_with_capital(string s) { if (s.len == 0 || !u8_is_capital(s.str[ 0])) { return false; } return true; } string string_find_between(string s, string start, string end) { int start_pos = string_index_(s, start); if (start_pos == -1) { return _S(""); } string val = string_substr(s, (int)(start_pos + start.len), 2147483647); int end_pos = string_index_(val, end); if (end_pos == -1) { return _S(""); } return string_substr(val, 0, end_pos); } inline string string_trim_space(string s) { return string_trim(s, _S(" \n\t\v\f\r")); } string string_trim(string s, string cutset) { if ((s).len == 0 || (cutset).len == 0) { return string_clone(s); } if (string_is_pure_ascii(cutset)) { return string_trim_chars(s, cutset, TrimMode__trim_both); } else { return string_trim_runes(s, cutset, TrimMode__trim_both); } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC string string_trim_chars(string s, string cutset, TrimMode mode) { int pos_left = 0; int pos_right = (int)(s.len - 1); bool cs_match = true; for (;;) { if (!(pos_left <= s.len && pos_right >= -1 && cs_match)) break; cs_match = false; if (mode == TrimMode__trim_left || mode == TrimMode__trim_both) { for (int _t1 = 0; _t1 < cutset.len; ++_t1) { u8 cs = cutset.str[_t1]; if (s.str[ pos_left] == cs) { pos_left++; cs_match = true; break; } } } if (mode == TrimMode__trim_right || mode == TrimMode__trim_both) { for (int _t2 = 0; _t2 < cutset.len; ++_t2) { u8 cs = cutset.str[_t2]; if (s.str[ pos_right] == cs) { pos_right--; cs_match = true; break; } } } if (pos_left > pos_right) { return _S(""); } } return string_substr(s, pos_left, (int)(pos_right + 1)); } VV_LOC string string_trim_runes(string s, string cutset, TrimMode mode) { Array_rune s_runes = string_runes(s); int pos_left = 0; int pos_right = (int)(s_runes.len - 1); bool cs_match = true; for (;;) { if (!(pos_left <= s_runes.len && pos_right >= -1 && cs_match)) break; cs_match = false; if (mode == TrimMode__trim_left || mode == TrimMode__trim_both) { RunesIterator _t1 = string_runes_iterator(cutset); while (1) { _option_rune _t2 = RunesIterator_next(&_t1); if (_t2.state != 0) break; rune cs = *(rune*)_t2.data; if (((rune*)s_runes.data)[pos_left] == cs) { pos_left++; cs_match = true; break; } } } if (mode == TrimMode__trim_right || mode == TrimMode__trim_both) { RunesIterator _t3 = string_runes_iterator(cutset); while (1) { _option_rune _t4 = RunesIterator_next(&_t3); if (_t4.state != 0) break; rune cs = *(rune*)_t4.data; if (((rune*)s_runes.data)[pos_right] == cs) { pos_right--; cs_match = true; break; } } } if (pos_left > pos_right) { return _S(""); } } return Array_rune_string(array_slice(s_runes, pos_left, (int)(pos_right + 1))); } string string_trim_left(string s, string cutset) { if ((s).len == 0 || (cutset).len == 0) { return string_clone(s); } if (string_is_pure_ascii(cutset)) { return string_trim_chars(s, cutset, TrimMode__trim_left); } else { return string_trim_runes(s, cutset, TrimMode__trim_left); } return (string){.str=(byteptr)"", .is_lit=1}; } string string_trim_right(string s, string cutset) { if (s.len < 1 || cutset.len < 1) { return string_clone(s); } if (string_is_pure_ascii(cutset)) { return string_trim_chars(s, cutset, TrimMode__trim_right); } else { return string_trim_runes(s, cutset, TrimMode__trim_right); } return (string){.str=(byteptr)"", .is_lit=1}; } string string_trim_string_left(string s, string str) { if (string_starts_with(s, str)) { return string_substr(s, str.len, 2147483647); } return string_clone(s); } string string_trim_string_right(string s, string str) { if (string_ends_with(s, str)) { return string_substr(s, 0, (int)(s.len - str.len)); } return string_clone(s); } inline string string_str(string s) { return string_clone(s); } VV_LOC u8 string_at(string s, int idx) { #if !defined(CUSTOM_DEFINE_no_bounds_checking) { if (idx < 0 || idx >= s.len) { panic_n2(_S("string index out of range(idx,s.len):"), idx, s.len); VUNREACHABLE(); } } #endif return s.str[idx]; } VV_LOC _option_u8 string_at_with_check(string s, int idx) { if (idx < 0 || idx >= s.len) { return (_option_u8){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } { // Unsafe block _option_u8 _t2; _option_ok(&(u8[]) { s.str[idx] }, (_option*)(&_t2), sizeof(u8)); return _t2; } return (_option_u8){.state=2, .err=_const_none__, .data={E_STRUCT}}; } bool string_is_int(string str) { int i = 0; if (str.len == 0) { return false; } if ((str.str[ i] != '-' && str.str[ i] != '+') && (!u8_is_digit(str.str[ i]))) { return false; } else { i++; } if (i == str.len && (!u8_is_digit(str.str[ (int)(i - 1)]))) { return false; } for (;;) { if (!(i < str.len)) break; if (str.str[ i] < '0' || str.str[ i] > '9') { return false; } i++; } return true; } inline bool u8_is_space(u8 c) { return c == 32 || (c > 8 && c < 14) || c == 0x85 || c == 0xa0; } inline bool u8_is_digit(u8 c) { return c >= '0' && c <= '9'; } inline bool u8_is_hex_digit(u8 c) { return u8_is_digit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } inline bool u8_is_oct_digit(u8 c) { return c >= '0' && c <= '7'; } inline bool u8_is_bin_digit(u8 c) { return c == '0' || c == '1'; } inline bool u8_is_letter(u8 c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } inline bool u8_is_alnum(u8 c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); } void string_free(string* s) { #if defined(_VPREALLOC) { return; } #endif if (s->is_lit == -98761234) { u8* double_free_msg = ((u8*)("double string.free() detected\n")); int double_free_msg_len = vstrlen(double_free_msg); #if defined(_VFREESTANDING) { } #else { _write_buf_to_fd(1, double_free_msg, double_free_msg_len); } #endif return; } if (s->is_lit == 1 || s->str == 0) { return; } { // Unsafe block _v_free(s->str); s->str = ((void*)0); } s->is_lit = -98761234; } string string_all_before(string s, string sub) { int pos = string_index_(s, sub); if (pos == -1) { return string_clone(s); } return string_substr(s, 0, pos); } string string_all_before_last(string s, string sub) { int pos = string_index_last_(s, sub); if (pos == -1) { return string_clone(s); } return string_substr(s, 0, pos); } string string_all_after(string s, string sub) { int pos = string_index_(s, sub); if (pos == -1) { return string_clone(s); } return string_substr(s, (int)(pos + sub.len), 2147483647); } string string_all_after_last(string s, string sub) { int pos = string_index_last_(s, sub); if (pos == -1) { return string_clone(s); } return string_substr(s, (int)(pos + sub.len), 2147483647); } string string_all_after_first(string s, string sub) { int pos = string_index_(s, sub); if (pos == -1) { return string_clone(s); } return string_substr(s, (int)(pos + sub.len), 2147483647); } inline string string_after(string s, string sub) { return string_all_after_last(s, sub); } string string_after_char(string s, u8 sub) { int pos = -1; for (int i = 0; i < s.len; ++i) { u8 c = s.str[i]; if (c == sub) { pos = i; break; } } if (pos == -1) { return string_clone(s); } return string_substr(s, (int)(pos + 1), 2147483647); } string Array_string_join(Array_string a, string sep) { if (a.len == 0) { return _S(""); } int len = 0; for (int _t2 = 0; _t2 < a.len; ++_t2) { string val = ((string*)a.data)[_t2]; len += (int)(val.len + sep.len); } len -= sep.len; string res = ((string){.str = malloc_noscan((int)(len + 1)), .len = len}); int idx = 0; for (int i = 0; i < a.len; ++i) { string val = ((string*)a.data)[i]; { // Unsafe block vmemcpy(((voidptr)(res.str + idx)), val.str, val.len); idx += val.len; } if (i != (int)(a.len - 1)) { { // Unsafe block vmemcpy(((voidptr)(res.str + idx)), sep.str, sep.len); idx += sep.len; } } } { // Unsafe block res.str[res.len] = 0; } return res; } Array_u8 string_bytes(string s) { if (s.len == 0) { return __new_array_with_default(0, 0, sizeof(u8), 0); } Array_u8 buf = __new_array_with_default(s.len, 0, sizeof(u8), 0); vmemcpy(buf.data, s.str, s.len); return buf; } string string_repeat(string s, int count) { if (count <= 0) { return _S(""); } else if (count == 1) { return string_clone(s); } u8* ret = malloc_noscan((int)((int)(s.len * count) + 1)); for (int i = 0; i < count; ++i) { vmemcpy(ret + (int)(i * s.len), s.str, s.len); } int new_len = (int)(s.len * count); { // Unsafe block ret[new_len] = 0; } return u8_vstring_with_len(ret, new_len); } Array_string string_fields(string s) { bool string_fields_defer_0 = false; Array_string res; res = __new_array_with_default(0, 0, sizeof(string), 0); ArrayFlags_set(&res.flags, ArrayFlags__noslices); string_fields_defer_0 = true; int word_start = 0; int word_len = 0; bool is_in_word = false; bool is_space = false; for (int i = 0; i < s.len; ++i) { u8 c = s.str[i]; is_space = (c == 32 || c == 9 || c == 10); if (!is_space) { word_len++; } if (!is_in_word && !is_space) { word_start = i; is_in_word = true; continue; } if (is_space && is_in_word) { array_push((array*)&res, _MOV((string[]){ string_substr(s, word_start, (int)(word_start + word_len)) })); is_in_word = false; word_len = 0; word_start = 0; continue; } } if (is_in_word && word_len > 0) { array_push((array*)&res, _MOV((string[]){ string_substr(s, word_start, s.len) })); } Array_string _t3 = res; // Defer begin if (string_fields_defer_0) { ArrayFlags_clear(&res.flags, ArrayFlags__noslices); } // Defer end return _t3; } inline string string_strip_margin(string s) { return string_strip_margin_custom(s, '|'); } string string_strip_margin_custom(string s, u8 del) { u8 sep = del; if (u8_is_space(sep)) { println(_S("Warning: `strip_margin` cannot use white-space as a delimiter")); println(_S(" Defaulting to `|`")); sep = '|'; } u8* ret = malloc_noscan((int)(s.len + 1)); int count = 0; for (int i = 0; i < s.len; i++) { if (s.str[ i] == 10 || s.str[ i] == 13) { { // Unsafe block ret[count] = s.str[ i]; } count++; if (s.str[ i] == 13 && i < (int)(s.len - 1) && s.str[ (int)(i + 1)] == 10) { { // Unsafe block ret[count] = s.str[ (int)(i + 1)]; } count++; i++; } for (;;) { if (!(s.str[ i] != sep)) break; i++; if (i >= s.len) { break; } } } else { { // Unsafe block ret[count] = s.str[ i]; } count++; } } { // Unsafe block ret[count] = 0; return u8_vstring_with_len(ret, count); } return (string){.str=(byteptr)"", .is_lit=1}; } bool string_is_blank(string s) { if (s.len == 0) { return true; } for (int _t2 = 0; _t2 < s.len; ++_t2) { u8 c = s.str[_t2]; if (!u8_is_space(c)) { return false; } } return true; } bool string_match_glob(string name, string pattern) { int px = 0; int nx = 0; int next_px = 0; int next_nx = 0; int plen = pattern.len; int nlen = name.len; for (;;) { if (!(px < plen || nx < nlen)) break; if (px < plen) { u8 c = pattern.str[ px]; if (c == ('?')) { if (nx < nlen) { px++; nx++; continue; } } else if (c == ('*')) { next_px = px; next_nx = (int)(nx + 1); px++; continue; } else if (c == ('[')) { if (nx < nlen) { u8 wanted_c = name.str[ nx]; int bstart = px; bool is_inverted = false; bool inner_match = false; int inner_idx = (int)(bstart + 1); int inner_c = 0; if (inner_idx < plen) { inner_c = pattern.str[ inner_idx]; if (inner_c == '^') { is_inverted = true; inner_idx++; } } for (; inner_idx < plen; inner_idx++) { inner_c = pattern.str[ inner_idx]; if (inner_c == ']') { break; } if (inner_c == wanted_c) { inner_match = true; for (;;) { if (!(px < plen && pattern.str[ px] != ']')) break; px++; } break; } } if (is_inverted) { if (inner_match) { return false; } else { px = inner_idx; } } } px++; nx++; continue; } else { if (nx < nlen && name.str[ nx] == c) { px++; nx++; continue; } } } if (0 < next_nx && next_nx <= nlen) { px = next_px; nx = next_nx; continue; } return false; } return true; } string string_wrap(string s, WrapConfig config) { if (config.width <= 0) { return _S(""); } Array_string words = string_fields(s); if (words.len == 0) { return _S(""); } strings__Builder sb = strings__new_builder(s.len); strings__Builder_write_string(&sb, (*(string*)array_get(words, 0))); int space_left = (int)(config.width - (*(string*)array_get(words, 0)).len); for (int i = 1; i < words.len; ++i) { string word = (*(string*)array_get(words, i)); if ((int)(word.len + 1) > space_left) { strings__Builder_write_string(&sb, config.end); strings__Builder_write_string(&sb, word); space_left = (int)(config.width - word.len); } else { strings__Builder_write_string(&sb, _S(" ")); strings__Builder_write_string(&sb, word); space_left -= (int)(1 + word.len); } } return strings__Builder_str(&sb); } RunesIterator string_runes_iterator(string s) { return ((RunesIterator){.s = s,.i = 0,}); } _option_rune RunesIterator_next(RunesIterator* ri) { for (;;) { if (!(ri->i >= ri->s.len)) break; return (_option_rune){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } int char_len = utf8_char_len(ri->s.str[ri->i]); if (char_len == 1) { u8 res = ri->s.str[ri->i]; ri->i++; _option_rune _t2; _option_ok(&(rune[]) { res }, (_option*)(&_t2), sizeof(rune)); return _t2; } u8* start = ((u8*)(&ri->s.str[ri->i])); int len = ((int)(ri->s.len - 1) >= (int)(ri->i + char_len) ? (char_len) : ((int)(ri->s.len - ri->i))); ri->i += char_len; if (char_len > 4) { _option_rune _t3; _option_ok(&(rune[]) { 0 }, (_option*)(&_t3), sizeof(rune)); return _t3; } _option_rune _t4; _option_ok(&(rune[]) { ((rune)(impl_utf8_to_utf32(start, len))) }, (_option*)(&_t4), sizeof(rune)); return _t4; } string charptr_vstring_literal(charptr cp) { return ((string){.str = ((byteptr)(cp)), .len = vstrlen_char(cp), .is_lit = 1}); } string StrIntpType_str(StrIntpType x) { string _t2 = (string){.str=(byteptr)"", .is_lit=1}; switch (x) { case StrIntpType__si_no_str: { _t2 = _S("no_str"); break; } case StrIntpType__si_c: { _t2 = _S("c"); break; } case StrIntpType__si_u8: { _t2 = _S("u8"); break; } case StrIntpType__si_i8: { _t2 = _S("i8"); break; } case StrIntpType__si_u16: { _t2 = _S("u16"); break; } case StrIntpType__si_i16: { _t2 = _S("i16"); break; } case StrIntpType__si_u32: { _t2 = _S("u32"); break; } case StrIntpType__si_i32: { _t2 = _S("i32"); break; } case StrIntpType__si_u64: { _t2 = _S("u64"); break; } case StrIntpType__si_i64: { _t2 = _S("i64"); break; } case StrIntpType__si_f32: { _t2 = _S("f32"); break; } case StrIntpType__si_f64: { _t2 = _S("f64"); break; } case StrIntpType__si_g32: { _t2 = _S("f32"); break; } case StrIntpType__si_g64: { _t2 = _S("f64"); break; } case StrIntpType__si_e32: { _t2 = _S("f32"); break; } case StrIntpType__si_e64: { _t2 = _S("f64"); break; } case StrIntpType__si_s: { _t2 = _S("s"); break; } case StrIntpType__si_p: { _t2 = _S("p"); break; } case StrIntpType__si_r: { _t2 = _S("r"); break; } case StrIntpType__si_vp: { _t2 = _S("vp"); break; } } return _t2; } inline VV_LOC f32 fabs32(f32 x) { return (x < 0 ? (-x) : (x)); } inline VV_LOC f64 fabs64(f64 x) { return (x < 0 ? (-x) : (x)); } inline VV_LOC u64 abs64(i64 x) { return (x < 0 ? (((u64)(-x))) : (((u64)(x)))); } u32 get_str_intp_u32_format(StrIntpType fmt_type, int in_width, int in_precision, bool in_tail_zeros, bool in_sign, u8 in_pad_ch, int in_base, bool in_upper_case) { u64 width = (in_width != 0 ? (abs64(in_width)) : (((u32)(0U)))); u32 align = (in_width > 0 ? (((u32)(32U))) : (((u32)(0U)))); u32 upper_case = (in_upper_case ? (((u32)(128U))) : (((u32)(0U)))); u32 sign = (in_sign ? (((u32)(256U))) : (((u32)(0U)))); u32 precision = (in_precision != 987698 ? (((((u32)((in_precision & 0x7F))) << 9U))) : ((((u32)(0x7FU)) << 9U))); u32 tail_zeros = (in_tail_zeros ? ((((u32)(1U)) << 16U)) : (((u32)(0U)))); u32 base = ((u32)((((u32)((in_base & 0xf))) << 27U))); u32 res = ((u32)(((((((((((((u32)(fmt_type)) & 0x1FU)) | align) | upper_case) | sign) | precision) | tail_zeros) | ((((u32)((width & 0x3FFU))) << 17U))) | base) | ((((u32)((in_pad_ch & 1))) << 31U))))); return res; } VV_LOC void StrIntpData_process_str_intp_data(StrIntpData* data, strings__Builder* sb) { u32 x = data->fmt; StrIntpType typ = ((StrIntpType)((x & 0x1FU))); int align = ((int)((((x >> 5U)) & 0x01U))); bool upper_case = ((((x >> 7U)) & 0x01U)) > 0U; int sign = ((int)((((x >> 8U)) & 0x01U))); int precision = ((int)((((x >> 9U)) & 0x7FU))); bool tail_zeros = ((((x >> 16U)) & 0x01U)) > 0U; int width = ((int)(((i16)((((x >> 17U)) & 0x3FFU))))); int base = (((int)((x >> 27U))) & 0xF); u8 fmt_pad_ch = ((u8)((((x >> 31U)) & 0xFFU))); if (typ == StrIntpType__si_no_str) { return; } if (base > 0) { base += 2; } u8 pad_ch = ((u8)(' ')); if (fmt_pad_ch > 0) { pad_ch = '0'; } int len0_set = (width > 0 ? (width) : (-1)); int len1_set = (precision == 0x7F ? (-1) : (precision)); bool sign_set = sign == 1; strconv__BF_param bf = ((strconv__BF_param){ .pad_ch = pad_ch, .len0 = len0_set, .len1 = len1_set, .positive = true, .sign_flag = sign_set, .align = strconv__Align_text__left, .rm_tail_zero = tail_zeros, }); if (fmt_pad_ch == 0 || pad_ch == '0') { switch (align) { case 0: { bf.align = strconv__Align_text__left; break; } case 1: { bf.align = strconv__Align_text__right; break; } default: { { bf.align = strconv__Align_text__left; break; } } } } else { bf.align = strconv__Align_text__right; } { // Unsafe block if (typ == StrIntpType__si_s) { if (upper_case) { string s = string_to_upper(data->d.d_s); if (width == 0) { strings__Builder_write_string(sb, s); } else { strconv__format_str_sb(s, bf, sb); } string_free(&s); } else { if (width == 0) { strings__Builder_write_string(sb, data->d.d_s); } else { strconv__format_str_sb(data->d.d_s, bf, sb); } } return; } if (typ == StrIntpType__si_r) { if (width > 0) { if (upper_case) { string s = string_to_upper(data->d.d_s); for (int _t1 = 1; _t1 < ((int)(1 + ((width > 0 ? (width) : (0))))); ++_t1) { strings__Builder_write_string(sb, s); } string_free(&s); } else { for (int _t2 = 1; _t2 < ((int)(1 + ((width > 0 ? (width) : (0))))); ++_t2) { strings__Builder_write_string(sb, data->d.d_s); } } } return; } if (typ == StrIntpType__si_i8 || typ == StrIntpType__si_i16 || typ == StrIntpType__si_i32 || typ == StrIntpType__si_i64) { i64 d = data->d.d_i64; if (typ == StrIntpType__si_i8) { d = ((i64)(data->d.d_i8)); } else if (typ == StrIntpType__si_i16) { d = ((i64)(data->d.d_i16)); } else if (typ == StrIntpType__si_i32) { d = ((i64)(data->d.d_i32)); } if (base == 0) { if (width == 0) { string d_str = i64_str(d); strings__Builder_write_string(sb, d_str); string_free(&d_str); return; } if (d < 0) { bf.positive = false; } strconv__format_dec_sb(abs64(d), bf, sb); } else { if (base == 3) { base = 2; } i64 absd = d; bool write_minus = false; if (d < 0 && pad_ch != ' ') { absd = -d; write_minus = true; } string hx = strconv__format_int(absd, base); if (upper_case) { string tmp = hx; hx = string_to_upper(hx); string_free(&tmp); } if (write_minus) { strings__Builder_write_u8(sb, '-'); bf.len0--; } if (width == 0) { strings__Builder_write_string(sb, hx); } else { strconv__format_str_sb(hx, bf, sb); } string_free(&hx); } return; } if (typ == StrIntpType__si_u8 || typ == StrIntpType__si_u16 || typ == StrIntpType__si_u32 || typ == StrIntpType__si_u64) { u64 d = data->d.d_u64; if (typ == StrIntpType__si_u8) { d = ((u64)(data->d.d_u8)); } else if (typ == StrIntpType__si_u16) { d = ((u64)(data->d.d_u16)); } else if (typ == StrIntpType__si_u32) { d = ((u64)(data->d.d_u32)); } if (base == 0) { if (width == 0) { string d_str = u64_str(d); strings__Builder_write_string(sb, d_str); string_free(&d_str); return; } strconv__format_dec_sb(d, bf, sb); } else { if (base == 3) { base = 2; } string hx = strconv__format_uint(d, base); if (upper_case) { string tmp = hx; hx = string_to_upper(hx); string_free(&tmp); } if (width == 0) { strings__Builder_write_string(sb, hx); } else { strconv__format_str_sb(hx, bf, sb); } string_free(&hx); } return; } if (typ == StrIntpType__si_p) { u64 d = data->d.d_u64; base = 16; if (base == 0) { if (width == 0) { string d_str = u64_str(d); strings__Builder_write_string(sb, d_str); string_free(&d_str); return; } strconv__format_dec_sb(d, bf, sb); } else { string hx = strconv__format_uint(d, base); if (upper_case) { string tmp = hx; hx = string_to_upper(hx); string_free(&tmp); } if (width == 0) { strings__Builder_write_string(sb, hx); } else { strconv__format_str_sb(hx, bf, sb); } string_free(&hx); } return; } bool use_default_str = false; if (width == 0 && precision == 0x7F) { bf.len1 = 3; use_default_str = true; } if (bf.len1 < 0) { bf.len1 = 3; } switch (typ) { case StrIntpType__si_f32: { #if !defined(CUSTOM_DEFINE_nofloat) { if (use_default_str) { string f = f32_str(data->d.d_f32); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } else { if (data->d.d_f32 < 0) { bf.positive = false; } string f = strconv__format_fl(data->d.d_f32, bf); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } } #endif break; } case StrIntpType__si_f64: { #if !defined(CUSTOM_DEFINE_nofloat) { if (use_default_str) { string f = f64_str(data->d.d_f64); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } else { if (data->d.d_f64 < 0) { bf.positive = false; } strconv__Float64u f_union = ((strconv__Float64u){.f = data->d.d_f64,}); if (f_union.u == _const_strconv__double_minus_zero) { bf.positive = false; } string f = strconv__format_fl(data->d.d_f64, bf); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } } #endif break; } case StrIntpType__si_g32: { if (use_default_str) { #if !defined(CUSTOM_DEFINE_nofloat) { string f = f32_strg(data->d.d_f32); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } #endif } else { if (data->d.d_f32 == _const_strconv__single_plus_zero) { string tmp_str = _S("0"); strconv__format_str_sb(tmp_str, bf, sb); string_free(&tmp_str); return; } if (data->d.d_f32 == _const_strconv__single_minus_zero) { string tmp_str = _S("-0"); strconv__format_str_sb(tmp_str, bf, sb); string_free(&tmp_str); return; } if (data->d.d_f32 == _const_strconv__single_plus_infinity) { string tmp_str = _S("+inf"); if (upper_case) { tmp_str = _S("+INF"); } strconv__format_str_sb(tmp_str, bf, sb); string_free(&tmp_str); } if (data->d.d_f32 == _const_strconv__single_minus_infinity) { string tmp_str = _S("-inf"); if (upper_case) { tmp_str = _S("-INF"); } strconv__format_str_sb(tmp_str, bf, sb); string_free(&tmp_str); } if (data->d.d_f32 < 0) { bf.positive = false; } f32 d = fabs32(data->d.d_f32); if (d < ((f32)(999999.0)) && d >= ((f32)(0.00001))) { string f = strconv__format_fl(data->d.d_f32, bf); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); return; } bf.len1--; string f = strconv__format_es(data->d.d_f32, bf); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } break; } case StrIntpType__si_g64: { if (use_default_str) { #if !defined(CUSTOM_DEFINE_nofloat) { string f = f64_strg(data->d.d_f64); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } #endif } else { if (data->d.d_f64 == _const_strconv__double_plus_zero) { string tmp_str = _S("0"); strconv__format_str_sb(tmp_str, bf, sb); string_free(&tmp_str); return; } if (data->d.d_f64 == _const_strconv__double_minus_zero) { string tmp_str = _S("-0"); strconv__format_str_sb(tmp_str, bf, sb); string_free(&tmp_str); return; } if (data->d.d_f64 == _const_strconv__double_plus_infinity) { string tmp_str = _S("+inf"); if (upper_case) { tmp_str = _S("+INF"); } strconv__format_str_sb(tmp_str, bf, sb); string_free(&tmp_str); } if (data->d.d_f64 == _const_strconv__double_minus_infinity) { string tmp_str = _S("-inf"); if (upper_case) { tmp_str = _S("-INF"); } strconv__format_str_sb(tmp_str, bf, sb); string_free(&tmp_str); } if (data->d.d_f64 < 0) { bf.positive = false; } f64 d = fabs64(data->d.d_f64); if (d < ((f64)(999999.0)) && d >= ((f64)(0.00001))) { string f = strconv__format_fl(data->d.d_f64, bf); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); return; } bf.len1--; string f = strconv__format_es(data->d.d_f64, bf); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } break; } case StrIntpType__si_e32: { #if !defined(CUSTOM_DEFINE_nofloat) { if (use_default_str) { string f = f32_str(data->d.d_f32); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } else { if (data->d.d_f32 < 0) { bf.positive = false; } string f = strconv__format_es(data->d.d_f32, bf); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } } #endif break; } case StrIntpType__si_e64: { #if !defined(CUSTOM_DEFINE_nofloat) { if (use_default_str) { string f = f64_str(data->d.d_f64); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } else { if (data->d.d_f64 < 0) { bf.positive = false; } string f = strconv__format_es(data->d.d_f64, bf); if (upper_case) { string tmp = f; f = string_to_upper(f); string_free(&tmp); } strings__Builder_write_string(sb, f); string_free(&f); } } #endif break; } case StrIntpType__si_c: { string ss = utf32_to_str(data->d.d_c); strings__Builder_write_string(sb, ss); string_free(&ss); break; } case StrIntpType__si_vp: { string ss = u64_hex(((u64)(data->d.d_vp))); strings__Builder_write_string(sb, ss); string_free(&ss); break; } case StrIntpType__si_no_str: case StrIntpType__si_u8: case StrIntpType__si_i8: case StrIntpType__si_u16: case StrIntpType__si_i16: case StrIntpType__si_u32: case StrIntpType__si_i32: case StrIntpType__si_u64: case StrIntpType__si_i64: case StrIntpType__si_s: case StrIntpType__si_p: case StrIntpType__si_r: default: { { strings__Builder_write_string(sb, _S("***ERROR!***")); break; } } } } } string str_intp(int data_len, StrIntpData* input_base) { strings__Builder res = strings__new_builder(64); for (int i = 0; i < data_len; i++) { StrIntpData* data = &input_base[i]; if (data->str.len != 0) { strings__Builder_write_string(&res, data->str); } if (data->fmt != 0U) { StrIntpData_process_str_intp_data(data, (voidptr)&res); } } string ret = strings__Builder_str(&res); strings__Builder_free(&res); return ret; } inline string str_intp_sq(string in_str) { return str_intp(3, _MOV((StrIntpData[]){{_S("str_intp(2, _MOV((StrIntpData[]){{_S(\"\'\"), "), 0xfe10, {.d_s = _const_si_s_code}}, {_S(", {.d_s = "), 0xfe10, {.d_s = in_str}}, {_S("}},{_S(\"\'\"), 0, {.d_c = 0 }}}))"), 0, { .d_c = 0 }}})); } inline string str_intp_rune(string in_str) { return str_intp(3, _MOV((StrIntpData[]){{_S("str_intp(2, _MOV((StrIntpData[]){{_S(\"`\"), "), 0xfe10, {.d_s = _const_si_s_code}}, {_S(", {.d_s = "), 0xfe10, {.d_s = in_str}}, {_S("}},{_S(\"`\"), 0, {.d_c = 0 }}}))"), 0, { .d_c = 0 }}})); } inline string str_intp_g32(string in_str) { return str_intp(3, _MOV((StrIntpData[]){{_S("str_intp(1, _MOV((StrIntpData[]){{_SLIT0, "), 0xfe10, {.d_s = _const_si_g32_code}}, {_S(", {.d_f32 = "), 0xfe10, {.d_s = in_str}}, {_S(" }}}))"), 0, { .d_c = 0 }}})); } inline string str_intp_g64(string in_str) { return str_intp(3, _MOV((StrIntpData[]){{_S("str_intp(1, _MOV((StrIntpData[]){{_SLIT0, "), 0xfe10, {.d_s = _const_si_g64_code}}, {_S(", {.d_f64 = "), 0xfe10, {.d_s = in_str}}, {_S(" }}}))"), 0, { .d_c = 0 }}})); } string str_intp_sub(string base_str, string in_str) { _option_int _t1 = string_index(base_str, _S("%%")); if (_t1.state != 0) { IError err = _t1.err; eprintln(_S("No string interpolation %% parameters")); _v_exit(1); VUNREACHABLE(); ; } int index = (*(int*)_t1.data); { // Unsafe block string st_str = string_substr(base_str, 0, index); if ((int)(index + 2) < base_str.len) { string en_str = string_substr(base_str, (int)(index + 2), 2147483647); string res_str = str_intp(5, _MOV((StrIntpData[]){{_S("str_intp(2, _MOV((StrIntpData[]){{_S(\""), 0xfe10, {.d_s = st_str}}, {_S("\"), "), 0xfe10, {.d_s = _const_si_s_code}}, {_S(", {.d_s = "), 0xfe10, {.d_s = in_str}}, {_S(" }},{_S(\""), 0xfe10, {.d_s = en_str}}, {_S("\"), 0, {.d_c = 0}}}))"), 0, { .d_c = 0 }}})); string_free(&st_str); string_free(&en_str); return res_str; } string res2_str = str_intp(4, _MOV((StrIntpData[]){{_S("str_intp(1, _MOV((StrIntpData[]){{_S(\""), 0xfe10, {.d_s = st_str}}, {_S("\"), "), 0xfe10, {.d_s = _const_si_s_code}}, {_S(", {.d_s = "), 0xfe10, {.d_s = in_str}}, {_S(" }}}))"), 0, { .d_c = 0 }}})); string_free(&st_str); return res2_str; } return (string){.str=(byteptr)"", .is_lit=1}; } u16* string_to_wide(string _str) { #if defined(_WIN32) { { // Unsafe block int num_chars = (MultiByteToWideChar(_const_cp_utf8, 0U, ((char*)(_str.str)), _str.len, 0, 0)); u16* wstr = ((u16*)(malloc_noscan((int)(((int)(num_chars + 1)) * 2)))); if (wstr != 0) { MultiByteToWideChar(_const_cp_utf8, 0U, ((char*)(_str.str)), _str.len, wstr, num_chars); memset(((u8*)(wstr)) + (int)(num_chars * 2), 0, 2); } return wstr; } } #else { Array_rune srunes = string_runes(_str); { // Unsafe block u16* result = ((u16*)(vcalloc_noscan((int)(((int)(srunes.len + 1)) * 2)))); for (int i = 0; i < srunes.len; ++i) { rune r = ((rune*)srunes.data)[i]; result[i] = ((u16)(r)); } result[srunes.len] = 0U; return result; } } #endif return 0; } string string_from_wide(u16* _wstr) { #if defined(_WIN32) { { // Unsafe block usize wstr_len = wcslen(_wstr); return string_from_wide2(_wstr, ((int)(wstr_len))); } } #else { int i = 0; for (;;) { if (!(_wstr[i] != 0U)) break; i++; } return string_from_wide2(_wstr, i); } #endif return (string){.str=(byteptr)"", .is_lit=1}; } string string_from_wide2(u16* _wstr, int len) { #if defined(_WIN32) { { // Unsafe block int num_chars = WideCharToMultiByte(_const_cp_utf8, 0U, _wstr, len, 0, 0, 0, 0); u8* str_to = malloc_noscan((int)(num_chars + 1)); if (str_to != 0) { WideCharToMultiByte(_const_cp_utf8, 0U, _wstr, len, ((char*)(str_to)), num_chars, 0, 0); memset(str_to + num_chars, 0, 1); } return tos2(str_to); } } #else { strings__Builder sb = strings__new_builder(len); for (int i = 0; i < len; i++) { rune u = ((rune)(_wstr[i])); strings__Builder_write_rune(&sb, u); } string res = strings__Builder_str(&sb); strings__Builder_free(&sb); return res; } #endif return (string){.str=(byteptr)"", .is_lit=1}; } Array_u8 wide_to_ansi(u16* _wstr) { #if defined(_WIN32) { int num_bytes = WideCharToMultiByte(_const_cp_acp, 0U, _wstr, -1, 0, 0, 0, 0); if (num_bytes != 0) { Array_u8 str_to = __new_array_with_default(num_bytes, 0, sizeof(u8), 0); WideCharToMultiByte(_const_cp_acp, 0U, _wstr, -1, ((char*)(str_to.data)), str_to.len, 0, 0); return str_to; } else { return __new_array_with_default(0, 0, sizeof(u8), 0); } } #else { string s = string_from_wide(_wstr); Array_u8 str_to = __new_array_with_default((int)(s.len + 1), 0, sizeof(u8), 0); vmemcpy(str_to.data, s.str, s.len); return str_to; } #endif return __new_array_with_default(0, 0, sizeof(u8), 0); } int utf8_char_len(u8 b) { return (int_literal)(((((0xe5000000 >> ((((b >> 3)) & 0x1e)))) & 3)) + 1); } string utf32_to_str(u32 code) { { // Unsafe block u8* buffer = malloc_noscan(5); string res = utf32_to_str_no_malloc(code, buffer); if (res.len == 0) { _v_free(buffer); } return res; } return (string){.str=(byteptr)"", .is_lit=1}; } string utf32_to_str_no_malloc(u32 code, u8* buf) { { // Unsafe block int len = utf32_decode_to_buffer(code, buf); if (len == 0) { return _S(""); } buf[len] = 0; return tos(buf, len); } return (string){.str=(byteptr)"", .is_lit=1}; } int utf32_decode_to_buffer(u32 code, u8* buf) { { // Unsafe block int icode = ((int)(code)); u8* buffer = ((u8*)(buf)); if (icode <= 127) { buffer[0] = ((u8)(icode)); return 1; } else if (icode <= 2047) { buffer[0] = (192 | ((u8)((icode >> 6)))); buffer[1] = (128 | ((u8)((icode & 63)))); return 2; } else if (icode <= 65535) { buffer[0] = (224 | ((u8)((icode >> 12)))); buffer[1] = (128 | ((((u8)((icode >> 6))) & 63))); buffer[2] = (128 | ((u8)((icode & 63)))); return 3; } else if (icode <= 1114111) { buffer[0] = (240 | ((u8)((icode >> 18)))); buffer[1] = (128 | ((((u8)((icode >> 12))) & 63))); buffer[2] = (128 | ((((u8)((icode >> 6))) & 63))); buffer[3] = (128 | ((u8)((icode & 63)))); return 4; } } return 0; } int string_utf32_code(string _rune) { if (_rune.len > 4) { return 0; } return ((int)(impl_utf8_to_utf32(((u8*)(_rune.str)), _rune.len))); } VV_LOC rune impl_utf8_to_utf32(u8* _bytes, int _bytes_len) { if (_bytes_len == 0) { return 0; } if (_bytes_len == 1) { return ((rune)(_bytes[0])); } u8 b = ((u8)(((int)(_bytes[0])))); b = (b << _bytes_len); rune res = ((rune)(b)); int shift = (int)(6 - _bytes_len); for (int i = 1; i < _bytes_len; i++) { rune c = ((rune)(_bytes[i])); res = (((rune)(res)) << shift); res |= (c & 63); shift = 6; } return res; } int utf8_str_visible_length(string s) { int l = 0; int ul = 1; for (int i = 0; i < s.len; i += ul) { u8 c = s.str[i]; ul = (int_literal)(((((0xe5000000 >> ((((s.str[i] >> 3)) & 0x1e)))) & 3)) + 1); if ((int)(i + ul) > s.len) { return l; } l++; if (ul == 1) { continue; } if (ul == (2)) { u64 r = ((u64)((((((u16)(c)) << 8U)) | s.str[(int)(i + 1)]))); if (r >= 0xcc80U && r < 0xcdb0U) { l--; } } else if (ul == (3)) { u64 r = ((u64)((((((u32)(c)) << 16U)) | (((((u32)(s.str[(int)(i + 1)])) << 8U)) | s.str[(int)(i + 2)])))); if ((r >= 0xe1aab0U && r <= 0xe1ac7fU) || (r >= 0xe1b780U && r <= 0xe1b87fU) || (r >= 0xe28390U && r <= 0xe2847fU) || (r >= 0xefb8a0U && r <= 0xefb8afU)) { l--; } else if ((r >= 0xe18480U && r <= 0xe1859fU) || (r >= 0xe2ba80U && r <= 0xe2bf95U) || (r >= 0xe38080U && r <= 0xe4b77fU) || (r >= 0xe4b880U && r <= 0xea807fU) || (r >= 0xeaa5a0U && r <= 0xeaa79fU) || (r >= 0xeab080U && r <= 0xed9eafU) || (r >= 0xefa480U && r <= 0xefac7fU) || (r >= 0xefb8b8U && r <= 0xefb9afU)) { l++; } } else if (ul == (4)) { u64 r = ((u64)((((((u32)(c)) << 24U)) | ((((((u32)(s.str[(int)(i + 1)])) << 16U)) | ((((u32)(s.str[(int)(i + 2)])) << 8U))) | s.str[(int)(i + 3)])))); if ((r >= 0x0f9f8880U && r <= 0xf09f8a8fU) || (r >= 0xf09f8c80U && r <= 0xf09f9c90U) || (r >= 0xf09fa490U && r <= 0xf09fa7afU) || (r >= 0xf0a08080U && r <= 0xf180807fU)) { l++; } } else { } } return l; } Array_u8 string_to_ansi_not_null_terminated(string _str) { u16* wstr = string_to_wide(_str); Array_u8 ansi = wide_to_ansi(wstr); if (ansi.len > 0) { ansi.len--; } return ansi; } inline bool ArrayFlags_has(ArrayFlags* e, ArrayFlags flag_) { return ((((int)(*e)) & (((int)(flag_))))) != 0; } inline bool ArrayFlags_all(ArrayFlags* e, ArrayFlags flag_) { return ((((int)(*e)) & (((int)(flag_))))) == ((int)(flag_)); } inline void ArrayFlags_set(ArrayFlags* e, ArrayFlags flag_) { { // Unsafe block *e = ((ArrayFlags)((((int)(*e)) | (((int)(flag_)))))); } } inline void ArrayFlags_clear(ArrayFlags* e, ArrayFlags flag_) { { // Unsafe block *e = ((ArrayFlags)((((int)(*e)) & ~(((int)(flag_)))))); } } strings__textscanner__TextScanner strings__textscanner__new(string input) { return ((strings__textscanner__TextScanner){.input = input,.ilen = input.len,.pos = 0,}); } void strings__textscanner__TextScanner_free(strings__textscanner__TextScanner* ss) { string_free(&ss->input); } inline int strings__textscanner__TextScanner_next(strings__textscanner__TextScanner* ss) { if (ss->pos < ss->ilen) { int opos = ss->pos; ss->pos++; return ss->input.str[ opos]; } return -1; } inline void strings__textscanner__TextScanner_skip_n(strings__textscanner__TextScanner* ss, int n) { ss->pos += n; if (ss->pos > ss->ilen) { ss->pos = ss->ilen; } } inline int strings__textscanner__TextScanner_peek(strings__textscanner__TextScanner* ss) { if (ss->pos < ss->ilen) { return ss->input.str[ ss->pos]; } return -1; } inline int strings__textscanner__TextScanner_peek_back(strings__textscanner__TextScanner* ss) { return strings__textscanner__TextScanner_peek_back_n(ss, 1); } inline int strings__textscanner__TextScanner_peek_back_n(strings__textscanner__TextScanner* ss, int n) { int offset = (int)(n + 1); if (ss->pos >= offset) { return ss->input.str[ (int)(ss->pos - offset)]; } return -1; } inline int strings__textscanner__TextScanner_current(strings__textscanner__TextScanner* ss) { if (ss->pos > 0) { return ss->input.str[ (int)(ss->pos - 1)]; } return -1; } i64 time__Duration_nanoseconds(time__Duration d) { return ((i64)(d)); } i64 time__Duration_microseconds(time__Duration d) { return ((i64)(d)) / _const_time__microsecond; } i64 time__Duration_milliseconds(time__Duration d) { return ((i64)(d)) / _const_time__millisecond; } string time__Duration_str(time__Duration d) { if (d == _const_time__infinite) { return _S("inf"); } string sign = _S(""); i64 t = ((i64)(d)); if (t < 0) { sign = _S("-"); t = -t; } i64 hr = t / _const_time__hour; t -= hr * _const_time__hour; i64 min = t / _const_time__minute; t -= min * _const_time__minute; i64 sec = t / _const_time__second; t -= sec * _const_time__second; i64 ms = t / _const_time__millisecond; t -= ms * _const_time__millisecond; i64 us = t / _const_time__microsecond; t -= us * _const_time__microsecond; i64 ns = t; bool _t3 = true; return ((_t3 == (hr > 0))? (str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sign}}, {_SLIT0, 0xfe09, {.d_i64 = hr}}, {_S(":"), 0x8004fe29, {.d_i64 = min}}, {_S(":"), 0x8004fe29, {.d_i64 = sec}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (_t3 == (min > 0))? (str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sign}}, {_SLIT0, 0xfe09, {.d_i64 = min}}, {_S(":"), 0x8004fe29, {.d_i64 = sec}}, {_S("."), 0x8006fe29, {.d_i64 = ms}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (_t3 == (sec > 0))? (str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sign}}, {_SLIT0, 0xfe09, {.d_i64 = sec}}, {_S("."), 0x8006fe29, {.d_i64 = ms}}, {_S("s"), 0, { .d_c = 0 }}}))) : (_t3 == (ms > 0))? (str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sign}}, {_SLIT0, 0xfe09, {.d_i64 = ms}}, {_S("."), 0x8006fe29, {.d_i64 = us}}, {_S("ms"), 0, { .d_c = 0 }}}))) : (_t3 == (us > 0))? (str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sign}}, {_SLIT0, 0xfe09, {.d_i64 = us}}, {_S("."), 0x8006fe29, {.d_i64 = ns}}, {_S("us"), 0, { .d_c = 0 }}}))) : (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sign}}, {_SLIT0, 0xfe09, {.d_i64 = ns}}, {_S("ns"), 0, { .d_c = 0 }}})))); } VV_LOC void time__int_to_byte_array_no_pad(int value, Array_u8* arr, int size) { int num = value; if (size <= 0 || num < 0) { return; } int i = (int)(size - 1); for (;;) { if (!(num > 0 && i >= 0)) break; ((u8*)arr->data)[i] = (rune)(((int)(num % 10)) + '0'); num /= 10; i--; } } string time__Time_format_ss(time__Time t) { bool time__Time_format_ss_defer_0 = false; Array_u8 buf; buf = new_array_from_c_array(19, 19, sizeof(u8), _MOV((u8[19]){ ((u8)('0')), '0', '0', '0', '-', '0', '0', '-', '0', '0', ' ', '0', '0', ':', '0', '0', ':', '0', '0'})); time__Time_format_ss_defer_0 = true; time__int_to_byte_array_no_pad(t.year, &buf, 4); time__int_to_byte_array_no_pad(t.month, &buf, 7); time__int_to_byte_array_no_pad(t.day, &buf, 10); time__int_to_byte_array_no_pad(t.hour, &buf, 13); time__int_to_byte_array_no_pad(t.minute, &buf, 16); time__int_to_byte_array_no_pad(t.second, &buf, 19); string _t1 = Array_u8_bytestr(buf); // Defer begin if (time__Time_format_ss_defer_0) { array_free(&buf); } // Defer end return _t1; } string time__Time_ymmdd(time__Time t) { return time__Time_get_fmt_date_str(t, time__FormatDelimiter__hyphen, time__FormatDate__yyyymmdd); } string time__Time_get_fmt_date_str(time__Time t, time__FormatDelimiter fmt_dlmtr, time__FormatDate fmt_date) { if (fmt_date == time__FormatDate__no_date) { return _S(""); } string month = time__Time_smonth(t); string year = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0x8004fe27, {.d_i32 = ((int)(t.year % 100))}}, {_SLIT0, 0, { .d_c = 0 }}})); string _t2 = (string){.str=(byteptr)"", .is_lit=1}; switch (fmt_date) { case time__FormatDate__ddmmyy: { _t2 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0x8004fe27, {.d_i32 = t.day}}, {_S("|"), 0x8004fe27, {.d_i32 = t.month}}, {_S("|"), 0xfe10, {.d_s = year}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } case time__FormatDate__ddmmyyyy: { _t2 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0x8004fe27, {.d_i32 = t.day}}, {_S("|"), 0x8004fe27, {.d_i32 = t.month}}, {_S("|"), 0x8008fe27, {.d_i32 = t.year}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } case time__FormatDate__mmddyy: { _t2 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0x8004fe27, {.d_i32 = t.month}}, {_S("|"), 0x8004fe27, {.d_i32 = t.day}}, {_S("|"), 0xfe10, {.d_s = year}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } case time__FormatDate__mmddyyyy: { _t2 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0x8004fe27, {.d_i32 = t.month}}, {_S("|"), 0x8004fe27, {.d_i32 = t.day}}, {_S("|"), 0x8008fe27, {.d_i32 = t.year}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } case time__FormatDate__mmmd: { _t2 = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = month}}, {_S("|"), 0xfe07, {.d_i32 = t.day}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } case time__FormatDate__mmmdd: { _t2 = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = month}}, {_S("|"), 0x8004fe27, {.d_i32 = t.day}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } case time__FormatDate__mmmddyy: { _t2 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = month}}, {_S("|"), 0x8004fe27, {.d_i32 = t.day}}, {_S("|"), 0xfe10, {.d_s = year}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } case time__FormatDate__mmmddyyyy: { _t2 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = month}}, {_S("|"), 0x8004fe27, {.d_i32 = t.day}}, {_S("|"), 0x8008fe27, {.d_i32 = t.year}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } case time__FormatDate__yyyymmdd: { _t2 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0x8008fe27, {.d_i32 = t.year}}, {_S("|"), 0x8004fe27, {.d_i32 = t.month}}, {_S("|"), 0x8004fe27, {.d_i32 = t.day}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } case time__FormatDate__yymmdd: { _t2 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = year}}, {_S("|"), 0x8004fe27, {.d_i32 = t.month}}, {_S("|"), 0x8004fe27, {.d_i32 = t.day}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } case time__FormatDate__no_date: default: { { _t2 = str_intp(2, _MOV((StrIntpData[]){{_S("unknown enumeration "), 0xfe10, {.d_s = time__FormatDate_str(fmt_date)}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } } } string res = _t2; string del = ((fmt_dlmtr == (time__FormatDelimiter__dot))? (_S(".")) : (fmt_dlmtr == (time__FormatDelimiter__hyphen))? (_S("-")) : (fmt_dlmtr == (time__FormatDelimiter__slash))? (_S("/")) : (fmt_dlmtr == (time__FormatDelimiter__space))? (_S(" ")) : (_S(""))); res = string_replace(res, _S("|"), del); return res; } inline bool time__Time__eq(time__Time t1, time__Time t2) { return time__Time_unix(t1) == time__Time_unix(t2) && t1.nanosecond == t2.nanosecond; } inline bool time__Time__lt(time__Time t1, time__Time t2) { return time__Time_unix(t1) < time__Time_unix(t2) || (time__Time_unix(t1) == time__Time_unix(t2) && t1.nanosecond < t2.nanosecond); } inline time__Duration time__Time__minus(time__Time lhs, time__Time rhs) { i64 unixs = ((i64)((i64)(time__Time_unix(lhs) - time__Time_unix(rhs)))) * _const_time__second; int nanos = (int)(lhs.nanosecond - rhs.nanosecond); return (i64)(unixs + nanos); } _result_time__Time time__parse_iso8601(string s) { if ((s).len == 0) { return (_result_time__Time){ .is_error=true, .err=time__error_invalid_time(0, _S("datetime string is empty")), .data={E_STRUCT} }; } _option_int _t2 = string_index(s, _S("T")); if (_t2.state != 0) { IError err = _t2.err; *(int*) _t2.data = -1; } int t_i = (*(int*)_t2.data); Array_string parts = (t_i != -1 ? (new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){string_substr(s, 0, t_i), string_substr(s, (int)(t_i + 1), 2147483647)}))) : (string_split(s, _S(" ")))); if (!(parts.len == 1 || parts.len == 2)) { return (_result_time__Time){ .is_error=true, .err=time__error_invalid_time(12, _S("malformed date")), .data={E_STRUCT} }; } _result_multi_return_int_int_int _t4 = time__parse_iso8601_date((*(string*)array_get(parts, 0))); if (_t4.is_error) { _result_time__Time _t5 = {0}; _t5.is_error = true; _t5.err = _t4.err; return _t5; } multi_return_int_int_int mr_12451 = (*(multi_return_int_int_int*)_t4.data); int year = mr_12451.arg0; int month = mr_12451.arg1; int day = mr_12451.arg2; int hour_ = 0; int minute_ = 0; int second_ = 0; int microsecond_ = 0; int nanosecond_ = 0; i64 unix_offset = ((i64)(0)); bool is_local_time = true; if (parts.len == 2) { _result_multi_return_int_int_int_int_int_i64_bool _t6 = time__parse_iso8601_time((*(string*)array_get(parts, 1))); if (_t6.is_error) { _result_time__Time _t7 = {0}; _t7.is_error = true; _t7.err = _t6.err; return _t7; } multi_return_int_int_int_int_int_i64_bool mr_12725 = (*(multi_return_int_int_int_int_int_i64_bool*)_t6.data); hour_ = mr_12725.arg0; minute_ = mr_12725.arg1; second_ = mr_12725.arg2; microsecond_ = mr_12725.arg3; nanosecond_ = mr_12725.arg4; unix_offset = mr_12725.arg5; is_local_time = mr_12725.arg6; } time__Time t = time__new(((time__Time){ .__v_unix = 0, .year = year, .month = month, .day = day, .hour = hour_, .minute = minute_, .second = second_, .nanosecond = nanosecond_, .is_local = 0, })); if (is_local_time) { _result_time__Time _t8 = {0}; _result_ok(&(time__Time[]) { t }, (_result*)(&_t8), sizeof(time__Time)); return _t8; } i64 unix_time = t.__v_unix; if (unix_offset < 0) { unix_time -= (-unix_offset); } else if (unix_offset > 0) { unix_time += unix_offset; } t = time__unix_nanosecond(((i64)(unix_time)), t.nanosecond); _result_time__Time _t9 = {0}; _result_ok(&(time__Time[]) { t }, (_result*)(&_t9), sizeof(time__Time)); return _t9; } VV_LOC _result_multi_return_int_int_int time__parse_iso8601_date(string s) { int year = 0; int month = 0; int day = 0; u8 dummy = ((u8)(0)); int count = sscanf(((char*)(s.str)), "%4d-%2d-%2d%c", &year, &month, &day, &dummy); if (count != 3) { return (_result_multi_return_int_int_int){ .is_error=true, .err=time__error_invalid_time(10, str_intp(2, _MOV((StrIntpData[]){{_S("datetime string must have 3 components, but has "), 0xfe07, {.d_i32 = count}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } if (year > 9999) { return (_result_multi_return_int_int_int){ .is_error=true, .err=time__error_invalid_time(13, _S("year must be smaller than 10000")), .data={E_STRUCT} }; } if (month > 12) { return (_result_multi_return_int_int_int){ .is_error=true, .err=time__error_invalid_time(14, _S("month must be smaller than 12")), .data={E_STRUCT} }; } if (day > 31) { return (_result_multi_return_int_int_int){ .is_error=true, .err=time__error_invalid_time(15, _S("day must be smaller than 31")), .data={E_STRUCT} }; } _result_multi_return_int_int_int _t5; _result_ok(&(multi_return_int_int_int[]) { (multi_return_int_int_int){.arg0=year, .arg1=month, .arg2=day} }, (_result*)(&_t5), sizeof(multi_return_int_int_int)); return _t5; } VV_LOC _result_multi_return_int_int_int_int_int_i64_bool time__parse_iso8601_time(string s) { int hour_ = 0; int minute_ = 0; int second_ = 0; int microsecond_ = 0; int nanosecond_ = 0; rune plus_min_z = 'a'; int offset_hour = 0; int offset_minute = 0; int count = 0; count = sscanf(((char*)(s.str)), "%2d:%2d:%2d.%9d%c", &hour_, &minute_, &second_, &nanosecond_, ((char*)(&plus_min_z))); if (count == 5 && plus_min_z == 'Z') { int ndigits = 0; _option_int _t1; if (_t1 = string_index(s, _S(".")), _t1.state == 0) { int pos = *(int*)_t1.data; pos++; for (; pos < s.len && u8_is_digit(string_at(s, pos)); pos++) { ndigits++; } } for (;;) { if (!(ndigits < 9)) break; nanosecond_ *= 10; ndigits++; } microsecond_ = (int)(nanosecond_ / 1000); } else { count = sscanf(((char*)(s.str)), "%2d:%2d:%2d.%9d%c%2d:%2d", &hour_, &minute_, &second_, µsecond_, ((char*)(&plus_min_z)), &offset_hour, &offset_minute); if (count < 4) { count = sscanf(((char*)(s.str)), "%2d:%2d:%2d%c%2d:%2d", &hour_, &minute_, &second_, ((char*)(&plus_min_z)), &offset_hour, &offset_minute); count++; } if (count < 4) { return (_result_multi_return_int_int_int_int_int_i64_bool){ .is_error=true, .err=time__error_invalid_time(10, _S("malformed date")), .data={E_STRUCT} }; } nanosecond_ = (int)(microsecond_ * 1000); } bool is_local_time = plus_min_z == 'a' && count == 4; bool is_utc = plus_min_z == 'Z' && count == 5; if (!(count == 7 || is_local_time || is_utc)) { return (_result_multi_return_int_int_int_int_int_i64_bool){ .is_error=true, .err=time__error_invalid_time(11, _S("malformed date")), .data={E_STRUCT} }; } if (plus_min_z != '+' && plus_min_z != '-' && !is_utc && !is_local_time) { return (_result_multi_return_int_int_int_int_int_i64_bool){ .is_error=true, .err=time__error_invalid_time(12, _S("missing timezone")), .data={E_STRUCT} }; } int unix_offset = 0; if (offset_hour > 0) { unix_offset += (int)(3600 * offset_hour); } if (offset_minute > 0) { unix_offset += (int)(60 * offset_minute); } if (plus_min_z == '+') { unix_offset *= -1; } _result_multi_return_int_int_int_int_int_i64_bool _t5; _result_ok(&(multi_return_int_int_int_int_int_i64_bool[]) { (multi_return_int_int_int_int_int_i64_bool){.arg0=hour_, .arg1=minute_, .arg2=second_, .arg3=microsecond_, .arg4=nanosecond_, .arg5=unix_offset, .arg6=is_local_time} }, (_result*)(&_t5), sizeof(multi_return_int_int_int_int_int_i64_bool)); return _t5; } string time__TimeParseError_msg(time__TimeParseError err) { return str_intp(3, _MOV((StrIntpData[]){{_S("Invalid time format code: "), 0xfe07, {.d_i32 = err.code}}, {_S(", error: "), 0xfe10, {.d_s = err.message}}, {_SLIT0, 0, { .d_c = 0 }}})); } VV_LOC IError time__error_invalid_time(int code, string message) { return I_time__TimeParseError_to_Interface_IError(((time__TimeParseError*)memdup(&(time__TimeParseError){.Error = ((Error){E_STRUCT}),.code = code,.message = message,}, sizeof(time__TimeParseError)))); } time__StopWatch time__new_stopwatch(time__StopWatchOptions opts) { u64 initial = ((u64)(0U)); if (opts.auto_start) { initial = time__sys_mono_now(); } return ((time__StopWatch){.elapsed = 0U,.start = initial,.end = 0U,}); } void time__StopWatch_start(time__StopWatch* t) { t->start = time__sys_mono_now(); t->end = 0U; } void time__StopWatch_pause(time__StopWatch* t) { if (t->start > 0U) { if (t->end == 0U) { t->elapsed += (u64)(time__sys_mono_now() - t->start); } else { t->elapsed += (u64)(t->end - t->start); } } t->start = 0U; } time__Duration time__StopWatch_elapsed(time__StopWatch t) { if (t.start > 0U) { if (t.end == 0U) { return ((((i64)((u64)((u64)(time__sys_mono_now() - t.start) + t.elapsed))))); } else { return ((((i64)((u64)((u64)(t.end - t.start) + t.elapsed))))); } } return ((((i64)(t.elapsed)))); } time__Time time__now(void) { #if defined(__APPLE__) { return time__darwin_now(); } #endif #if defined(_WIN32) { return time__win_now(); } #endif #if defined(__sun) { return time__solaris_now(); } #endif return time__linux_now(); } time__Time time__utc(void) { #if defined(__APPLE__) { return time__darwin_utc(); } #endif #if defined(_WIN32) { return time__win_utc(); } #endif #if defined(__sun) { return time__solaris_utc(); } #endif return time__linux_utc(); } VV_LOC time__Time time__time_with_unix(time__Time t) { if (t.__v_unix != 0) { return t; } struct tm tt = ((struct tm){ .tm_sec = t.second, .tm_min = t.minute, .tm_hour = t.hour, .tm_mday = t.day, .tm_mon = (int)(t.month - 1), .tm_year = (int)(t.year - 1900), .tm_wday = 0, .tm_yday = 0, .tm_isdst = 0, .tm_gmtoff = 0, }); i64 utime = time__make_unix_time(tt); return ((time__Time){.__v_unix = utime,.year = (t).year,.month = (t).month,.day = (t).day,.hour = (t).hour,.minute = (t).minute,.second = (t).second,.nanosecond = (t).nanosecond,.is_local = (t).is_local,}); } string time__Time_str(time__Time t) { return time__Time_format_ss(t); } VV_LOC time__Time time__convert_ctime(struct tm t, int nanosecond) { return ((time__Time){ .__v_unix = time__make_unix_time(t), .year = (int)(t.tm_year + 1900), .month = (int)(t.tm_mon + 1), .day = t.tm_mday, .hour = t.tm_hour, .minute = t.tm_min, .second = t.tm_sec, .nanosecond = nanosecond, .is_local = true, }); } string time__Time_strftime(time__Time t, string fmt) { struct tm* tm = ((struct tm*)memdup(&(struct tm){.tm_sec = 0,.tm_min = 0,.tm_hour = 0,.tm_mday = 0,.tm_mon = 0,.tm_year = 0,.tm_wday = 0,.tm_yday = 0,.tm_isdst = 0,.tm_gmtoff = 0,}, sizeof(struct tm))); #if defined(_WIN32) { tm = gmtime(((voidptr)(&t.__v_unix))); } #else { gmtime_r(((voidptr)(&t.__v_unix)), tm); } #endif Array_fixed_char_1024 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; char* fmt_c = ((char*)(fmt.str)); strftime(&buf[0], ((usize)(sizeof(Array_fixed_char_1024))), fmt_c, tm); return cstring_to_vstring(((char*)(&buf[0]))); } time__Time time__new(time__Time t) { return time__time_with_unix(t); } string time__Time_smonth(time__Time t) { if (t.month <= 0 || t.month > 12) { return _S("---"); } int i = (int)(t.month - 1); return string_substr(_const_time__months_string, (int)(i * 3), (int)(((int)(i + 1)) * 3)); } inline i64 time__Time_unix(time__Time t) { return time__time_with_unix(t).__v_unix; } inline i64 time__Time_unix_milli(time__Time t) { return (i64)((i64)(time__Time_unix(t) * 1000) + ((i64)(((i64)(t.nanosecond)) / 1000000))); } time__Time time__Time_add(time__Time t, time__Duration duration_in_nanosecond) { i64 increased_time_nanosecond = (i64)(((i64)(t.nanosecond)) + time__Duration_nanoseconds(duration_in_nanosecond)); i64 increased_time_second = (i64)(time__Time_unix(t) + (increased_time_nanosecond / _const_time__second)); increased_time_nanosecond = increased_time_nanosecond % _const_time__second; if (increased_time_nanosecond < 0) { increased_time_second--; increased_time_nanosecond += _const_time__second; } time__Time res = time__unix_nanosecond(increased_time_second, ((int)(increased_time_nanosecond))); return (t.is_local ? (time__Time_as_local(res)) : (res)); } time__Time time__Time_add_days(time__Time t, int days) { return time__Time_add(time__time_with_unix(t), (int)(days * 24) * _const_time__hour); } time__Time time__Time_as_local(time__Time t) { return ((time__Time){.__v_unix = (t).__v_unix,.year = (t).year,.month = (t).month,.day = (t).day,.hour = (t).hour,.minute = (t).minute,.second = (t).second,.nanosecond = (t).nanosecond,.is_local = true,}); } VV_LOC u64 time__sys_mono_now_darwin(void) { return 0U; } VV_LOC time__Time time__darwin_now(void) { return ((time__Time){.__v_unix = 0,.year = 0,.month = 0,.day = 0,.hour = 0,.minute = 0,.second = 0,.nanosecond = 0,.is_local = 0,}); } VV_LOC time__Time time__solaris_now(void) { return ((time__Time){.__v_unix = 0,.year = 0,.month = 0,.day = 0,.hour = 0,.minute = 0,.second = 0,.nanosecond = 0,.is_local = 0,}); } VV_LOC time__Time time__darwin_utc(void) { return ((time__Time){.__v_unix = 0,.year = 0,.month = 0,.day = 0,.hour = 0,.minute = 0,.second = 0,.nanosecond = 0,.is_local = 0,}); } VV_LOC time__Time time__solaris_utc(void) { return ((time__Time){.__v_unix = 0,.year = 0,.month = 0,.day = 0,.hour = 0,.minute = 0,.second = 0,.nanosecond = 0,.is_local = 0,}); } VV_LOC i64 time__make_unix_time(struct tm t) { return ((i64)(timegm(&t))); } u64 time__sys_mono_now(void) { #if defined(__APPLE__) { return time__sys_mono_now_darwin(); } #else { struct timespec ts = ((struct timespec){.tv_sec = 0,.tv_nsec = 0,}); clock_gettime(CLOCK_MONOTONIC, &ts); return (u64)((u64)(((u64)(ts.tv_sec)) * 1000000000U) + ((u64)(ts.tv_nsec))); } #endif return 0; } VV_LOC time__Time time__linux_now(void) { struct timespec ts = ((struct timespec){.tv_sec = 0,.tv_nsec = 0,}); clock_gettime(CLOCK_REALTIME, &ts); struct tm loc_tm = ((struct tm){.tm_sec = 0,.tm_min = 0,.tm_hour = 0,.tm_mday = 0,.tm_mon = 0,.tm_year = 0,.tm_wday = 0,.tm_yday = 0,.tm_isdst = 0,.tm_gmtoff = 0,}); localtime_r(((voidptr)(&ts.tv_sec)), &loc_tm); return time__convert_ctime(loc_tm, ((int)(ts.tv_nsec))); } VV_LOC time__Time time__linux_utc(void) { struct timespec ts = ((struct timespec){.tv_sec = 0,.tv_nsec = 0,}); clock_gettime(CLOCK_REALTIME, &ts); return time__unix_nanosecond(((i64)(ts.tv_sec)), ((int)(ts.tv_nsec))); } VV_LOC time__Time time__win_now(void) { return ((time__Time){.__v_unix = 0,.year = 0,.month = 0,.day = 0,.hour = 0,.minute = 0,.second = 0,.nanosecond = 0,.is_local = 0,}); } VV_LOC time__Time time__win_utc(void) { return ((time__Time){.__v_unix = 0,.year = 0,.month = 0,.day = 0,.hour = 0,.minute = 0,.second = 0,.nanosecond = 0,.is_local = 0,}); } void time__sleep(time__Duration duration) { struct timespec req = ((struct timespec){.tv_sec = duration / _const_time__second,.tv_nsec = duration % _const_time__second,}); struct timespec rem = ((struct timespec){.tv_sec = 0,.tv_nsec = 0,}); for (;;) { if (!(nanosleep(&req, &rem) < 0)) break; if (errno == EINTR) { req = rem; } else { break; } } } time__Time time__unix_nanosecond(i64 abs_unix_timestamp, int nanosecond) { i64 day_offset = (i64)(abs_unix_timestamp / 86400); if ((i64)(abs_unix_timestamp % 86400) < 0) { day_offset--; } multi_return_int_int_int mr_1698 = time__calculate_date_from_day_offset(day_offset); int year = mr_1698.arg0; int month = mr_1698.arg1; int day = mr_1698.arg2; multi_return_int_int_int mr_1769 = time__calculate_time_from_second_offset((i64)(abs_unix_timestamp % 86400)); int hour_ = mr_1769.arg0; int minute_ = mr_1769.arg1; int second_ = mr_1769.arg2; return ((time__Time){ .__v_unix = abs_unix_timestamp, .year = year, .month = month, .day = day, .hour = hour_, .minute = minute_, .second = second_, .nanosecond = nanosecond, .is_local = 0, }); } VV_LOC multi_return_int_int_int time__calculate_date_from_day_offset(i64 day_offset_) { i64 day_offset = day_offset_; day_offset += 719468; int era = 0; if (day_offset >= 0) { era = ((int)((i64)(day_offset / 146097))); } else { era = ((int)((i64)(((i64)((i64)(day_offset - 146097) - 1)) / 146097))); } i64 day_of_era = (i64)(day_offset - (int)(era * 146097)); i64 year_of_era = (i64)(((i64)((i64)((i64)(day_of_era - (i64)(day_of_era / (1460))) + (i64)(day_of_era / 36524)) - (i64)(day_of_era / (146096)))) / 365); int year = ((int)((i64)(year_of_era + (int)(era * 400)))); i64 day_of_year = (i64)(day_of_era - ((i64)((i64)((i64)(365 * year_of_era) + (i64)(year_of_era / 4)) - (i64)(year_of_era / 100)))); i64 month_position = (i64)(((i64)((i64)(5 * day_of_year) + 2)) / 153); int day = ((int)((i64)((i64)(day_of_year - (i64)(((i64)((i64)(153 * month_position) + 2)) / 5)) + 1))); int month = ((int)(month_position)); if (month_position < 10) { month += 3; } else { month -= 9; } if (month <= 2) { year += 1; } return (multi_return_int_int_int){.arg0=year, .arg1=month, .arg2=day}; } VV_LOC multi_return_int_int_int time__calculate_time_from_second_offset(i64 second_offset_) { i64 second_offset = second_offset_; if (second_offset < 0) { second_offset += _const_time__seconds_per_day; } i64 hour_ = (i64)(second_offset / 3600); second_offset %= _const_time__seconds_per_hour; i64 minute_ = (i64)(second_offset / 60); second_offset %= _const_time__seconds_per_minute; return (multi_return_int_int_int){.arg0=((int)(hour_)), .arg1=((int)(minute_)), .arg2=((int)(second_offset))}; } string os__cmdline__option(Array_string args, string param, string def) { bool found = false; for (int _t1 = 0; _t1 < args.len; ++_t1) { string arg = ((string*)args.data)[_t1]; if (found) { return arg; } else if (string__eq(param, arg)) { found = true; } } return def; } Array_string os__cmdline__options_before(Array_string args, Array_string what) { Array_string args_before = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < args.len; ++_t1) { string a = ((string*)args.data)[_t1]; if ((Array_string_contains(what, a))) { break; } array_push((array*)&args_before, _MOV((string[]){ string_clone(a) })); } return args_before; } Array_string os__cmdline__options_after(Array_string args, Array_string what) { bool found = false; Array_string args_after = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < args.len; ++_t1) { string a = ((string*)args.data)[_t1]; if ((Array_string_contains(what, a))) { found = true; continue; } if (found) { array_push((array*)&args_after, _MOV((string[]){ string_clone(a) })); } } return args_after; } int v__token__KeywordsMatcherTrie_find(v__token__KeywordsMatcherTrie* km, string word) { int wlen = word.len; if (wlen < km->min_len || wlen > km->max_len) { return -1; } v__token__TrieNode* node = ((v__token__TrieNode**)km->nodes.data)[wlen]; if (node == ((void*)0)) { return -1; } return v__token__TrieNode_find(node, word); } inline bool v__token__KeywordsMatcherTrie_matches(v__token__KeywordsMatcherTrie* km, string word) { return v__token__KeywordsMatcherTrie_find(km, word) != -1; } void v__token__KeywordsMatcherTrie_add_word(v__token__KeywordsMatcherTrie* km, string word, int value) { int wlen = word.len; if (km->max_len < wlen) { km->max_len = wlen; } if (km->min_len > wlen) { km->min_len = wlen; } for (;;) { if (!(km->nodes.len < (int)(wlen + 1))) break; array_push((array*)&km->nodes, _MOV((v__token__TrieNode*[]){ ((v__token__TrieNode*)(((void*)0))) })); } if (((v__token__TrieNode**)km->nodes.data)[wlen] == ((void*)0)) { ((v__token__TrieNode**)km->nodes.data)[wlen] = v__token__new_trie_node(); } v__token__TrieNode_add_word(((v__token__TrieNode**)km->nodes.data)[wlen], word, value, 0); } v__token__KeywordsMatcherTrie v__token__KeywordsMatcherTrie__static__new(int cap) { v__token__KeywordsMatcherTrie *km = HEAP(v__token__KeywordsMatcherTrie, (((v__token__KeywordsMatcherTrie){.nodes = __new_array_with_default(0, cap, sizeof(v__token__TrieNode*), 0),.min_len = 999999,.max_len = 0,}))); for (int _t1 = 0; _t1 < cap; ++_t1) { array_push((array*)&(*(km)).nodes, _MOV((v__token__TrieNode*[]){ ((v__token__TrieNode*)(((void*)0))) })); } return (*(km)); } v__token__KeywordsMatcherTrie v__token__new_keywords_matcher_trie_T_int(Map_string_int kw_map) { v__token__KeywordsMatcherTrie *km = HEAP(v__token__KeywordsMatcherTrie, (v__token__KeywordsMatcherTrie__static__new(10))); int _t2 = kw_map.key_values.len; for (int _t1 = 0; _t1 < _t2; ++_t1 ) { int _t3 = kw_map.key_values.len - _t2; _t2 = kw_map.key_values.len; if (_t3 < 0) { _t1 = -1; continue; } if (!DenseArray_has_index(&kw_map.key_values, _t1)) {continue;} string k = *(string*)DenseArray_key(&kw_map.key_values, _t1); k = string_clone(k); int v = (*(int*)DenseArray_value(&kw_map.key_values, _t1)); v__token__KeywordsMatcherTrie_add_word(&(*(km)), k, ((int)(v))); } return (*(km)); } v__token__KeywordsMatcherTrie v__token__new_keywords_matcher_trie_T_v__token__Kind(Map_string_v__token__Kind kw_map) { v__token__KeywordsMatcherTrie *km = HEAP(v__token__KeywordsMatcherTrie, (v__token__KeywordsMatcherTrie__static__new(10))); int _t2 = kw_map.key_values.len; for (int _t1 = 0; _t1 < _t2; ++_t1 ) { int _t3 = kw_map.key_values.len - _t2; _t2 = kw_map.key_values.len; if (_t3 < 0) { _t1 = -1; continue; } if (!DenseArray_has_index(&kw_map.key_values, _t1)) {continue;} string k = *(string*)DenseArray_key(&kw_map.key_values, _t1); k = string_clone(k); v__token__Kind v = (*(v__token__Kind*)DenseArray_value(&kw_map.key_values, _t1)); v__token__KeywordsMatcherTrie_add_word(&(*(km)), k, ((int)(v))); } return (*(km)); } v__token__KeywordsMatcherTrie v__token__new_keywords_matcher_from_array_trie(Array_string names) { Map_string_int m = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int i = 0; i < names.len; ++i) { string name = ((string*)names.data)[i]; map_set(&m, &(string[]){name}, &(int[]) { i }); } return v__token__new_keywords_matcher_trie_T_int(m); } v__token__TrieNode* v__token__new_trie_node(void) { return ((v__token__TrieNode*)memdup(&(v__token__TrieNode){.children = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},.value = -1,}, sizeof(v__token__TrieNode))); } void v__token__TrieNode_add_word(v__token__TrieNode* node, string word, int value, int word_idx) { _option_u8 _t1 = string_at_with_check(word, word_idx); ; if (_t1.state != 0) { IError err = _t1.err; node->value = value; return; } u8 first = ((u8)(*(byte*)&_t1.data)); v__token__TrieNode* child_node = node->children[first]; if (child_node == ((void*)0)) { child_node = v__token__new_trie_node(); node->children[first] = child_node; } v__token__TrieNode_add_word(child_node, word, value, (int)(word_idx + 1)); } int v__token__TrieNode_find(v__token__TrieNode* root, string word) { int wlen = word.len; v__token__TrieNode* node = ((v__token__TrieNode*)(root)); int idx = 0; for (;;) { if (idx == wlen) { int k = node->value; if (k != -1) { return k; } return -1; } u8 c = word.str[ idx]; v__token__TrieNode* child = node->children[c]; if (child == ((void*)0)) { return -1; } node = child; idx++; } return -1; } void v__token__Pos_free(v__token__Pos* p) { } string v__token__Pos_line_str(v__token__Pos p) { return str_intp(5, _MOV((StrIntpData[]){{_S("{l: "), 0xafe27, {.d_i32 = (int)(p.line_nr + 1)}}, {_S(", c: "), 0x6fe27, {.d_i32 = p.col}}, {_S(", p: "), 0xafe27, {.d_i32 = p.pos}}, {_S(", ll: "), 0xafe27, {.d_i32 = (int)(p.last_line + 1)}}, {_S("}"), 0, { .d_c = 0 }}})); } v__token__Pos v__token__Pos_extend(v__token__Pos pos, v__token__Pos end) { return ((v__token__Pos){.len = (int)((int)(end.pos - pos.pos) + end.len),.line_nr = (pos).line_nr,.pos = (pos).pos,.col = (pos).col,.last_line = end.last_line,}); } v__token__Pos v__token__Pos_extend_with_last_line(v__token__Pos pos, v__token__Pos end, int last_line) { return ((v__token__Pos){.len = (int)((int)(end.pos - pos.pos) + end.len),.line_nr = pos.line_nr,.pos = pos.pos,.col = pos.col,.last_line = (int)(last_line - 1),}); } void v__token__Pos_update_last_line(v__token__Pos* pos, int last_line) { pos->last_line = (int)(last_line - 1); } inline v__token__Pos v__token__Token_pos(v__token__Token* tok) { return ((v__token__Pos){.len = tok->len,.line_nr = (int)(tok->line_nr - 1),.pos = tok->pos,.col = (int)(tok->col - 1),.last_line = (int)(tok->line_nr - 1),}); } VV_LOC Map_string_v__token__Kind v__token__build_keys(void) { Map_string_v__token__Kind res = new_map(sizeof(string), sizeof(v__token__Kind), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int t = (int)(((int)(v__token__Kind__keyword_beg)) + 1); t < ((int)(v__token__Kind__keyword_end)); ++t) { string key = (*(string*)array_get(_const_v__token__token_str, t)); if ((Array_string_contains(_const_v__token__orm_custom_operators, key))) { continue; } map_set(&res, &(string[]){key}, &(v__token__Kind[]) { ((v__token__Kind)(t)) }); } return res; } VV_LOC Array_string v__token__build_token_str(void) { Array_string s = __new_array_with_default(((int)(v__token__Kind___end_)), 0, sizeof(string), &(string[]){_S("")}); array_set(&s, v__token__Kind__unknown, &(string[]) { _S("unknown") }); array_set(&s, v__token__Kind__eof, &(string[]) { _S("eof") }); array_set(&s, v__token__Kind__name, &(string[]) { _S("name") }); array_set(&s, v__token__Kind__number, &(string[]) { _S("number") }); array_set(&s, v__token__Kind__string, &(string[]) { _S("string") }); array_set(&s, v__token__Kind__chartoken, &(string[]) { _S("char") }); array_set(&s, v__token__Kind__plus, &(string[]) { _S("+") }); array_set(&s, v__token__Kind__minus, &(string[]) { _S("-") }); array_set(&s, v__token__Kind__mul, &(string[]) { _S("*") }); array_set(&s, v__token__Kind__div, &(string[]) { _S("/") }); array_set(&s, v__token__Kind__mod, &(string[]) { _S("%") }); array_set(&s, v__token__Kind__xor, &(string[]) { _S("^") }); array_set(&s, v__token__Kind__bit_not, &(string[]) { _S("~") }); array_set(&s, v__token__Kind__pipe, &(string[]) { _S("|") }); array_set(&s, v__token__Kind__hash, &(string[]) { _S("#") }); array_set(&s, v__token__Kind__amp, &(string[]) { _S("&") }); array_set(&s, v__token__Kind__inc, &(string[]) { _S("++") }); array_set(&s, v__token__Kind__dec, &(string[]) { _S("--") }); array_set(&s, v__token__Kind__and, &(string[]) { _S("&&") }); array_set(&s, v__token__Kind__logical_or, &(string[]) { _S("||") }); array_set(&s, v__token__Kind__not, &(string[]) { _S("!") }); array_set(&s, v__token__Kind__dot, &(string[]) { _S(".") }); array_set(&s, v__token__Kind__dotdot, &(string[]) { _S("..") }); array_set(&s, v__token__Kind__ellipsis, &(string[]) { _S("...") }); array_set(&s, v__token__Kind__comma, &(string[]) { _S(",") }); array_set(&s, v__token__Kind__not_in, &(string[]) { _S("!in") }); array_set(&s, v__token__Kind__not_is, &(string[]) { _S("!is") }); array_set(&s, v__token__Kind__semicolon, &(string[]) { _S(";") }); array_set(&s, v__token__Kind__colon, &(string[]) { _S(":") }); array_set(&s, v__token__Kind__arrow, &(string[]) { _S("<-") }); array_set(&s, v__token__Kind__assign, &(string[]) { _S("=") }); array_set(&s, v__token__Kind__decl_assign, &(string[]) { _S(":=") }); array_set(&s, v__token__Kind__plus_assign, &(string[]) { _S("+=") }); array_set(&s, v__token__Kind__minus_assign, &(string[]) { _S("-=") }); array_set(&s, v__token__Kind__mult_assign, &(string[]) { _S("*=") }); array_set(&s, v__token__Kind__div_assign, &(string[]) { _S("/=") }); array_set(&s, v__token__Kind__xor_assign, &(string[]) { _S("^=") }); array_set(&s, v__token__Kind__mod_assign, &(string[]) { _S("%=") }); array_set(&s, v__token__Kind__or_assign, &(string[]) { _S("|=") }); array_set(&s, v__token__Kind__and_assign, &(string[]) { _S("&=") }); array_set(&s, v__token__Kind__right_shift_assign, &(string[]) { _S(">>=") }); array_set(&s, v__token__Kind__unsigned_right_shift_assign, &(string[]) { _S(">>>=") }); array_set(&s, v__token__Kind__left_shift_assign, &(string[]) { _S("<<=") }); array_set(&s, v__token__Kind__boolean_or_assign, &(string[]) { _S("||=") }); array_set(&s, v__token__Kind__boolean_and_assign, &(string[]) { _S("&&=") }); array_set(&s, v__token__Kind__lcbr, &(string[]) { _S("{") }); array_set(&s, v__token__Kind__rcbr, &(string[]) { _S("}") }); array_set(&s, v__token__Kind__lpar, &(string[]) { _S("(") }); array_set(&s, v__token__Kind__rpar, &(string[]) { _S(")") }); array_set(&s, v__token__Kind__lsbr, &(string[]) { _S("[") }); array_set(&s, v__token__Kind__nilsbr, &(string[]) { _S("#[") }); array_set(&s, v__token__Kind__rsbr, &(string[]) { _S("]") }); array_set(&s, v__token__Kind__eq, &(string[]) { _S("==") }); array_set(&s, v__token__Kind__ne, &(string[]) { _S("!=") }); array_set(&s, v__token__Kind__gt, &(string[]) { _S(">") }); array_set(&s, v__token__Kind__lt, &(string[]) { _S("<") }); array_set(&s, v__token__Kind__ge, &(string[]) { _S(">=") }); array_set(&s, v__token__Kind__le, &(string[]) { _S("<=") }); array_set(&s, v__token__Kind__question, &(string[]) { _S("?") }); array_set(&s, v__token__Kind__left_shift, &(string[]) { _S("<<") }); array_set(&s, v__token__Kind__right_shift, &(string[]) { _S(">>") }); array_set(&s, v__token__Kind__unsigned_right_shift, &(string[]) { _S(">>>") }); array_set(&s, v__token__Kind__comment, &(string[]) { _S("comment") }); array_set(&s, v__token__Kind__nl, &(string[]) { _S("NLL") }); array_set(&s, v__token__Kind__dollar, &(string[]) { _S("$") }); array_set(&s, v__token__Kind__at, &(string[]) { _S("@") }); array_set(&s, v__token__Kind__str_dollar, &(string[]) { _S("$2") }); array_set(&s, v__token__Kind__key_assert, &(string[]) { _S("assert") }); array_set(&s, v__token__Kind__key_struct, &(string[]) { _S("struct") }); array_set(&s, v__token__Kind__key_if, &(string[]) { _S("if") }); array_set(&s, v__token__Kind__key_else, &(string[]) { _S("else") }); array_set(&s, v__token__Kind__key_asm, &(string[]) { _S("asm") }); array_set(&s, v__token__Kind__key_return, &(string[]) { _S("return") }); array_set(&s, v__token__Kind__key_module, &(string[]) { _S("module") }); array_set(&s, v__token__Kind__key_sizeof, &(string[]) { _S("sizeof") }); array_set(&s, v__token__Kind__key_isreftype, &(string[]) { _S("isreftype") }); array_set(&s, v__token__Kind__key_likely, &(string[]) { _S("_likely_") }); array_set(&s, v__token__Kind__key_unlikely, &(string[]) { _S("_unlikely_") }); array_set(&s, v__token__Kind__key_go, &(string[]) { _S("go") }); array_set(&s, v__token__Kind__key_goto, &(string[]) { _S("goto") }); array_set(&s, v__token__Kind__key_const, &(string[]) { _S("const") }); array_set(&s, v__token__Kind__key_mut, &(string[]) { _S("mut") }); array_set(&s, v__token__Kind__key_shared, &(string[]) { _S("shared") }); array_set(&s, v__token__Kind__key_lock, &(string[]) { _S("lock") }); array_set(&s, v__token__Kind__key_rlock, &(string[]) { _S("rlock") }); array_set(&s, v__token__Kind__key_type, &(string[]) { _S("type") }); array_set(&s, v__token__Kind__key_for, &(string[]) { _S("for") }); array_set(&s, v__token__Kind__key_fn, &(string[]) { _S("fn") }); array_set(&s, v__token__Kind__key_true, &(string[]) { _S("true") }); array_set(&s, v__token__Kind__key_false, &(string[]) { _S("false") }); array_set(&s, v__token__Kind__key_continue, &(string[]) { _S("continue") }); array_set(&s, v__token__Kind__key_break, &(string[]) { _S("break") }); array_set(&s, v__token__Kind__key_import, &(string[]) { _S("import") }); array_set(&s, v__token__Kind__key_unsafe, &(string[]) { _S("unsafe") }); array_set(&s, v__token__Kind__key_typeof, &(string[]) { _S("typeof") }); array_set(&s, v__token__Kind__key_dump, &(string[]) { _S("dump") }); array_set(&s, v__token__Kind__key_enum, &(string[]) { _S("enum") }); array_set(&s, v__token__Kind__key_interface, &(string[]) { _S("interface") }); array_set(&s, v__token__Kind__key_pub, &(string[]) { _S("pub") }); array_set(&s, v__token__Kind__key_in, &(string[]) { _S("in") }); array_set(&s, v__token__Kind__key_atomic, &(string[]) { _S("atomic") }); array_set(&s, v__token__Kind__key_orelse, &(string[]) { _S("or") }); array_set(&s, v__token__Kind__key_global, &(string[]) { _S("__global") }); array_set(&s, v__token__Kind__key_union, &(string[]) { _S("union") }); array_set(&s, v__token__Kind__key_static, &(string[]) { _S("static") }); array_set(&s, v__token__Kind__key_volatile, &(string[]) { _S("volatile") }); array_set(&s, v__token__Kind__key_as, &(string[]) { _S("as") }); array_set(&s, v__token__Kind__key_defer, &(string[]) { _S("defer") }); array_set(&s, v__token__Kind__key_match, &(string[]) { _S("match") }); array_set(&s, v__token__Kind__key_select, &(string[]) { _S("select") }); array_set(&s, v__token__Kind__key_like, &(string[]) { _S("like") }); array_set(&s, v__token__Kind__key_ilike, &(string[]) { _S("ilike") }); array_set(&s, v__token__Kind__key_none, &(string[]) { _S("none") }); array_set(&s, v__token__Kind__key_nil, &(string[]) { _S("nil") }); array_set(&s, v__token__Kind__key_offsetof, &(string[]) { _S("__offsetof") }); array_set(&s, v__token__Kind__key_is, &(string[]) { _S("is") }); array_set(&s, v__token__Kind__key_spawn, &(string[]) { _S("spawn") }); array_set(&s, v__token__Kind__key_implements, &(string[]) { _S("implements") }); array_set(&s, v__token__Kind__keyword_beg, &(string[]) { _S("keyword_beg") }); array_set(&s, v__token__Kind__keyword_end, &(string[]) { _S("keyword_end") }); array_set(&s, v__token__Kind__str_inter, &(string[]) { _S("str_inter") }); #if defined(CUSTOM_DEFINE_debug_build_token_str) { for (int k = 0; k < s.len; ++k) { string v = ((string*)s.data)[k]; if ((v).len == 0) { eprintln(str_intp(5, _MOV((StrIntpData[]){{_S(">>> "), 0xfe10, {.d_s = _S("v.token")}}, {_S("."), 0xfe10, {.d_s = _S("build_token_str")}}, {_S(" missing k: "), 0xfe07, {.d_i32 = k}}, {_S(" | ."), 0xfe10, {.d_s = v__token__kind_to_string(((v__token__Kind)(k)))}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } } #endif return s; } inline bool v__token__is_key(string key) { return ((int)((*(v__token__Kind*)map_get(ADDR(map, _const_v__token__keywords), &(string[]){key}, &(v__token__Kind[]){ 0 })))) > 0; } inline bool v__token__is_decl(v__token__Kind t) { return (t == v__token__Kind__key_enum || t == v__token__Kind__key_interface || t == v__token__Kind__key_fn || t == v__token__Kind__key_struct || t == v__token__Kind__key_type || t == v__token__Kind__key_const || t == v__token__Kind__key_pub || t == v__token__Kind__eof); } inline bool v__token__Kind_is_assign(v__token__Kind t) { return (Array_v__token__Kind_contains(_const_v__token__assign_tokens, t)); } inline string v__token__Kind_str(v__token__Kind t) { int idx = ((int)(t)); if (idx < 0 || _const_v__token__token_str.len <= idx) { return _S("unknown"); } return (*(string*)array_get(_const_v__token__token_str, idx)); } inline bool v__token__Token_is_next_to(v__token__Token t, v__token__Token pre_token) { return (int)(t.pos - pre_token.pos) == pre_token.len; } string v__token__Token_str(v__token__Token t) { string s = v__token__Kind_str(t.kind); if (s.len == 0) { eprintln(_S("missing token kind string")); } else if (!u8_is_letter(string_at(s, 0))) { return str_intp(2, _MOV((StrIntpData[]){{_S("token `"), 0xfe10, {.d_s = s}}, {_S("`"), 0, { .d_c = 0 }}})); } if (v__token__is_key(t.lit)) { s = _S("keyword"); } if ((t.lit).len != 0) { s = string__plus(s, str_intp(2, _MOV((StrIntpData[]){{_S(" `"), 0xfe10, {.d_s = t.lit}}, {_S("`"), 0, { .d_c = 0 }}}))); } return s; } Array_v__token__Precedence v__token__build_precedences(void) { Array_v__token__Precedence p = __new_array_with_default(((int)(v__token__Kind___end_)), 0, sizeof(v__token__Precedence), &(v__token__Precedence[]){v__token__Precedence__lowest}); array_set(&p, v__token__Kind__lsbr, &(v__token__Precedence[]) { v__token__Precedence__index }); array_set(&p, v__token__Kind__nilsbr, &(v__token__Precedence[]) { v__token__Precedence__index }); array_set(&p, v__token__Kind__dot, &(v__token__Precedence[]) { v__token__Precedence__call }); array_set(&p, v__token__Kind__inc, &(v__token__Precedence[]) { v__token__Precedence__postfix }); array_set(&p, v__token__Kind__dec, &(v__token__Precedence[]) { v__token__Precedence__postfix }); array_set(&p, v__token__Kind__question, &(v__token__Precedence[]) { v__token__Precedence__postfix }); array_set(&p, v__token__Kind__mul, &(v__token__Precedence[]) { v__token__Precedence__product }); array_set(&p, v__token__Kind__div, &(v__token__Precedence[]) { v__token__Precedence__product }); array_set(&p, v__token__Kind__mod, &(v__token__Precedence[]) { v__token__Precedence__product }); array_set(&p, v__token__Kind__left_shift, &(v__token__Precedence[]) { v__token__Precedence__product }); array_set(&p, v__token__Kind__right_shift, &(v__token__Precedence[]) { v__token__Precedence__product }); array_set(&p, v__token__Kind__unsigned_right_shift, &(v__token__Precedence[]) { v__token__Precedence__product }); array_set(&p, v__token__Kind__amp, &(v__token__Precedence[]) { v__token__Precedence__product }); array_set(&p, v__token__Kind__arrow, &(v__token__Precedence[]) { v__token__Precedence__product }); array_set(&p, v__token__Kind__plus, &(v__token__Precedence[]) { v__token__Precedence__sum }); array_set(&p, v__token__Kind__minus, &(v__token__Precedence[]) { v__token__Precedence__sum }); array_set(&p, v__token__Kind__pipe, &(v__token__Precedence[]) { v__token__Precedence__sum }); array_set(&p, v__token__Kind__xor, &(v__token__Precedence[]) { v__token__Precedence__sum }); array_set(&p, v__token__Kind__eq, &(v__token__Precedence[]) { v__token__Precedence__eq }); array_set(&p, v__token__Kind__ne, &(v__token__Precedence[]) { v__token__Precedence__eq }); array_set(&p, v__token__Kind__lt, &(v__token__Precedence[]) { v__token__Precedence__eq }); array_set(&p, v__token__Kind__le, &(v__token__Precedence[]) { v__token__Precedence__eq }); array_set(&p, v__token__Kind__gt, &(v__token__Precedence[]) { v__token__Precedence__eq }); array_set(&p, v__token__Kind__ge, &(v__token__Precedence[]) { v__token__Precedence__eq }); array_set(&p, v__token__Kind__key_like, &(v__token__Precedence[]) { v__token__Precedence__eq }); array_set(&p, v__token__Kind__key_ilike, &(v__token__Precedence[]) { v__token__Precedence__eq }); array_set(&p, v__token__Kind__assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__plus_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__minus_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__div_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__mod_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__or_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__and_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__left_shift_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__right_shift_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__unsigned_right_shift_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__mult_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__xor_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__boolean_or_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__boolean_and_assign, &(v__token__Precedence[]) { v__token__Precedence__assign }); array_set(&p, v__token__Kind__key_in, &(v__token__Precedence[]) { v__token__Precedence__in_as }); array_set(&p, v__token__Kind__not_in, &(v__token__Precedence[]) { v__token__Precedence__in_as }); array_set(&p, v__token__Kind__key_as, &(v__token__Precedence[]) { v__token__Precedence__in_as }); array_set(&p, v__token__Kind__key_is, &(v__token__Precedence[]) { v__token__Precedence__in_as }); array_set(&p, v__token__Kind__not_is, &(v__token__Precedence[]) { v__token__Precedence__in_as }); array_set(&p, v__token__Kind__logical_or, &(v__token__Precedence[]) { v__token__Precedence__cond }); array_set(&p, v__token__Kind__and, &(v__token__Precedence[]) { v__token__Precedence__cond }); return p; } inline int v__token__Kind_precedence(v__token__Kind kind) { return ((int)(((v__token__Precedence*)_const_v__token__precedences.data)[kind])); } inline bool v__token__Kind_is_relational(v__token__Kind tok) { return (tok == v__token__Kind__lt || tok == v__token__Kind__le || tok == v__token__Kind__gt || tok == v__token__Kind__ge || tok == v__token__Kind__eq || tok == v__token__Kind__ne); } inline bool v__token__Kind_is_start_of_type(v__token__Kind k) { return (k == v__token__Kind__name || k == v__token__Kind__lpar || k == v__token__Kind__amp || k == v__token__Kind__lsbr || k == v__token__Kind__question || k == v__token__Kind__key_shared || k == v__token__Kind__not); } inline bool v__token__Kind_is_infix(v__token__Kind kind) { return (kind == v__token__Kind__plus || kind == v__token__Kind__minus || kind == v__token__Kind__mod || kind == v__token__Kind__mul || kind == v__token__Kind__div || kind == v__token__Kind__eq || kind == v__token__Kind__ne || kind == v__token__Kind__gt || kind == v__token__Kind__lt || kind == v__token__Kind__key_in || kind == v__token__Kind__key_as || kind == v__token__Kind__ge || kind == v__token__Kind__le || kind == v__token__Kind__logical_or || kind == v__token__Kind__xor || kind == v__token__Kind__not_in || kind == v__token__Kind__key_is || kind == v__token__Kind__not_is || kind == v__token__Kind__and || kind == v__token__Kind__dot || kind == v__token__Kind__pipe || kind == v__token__Kind__amp || kind == v__token__Kind__left_shift || kind == v__token__Kind__right_shift || kind == v__token__Kind__unsigned_right_shift || kind == v__token__Kind__arrow || kind == v__token__Kind__key_like || kind == v__token__Kind__key_ilike); } string v__token__kind_to_string(v__token__Kind k) { string _t2 = (string){.str=(byteptr)"", .is_lit=1}; switch (k) { case v__token__Kind__unknown: { _t2 = _S("unknown"); break; } case v__token__Kind__eof: { _t2 = _S("eof"); break; } case v__token__Kind__name: { _t2 = _S("name"); break; } case v__token__Kind__number: { _t2 = _S("number"); break; } case v__token__Kind__string: { _t2 = _S("string"); break; } case v__token__Kind__str_inter: { _t2 = _S("str_inter"); break; } case v__token__Kind__chartoken: { _t2 = _S("chartoken"); break; } case v__token__Kind__plus: { _t2 = _S("plus"); break; } case v__token__Kind__minus: { _t2 = _S("minus"); break; } case v__token__Kind__mul: { _t2 = _S("mul"); break; } case v__token__Kind__div: { _t2 = _S("div"); break; } case v__token__Kind__mod: { _t2 = _S("mod"); break; } case v__token__Kind__xor: { _t2 = _S("xor"); break; } case v__token__Kind__pipe: { _t2 = _S("pipe"); break; } case v__token__Kind__inc: { _t2 = _S("inc"); break; } case v__token__Kind__dec: { _t2 = _S("dec"); break; } case v__token__Kind__and: { _t2 = _S("and"); break; } case v__token__Kind__logical_or: { _t2 = _S("logical_or"); break; } case v__token__Kind__not: { _t2 = _S("not"); break; } case v__token__Kind__bit_not: { _t2 = _S("bit_not"); break; } case v__token__Kind__question: { _t2 = _S("question"); break; } case v__token__Kind__comma: { _t2 = _S("comma"); break; } case v__token__Kind__semicolon: { _t2 = _S("semicolon"); break; } case v__token__Kind__colon: { _t2 = _S("colon"); break; } case v__token__Kind__arrow: { _t2 = _S("arrow"); break; } case v__token__Kind__amp: { _t2 = _S("amp"); break; } case v__token__Kind__hash: { _t2 = _S("hash"); break; } case v__token__Kind__dollar: { _t2 = _S("dollar"); break; } case v__token__Kind__at: { _t2 = _S("at"); break; } case v__token__Kind__str_dollar: { _t2 = _S("str_dollar"); break; } case v__token__Kind__left_shift: { _t2 = _S("left_shift"); break; } case v__token__Kind__right_shift: { _t2 = _S("right_shift"); break; } case v__token__Kind__unsigned_right_shift: { _t2 = _S("unsigned_right_shift"); break; } case v__token__Kind__not_in: { _t2 = _S("not_in"); break; } case v__token__Kind__not_is: { _t2 = _S("not_is"); break; } case v__token__Kind__assign: { _t2 = _S("assign"); break; } case v__token__Kind__decl_assign: { _t2 = _S("decl_assign"); break; } case v__token__Kind__plus_assign: { _t2 = _S("plus_assign"); break; } case v__token__Kind__minus_assign: { _t2 = _S("minus_assign"); break; } case v__token__Kind__div_assign: { _t2 = _S("div_assign"); break; } case v__token__Kind__mult_assign: { _t2 = _S("mult_assign"); break; } case v__token__Kind__xor_assign: { _t2 = _S("xor_assign"); break; } case v__token__Kind__mod_assign: { _t2 = _S("mod_assign"); break; } case v__token__Kind__or_assign: { _t2 = _S("or_assign"); break; } case v__token__Kind__and_assign: { _t2 = _S("and_assign"); break; } case v__token__Kind__right_shift_assign: { _t2 = _S("right_shift_assign"); break; } case v__token__Kind__left_shift_assign: { _t2 = _S("left_shift_assign"); break; } case v__token__Kind__unsigned_right_shift_assign: { _t2 = _S("unsigned_right_shift_assign"); break; } case v__token__Kind__boolean_and_assign: { _t2 = _S("boolean_and_assign"); break; } case v__token__Kind__boolean_or_assign: { _t2 = _S("boolean_or_assign"); break; } case v__token__Kind__lcbr: { _t2 = _S("lcbr"); break; } case v__token__Kind__rcbr: { _t2 = _S("rcbr"); break; } case v__token__Kind__lpar: { _t2 = _S("lpar"); break; } case v__token__Kind__rpar: { _t2 = _S("rpar"); break; } case v__token__Kind__lsbr: { _t2 = _S("lsbr"); break; } case v__token__Kind__nilsbr: { _t2 = _S("nilsbr"); break; } case v__token__Kind__rsbr: { _t2 = _S("rsbr"); break; } case v__token__Kind__eq: { _t2 = _S("eq"); break; } case v__token__Kind__ne: { _t2 = _S("ne"); break; } case v__token__Kind__gt: { _t2 = _S("gt"); break; } case v__token__Kind__lt: { _t2 = _S("lt"); break; } case v__token__Kind__ge: { _t2 = _S("ge"); break; } case v__token__Kind__le: { _t2 = _S("le"); break; } case v__token__Kind__comment: { _t2 = _S("comment"); break; } case v__token__Kind__nl: { _t2 = _S("nl"); break; } case v__token__Kind__dot: { _t2 = _S("dot"); break; } case v__token__Kind__dotdot: { _t2 = _S("dotdot"); break; } case v__token__Kind__ellipsis: { _t2 = _S("ellipsis"); break; } case v__token__Kind__keyword_beg: { _t2 = _S("keyword_beg"); break; } case v__token__Kind__key_as: { _t2 = _S("key_as"); break; } case v__token__Kind__key_asm: { _t2 = _S("key_asm"); break; } case v__token__Kind__key_assert: { _t2 = _S("key_assert"); break; } case v__token__Kind__key_atomic: { _t2 = _S("key_atomic"); break; } case v__token__Kind__key_break: { _t2 = _S("key_break"); break; } case v__token__Kind__key_const: { _t2 = _S("key_const"); break; } case v__token__Kind__key_continue: { _t2 = _S("key_continue"); break; } case v__token__Kind__key_defer: { _t2 = _S("key_defer"); break; } case v__token__Kind__key_else: { _t2 = _S("key_else"); break; } case v__token__Kind__key_enum: { _t2 = _S("key_enum"); break; } case v__token__Kind__key_false: { _t2 = _S("key_false"); break; } case v__token__Kind__key_for: { _t2 = _S("key_for"); break; } case v__token__Kind__key_fn: { _t2 = _S("key_fn"); break; } case v__token__Kind__key_global: { _t2 = _S("key_global"); break; } case v__token__Kind__key_go: { _t2 = _S("key_go"); break; } case v__token__Kind__key_goto: { _t2 = _S("key_goto"); break; } case v__token__Kind__key_if: { _t2 = _S("key_if"); break; } case v__token__Kind__key_import: { _t2 = _S("key_import"); break; } case v__token__Kind__key_in: { _t2 = _S("key_in"); break; } case v__token__Kind__key_interface: { _t2 = _S("key_interface"); break; } case v__token__Kind__key_is: { _t2 = _S("key_is"); break; } case v__token__Kind__key_match: { _t2 = _S("key_match"); break; } case v__token__Kind__key_module: { _t2 = _S("key_module"); break; } case v__token__Kind__key_mut: { _t2 = _S("key_mut"); break; } case v__token__Kind__key_shared: { _t2 = _S("key_shared"); break; } case v__token__Kind__key_lock: { _t2 = _S("key_lock"); break; } case v__token__Kind__key_rlock: { _t2 = _S("key_rlock"); break; } case v__token__Kind__key_none: { _t2 = _S("key_none"); break; } case v__token__Kind__key_return: { _t2 = _S("key_return"); break; } case v__token__Kind__key_select: { _t2 = _S("key_select"); break; } case v__token__Kind__key_like: { _t2 = _S("key_like"); break; } case v__token__Kind__key_ilike: { _t2 = _S("key_ilike"); break; } case v__token__Kind__key_sizeof: { _t2 = _S("key_sizeof"); break; } case v__token__Kind__key_isreftype: { _t2 = _S("key_isreftype"); break; } case v__token__Kind__key_likely: { _t2 = _S("key_likely"); break; } case v__token__Kind__key_unlikely: { _t2 = _S("key_unlikely"); break; } case v__token__Kind__key_offsetof: { _t2 = _S("key_offsetof"); break; } case v__token__Kind__key_struct: { _t2 = _S("key_struct"); break; } case v__token__Kind__key_true: { _t2 = _S("key_true"); break; } case v__token__Kind__key_type: { _t2 = _S("key_type"); break; } case v__token__Kind__key_typeof: { _t2 = _S("key_typeof"); break; } case v__token__Kind__key_dump: { _t2 = _S("key_dump"); break; } case v__token__Kind__key_orelse: { _t2 = _S("key_orelse"); break; } case v__token__Kind__key_union: { _t2 = _S("key_union"); break; } case v__token__Kind__key_pub: { _t2 = _S("key_pub"); break; } case v__token__Kind__key_static: { _t2 = _S("key_static"); break; } case v__token__Kind__key_volatile: { _t2 = _S("key_volatile"); break; } case v__token__Kind__key_unsafe: { _t2 = _S("key_unsafe"); break; } case v__token__Kind__key_spawn: { _t2 = _S("key_spawn"); break; } case v__token__Kind__key_implements: { _t2 = _S("key_implements"); break; } case v__token__Kind__keyword_end: { _t2 = _S("keyword_end"); break; } case v__token__Kind___end_: { _t2 = _S("_end_"); break; } case v__token__Kind__key_nil: { _t2 = _S("key_nil"); break; } } return _t2; } void v__dotgraph__start_digraph(void) { println(_S("digraph G {")); _result_void _t1 = at_exit((voidptr) anon_fn_40181cb3d9c4559e__81); (void)_t1; ; } v__dotgraph__DotGraph* v__dotgraph__new(string name, string label, string color) { v__dotgraph__DotGraph* res = ((v__dotgraph__DotGraph*)memdup(&(v__dotgraph__DotGraph){.sb = strings__new_builder(1024),}, sizeof(v__dotgraph__DotGraph))); v__dotgraph__DotGraph_writeln(res, str_intp(2, _MOV((StrIntpData[]){{_S(" subgraph cluster_"), 0xfe10, {.d_s = name}}, {_S(" {"), 0, { .d_c = 0 }}}))); v__dotgraph__DotGraph_writeln(res, _S("\tedge [fontname=\"Helvetica\",fontsize=\"10\",labelfontname=\"Helvetica\",labelfontsize=\"10\",style=\"solid\",color=\"black\"];")); v__dotgraph__DotGraph_writeln(res, _S("\tnode [fontname=\"Helvetica\",fontsize=\"10\",style=\"filled\",fontcolor=\"black\",fillcolor=\"white\",color=\"black\",shape=\"box\"];")); v__dotgraph__DotGraph_writeln(res, _S("\trankdir=\"LR\";")); v__dotgraph__DotGraph_writeln(res, str_intp(2, _MOV((StrIntpData[]){{_S("\tcolor=\""), 0xfe10, {.d_s = color}}, {_S("\";"), 0, { .d_c = 0 }}}))); v__dotgraph__DotGraph_writeln(res, str_intp(2, _MOV((StrIntpData[]){{_S("\tlabel=\""), 0xfe10, {.d_s = label}}, {_S("\";"), 0, { .d_c = 0 }}}))); return res; } void v__dotgraph__DotGraph_writeln(v__dotgraph__DotGraph* d, string line) { strings__Builder_writeln(&d->sb, line); } void v__dotgraph__DotGraph_finish(v__dotgraph__DotGraph* d) { strings__Builder_writeln(&d->sb, _S(" }")); println(strings__Builder_str(&d->sb)); } void v__dotgraph__DotGraph_new_node(v__dotgraph__DotGraph* d, string nlabel, v__dotgraph__NewNodeConfig cfg) { string nname = cfg.name2node_fn(nlabel, cfg.ctx); if ((cfg.node_name).len != 0) { nname = cfg.node_name; } if (cfg.should_highlight) { v__dotgraph__DotGraph_writeln(d, str_intp(4, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = nname}}, {_S(" [label=\""), 0xfe10, {.d_s = nlabel}}, {_S("\",color=\"blue\",height=0.2,width=0.4,fillcolor=\"#00FF00\",tooltip=\""), 0xfe10, {.d_s = cfg.tooltip}}, {_S("\",shape=oval];"), 0, { .d_c = 0 }}}))); } else { v__dotgraph__DotGraph_writeln(d, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = nname}}, {_S(" [shape=\"box\",label=\""), 0xfe10, {.d_s = nlabel}}, {_S("\"];"), 0, { .d_c = 0 }}}))); } } void v__dotgraph__DotGraph_new_edge(v__dotgraph__DotGraph* d, string source, string target, v__dotgraph__NewEdgeConfig cfg) { string nsource = cfg.name2node_fn(source, cfg.ctx); string ntarget = cfg.name2node_fn(target, cfg.ctx); if (cfg.should_highlight) { v__dotgraph__DotGraph_writeln(d, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = nsource}}, {_S(" -> "), 0xfe10, {.d_s = ntarget}}, {_S(" [color=\"blue\"];"), 0, { .d_c = 0 }}}))); } else { v__dotgraph__DotGraph_writeln(d, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = nsource}}, {_S(" -> "), 0xfe10, {.d_s = ntarget}}, {_S(";"), 0, { .d_c = 0 }}}))); } } string v__dotgraph__node_name(string name, voidptr context) { return string_replace(name, _S("."), _S("_")); } inline u64 hash__wyhash_c(u8* key, u64 len, u64 seed) { return wyhash(key, len, seed, ((u64*)(((voidptr)(_wyp))))); } inline u64 hash__sum64_string(string key, u64 seed) { return hash__wyhash_c(key.str, ((u64)(key.len)), seed); } inline u64 hash__wymum(u64 a, u64 b) { u32 mask32 = ((u32)(4294967295U)); u64 x0 = (a & mask32); u64 x1 = (a >> 32U); u64 y0 = (b & mask32); u64 y1 = (b >> 32U); u64 w0 = (u64)(x0 * y0); u64 t = (u64)((u64)(x1 * y0) + ((w0 >> 32U))); u64 w1 = (t & mask32); u64 w2 = (t >> 32U); w1 += (u64)(x0 * y1); u64 hi = (u64)((u64)((u64)(x1 * y1) + w2) + ((w1 >> 32U))); u64 lo = (u64)(a * b); return (hi ^ lo); } #if defined(_WIN32) #else #endif #if defined(__linux__) #if defined(__TINYC__) #if defined(__V_amd64) #if defined(CUSTOM_DEFINE_musl) #endif #elif defined(__V_arm64) #if defined(CUSTOM_DEFINE_musl) #endif #endif #endif #endif #if defined(CUSTOM_DEFINE_valgrind) #endif inline i64 sync__stdatomic__add_i64(i64* ptr, int delta) { atomic_fetch_add_u64(((voidptr)(ptr)), delta); return *ptr; } inline i64 sync__stdatomic__sub_i64(i64* ptr, int delta) { atomic_fetch_sub_u64(((voidptr)(ptr)), delta); return *ptr; } #if !defined(_WIN32) && !defined(__ANDROID__) #endif inline u64 hash__fnv1a__sum64_string(string data) { u64 hash = _const_hash__fnv1a__fnv64_offset_basis; for (int i = 0; i < data.len; ++i) { hash = (u64)(((hash ^ ((u64)(data.str[ i])))) * _const_hash__fnv1a__fnv64_prime); } return hash; } bool encoding__utf8__validate__utf8_string(string s) { return encoding__utf8__validate__utf8_data(s.str, s.len); } bool encoding__utf8__validate__utf8_data(u8* data, int len) { encoding__utf8__validate__Utf8State state = ((encoding__utf8__validate__Utf8State){.index = 0,.subindex = 0,.failed = 0,}); for (int i = 0; i < len; i++) { u8 s = data[i]; if (s == 0) { break; } encoding__utf8__validate__Utf8State_next_state(&state, s); if (state.failed) { return false; } } return !state.failed && state.subindex <= 0; } VV_LOC bool encoding__utf8__validate__Utf8State_seq(encoding__utf8__validate__Utf8State* s, bool r0, bool r1, bool is_tail) { if (s->subindex == 0 || (s->index > 1 && s->subindex == 1) || (s->index >= 6 && s->subindex == 2)) { if ((s->subindex == 0 && r0) || (s->subindex == 1 && r1) || (s->subindex == 2 && is_tail)) { s->subindex++; return true; } } else { s->failed = true; if (is_tail) { s->index = 0; s->subindex = 0; s->failed = false; } return true; } s->index++; s->subindex = 0; return false; } VV_LOC void encoding__utf8__validate__Utf8State_next_state(encoding__utf8__validate__Utf8State* s, u8 c) { if (s->index == 0) { if ((c >= 1 && c <= 0x7F) || c == 0x00) { return; } s->index++; s->subindex = 0; } bool is_tail = c >= 0x80 && c <= 0xBF; if (s->index == 1 && encoding__utf8__validate__Utf8State_seq(s, c >= 0xC2 && c <= 0xDF, false, is_tail)) { return; } if (s->index == 2 && encoding__utf8__validate__Utf8State_seq(s, c == 0xE0, c >= 0xA0 && c <= 0xBF, is_tail)) { return; } if (s->index == 3 && encoding__utf8__validate__Utf8State_seq(s, c >= 0xE1 && c <= 0xEC, c >= 0x80 && c <= 0xBF, is_tail)) { return; } if (s->index == 4 && encoding__utf8__validate__Utf8State_seq(s, c == 0xED, c >= 0x80 && c <= 0x9F, is_tail)) { return; } if (s->index == 5 && encoding__utf8__validate__Utf8State_seq(s, c >= 0xEE && c <= 0xEF, c >= 0x80 && c <= 0xBF, is_tail)) { return; } if (s->index == 6 && encoding__utf8__validate__Utf8State_seq(s, c == 0xF0, c >= 0x90 && c <= 0xBF, is_tail)) { return; } if (s->index == 7 && encoding__utf8__validate__Utf8State_seq(s, c >= 0xF1 && c <= 0xF3, c >= 0x80 && c <= 0xBF, is_tail)) { return; } if (s->index == 8 && encoding__utf8__validate__Utf8State_seq(s, c == 0xF4, c >= 0x80 && c <= 0x8F, is_tail)) { return; } s->failed = true; } VV_LOC string flag__UnknownFlagError_msg(flag__UnknownFlagError err) { return str_intp(2, _MOV((StrIntpData[]){{_S("Unknown flag `"), 0xfe10, {.d_s = err.flag}}, {_S("`"), 0, { .d_c = 0 }}})); } VV_LOC string flag__ArgsCountError_msg(flag__ArgsCountError err) { if (err.want == 0) { return str_intp(2, _MOV((StrIntpData[]){{_S("Expected no arguments, but got "), 0xfe07, {.d_i32 = err.got}}, {_SLIT0, 0, { .d_c = 0 }}})); } else if (err.got > err.want) { return str_intp(3, _MOV((StrIntpData[]){{_S("Expected at most "), 0xfe07, {.d_i32 = err.want}}, {_S(" arguments, but got "), 0xfe07, {.d_i32 = err.got}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { return str_intp(3, _MOV((StrIntpData[]){{_S("Expected at least "), 0xfe07, {.d_i32 = err.want}}, {_S(" arguments, but got "), 0xfe07, {.d_i32 = err.got}}, {_SLIT0, 0, { .d_c = 0 }}})); } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC void flag__Flag_free(flag__Flag* f) { { // Unsafe block string_free(&f->name); string_free(&f->usage); string_free(&f->val_desc); } } string flag__Flag_str(flag__Flag f) { return str_intp(5, _MOV((StrIntpData[]){{_S(" flag:\n name: "), 0xfe10, {.d_s = f.name}}, {_S("\n abbr: `"), 0xfe10, {.d_s = u8_ascii_str(f.abbr)}}, {_S("`\n usage: "), 0xfe10, {.d_s = f.usage}}, {_S("\n desc: "), 0xfe10, {.d_s = f.val_desc}}, {_SLIT0, 0, { .d_c = 0 }}})); } string Array_flag__Flag_str(Array_flag__Flag af) { Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); array_push((array*)&res, _MOV((string[]){ _S("\n []Flag = [") })); for (int _t2 = 0; _t2 < af.len; ++_t2) { flag__Flag f = ((flag__Flag*)af.data)[_t2]; array_push((array*)&res, _MOV((string[]){ flag__Flag_str(f) })); } array_push((array*)&res, _MOV((string[]){ _S(" ]") })); return Array_string_join(res, _S("\n")); } VV_LOC void flag__FlagParser_free(flag__FlagParser* f) { { // Unsafe block for (int _t1 = 0; _t1 < f->args.len; ++_t1) { string a = ((string*)f->args.data)[_t1]; string_free(&a); } Array_string_free(&f->args); for (int _t2 = 0; _t2 < f->flags.len; ++_t2) { flag__Flag flag = ((flag__Flag*)f->flags.data)[_t2]; flag__Flag_free(&flag); } array_free(&f->flags); string_free(&f->application_name); string_free(&f->application_version); string_free(&f->application_description); string_free(&f->args_description); } } flag__FlagParser* flag__new_flag_parser(Array_string args) { Array_string original_args = array_clone_to_depth(&args, 0); int idx_dashdash = Array_string_index(args, _S("--")); Array_string all_before_dashdash = array_clone_to_depth(&args, 0); Array_string all_after_dashdash = __new_array_with_default(0, 0, sizeof(string), 0); if (idx_dashdash >= 0) { array_trim(&all_before_dashdash, idx_dashdash); if (idx_dashdash < original_args.len) { all_after_dashdash = array_slice(original_args, (int)(idx_dashdash + 1), 2147483647); } } return ((flag__FlagParser*)memdup(&(flag__FlagParser){.original_args = original_args,.idx_dashdash = idx_dashdash,.all_after_dashdash = all_after_dashdash,.usage_examples = __new_array(0, 0, sizeof(string)),.default_help_label = _S("display this help and exit"),.default_version_label = _S("output version information and exit"),.args = all_before_dashdash,.max_free_args = _const_flag__max_args_number,.flags = __new_array(0, 0, sizeof(flag__Flag)),.application_name = (string){.str=(byteptr)"", .is_lit=1},.application_version = (string){.str=(byteptr)"", .is_lit=1},.application_description = (string){.str=(byteptr)"", .is_lit=1},.min_free_args = 0,.args_description = (string){.str=(byteptr)"", .is_lit=1},.allow_unknown_args = 0,.footers = __new_array(0, 0, sizeof(string)),}, sizeof(flag__FlagParser))); } void flag__FlagParser_application(flag__FlagParser* fs, string name) { fs->application_name = name; } void flag__FlagParser_version(flag__FlagParser* fs, string vers) { fs->application_version = vers; } VV_LOC void flag__FlagParser_add_flag(flag__FlagParser* fs, string name, u8 abbr, string usage, string desc) { array_push((array*)&fs->flags, _MOV((flag__Flag[]){ ((flag__Flag){.name = name,.abbr = abbr,.usage = usage,.val_desc = desc,}) })); } VV_LOC Array_string flag__FlagParser_parse_value(flag__FlagParser* fs, string longhand, u8 shorthand) { bool flag__FlagParser_parse_value_defer_0 = false; string full; bool flag__FlagParser_parse_value_defer_1 = false; Array_int to_delete; full = str_intp(2, _MOV((StrIntpData[]){{_S("--"), 0xfe10, {.d_s = longhand}}, {_SLIT0, 0, { .d_c = 0 }}})); flag__FlagParser_parse_value_defer_0 = true; Array_string found_entries = __new_array_with_default(0, 0, sizeof(string), 0); to_delete = __new_array_with_default(0, 0, sizeof(int), 0); flag__FlagParser_parse_value_defer_1 = true; bool should_skip_one = false; for (int i = 0; i < fs->args.len; ++i) { string arg = ((string*)fs->args.data)[i]; if (should_skip_one) { should_skip_one = false; continue; } if (arg.len == 0 || string_at(arg, 0) != '-') { continue; } if ((arg.len == 2 && string_at(arg, 0) == '-' && string_at(arg, 1) == shorthand) || string__eq(arg, full)) { if ((int)(i + 1) >= fs->args.len) { Array_string _t1 = __new_array_with_default(0, 0, sizeof(string), 0); // Defer begin if (flag__FlagParser_parse_value_defer_1) { array_free(&to_delete); } // Defer end // Defer begin if (flag__FlagParser_parse_value_defer_0) { string_free(&full); } // Defer end return _t1; } string nextarg = (*(string*)array_get(fs->args, (int)(i + 1))); if (nextarg.len > 2) { string nextarg_rest = string_substr(nextarg, 0, 2); if (_SLIT_EQ(nextarg_rest.str, nextarg_rest.len, "--")) { string_free(&nextarg_rest); Array_string _t2 = __new_array_with_default(0, 0, sizeof(string), 0); // Defer begin if (flag__FlagParser_parse_value_defer_1) { array_free(&to_delete); } // Defer end // Defer begin if (flag__FlagParser_parse_value_defer_0) { string_free(&full); } // Defer end return _t2; } string_free(&nextarg_rest); } array_push((array*)&found_entries, _MOV((string[]){ (*(string*)array_get(fs->args, (int)(i + 1))) })); array_push((array*)&to_delete, _MOV((int[]){ i })); array_push((array*)&to_delete, _MOV((int[]){ (int)(i + 1) })); should_skip_one = true; continue; } if (arg.len > (int)(full.len + 1) && string__eq(string_substr(arg, 0, (int)(full.len + 1)), str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = full}}, {_S("="), 0, { .d_c = 0 }}})))) { array_push((array*)&found_entries, _MOV((string[]){ string_substr(arg, (int)(full.len + 1), 2147483647) })); array_push((array*)&to_delete, _MOV((int[]){ i })); continue; } } for (int i = 0; i < to_delete.len; ++i) { int del = ((int*)to_delete.data)[i]; array_delete(&fs->args, (int)(del - i)); } Array_string _t8 = found_entries; // Defer begin if (flag__FlagParser_parse_value_defer_1) { array_free(&to_delete); } // Defer end // Defer begin if (flag__FlagParser_parse_value_defer_0) { string_free(&full); } // Defer end return _t8; } VV_LOC _result_string flag__FlagParser_parse_bool_value(flag__FlagParser* fs, string longhand, u8 shorthand) { string full = str_intp(2, _MOV((StrIntpData[]){{_S("--"), 0xfe10, {.d_s = longhand}}, {_SLIT0, 0, { .d_c = 0 }}})); for (int i = 0; i < fs->args.len; ++i) { string arg = ((string*)fs->args.data)[i]; if (arg.len == 0) { continue; } if (string_at(arg, 0) != '-') { continue; } if ((arg.len == 2 && string_at(arg, 0) == '-' && string_at(arg, 1) == shorthand) || string__eq(arg, full)) { if (fs->args.len > (int)(i + 1) && (fast_string_eq((*(string*)array_get(fs->args, (int)(i + 1))), _S("true")) || fast_string_eq((*(string*)array_get(fs->args, (int)(i + 1))), _S("false")))) { string val = (*(string*)array_get(fs->args, (int)(i + 1))); array_delete(&fs->args, (int)(i + 1)); array_delete(&fs->args, i); _result_string _t1 = {0}; _result_ok(&(string[]) { val }, (_result*)(&_t1), sizeof(string)); return _t1; } else { array_delete(&fs->args, i); _result_string _t2 = {0}; _result_ok(&(string[]) { _S("true") }, (_result*)(&_t2), sizeof(string)); return _t2; } } if (arg.len > (int)(full.len + 1) && string__eq(string_substr(arg, 0, (int)(full.len + 1)), str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = full}}, {_S("="), 0, { .d_c = 0 }}})))) { string val = string_substr(arg, (int)(full.len + 1), 2147483647); array_delete(&fs->args, i); _result_string _t3 = {0}; _result_ok(&(string[]) { val }, (_result*)(&_t3), sizeof(string)); return _t3; } if (arg.len > 1 && string_at(arg, 0) == '-' && string_at(arg, 1) != '-') { bool found = false; for (int j = 1; j < arg.len; ++j) { if (u8_is_space(string_at(arg, j))) { break; } else if (string_at(arg, j) == shorthand) { found = true; } } if (found) { array_set(&fs->args, i, &(string[]) { string_replace(arg, u8_ascii_str(shorthand), _S("")) }); _result_string _t4 = {0}; _result_ok(&(string[]) { _S("true") }, (_result*)(&_t4), sizeof(string)); return _t4; } } } return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("parameter '"), 0xfe10, {.d_s = longhand}}, {_S("' not found"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } _result_bool flag__FlagParser_bool_opt(flag__FlagParser* fs, string name, u8 abbr, string usage, flag__FlagConfig c) { string val_desc = ((c.val_desc).len == 0 ? (_S("")) : (c.val_desc)); flag__FlagParser_add_flag(fs, name, abbr, usage, val_desc); _result_string _t1 = flag__FlagParser_parse_bool_value(fs, name, abbr); if (_t1.is_error) { IError err = _t1.err; return (_result_bool){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("parameter '"), 0xfe10, {.d_s = name}}, {_S("' not provided"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } string parsed = (*(string*)_t1.data); _result_bool _t3 = {0}; _result_ok(&(bool[]) { _SLIT_EQ(parsed.str, parsed.len, "true") }, (_result*)(&_t3), sizeof(bool)); return _t3; } bool flag__FlagParser_bool(flag__FlagParser* fs, string name, u8 abbr, bool bdefault, string usage, flag__FlagConfig c) { _result_bool _t1 = flag__FlagParser_bool_opt(fs, name, abbr, usage, c); if (_t1.is_error) { IError err = _t1.err; return bdefault; } bool value = (*(bool*)_t1.data); return value; } _result_string flag__FlagParser_string_opt(flag__FlagParser* fs, string name, u8 abbr, string usage, flag__FlagConfig c) { string val_desc = ((c.val_desc).len == 0 ? (_S("")) : (c.val_desc)); flag__FlagParser_add_flag(fs, name, abbr, usage, val_desc); Array_string parsed = flag__FlagParser_parse_value(fs, name, abbr); if (parsed.len == 0) { return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("parameter '"), 0xfe10, {.d_s = name}}, {_S("' not provided"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } _result_string _t2 = {0}; _result_ok(&(string[]) { (*(string*)array_get(parsed, 0)) }, (_result*)(&_t2), sizeof(string)); return _t2; } string flag__FlagParser_string(flag__FlagParser* fs, string name, u8 abbr, string sdefault, string usage, flag__FlagConfig c) { _result_string _t1 = flag__FlagParser_string_opt(fs, name, abbr, usage, c); if (_t1.is_error) { IError err = _t1.err; return sdefault; } string value = (*(string*)_t1.data); return value; } string flag__FlagParser_usage(flag__FlagParser* fs) { bool positive_min_arg = (fs->min_free_args > 0); bool positive_max_arg = (fs->max_free_args > 0 && fs->max_free_args != 4048); bool no_arguments = (fs->min_free_args == 0 && fs->max_free_args == 0); string adesc = (fs->args_description.len > 0 ? (fs->args_description) : (_S("[ARGS]"))); if (no_arguments) { adesc = _S(""); } Array_string use = __new_array_with_default(0, 0, sizeof(string), 0); if ((fs->application_version).len != 0) { array_push((array*)&use, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fs->application_name}}, {_S(" "), 0xfe10, {.d_s = fs->application_version}}, {_SLIT0, 0, { .d_c = 0 }}})) })); array_push((array*)&use, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_flag__underline}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if (fs->usage_examples.len == 0) { array_push((array*)&use, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_S("Usage: "), 0xfe10, {.d_s = fs->application_name}}, {_S(" [options] "), 0xfe10, {.d_s = adesc}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else { for (int i = 0; i < fs->usage_examples.len; ++i) { string example = ((string*)fs->usage_examples.data)[i]; if (i == 0) { array_push((array*)&use, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_S("Usage: "), 0xfe10, {.d_s = fs->application_name}}, {_S(" "), 0xfe10, {.d_s = example}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else { array_push((array*)&use, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_S(" or: "), 0xfe10, {.d_s = fs->application_name}}, {_S(" "), 0xfe10, {.d_s = example}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } } array_push((array*)&use, _MOV((string[]){ _S("") })); if ((fs->application_description).len != 0) { array_push((array*)&use, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("Description: "), 0xfe10, {.d_s = fs->application_description}}, {_SLIT0, 0, { .d_c = 0 }}})) })); array_push((array*)&use, _MOV((string[]){ _S("") })); } if (positive_min_arg || positive_max_arg || no_arguments) { if (no_arguments) { array_push((array*)&use, _MOV((string[]){ _S("This application does not expect any arguments") })); array_push((array*)&use, _MOV((string[]){ _S("") })); } else { Array_string s = __new_array_with_default(0, 0, sizeof(string), 0); if (positive_min_arg) { array_push((array*)&s, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("at least "), 0xfe07, {.d_i32 = fs->min_free_args}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if (positive_max_arg) { array_push((array*)&s, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("at most "), 0xfe07, {.d_i32 = fs->max_free_args}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if (positive_min_arg && positive_max_arg && fs->min_free_args == fs->max_free_args) { s = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){str_intp(2, _MOV((StrIntpData[]){{_S("exactly "), 0xfe07, {.d_i32 = fs->min_free_args}}, {_SLIT0, 0, { .d_c = 0 }}}))})); } string sargs = Array_string_join(s, _S(" and ")); array_push((array*)&use, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("The arguments should be "), 0xfe10, {.d_s = sargs}}, {_S(" in number."), 0, { .d_c = 0 }}})) })); array_push((array*)&use, _MOV((string[]){ _S("") })); } } if (fs->flags.len > 0) { array_push((array*)&use, _MOV((string[]){ _S("Options:") })); for (int _t16 = 0; _t16 < fs->flags.len; ++_t16) { flag__Flag f = ((flag__Flag*)fs->flags.data)[_t16]; Array_string onames = __new_array_with_default(0, 0, sizeof(string), 0); if (f.abbr != 0) { array_push((array*)&onames, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-"), 0xfe10, {.d_s = u8_ascii_str(f.abbr)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if ((f.name).len != 0) { if (!string_contains(f.val_desc, _S(""))) { array_push((array*)&onames, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_S("--"), 0xfe10, {.d_s = f.name}}, {_S(" "), 0xfe10, {.d_s = f.val_desc}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else { array_push((array*)&onames, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("--"), 0xfe10, {.d_s = f.name}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } string option_names = string__plus(_S(" "), Array_string_join(onames, _S(", "))); string xspace = _S(""); if (option_names.len > (int)(_const_flag__space.len - 2)) { xspace = str_intp(2, _MOV((StrIntpData[]){{_S("\n"), 0xfe10, {.d_s = _const_flag__space}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { xspace = string_substr(_const_flag__space, option_names.len, 2147483647); } string fdesc = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = option_names}}, {_SLIT0, 0xfe10, {.d_s = xspace}}, {_SLIT0, 0xfe10, {.d_s = f.usage}}, {_SLIT0, 0, { .d_c = 0 }}})); array_push((array*)&use, _MOV((string[]){ string_clone(fdesc) })); } } for (int _t21 = 0; _t21 < fs->footers.len; ++_t21) { string footer = ((string*)fs->footers.data)[_t21]; array_push((array*)&use, _MOV((string[]){ string_clone(footer) })); } return string_replace(Array_string_join(use, _S("\n")), _S("- ,"), _S(" ")); } VV_LOC bool semver__compare_eq(semver__Version v1, semver__Version v2) { return v1.major == v2.major && v1.minor == v2.minor && v1.patch == v2.patch && string__eq(v1.prerelease, v2.prerelease); } VV_LOC bool semver__compare_lt(semver__Version v1, semver__Version v2) { bool _t2 = true; return ((_t2 == (v1.major > v2.major))? (false) : (_t2 == (v1.major < v2.major))? (true) : (_t2 == (v1.minor > v2.minor))? (false) : (_t2 == (v1.minor < v2.minor))? (true) : (v1.patch < v2.patch)); } VV_LOC semver__RawVersion semver__parse(string input) { string raw_version = input; string prerelease = _S(""); string metadata = _S(""); int plus_idx = string_last_index_u8(raw_version, '+'); if (plus_idx > 0) { metadata = string_substr(raw_version, ((int)(plus_idx + 1)), 2147483647); raw_version = string_substr(raw_version, 0, plus_idx); } _option_int _t1 = string_index(raw_version, _S("-")); if (_t1.state != 0) { IError err = _t1.err; *(int*) _t1.data = -1; } int hyphen_idx = (*(int*)_t1.data); if (hyphen_idx > 0) { prerelease = string_substr(raw_version, ((int)(hyphen_idx + 1)), 2147483647); raw_version = string_substr(raw_version, 0, hyphen_idx); } Array_string raw_ints = string_split(raw_version, _S(".")); return ((semver__RawVersion){.prerelease = prerelease,.metadata = metadata,.raw_ints = raw_ints,}); } VV_LOC bool semver__RawVersion_is_valid(semver__RawVersion ver) { if (ver.raw_ints.len != 3) { return false; } return semver__is_valid_number((*(string*)array_get(ver.raw_ints, _const_semver__ver_major))) && semver__is_valid_number((*(string*)array_get(ver.raw_ints, _const_semver__ver_minor))) && semver__is_valid_number((*(string*)array_get(ver.raw_ints, _const_semver__ver_patch))) && semver__is_valid_string(ver.prerelease) && semver__is_valid_string(ver.metadata); } VV_LOC _option_semver__Version semver__RawVersion_validate(semver__RawVersion raw_ver) { if (!semver__RawVersion_is_valid(raw_ver)) { return (_option_semver__Version){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_semver__Version _t2; _option_ok(&(semver__Version[]) { semver__RawVersion_to_version(raw_ver) }, (_option*)(&_t2), sizeof(semver__Version)); return _t2; } VV_LOC semver__Version semver__RawVersion_to_version(semver__RawVersion raw_ver) { return ((semver__Version){.major = string_int((*(string*)array_get(raw_ver.raw_ints, _const_semver__ver_major))),.minor = string_int((*(string*)array_get(raw_ver.raw_ints, _const_semver__ver_minor))),.patch = string_int((*(string*)array_get(raw_ver.raw_ints, _const_semver__ver_patch))),.prerelease = raw_ver.prerelease,.metadata = raw_ver.metadata,}); } string semver__EmptyInputError_msg(semver__EmptyInputError err) { return _S("Empty input"); } string semver__InvalidVersionFormatError_msg(semver__InvalidVersionFormatError err) { return str_intp(2, _MOV((StrIntpData[]){{_S("Invalid version format for input \""), 0xfe10, {.d_s = err.input}}, {_S("\""), 0, { .d_c = 0 }}})); } _result_semver__Version semver__from(string input) { if (input.len == 0) { return (_result_semver__Version){ .is_error=true, .err=I_semver__EmptyInputError_to_Interface_IError(((semver__EmptyInputError*)memdup(&(semver__EmptyInputError){.Error = ((Error){E_STRUCT}),}, sizeof(semver__EmptyInputError)))), .data={E_STRUCT} }; } semver__RawVersion raw_version = semver__parse(input); _option_semver__Version _t3 = semver__RawVersion_validate(raw_version); if (_t3.state != 0) { IError err = _t3.err; return (_result_semver__Version){ .is_error=true, .err=I_semver__InvalidVersionFormatError_to_Interface_IError(((semver__InvalidVersionFormatError*)memdup(&(semver__InvalidVersionFormatError){.Error = ((Error){E_STRUCT}),.input = input,}, sizeof(semver__InvalidVersionFormatError)))), .data={E_STRUCT} }; } _result_semver__Version _t2 = {0}; _result_ok(&(semver__Version[]) { (*(semver__Version*)_t3.data) }, (_result*)(&_t2), sizeof(semver__Version)); return _t2; } bool semver__Version__eq(semver__Version v1, semver__Version v2) { return semver__compare_eq(v1, v2); } bool semver__Version__lt(semver__Version v1, semver__Version v2) { return semver__compare_lt(v1, v2); } string semver__Version_str(semver__Version ver) { string common_string = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ver.major}}, {_S("."), 0xfe07, {.d_i32 = ver.minor}}, {_S("."), 0xfe07, {.d_i32 = ver.patch}}, {_SLIT0, 0, { .d_c = 0 }}})); string prerelease_string = (ver.prerelease.len > 0 ? (str_intp(2, _MOV((StrIntpData[]){{_S("-"), 0xfe10, {.d_s = ver.prerelease}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (_S(""))); string metadata_string = (ver.metadata.len > 0 ? (str_intp(2, _MOV((StrIntpData[]){{_S("+"), 0xfe10, {.d_s = ver.metadata}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (_S(""))); return str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = common_string}}, {_SLIT0, 0xfe10, {.d_s = prerelease_string}}, {_SLIT0, 0xfe10, {.d_s = metadata_string}}, {_SLIT0, 0, { .d_c = 0 }}})); } VV_LOC bool semver__is_valid_string(string input) { for (int _t1 = 0; _t1 < input.len; ++_t1) { u8 c = input.str[_t1]; if (!(u8_is_letter(c) || u8_is_digit(c) || c == '.' || c == '-')) { return false; } } return true; } VV_LOC bool semver__is_valid_number(string input) { for (int _t1 = 0; _t1 < input.len; ++_t1) { u8 c = input.str[_t1]; if (!u8_is_digit(c)) { return false; } } return true; } string os__getenv(string key) { _option_string _t2 = os__getenv_opt(key); if (_t2.state != 0) { IError err = _t2.err; *(string*) _t2.data = _S(""); } return (*(string*)_t2.data); } _option_string os__getenv_opt(string key) { bool os__getenv_opt_defer_0 = false; u16* kw; { // Unsafe block #if defined(_WIN32) { kw = string_to_wide(key); os__getenv_opt_defer_0 = true; voidptr s = _wgetenv(kw); if (s == 0) { _option_string _t2 = (_option_string){ .state=2, .err=_const_none__, .data={E_STRUCT} }; // Defer begin if (os__getenv_opt_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(kw))); #endif } // Defer end return _t2; } _option_string _t3; _option_ok(&(string[]) { string_from_wide(s) }, (_option*)(&_t3), sizeof(string)); // Defer begin if (os__getenv_opt_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(kw))); #endif } // Defer end return _t3; } #else { char* s = getenv(((char*)(key.str))); if (s == ((void*)0)) { _option_string _t4 = (_option_string){ .state=2, .err=_const_none__, .data={E_STRUCT} }; // Defer begin if (os__getenv_opt_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(kw))); #endif } // Defer end return _t4; } _option_string _t5; _option_ok(&(string[]) { cstring_to_vstring(s) }, (_option*)(&_t5), sizeof(string)); // Defer begin if (os__getenv_opt_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(kw))); #endif } // Defer end return _t5; } #endif } return (_option_string){.state=2, .err=_const_none__, .data={E_STRUCT}}; } int os__setenv(string name, string value, bool overwrite) { bool os__setenv_defer_0 = false; u16* format; #if defined(_WIN32) { format = string_to_wide(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = name}}, {_S("="), 0xfe10, {.d_s = value}}, {_SLIT0, 0, { .d_c = 0 }}}))); os__setenv_defer_0 = true; if (overwrite) { { // Unsafe block int _t2 = _wputenv(format); // Defer begin if (os__setenv_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(format))); #endif } // Defer end return _t2; } } else { if (os__getenv(name).len == 0) { { // Unsafe block int _t3 = _wputenv(format); // Defer begin if (os__setenv_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(format))); #endif } // Defer end return _t3; } } } int _t4 = -1; // Defer begin if (os__setenv_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(format))); #endif } // Defer end return _t4; } #else { { // Unsafe block int _t5 = setenv(((char*)(name.str)), ((char*)(value.str)), overwrite); // Defer begin if (os__setenv_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(format))); #endif } // Defer end return _t5; } } #endif return 0; } Map_string_string os__environ(void) { Map_string_string res = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; #if defined(_WIN32) { u16* estrings = GetEnvironmentStringsW(); string eline = _S(""); for (u16* c = estrings; *c != 0U; ) { eline = string_from_wide(c); int eq_index = string_index_u8(eline, '='); if (eq_index > 0) { map_set(&res, &(string[]){string_substr(eline, 0, eq_index)}, &(string[]) { string_substr(eline, (int)(eq_index + 1), 2147483647) }); } { // Unsafe block c = c + eline.len + 1; } } FreeEnvironmentStringsW(estrings); } #else { char** start = ((char**)(((voidptr)(environ)))); int i = 0; for (;;) { char* x = start[i]; if (x == 0) { break; } string eline = cstring_to_vstring(x); int eq_index = string_index_u8(eline, '='); if (eq_index > 0) { map_set(&res, &(string[]){string_substr(eline, 0, eq_index)}, &(string[]) { string_substr(eline, (int)(eq_index + 1), 2147483647) }); } i++; } } #endif return res; } #if !defined(_WIN32) #endif #if defined(_WIN32) #endif int os__fd_close(int fd) { if (fd == -1) { return 0; } return close(fd); } VV_LOC string os__NotExpected_msg(os__NotExpected err) { return err.cause; } VV_LOC int os__NotExpected_code(os__NotExpected err) { return err.code; } _result_os__File os__create(string path) { _result_FILE_ptr _t1 = os__vfopen(path, _S("wb")); if (_t1.is_error) { _result_os__File _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } FILE* cfile = (*(FILE**)_t1.data); int fd = os__fileno(cfile); _result_os__File _t3 = {0}; _result_ok(&(os__File[]) { ((os__File){.cfile = (voidptr)cfile,.fd = fd,.is_opened = true,}) }, (_result*)(&_t3), sizeof(os__File)); return _t3; } _result_int os__File_writeln(os__File* f, string s) { if (!f->is_opened) { return (_result_int){ .is_error=true, .err=os__error_file_not_opened(), .data={E_STRUCT} }; } _result_int _t2 = os__File_write_string(f, s); if (_t2.is_error) { _result_int _t3 = {0}; _t3.is_error = true; _t3.err = _t2.err; return _t3; } int written = (*(int*)_t2.data); int x = fputs("\n", f->cfile); if (x < 0) { return (_result_int){ .is_error=true, .err=_v_error(_S("could not add newline")), .data={E_STRUCT} }; } _result_int _t5 = {0}; _result_ok(&(int[]) { (int)(written + 1) }, (_result*)(&_t5), sizeof(int)); return _t5; } _result_int os__File_write_string(os__File* f, string s) { _result_void _t1 = os__File_write_full_buffer(f, s.str, ((usize)(s.len))); if (_t1.is_error) { _result_int _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } ; _result_int _t3 = {0}; _result_ok(&(int[]) { s.len }, (_result*)(&_t3), sizeof(int)); return _t3; } _result_void os__File_write_full_buffer(os__File* f, voidptr buffer, usize buffer_len) { if (buffer_len <= ((usize)(0))) { return (_result_void){0}; } if (!f->is_opened) { return (_result_void){ .is_error=true, .err=os__error_file_not_opened(), .data={E_STRUCT} }; } u8* ptr = ((u8*)(buffer)); i64 remaining_bytes = ((i64)(buffer_len)); for (;;) { if (!(remaining_bytes > 0)) break; { // Unsafe block i64 x = ((i64)(fwrite(ptr, 1, remaining_bytes, f->cfile))); ptr += x; remaining_bytes -= x; if (x <= 0) { return (_result_void){ .is_error=true, .err=_v_error(_S("C.fwrite returned 0")), .data={E_STRUCT} }; } } } return (_result_void){0}; } VV_LOC _result_int os__fread(voidptr ptr, int item_size, int items, FILE* stream) { int nbytes = ((int)(fread(ptr, item_size, items, stream))); if (nbytes <= 0) { if (feof(stream) != 0) { return (_result_int){ .is_error=true, .err=I_os__Eof_to_Interface_IError(((os__Eof*)memdup(&(os__Eof){.Error = ((Error){E_STRUCT}),}, sizeof(os__Eof)))), .data={E_STRUCT} }; } if (ferror(stream) != 0) { return (_result_int){ .is_error=true, .err=_v_error(_S("file read error")), .data={E_STRUCT} }; } } _result_int _t3 = {0}; _result_ok(&(int[]) { nbytes }, (_result*)(&_t3), sizeof(int)); return _t3; } string os__FileNotOpenedError_msg(os__FileNotOpenedError err) { return _S("os: file not opened"); } string os__SizeOfTypeIs0Error_msg(os__SizeOfTypeIs0Error err) { return _S("os: size of type is 0"); } VV_LOC IError os__error_file_not_opened(void) { return I_os__FileNotOpenedError_to_Interface_IError(((os__FileNotOpenedError*)memdup(&(os__FileNotOpenedError){.Error = ((Error){E_STRUCT}),}, sizeof(os__FileNotOpenedError)))); } bool os__is_abs_path(string path) { if ((path).len == 0) { return false; } #if defined(_WIN32) { return os__is_unc_path(path) || os__is_drive_rooted(path) || os__is_normal_path(path); } #endif return string_at(path, 0) == _const_os__fslash; } string os__abs_path(string path) { string wd = os__getwd(); if ((path).len == 0) { return wd; } string npath = os__norm_path(path); if (_SLIT_EQ(npath.str, npath.len, ".")) { return wd; } if (!os__is_abs_path(npath)) { strings__Builder sb = strings__new_builder(npath.len); strings__Builder_write_string(&sb, wd); strings__Builder_write_string(&sb, _const_os__path_separator); strings__Builder_write_string(&sb, npath); return os__norm_path(strings__Builder_str(&sb)); } return npath; } string os__norm_path(string path) { if ((path).len == 0) { return _const_os__dot_str; } bool rooted = os__is_abs_path(path); int volume_len = os__win_volume_len(path); string volume = string_substr(path, 0, volume_len); if (volume_len != 0 && string_contains(volume, _const_os__fslash_str)) { volume = string_replace(volume, _const_os__fslash_str, _const_os__path_separator); } string cpath = os__clean_path(string_substr(path, volume_len, 2147483647)); if ((cpath).len == 0 && volume_len == 0) { return _const_os__dot_str; } Array_string spath = string_split(cpath, _const_os__path_separator); if (!(Array_string_contains(spath, _S("..")))) { return (volume_len != 0 ? (string__plus(volume, cpath)) : (cpath)); } int spath_len = spath.len; strings__Builder sb = strings__new_builder(cpath.len); if (rooted) { strings__Builder_write_string(&sb, _const_os__path_separator); } Array_string new_path = __new_array_with_default(0, spath_len, sizeof(string), 0); int backlink_count = 0; for (int i = (int)(spath_len - 1); i >= 0; i--) { string part = ((string*)spath.data)[i]; if ((part).len == 0) { continue; } if (_SLIT_EQ(part.str, part.len, "..")) { backlink_count++; continue; } if (backlink_count != 0) { backlink_count--; continue; } array_prepend(&new_path, &(string[]){part}); } if (backlink_count != 0 && !rooted) { for (int i = 0; i < backlink_count; ++i) { strings__Builder_write_string(&sb, _const_os__dot_dot); if (new_path.len == 0 && i == (int)(backlink_count - 1)) { break; } strings__Builder_write_string(&sb, _const_os__path_separator); } } strings__Builder_write_string(&sb, Array_string_join(new_path, _const_os__path_separator)); string res = strings__Builder_str(&sb); if (res.len == 0) { if (volume_len != 0) { return volume; } if (!rooted) { return _const_os__dot_str; } return _const_os__path_separator; } if (volume_len != 0) { return string__plus(volume, res); } return res; } VV_LOC string os__clean_path(string path) { if ((path).len == 0) { return _const_os__empty_str; } strings__Builder sb = strings__new_builder(path.len); strings__textscanner__TextScanner sc = strings__textscanner__new(path); for (;;) { if (!(strings__textscanner__TextScanner_next(&sc) != -1)) break; u8 curr = ((u8)(strings__textscanner__TextScanner_current(&sc))); int back = strings__textscanner__TextScanner_peek_back(&sc); int peek = strings__textscanner__TextScanner_peek(&sc); if (back != -1 && os__is_slash(((u8)(back))) && os__is_slash(curr)) { continue; } if (os__is_curr_dir_ref(back, curr, peek)) { if (peek != -1 && os__is_slash(((u8)(peek)))) { strings__textscanner__TextScanner_skip_n(&sc, 1); } continue; } #if defined(_WIN32) { if (curr == _const_os__fslash) { strings__Builder_write_u8(&sb, _const_os__bslash); continue; } } #endif strings__Builder_write_u8(&sb, ((u8)(strings__textscanner__TextScanner_current(&sc)))); } string res = strings__Builder_str(&sb); if (res.len > 1 && os__is_slash(string_at(res, (int)(res.len - 1)))) { return string_substr(res, 0, (int)(res.len - 1)); } return res; } VV_LOC int os__win_volume_len(string path) { #if !defined(_WIN32) { return 0; } #endif int plen = path.len; if (plen < 2) { return 0; } if (os__has_drive_letter(path)) { return 2; } if (plen >= 5 && os__starts_w_slash_slash(path) && !os__is_slash(string_at(path, 2))) { for (int i = 3; i < plen; i++) { if (os__is_slash(string_at(path, i))) { if ((int)(i + 1) >= plen || os__is_slash(string_at(path, (int)(i + 1)))) { break; } i++; for (; i < plen; i++) { if (os__is_slash(string_at(path, i))) { return i; } } return i; } } } return 0; } VV_LOC bool os__is_slash(u8 b) { #if defined(_WIN32) { return b == _const_os__bslash || b == _const_os__fslash; } #endif return b == _const_os__fslash; } VV_LOC bool os__is_unc_path(string path) { return os__win_volume_len(path) >= 5 && os__starts_w_slash_slash(path); } VV_LOC bool os__has_drive_letter(string path) { return path.len >= 2 && u8_is_letter(string_at(path, 0)) && string_at(path, 1) == ':'; } VV_LOC bool os__starts_w_slash_slash(string path) { return path.len >= 2 && os__is_slash(string_at(path, 0)) && os__is_slash(string_at(path, 1)); } VV_LOC bool os__is_drive_rooted(string path) { return path.len >= 3 && os__has_drive_letter(path) && os__is_slash(string_at(path, 2)); } VV_LOC bool os__is_normal_path(string path) { int plen = path.len; if (plen == 0) { return false; } return (plen == 1 && os__is_slash(string_at(path, 0))) || (plen >= 2 && os__is_slash(string_at(path, 0)) && !os__is_slash(string_at(path, 1))); } VV_LOC bool os__is_curr_dir_ref(int byte_one, int byte_two, int byte_three) { if (((u8)(byte_two)) != _const_os__dot) { return false; } return (byte_one < 0 || os__is_slash(((u8)(byte_one)))) && (byte_three < 0 || os__is_slash(((u8)(byte_three)))); } #if defined(__FreeBSD__) || defined(__OpenBSD__) #endif _result_Array_u8 os__read_bytes(string path) { bool os__read_bytes_defer_0 = false; FILE* fp; _result_FILE_ptr _t1 = os__vfopen(path, _S("rb")); if (_t1.is_error) { _result_Array_u8 _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } fp = (*(FILE**)_t1.data); os__read_bytes_defer_0 = true; _result_int _t3 = os__find_cfile_size(fp); if (_t3.is_error) { // Defer begin if (os__read_bytes_defer_0) { fclose(fp); } // Defer end _result_Array_u8 _t4 = {0}; _t4.is_error = true; _t4.err = _t3.err; return _t4; } int fsize = (*(int*)_t3.data); if (fsize == 0) { _result_strings__Builder _t5 = os__slurp_file_in_builder(fp); if (_t5.is_error) { // Defer begin if (os__read_bytes_defer_0) { fclose(fp); } // Defer end _result_Array_u8 _t6 = {0}; _t6.is_error = true; _t6.err = _t5.err; return _t6; } strings__Builder sb = (*(strings__Builder*)_t5.data); _result_Array_u8 _t7 = {0}; _result_ok(&(Array_u8[]) { strings__Builder_reuse_as_plain_u8_array(&sb) }, (_result*)(&_t7), sizeof(Array_u8)); // Defer begin if (os__read_bytes_defer_0) { fclose(fp); } // Defer end return _t7; } Array_u8 res = __new_array_with_default(fsize, 0, sizeof(u8), 0); int nr_read_elements = ((int)(fread(res.data, 1, fsize, fp))); if (nr_read_elements == 0 && fsize > 0) { _result_Array_u8 _t8 = (_result_Array_u8){ .is_error=true, .err=_v_error(_S("fread failed")), .data={E_STRUCT} }; // Defer begin if (os__read_bytes_defer_0) { fclose(fp); } // Defer end return _t8; } array_trim(&res, nr_read_elements); _result_Array_u8 _t9 = {0}; _result_ok(&(Array_u8[]) { res }, (_result*)(&_t9), sizeof(Array_u8)); // Defer begin if (os__read_bytes_defer_0) { fclose(fp); } // Defer end return _t9; } VV_LOC _result_int os__find_cfile_size(FILE* fp) { int cseek = fseek(fp, 0, SEEK_END); isize raw_fsize = ftell(fp); if (raw_fsize != 0 && cseek != 0) { return (_result_int){ .is_error=true, .err=_v_error(_S("fseek failed")), .data={E_STRUCT} }; } if (cseek != 0 && raw_fsize < 0) { return (_result_int){ .is_error=true, .err=_v_error(_S("ftell failed")), .data={E_STRUCT} }; } int len = ((int)(raw_fsize)); if (((i64)(len)) < raw_fsize) { return (_result_int){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("int("), 0xfe09, {.d_i64 = raw_fsize}}, {_S(") cast results in "), 0xfe07, {.d_i32 = len}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } rewind(fp); _result_int _t4 = {0}; _result_ok(&(int[]) { len }, (_result*)(&_t4), sizeof(int)); return _t4; } VV_LOC _result_strings__Builder os__slurp_file_in_builder(FILE* fp) { Array_fixed_u8_4096 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; strings__Builder sb = strings__new_builder(_const_os__buf_size); for (;;) { _result_int _t1 = os__fread(&buf[0], 1, _const_os__buf_size, fp); if (_t1.is_error) { IError err = _t1.err; if ((err)._typ == _IError_os__Eof_index) { break; } strings__Builder_free(&sb); return (_result_strings__Builder){ .is_error=true, .err=err, .data={E_STRUCT} }; } int read_bytes = (*(int*)_t1.data); strings__Builder_write_ptr(&sb, &buf[0], read_bytes); } _result_strings__Builder _t3 = {0}; _result_ok(&(strings__Builder[]) { sb }, (_result*)(&_t3), sizeof(strings__Builder)); return _t3; } _result_string os__read_file(string path) { bool os__read_file_defer_0 = false; FILE* fp; string mode = _S("rb"); _result_FILE_ptr _t1 = os__vfopen(path, mode); if (_t1.is_error) { _result_string _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } fp = (*(FILE**)_t1.data); os__read_file_defer_0 = true; _result_int _t3 = os__find_cfile_size(fp); if (_t3.is_error) { // Defer begin if (os__read_file_defer_0) { fclose(fp); } // Defer end _result_string _t4 = {0}; _t4.is_error = true; _t4.err = _t3.err; return _t4; } int allocate = (*(int*)_t3.data); if (allocate == 0) { _result_strings__Builder _t5 = os__slurp_file_in_builder(fp); if (_t5.is_error) { // Defer begin if (os__read_file_defer_0) { fclose(fp); } // Defer end _result_string _t6 = {0}; _t6.is_error = true; _t6.err = _t5.err; return _t6; } strings__Builder sb = (*(strings__Builder*)_t5.data); string res = strings__Builder_str(&sb); strings__Builder_free(&sb); _result_string _t7 = {0}; _result_ok(&(string[]) { res }, (_result*)(&_t7), sizeof(string)); // Defer begin if (os__read_file_defer_0) { fclose(fp); } // Defer end return _t7; } { // Unsafe block u8* str = malloc_noscan((int)(allocate + 1)); int nelements = ((int)(fread(str, 1, allocate, fp))); int is_eof = ((int)(feof(fp))); int is_error = ((int)(ferror(fp))); if (is_eof == 0 && is_error != 0) { _v_free(str); _result_string _t8 = (_result_string){ .is_error=true, .err=_v_error(_S("fread failed")), .data={E_STRUCT} }; // Defer begin if (os__read_file_defer_0) { fclose(fp); } // Defer end return _t8; } str[nelements] = 0; if (nelements == 0) { _result_string _t9 = {0}; _result_ok(&(string[]) { u8_vstring(str) }, (_result*)(&_t9), sizeof(string)); // Defer begin if (os__read_file_defer_0) { fclose(fp); } // Defer end return _t9; } _result_string _t10 = {0}; _result_ok(&(string[]) { u8_vstring_with_len(str, nelements) }, (_result*)(&_t10), sizeof(string)); // Defer begin if (os__read_file_defer_0) { fclose(fp); } // Defer end return _t10; } return (_result_string){0}; } u64 os__file_size(string path) { _result_os__Stat _t1 = os__stat(path); if (_t1.is_error) { IError err = _t1.err; eprintln(string__plus(_S("os.file_size() Cannot determine file-size: "), os__posix_get_error_msg(errno))); return 0U; } os__Stat attr = (*(os__Stat*)_t1.data); return attr.size; } _result_void os__cp(string src, string dst) { #if defined(_WIN32) { string w_src = string_replace(src, _S("/"), _S("\\")); string w_dst = string_replace(dst, _S("/"), _S("\\")); if (CopyFile(string_to_wide(w_src), string_to_wide(w_dst), false) == 0) { int code = ((int)(GetLastError())); return (_result_void){ .is_error=true, .err=os__error_win32(((os__SystemError){.msg = str_intp(3, _MOV((StrIntpData[]){{_S("failed to copy "), 0xfe10, {.d_s = src}}, {_S(" to "), 0xfe10, {.d_s = dst}}, {_SLIT0, 0, { .d_c = 0 }}})),.code = code,})), .data={E_STRUCT} }; } } #else { int fp_from = open(((char*)(src.str)), O_RDONLY, 0); if (fp_from < 0) { return (_result_void){ .is_error=true, .err=error_with_code(str_intp(2, _MOV((StrIntpData[]){{_S("cp: failed to open "), 0xfe10, {.d_s = src}}, {_SLIT0, 0, { .d_c = 0 }}})), ((int)(fp_from))), .data={E_STRUCT} }; } int fp_to = open(((char*)(dst.str)), ((O_WRONLY | O_CREAT) | O_TRUNC), (S_IWUSR | S_IRUSR)); if (fp_to < 0) { close(fp_from); return (_result_void){ .is_error=true, .err=error_with_code(str_intp(3, _MOV((StrIntpData[]){{_S("cp (permission): failed to write to "), 0xfe10, {.d_s = dst}}, {_S(" (fp_to: "), 0xfe07, {.d_i32 = fp_to}}, {_S(")"), 0, { .d_c = 0 }}})), ((int)(fp_to))), .data={E_STRUCT} }; } Array_fixed_u8_1024 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int count = 0; for (;;) { count = read(fp_from, &buf[0], sizeof(Array_fixed_u8_1024)); if (count == 0) { break; } if (write(fp_to, &buf[0], count) < 0) { close(fp_to); close(fp_from); return (_result_void){ .is_error=true, .err=error_with_code(str_intp(2, _MOV((StrIntpData[]){{_S("cp: failed to write to "), 0xfe10, {.d_s = dst}}, {_SLIT0, 0, { .d_c = 0 }}})), ((int)(-1))), .data={E_STRUCT} }; } } _result_os__Stat _t6 = os__stat(src); if (_t6.is_error) { _result_void _t7 = {0}; _t7.is_error = true; _t7.err = _t6.err; return _t7; } os__Stat from_attr = (*(os__Stat*)_t6.data); if (chmod(((char*)(dst.str)), from_attr.mode) < 0) { close(fp_to); close(fp_from); return (_result_void){ .is_error=true, .err=error_with_code(str_intp(2, _MOV((StrIntpData[]){{_S("failed to set permissions for "), 0xfe10, {.d_s = dst}}, {_SLIT0, 0, { .d_c = 0 }}})), ((int)(-1))), .data={E_STRUCT} }; } close(fp_to); close(fp_from); } #endif return (_result_void){0}; } _result_FILE_ptr os__vfopen(string path, string mode) { if ((path).len == 0) { return (_result_FILE_ptr){ .is_error=true, .err=_v_error(_S("vfopen called with \"\"")), .data={E_STRUCT} }; } voidptr fp = ((void*)0); #if defined(_WIN32) { fp = _wfopen(string_to_wide(path), string_to_wide(mode)); } #else { fp = fopen(((char*)(path.str)), ((char*)(mode.str))); } #endif if (isnil(((voidptr)(fp)))) { return (_result_FILE_ptr){ .is_error=true, .err=os__error_posix(((os__SystemError){.msg = str_intp(2, _MOV((StrIntpData[]){{_S("failed to open file \""), 0xfe10, {.d_s = path}}, {_S("\""), 0, { .d_c = 0 }}})),.code = _const_os__error_code_not_set,})), .data={E_STRUCT} }; } else { _result_FILE_ptr _t4 = {0}; _result_ok(&(FILE*[]) { fp }, (_result*)(&_t4), sizeof(FILE*)); return _t4; } return (_result_FILE_ptr){0}; } int os__fileno(voidptr cfile) { #if defined(_WIN32) { return _fileno(cfile); } #else { FILE* cfile_casted = ((FILE*)(((void*)0))); cfile_casted = cfile; return fileno(cfile_casted); } #endif return 0; } VV_LOC voidptr os__vpopen(string path) { #if defined(_WIN32) { string mode = _S("rb"); u16* wpath = string_to_wide(path); return _wpopen(wpath, string_to_wide(mode)); } #else { u8* cpath = path.str; return popen(((char*)(cpath)), "r"); } #endif return 0; } VV_LOC multi_return_int_bool os__posix_wait4_to_exit_status(int waitret) { #if defined(_WIN32) { return (multi_return_int_bool){.arg0=waitret, .arg1=false}; } #else { int ret = 0; bool is_signaled = true; if (WIFEXITED(waitret)) { ret = WEXITSTATUS(waitret); is_signaled = false; } else if (WIFSIGNALED(waitret)) { ret = WTERMSIG(waitret); is_signaled = true; } return (multi_return_int_bool){.arg0=ret, .arg1=is_signaled}; } #endif return (multi_return_int_bool){0}; } string os__posix_get_error_msg(int code) { char* ptr_text = strerror(code); if (ptr_text == 0) { return _S(""); } return tos3(ptr_text); } VV_LOC int os__vpclose(voidptr f) { #if defined(_WIN32) { return _pclose(f); } #else { multi_return_int_bool mr_9767 = os__posix_wait4_to_exit_status(pclose(f)); int ret = mr_9767.arg0; return ret; } #endif return 0; } int os__system(string cmd) { int ret = 0; #if defined(_WIN32) { string wcmd = (cmd.len > 1 && string_at(cmd, 0) == '"' && string_at(cmd, 1) != '"' ? (str_intp(2, _MOV((StrIntpData[]){{_S("\""), 0xfe10, {.d_s = cmd}}, {_S("\""), 0, { .d_c = 0 }}}))) : (cmd)); flush_stdout(); flush_stderr(); { // Unsafe block ret = _wsystem(string_to_wide(wcmd)); } } #else { #if defined(__TARGET_IOS__) { { // Unsafe block Array_u8_ptr arg = new_array_from_c_array(4, 4, sizeof(u8*), _MOV((u8*[4]){"/bin/sh", "-c", ((u8*)(cmd.str)), 0})); int pid = 0; ret = posix_spawn(&pid, "/bin/sh", 0, 0, arg.data, 0); int status = 0; ret = waitpid(pid, &status, 0); if (WIFEXITED(status)) { ret = WEXITSTATUS(status); } } } #else { { // Unsafe block ret = system(((char*)(cmd.str))); } } #endif } #endif if (ret == -1) { os__print_c_errno(); } #if !defined(_WIN32) { multi_return_int_bool mr_10811 = os__posix_wait4_to_exit_status(ret); int pret = mr_10811.arg0; bool is_signaled = mr_10811.arg1; ret = pret; if (is_signaled) { eprintln(string__plus(string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("Terminated by signal "), 0x4fe27, {.d_i32 = pret}}, {_S(" ("), 0, { .d_c = 0 }}})), os__sigint_to_signal_name(pret)), _S(")"))); ret = (int)(pret + 128); } } #endif return ret; } bool os__exists(string path) { #if defined(_WIN32) { string p = string_replace(path, _S("/"), _S("\\")); return _waccess(string_to_wide(p), _const_os__f_ok) != -1; } #else { return access(((char*)(path.str)), _const_os__f_ok) != -1; } #endif return 0; } bool os__is_executable(string path) { #if defined(_WIN32) { string p = os__real_path(path); return os__exists(p) && (string_ends_with(p, _S(".exe")) || string_ends_with(p, _S(".bat")) || string_ends_with(p, _S(".cmd"))); } #endif #if defined(__sun) { _result_os__Stat _t4 = os__stat(path); if (_t4.is_error) { IError err = _t4.err; return false; } os__Stat attr = (*(os__Stat*)_t4.data); return ((((int)(attr.mode)) & (((_const_os__s_ixusr | _const_os__s_ixgrp) | _const_os__s_ixoth)))) != 0; } #endif return access(((char*)(path.str)), _const_os__x_ok) != -1; } bool os__is_readable(string path) { #if defined(_WIN32) { string p = string_replace(path, _S("/"), _S("\\")); u16* wp = string_to_wide(p); bool res = _waccess(wp, _const_os__r_ok) != -1; _v_free(wp); string_free(&p); return res; } #else { return access(((char*)(path.str)), _const_os__r_ok) != -1; } #endif return 0; } _result_void os__rm(string path) { int rc = 0; #if defined(_WIN32) { rc = _wremove(string_to_wide(path)); } #else { rc = remove(((char*)(path.str))); } #endif if (rc == -1) { return (_result_void){ .is_error=true, .err=os__error_posix(((os__SystemError){.msg = string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("Failed to remove \""), 0xfe10, {.d_s = path}}, {_S("\": "), 0, { .d_c = 0 }}})), os__posix_get_error_msg(errno)),.code = _const_os__error_code_not_set,})), .data={E_STRUCT} }; } return (_result_void){0}; } _result_void os__rmdir(string path) { #if defined(_WIN32) { bool rc = RemoveDirectory(string_to_wide(path)); if (!rc) { int code = ((int)(GetLastError())); return (_result_void){ .is_error=true, .err=os__error_win32(((os__SystemError){.msg = str_intp(2, _MOV((StrIntpData[]){{_S("Failed to remove \""), 0xfe10, {.d_s = path}}, {_S("\""), 0, { .d_c = 0 }}})),.code = code,})), .data={E_STRUCT} }; } } #else { int rc = rmdir(((char*)(path.str))); if (rc == -1) { return (_result_void){ .is_error=true, .err=os__error_posix(((os__SystemError){.msg = (string){.str=(byteptr)"", .is_lit=1},.code = _const_os__error_code_not_set,})), .data={E_STRUCT} }; } } #endif return (_result_void){0}; } VV_LOC void os__print_c_errno(void) { int e = errno; string se = tos_clone(((u8*)(strerror(e)))); eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("errno="), 0xfe07, {.d_i32 = e}}, {_S(" err="), 0xfe10, {.d_s = se}}, {_SLIT0, 0, { .d_c = 0 }}}))); } string os__get_raw_line(void) { bool os__get_raw_line_defer_0 = false; u8* buf; #if defined(_WIN32) { bool is_console = os__is_atty(0) > 0; int wide_char_size = (is_console ? (2) : (1)); voidptr h_input = GetStdHandle(STD_INPUT_HANDLE); if (h_input == INVALID_HANDLE_VALUE) { return _S(""); } { // Unsafe block int initial_size = (int)(256 * wide_char_size); buf = malloc_noscan(initial_size); os__get_raw_line_defer_0 = true; int capacity = initial_size; int offset = 0; for (;;) { int required_space = (int)(offset + wide_char_size); if (required_space > capacity) { int new_capacity = (int)(capacity * 2); u8* new_buf = realloc_data(buf, capacity, new_capacity); if (new_buf == 0) { break; } buf = new_buf; capacity = new_capacity; } u8* pos = buf + offset; u32 bytes_read = ((u32)(0U)); bool res = (is_console ? (ReadConsole(h_input, pos, 1U, ((voidptr)(&bytes_read)), 0)) : (ReadFile(h_input, pos, 1U, ((voidptr)(&bytes_read)), 0))); if (!res || bytes_read == 0U) { break; } if (is_console) { u16 read_char = *(((u16*)(pos))); if (read_char == '\n') { offset += wide_char_size; break; } else if (read_char == 0x1AU) { break; } } else { u8 read_byte = *pos; if (read_byte == '\n') { offset += wide_char_size; break; } else if (read_byte == 0x1A) { break; } } offset += wide_char_size; } string _t3 = (is_console ? (string_from_wide2(((u16*)(buf)), (int)(offset / 2))) : (string_clone(u8_vstring_with_len(buf, offset)))); // Defer begin if (os__get_raw_line_defer_0) { #if defined(_WIN32) u8_free(buf); #endif } // Defer end return _t3; } } #else { usize max = ((usize)(0)); buf = ((u8*)(((void*)0))); int nr_chars = getline(((voidptr)(&buf)), &max, stdin); string str = tos(buf, (nr_chars < 0 ? (0) : (nr_chars))); string ret = string_clone(str); #if !defined(_VAUTOFREE) { { // Unsafe block if (nr_chars > 0 && buf != 0) { free(buf); } } } #endif string _t5 = ret; // Defer begin if (os__get_raw_line_defer_0) { #if defined(_WIN32) u8_free(buf); #endif } // Defer end return _t5; } #endif return (string){.str=(byteptr)"", .is_lit=1}; } string os__executable(void) { bool os__executable_defer_0 = false; voidptr file; bool os__executable_defer_1 = false; string sret; bool os__executable_defer_2 = false; u8** pbuf; Array_fixed_u8_4096 result = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; #if defined(_WIN32) { u16* pu16_result = ((u16*)(&result[0])); u32 len = GetModuleFileName(0, pu16_result, 512U); u32 attrs = GetFileAttributesW(pu16_result); u32 is_set = (attrs & 0x400U); if (is_set != 0U) { file = CreateFile(pu16_result, 0x80000000U, 1U, 0, 3U, 0x80U, 0); if (file != ((voidptr)(-1))) { os__executable_defer_0 = true; Array_fixed_u8_4096 final_path = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; u32 final_len = GetFinalPathNameByHandleW(file, ((u16*)(&final_path[0])), _const_os__max_path_buffer_size, 0U); if (final_len < ((u32)(_const_os__max_path_buffer_size))) { sret = string_from_wide2(((u16*)(&final_path[0])), ((int)(final_len))); os__executable_defer_1 = true; string sret_slice = string_substr(sret, 4, 2147483647); string res = string_clone(sret_slice); string _t2 = res; // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t2; } else { eprintln(_S("os.executable() saw that the executable file path was too long")); } } } string res = string_from_wide2(pu16_result, ((int)(len))); string _t3 = res; // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t3; } #endif #if defined(__APPLE__) { int pid = getpid(); int ret = proc_pidpath(pid, &result[0], _const_os__max_path_len); if (ret <= 0) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("os.executable() failed at calling proc_pidpath with pid: "), 0xfe07, {.d_i32 = pid}}, {_S(" . proc_pidpath returned "), 0xfe07, {.d_i32 = ret}}, {_S(" "), 0, { .d_c = 0 }}}))); string _t5 = os__executable_fallback(); // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t5; } string res = tos_clone(&result[0]); string _t6 = res; // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t6; } #endif #if defined(__FreeBSD__) { usize bufsize = ((usize)(_const_os__max_path_buffer_size)); Array_fixed_int_4 mib = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; sysctl(&mib[0], 4, &result[0], &bufsize, 0, 0); string res = tos_clone(&result[0]); string _t8 = res; // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t8; } #endif #if defined(__OpenBSD__) { pbuf = ((u8**)(&result[0])); usize bufsize = ((usize)(_const_os__max_path_buffer_size)); int pid = getpid(); Array_fixed_int_4 mib = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV}; if (sysctl(&mib[0], 4, NULL, &bufsize, NULL, 0) == 0) { if (bufsize > _const_os__max_path_buffer_size) { pbuf = ((u8**)(_v_malloc(((int)(bufsize))))); os__executable_defer_2 = true; } if (sysctl(&mib[0], 4, pbuf, &bufsize, NULL, 0) == 0) { if (*pbuf[0] == '/') { string res = tos_clone(pbuf[0]); string _t10 = res; // Defer begin if (os__executable_defer_2) { #if defined(__OpenBSD__) _v_free(pbuf); #endif } // Defer end // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t10; } } } string _t11 = os__executable_fallback(); // Defer begin if (os__executable_defer_2) { #if defined(__OpenBSD__) _v_free(pbuf); #endif } // Defer end // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t11; } #endif #if defined(__NetBSD__) { int count = readlink("/proc/curproc/exe", ((char*)(&result[0])), _const_os__max_path_len); if (count < 0) { eprintln(_S("os.executable() failed at reading /proc/curproc/exe to get exe path")); string _t13 = os__executable_fallback(); // Defer begin if (os__executable_defer_2) { #if defined(__OpenBSD__) _v_free(pbuf); #endif } // Defer end // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t13; } string res = tos_clone(&result[0]); string _t14 = res; // Defer begin if (os__executable_defer_2) { #if defined(__OpenBSD__) _v_free(pbuf); #endif } // Defer end // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t14; } #endif #if defined(__DragonFly__) { int count = readlink("/proc/curproc/file", ((char*)(&result[0])), _const_os__max_path_len); if (count < 0) { eprintln(_S("os.executable() failed at reading /proc/curproc/file to get exe path")); string _t16 = os__executable_fallback(); // Defer begin if (os__executable_defer_2) { #if defined(__OpenBSD__) _v_free(pbuf); #endif } // Defer end // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t16; } string res = tos_clone(&result[0]); string _t17 = res; // Defer begin if (os__executable_defer_2) { #if defined(__OpenBSD__) _v_free(pbuf); #endif } // Defer end // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t17; } #endif #if defined(__linux__) { int count = readlink("/proc/self/exe", ((char*)(&result[0])), _const_os__max_path_len); if (count < 0) { eprintln(_S("os.executable() failed at reading /proc/self/exe to get exe path")); string _t19 = os__executable_fallback(); // Defer begin if (os__executable_defer_2) { #if defined(__OpenBSD__) _v_free(pbuf); #endif } // Defer end // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t19; } string res = tos_clone(&result[0]); string _t20 = res; // Defer begin if (os__executable_defer_2) { #if defined(__OpenBSD__) _v_free(pbuf); #endif } // Defer end // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t20; } #endif string _t21 = os__executable_fallback(); // Defer begin if (os__executable_defer_2) { #if defined(__OpenBSD__) _v_free(pbuf); #endif } // Defer end // Defer begin if (os__executable_defer_1) { #if defined(_WIN32) string_free(&sret); #endif } // Defer end // Defer begin if (os__executable_defer_0) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end return _t21; } _result_void os__chdir(string path) { int _t1; #if defined(_WIN32) _t1 = _wchdir(string_to_wide(path)); ; #else _t1 = chdir(((char*)(path.str))); ; #endif int ret = _t1; if (ret == -1) { return (_result_void){ .is_error=true, .err=os__error_posix(((os__SystemError){.msg = (string){.str=(byteptr)"", .is_lit=1},.code = _const_os__error_code_not_set,})), .data={E_STRUCT} }; } return (_result_void){0}; } string os__getwd(void) { { // Unsafe block Array_fixed_u8_4096 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; #if defined(_WIN32) { if (_wgetcwd(((u16*)(&buf[0])), _const_os__max_path_len) == 0) { return _S(""); } string res = string_from_wide(((u16*)(&buf[0]))); return res; } #else { if (getcwd(((char*)(&buf[0])), _const_os__max_path_len) == 0) { return _S(""); } string res = tos_clone(&buf[0]); return res; } #endif } return (string){.str=(byteptr)"", .is_lit=1}; } string os__real_path(string fpath) { bool os__real_path_defer_0 = false; u16* fpath_wide; bool os__real_path_defer_1 = false; voidptr file; Array_fixed_u8_4096 fullpath = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; string res = _S(""); #if defined(_WIN32) { u16* pu16_fullpath = ((u16*)(&fullpath[0])); fpath_wide = string_to_wide(fpath); os__real_path_defer_0 = true; file = CreateFile(fpath_wide, 0x80000000U, 1U, 0, 3U, 0x80U, 0); if (file != ((voidptr)(-1))) { os__real_path_defer_1 = true; u32 final_len = GetFinalPathNameByHandleW(file, pu16_fullpath, _const_os__max_path_buffer_size, 0U); if (final_len < ((u32)(_const_os__max_path_buffer_size))) { string rt = string_from_wide2(pu16_fullpath, ((int)(final_len))); string srt = string_substr(rt, 4, 2147483647); string_free(&res); res = string_clone(srt); } else { eprintln(_S("os.real_path() saw that the file path was too long")); string_free(&res); string _t2 = string_clone(fpath); // Defer begin if (os__real_path_defer_1) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end // Defer begin if (os__real_path_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(fpath_wide))); #endif } // Defer end return _t2; } } else { u32 ret = GetFullPathName(fpath_wide, _const_os__max_path_len, pu16_fullpath, 0); if (ret == 0U) { string_free(&res); string _t3 = string_clone(fpath); // Defer begin if (os__real_path_defer_1) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end // Defer begin if (os__real_path_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(fpath_wide))); #endif } // Defer end return _t3; } string_free(&res); res = string_from_wide(pu16_fullpath); } } #else { char* ret = ((char*)(realpath(((char*)(fpath.str)), ((char*)(&fullpath[0]))))); if (ret == 0) { string_free(&res); string _t4 = string_clone(fpath); // Defer begin if (os__real_path_defer_1) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end // Defer begin if (os__real_path_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(fpath_wide))); #endif } // Defer end return _t4; } string_free(&res); res = tos_clone(&fullpath[0]); } #endif os__normalize_drive_letter(res); string _t5 = res; // Defer begin if (os__real_path_defer_1) { #if defined(_WIN32) CloseHandle(file); #endif } // Defer end // Defer begin if (os__real_path_defer_0) { #if defined(_WIN32) _v_free(((voidptr)(fpath_wide))); #endif } // Defer end return _t5; } VV_LOC void os__normalize_drive_letter(string path) { #if !defined(_WIN32) { return; } #endif if (path.len > 2 && path.str[ 0] >= 'a' && path.str[ 0] <= 'z' && path.str[ 1] == ':' && path.str[ 2] == _const_os__path_separator.str[ 0]) { { // Unsafe block u8* x = &path.str[0]; *x = (u8)(*x - 32); } } } int os__fork(void) { int pid = -1; #if !defined(_WIN32) { pid = fork(); } #endif #if defined(_WIN32) { _v_panic(_S("os.fork not supported in windows")); VUNREACHABLE(); } #endif return pid; } i64 os__file_last_mod_unix(string path) { _result_os__Stat _t1; if (_t1 = os__stat(path), !_t1.is_error) { os__Stat attr = *(os__Stat*)_t1.data; return attr.mtime; } return 0; } _result_void os__chmod(string path, int mode) { if (chmod(((char*)(path.str)), mode) != 0) { return (_result_void){ .is_error=true, .err=os__error_posix(((os__SystemError){.msg = string__plus(_S("chmod failed: "), os__posix_get_error_msg(errno)),.code = _const_os__error_code_not_set,})), .data={E_STRUCT} }; } return (_result_void){0}; } _result_void os__execvp(string cmdpath, Array_string cmdargs) { Array_char_ptr cargs = __new_array_with_default(0, 0, sizeof(char*), 0); array_push((array*)&cargs, _MOV((char*[]){ ((char*)(cmdpath.str)) })); for (int i = 0; i < cmdargs.len; ++i) { array_push((array*)&cargs, _MOV((char*[]){ ((char*)((*(string*)array_get(cmdargs, i)).str)) })); } array_push((array*)&cargs, _MOV((char*[]){ ((char*)(((void*)0))) })); int res = ((int)(0)); #if defined(_WIN32) { res = _execvp(((char*)(cmdpath.str)), cargs.data); } #else { res = execvp(((char*)(cmdpath.str)), cargs.data); } #endif if (res == -1) { return (_result_void){ .is_error=true, .err=os__error_posix(((os__SystemError){.msg = (string){.str=(byteptr)"", .is_lit=1},.code = _const_os__error_code_not_set,})), .data={E_STRUCT} }; } _v_exit(res); VUNREACHABLE(); return (_result_void){0}; } _result_void os__execve(string cmdpath, Array_string cmdargs, Array_string envs) { Array_char_ptr cargv = __new_array_with_default(0, 0, sizeof(char*), 0); Array_char_ptr cenvs = __new_array_with_default(0, 0, sizeof(char*), 0); array_push((array*)&cargv, _MOV((char*[]){ ((char*)(cmdpath.str)) })); for (int i = 0; i < cmdargs.len; ++i) { array_push((array*)&cargv, _MOV((char*[]){ ((char*)((*(string*)array_get(cmdargs, i)).str)) })); } for (int i = 0; i < envs.len; ++i) { array_push((array*)&cenvs, _MOV((char*[]){ ((char*)((*(string*)array_get(envs, i)).str)) })); } array_push((array*)&cargv, _MOV((char*[]){ ((char*)(((void*)0))) })); array_push((array*)&cenvs, _MOV((char*[]){ ((char*)(((void*)0))) })); int res = ((int)(0)); #if defined(_WIN32) { res = _execve(((char*)(cmdpath.str)), cargv.data, cenvs.data); } #else { res = execve(((char*)(cmdpath.str)), cargv.data, cenvs.data); } #endif if (res == -1) { return (_result_void){ .is_error=true, .err=os__error_posix(((os__SystemError){.msg = (string){.str=(byteptr)"", .is_lit=1},.code = _const_os__error_code_not_set,})), .data={E_STRUCT} }; } return (_result_void){0}; } int os__is_atty(int fd) { #if defined(_WIN32) { u32 mode = ((u32)(0U)); voidptr osfh = ((voidptr)(_get_osfhandle(fd))); GetConsoleMode(osfh, ((voidptr)(&mode))); return ((int)(mode)); } #else { return isatty(fd); } #endif return 0; } _result_void os__write_file_array(string path, array buffer) { _result_os__File _t1 = os__create(path); if (_t1.is_error) { _result_void _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } os__File f = (*(os__File*)_t1.data); _result_void _t3 = os__File_write_full_buffer(&f, buffer.data, ((usize)((int)(buffer.len * buffer.element_size)))); if (_t3.is_error) { _result_void _t4 = {0}; _t4.is_error = true; _t4.err = _t3.err; return _t4; } ; os__File_close(&f); return (_result_void){0}; } inline IError os__error_posix(os__SystemError e) { int code = (e.code == _const_os__error_code_not_set ? (errno) : (e.code)); string message = ((e.msg).len == 0 ? (os__posix_get_error_msg(code)) : (e.msg)); return error_with_code(message, code); } inline IError os__error_win32(os__SystemError e) { #if defined(_WIN32) { if (e.code == _const_os__error_code_not_set) { _v_panic(_S("before calling `error_win32`, you must set `e.code` first.")); VUNREACHABLE(); } string message = ((e.msg).len == 0 ? (os__get_error_msg(e.code)) : (e.msg)); return error_with_code(message, e.code); } #else { _v_panic(_S("Win32 API not available on this platform.")); VUNREACHABLE(); } #endif return (IError){0}; } void os__Result_free(os__Result* result) { string_free(&result->output); } VV_LOC string os__executable_fallback(void) { if (_const_os__args.len == 0) { return _S(""); } string exepath = (*(string*)array_get(_const_os__args, 0)); #if defined(_WIN32) { if (!string_contains(exepath, _S(".exe"))) { exepath = string__plus(exepath, _S(".exe")); } } #endif if (!os__is_abs_path(exepath)) { string other_separator = (true ? (_S("\\")) : (_S("/"))); string rexepath = string_replace(exepath, other_separator, _const_os__path_separator); if (string_contains(rexepath, _const_os__path_separator)) { exepath = os__join_path_single(_const_os__wd_at_startup, exepath); } else { _result_string _t3 = os__find_abs_path_of_executable(exepath); if (_t3.is_error) { IError err = _t3.err; *(string*) _t3.data = _S(""); } string foundpath = (*(string*)_t3.data); if ((foundpath).len != 0) { exepath = foundpath; } } } exepath = os__real_path(exepath); return exepath; } _result_void os__cp_all(string src, string dst, bool overwrite) { string source_path = os__real_path(src); string dest_path = os__real_path(dst); if (!os__exists(source_path)) { return (_result_void){ .is_error=true, .err=_v_error(_S("Source path doesn't exist")), .data={E_STRUCT} }; } if (!os__is_dir(source_path)) { string fname = os__file_name(source_path); string adjusted_path = (os__is_dir(dest_path) ? (os__join_path_single(dest_path, fname)) : (dest_path)); if (os__exists(adjusted_path)) { if (overwrite) { _result_void _t2 = os__rm(adjusted_path); if (_t2.is_error) { _result_void _t3 = {0}; _t3.is_error = true; _t3.err = _t2.err; return _t3; } ; } else { return (_result_void){ .is_error=true, .err=_v_error(_S("Destination file path already exist")), .data={E_STRUCT} }; } } _result_void _t5 = os__cp(source_path, adjusted_path); if (_t5.is_error) { _result_void _t6 = {0}; _t6.is_error = true; _t6.err = _t5.err; return _t6; } ; return (_result_void){0}; } if (!os__exists(dest_path)) { _result_void _t7 = os__mkdir(dest_path, ((os__MkdirParams){.mode = 0777,})); if (_t7.is_error) { _result_void _t8 = {0}; _t8.is_error = true; _t8.err = _t7.err; return _t8; } ; } if (!os__is_dir(dest_path)) { return (_result_void){ .is_error=true, .err=_v_error(_S("Destination path is not a valid directory")), .data={E_STRUCT} }; } _result_Array_string _t10 = os__ls(source_path); if (_t10.is_error) { _result_void _t11 = {0}; _t11.is_error = true; _t11.err = _t10.err; return _t11; } Array_string files = (*(Array_string*)_t10.data); for (int _t12 = 0; _t12 < files.len; ++_t12) { string file = ((string*)files.data)[_t12]; string sp = os__join_path_single(source_path, file); string dp = os__join_path_single(dest_path, file); if (os__is_dir(sp)) { if (!os__exists(dp)) { _result_void _t13 = os__mkdir(dp, ((os__MkdirParams){.mode = 0777,})); if (_t13.is_error) { _result_void _t14 = {0}; _t14.is_error = true; _t14.err = _t13.err; return _t14; } ; } } _result_void _t15 = os__cp_all(sp, dp, overwrite); if (_t15.is_error) { IError err = _t15.err; _result_void _t16 = os__rmdir(dp); if (_t16.is_error) { IError err = _t16.err; return (_result_void){ .is_error=true, .err=err, .data={E_STRUCT} }; } ; return (_result_void){ .is_error=true, .err=err, .data={E_STRUCT} }; } ; } return (_result_void){0}; } _result_void os__mv_by_cp(string source, string target, os__MvParams opts) { _result_void _t1 = os__cp_all(source, target, opts.overwrite); if (_t1.is_error) { _result_void _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } ; if (os__is_dir(source)) { _result_void _t3 = os__rmdir_all(source); if (_t3.is_error) { _result_void _t4 = {0}; _t4.is_error = true; _t4.err = _t3.err; return _t4; } ; return (_result_void){0}; } _result_void _t5 = os__rm(source); if (_t5.is_error) { _result_void _t6 = {0}; _t6.is_error = true; _t6.err = _t5.err; return _t6; } ; return (_result_void){0}; } _result_Array_string os__read_lines(string path) { _result_string _t1 = os__read_file(path); if (_t1.is_error) { _result_Array_string _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } string buf = (*(string*)_t1.data); Array_string res = string_split_into_lines(buf); string_free(&buf); _result_Array_string _t3 = {0}; _result_ok(&(Array_string[]) { res }, (_result*)(&_t3), sizeof(Array_string)); return _t3; } string os__sigint_to_signal_name(int si) { switch (si) { case 1: { return _S("SIGHUP"); } case 2: { return _S("SIGINT"); } case 3: { return _S("SIGQUIT"); } case 4: { return _S("SIGILL"); } case 6: { return _S("SIGABRT"); } case 8: { return _S("SIGFPE"); } case 9: { return _S("SIGKILL"); } case 11: { return _S("SIGSEGV"); } case 13: { return _S("SIGPIPE"); } case 14: { return _S("SIGALRM"); } case 15: { return _S("SIGTERM"); } default: { { break; } } } #if defined(__linux__) { switch (si) { case 10: { return _S("SIGUSR1"); } case 12: { return _S("SIGUSR2"); } case 17: { return _S("SIGCHLD"); } case 18: { return _S("SIGCONT"); } case 19: { return _S("SIGSTOP"); } case 20: { return _S("SIGTSTP"); } case 21: { return _S("SIGTTIN"); } case 22: { return _S("SIGTTOU"); } case 5: { return _S("SIGTRAP"); } case 7: { return _S("SIGBUS"); } default: { { break; } } } } #endif return _S("unknown"); } _result_void os__rmdir_all(string path) { string ret_err = _S(""); _result_Array_string _t1 = os__ls(path); if (_t1.is_error) { _result_void _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } Array_string items = (*(Array_string*)_t1.data); for (int _t3 = 0; _t3 < items.len; ++_t3) { string item = ((string*)items.data)[_t3]; string fullpath = os__join_path_single(path, item); if (os__is_dir(fullpath) && !os__is_link(fullpath)) { _result_void _t4 = os__rmdir_all(fullpath); if (_t4.is_error) { IError err = _t4.err; ret_err = IError_name_table[err._typ]._method_msg(err._object); } ; } else { _result_void _t5 = os__rm(fullpath); if (_t5.is_error) { IError err = _t5.err; ret_err = IError_name_table[err._typ]._method_msg(err._object); } ; } } _result_void _t6 = os__rmdir(path); if (_t6.is_error) { IError err = _t6.err; ret_err = IError_name_table[err._typ]._method_msg(err._object); } ; if (ret_err.len > 0) { return (_result_void){ .is_error=true, .err=_v_error(ret_err), .data={E_STRUCT} }; } return (_result_void){0}; } string os__file_ext(string opath) { if (opath.len < 3) { return _S(""); } string path = os__file_name(opath); int pos = string_last_index_u8(path, '.'); if (pos == -1) { return _S(""); } if ((int)(pos + 1) >= path.len || pos == 0) { return _S(""); } return string_substr(path, pos, 2147483647); } string os__dir(string path) { if ((path).len == 0) { return _S("."); } string detected_path_separator = (string_contains(path, _S("/")) ? (_S("/")) : (_S("\\"))); _option_int _t2 = string_last_index(path, detected_path_separator); if (_t2.state != 0) { IError err = _t2.err; return _S("."); } int pos = (*(int*)_t2.data); if (pos == 0) { return detected_path_separator; } return string_substr(path, 0, pos); } string os__base(string path) { if ((path).len == 0) { return _S("."); } string detected_path_separator = (string_contains(path, _S("/")) ? (_S("/")) : (_S("\\"))); if (string__eq(path, detected_path_separator)) { return detected_path_separator; } if (string_ends_with(path, detected_path_separator)) { string path2 = string_substr(path, 0, (int)(path.len - 1)); _option_int _t3 = string_last_index(path2, detected_path_separator); if (_t3.state != 0) { IError err = _t3.err; return string_clone(path2); } int pos = (*(int*)_t3.data); return string_substr(path2, (int)(pos + 1), 2147483647); } _option_int _t6 = string_last_index(path, detected_path_separator); if (_t6.state != 0) { IError err = _t6.err; return string_clone(path); } int pos = (*(int*)_t6.data); return string_substr(path, (int)(pos + 1), 2147483647); } string os__file_name(string path) { string detected_path_separator = (string_contains(path, _S("/")) ? (_S("/")) : (_S("\\"))); return string_all_after_last(path, detected_path_separator); } Array_string os__get_raw_lines(void) { string line = _S(""); Array_string lines = __new_array_with_default(0, 0, sizeof(string), 0); for (;;) { line = os__get_raw_line(); if (line.len <= 0) { break; } array_push((array*)&lines, _MOV((string[]){ string_clone(line) })); } return lines; } string os__get_raw_lines_joined(void) { return Array_string_join(os__get_raw_lines(), _S("")); } string os__user_os(void) { #if defined(__linux__) { return _S("linux"); } #endif #if defined(__APPLE__) { return _S("macos"); } #endif #if defined(_WIN32) { return _S("windows"); } #endif #if defined(__FreeBSD__) { return _S("freebsd"); } #endif #if defined(__OpenBSD__) { return _S("openbsd"); } #endif #if defined(__NetBSD__) { return _S("netbsd"); } #endif #if defined(__DragonFly__) { return _S("dragonfly"); } #endif #if defined(__ANDROID__) { return _S("android"); } #endif #if defined(__TERMUX__) { return _S("termux"); } #endif #if defined(__sun) { return _S("solaris"); } #endif #if defined(__QNX__) { return _S("qnx"); } #endif #if defined(__HAIKU__) { return _S("haiku"); } #endif #if defined(__serenity__) { return _S("serenity"); } #endif #if defined(__vinix__) { return _S("vinix"); } #endif if ((os__getenv(_S("TERMUX_VERSION"))).len != 0) { return _S("termux"); } return _S("unknown"); } string os__home_dir(void) { #if defined(_WIN32) { return os__getenv(_S("USERPROFILE")); } #else { return os__getenv(_S("HOME")); } #endif return (string){.str=(byteptr)"", .is_lit=1}; } _result_void os__write_file(string path, string text) { _result_os__File _t1 = os__create(path); if (_t1.is_error) { _result_void _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } os__File f = (*(os__File*)_t1.data); _result_void _t3 = os__File_write_full_buffer(&f, text.str, ((usize)(text.len))); if (_t3.is_error) { _result_void _t4 = {0}; _t4.is_error = true; _t4.err = _t3.err; return _t4; } ; os__File_close(&f); return (_result_void){0}; } string os__ExecutableNotFoundError_msg(os__ExecutableNotFoundError err) { return _S("os: failed to find executable"); } VV_LOC IError os__error_failed_to_find_executable(void) { return I_os__ExecutableNotFoundError_to_Interface_IError(((os__ExecutableNotFoundError*)memdup(&(os__ExecutableNotFoundError){.Error = ((Error){E_STRUCT}),}, sizeof(os__ExecutableNotFoundError)))); } _result_string os__find_abs_path_of_executable(string exe_name) { if ((exe_name).len == 0) { return (_result_string){ .is_error=true, .err=_v_error(_S("expected non empty `exe_name`")), .data={E_STRUCT} }; } for (int _t2 = 0; _t2 < _const_os__executable_suffixes.len; ++_t2) { string suffix = ((string*)_const_os__executable_suffixes.data)[_t2]; string fexepath = string__plus(exe_name, suffix); if (os__is_abs_path(fexepath)) { _result_string _t3 = {0}; _result_ok(&(string[]) { fexepath }, (_result*)(&_t3), sizeof(string)); return _t3; } string res = _S(""); string path = os__getenv(_S("PATH")); Array_string paths = string_split(path, _const_os__path_delimiter); for (int _t4 = 0; _t4 < paths.len; ++_t4) { string p = ((string*)paths.data)[_t4]; string found_abs_path = os__join_path_single(p, fexepath); #if defined(CUSTOM_DEFINE_trace_find_abs_path_of_executable) { _v_dump_expr_string(_S("/home/runner/work/v/v/vlib/os/os.v"), 604, _S("found_abs_path"), found_abs_path); } #endif if (os__is_file(found_abs_path) && os__is_executable(found_abs_path)) { res = found_abs_path; break; } } if (res.len > 0) { _result_string _t6 = {0}; _result_ok(&(string[]) { os__abs_path(res) }, (_result*)(&_t6), sizeof(string)); return _t6; } } return (_result_string){ .is_error=true, .err=os__error_failed_to_find_executable(), .data={E_STRUCT} }; } bool os__is_file(string path) { return os__exists(path) && !os__is_dir(path); } string os__join_path(string base, Array_string dirs) { bool os__join_path_defer_0 = false; strings__Builder sb; bool os__join_path_defer_1 = false; string sbase; sb = strings__new_builder((int)(base.len + (int)(dirs.len * 50))); os__join_path_defer_0 = true; sbase = string_trim_right(base, _S("\\/")); os__join_path_defer_1 = true; strings__Builder_write_string(&sb, sbase); for (int _t1 = 0; _t1 < dirs.len; ++_t1) { string d = ((string*)dirs.data)[_t1]; if ((d).len != 0) { strings__Builder_write_string(&sb, _const_os__path_separator); strings__Builder_write_string(&sb, d); } } os__normalize_path_in_builder((voidptr)&sb); string res = strings__Builder_str(&sb); if ((base).len == 0) { res = string_trim_left(res, _const_os__path_separator); } string _t2 = res; // Defer begin if (os__join_path_defer_1) { string_free(&sbase); } // Defer end // Defer begin if (os__join_path_defer_0) { strings__Builder_free(&sb); } // Defer end return _t2; } string os__join_path_single(string base, string elem) { bool os__join_path_single_defer_0 = false; strings__Builder sb; bool os__join_path_single_defer_1 = false; string sbase; sb = strings__new_builder((int)((int)(base.len + elem.len) + 1)); os__join_path_single_defer_0 = true; sbase = string_trim_right(base, _S("\\/")); os__join_path_single_defer_1 = true; strings__Builder_write_string(&sb, sbase); if ((elem).len != 0) { strings__Builder_write_string(&sb, _const_os__path_separator); strings__Builder_write_string(&sb, elem); } os__normalize_path_in_builder((voidptr)&sb); string res = strings__Builder_str(&sb); if ((base).len == 0) { res = string_trim_left(res, _const_os__path_separator); } string _t1 = res; // Defer begin if (os__join_path_single_defer_1) { string_free(&sbase); } // Defer end // Defer begin if (os__join_path_single_defer_0) { strings__Builder_free(&sb); } // Defer end return _t1; } VV_LOC void os__normalize_path_in_builder(strings__Builder* sb) { rune fs = '\\'; rune rs = '/'; #if defined(_WIN32) { fs = '/'; rs = '\\'; } #endif for (int idx = 0; idx < sb->len; ++idx) { { // Unsafe block if (((u8*)sb->data)[idx] == fs) { ((u8*)sb->data)[idx] = rs; } } } for (int idx = 0; idx < (int)(sb->len - 3); ++idx) { if (((u8*)sb->data)[idx] == rs && ((u8*)sb->data)[(int_literal)(idx + 1)] == '.' && ((u8*)sb->data)[(int_literal)(idx + 2)] == rs) { { // Unsafe block for (int j = (int_literal)(idx + 1); j < (int)(sb->len - 2); j++) { ((u8*)sb->data)[j] = ((u8*)sb->data)[(int)(j + 2)]; } sb->len -= 2; } } if (((u8*)sb->data)[idx] == rs && ((u8*)sb->data)[(int_literal)(idx + 1)] == rs) { { // Unsafe block for (int j = (int_literal)(idx + 1); j < (int)(sb->len - 1); j++) { ((u8*)sb->data)[j] = ((u8*)sb->data)[(int)(j + 1)]; } sb->len -= 1; } } } } Array_string os__walk_ext(string path, string ext, os__WalkParams opts) { Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); os__impl_walk_ext(path, ext, &res, opts); return res; } VV_LOC void os__impl_walk_ext(string path, string ext, Array_string* out, os__WalkParams opts) { if (!os__is_dir(path)) { return; } _result_Array_string _t1 = os__ls(path); if (_t1.is_error) { IError err = _t1.err; return; } Array_string files = (*(Array_string*)_t1.data); string separator = (string_ends_with(path, _const_os__path_separator) ? (_S("")) : (_const_os__path_separator)); for (int _t2 = 0; _t2 < files.len; ++_t2) { string file = ((string*)files.data)[_t2]; if (!opts.hidden && string_starts_with(file, _S("."))) { continue; } string p = string__plus(string__plus(path, separator), file); if (os__is_dir(p) && !os__is_link(p)) { os__impl_walk_ext(p, ext, out, opts); } else if (string_ends_with(file, ext)) { array_push((array*)out, _MOV((string[]){ string_clone(p) })); } } } _result_void os__mkdir_all(string opath, os__MkdirParams params) { if (os__exists(opath)) { if (os__is_dir(opath)) { return (_result_void){0}; } return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("path `"), 0xfe10, {.d_s = opath}}, {_S("` already exists, and is not a folder"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } string other_separator = (true ? (_S("\\")) : (_S("/"))); string path = string_replace(opath, other_separator, _const_os__path_separator); string p = (string_starts_with(path, _const_os__path_separator) ? (_const_os__path_separator) : (_S(""))); Array_string path_parts = string_split(string_trim_left(path, _const_os__path_separator), _const_os__path_separator); for (int _t2 = 0; _t2 < path_parts.len; ++_t2) { string subdir = ((string*)path_parts.data)[_t2]; p = string__plus(p, string__plus(subdir, _S("/"))); if (os__exists(p) && os__is_dir(p)) { continue; } _result_void _t3 = os__mkdir(p, params); if (_t3.is_error) { IError err = _t3.err; return (_result_void){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("folder: "), 0xfe10, {.d_s = p}}, {_S(", error: "), 0xfe10, {.d_s = IError_str(err)}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } ; } return (_result_void){0}; } VV_LOC void os__create_folder_when_it_does_not_exist(string path) { if (os__is_dir(path) || os__is_link(path)) { return; } string error_msg = _S(""); for (int _t1 = 0; _t1 < 10; ++_t1) { _result_void _t2 = os__mkdir_all(path, ((os__MkdirParams){.mode = 0700U,})); if (_t2.is_error) { IError err = _t2.err; if (os__is_dir(path) || os__is_link(path)) { return; } error_msg = IError_name_table[err._typ]._method_msg(err._object); os__sleep_ms(1); continue; } ; break; } if (os__is_dir(path) || os__is_link(path)) { return; } _v_panic(error_msg); VUNREACHABLE(); } VV_LOC string os__xdg_home_folder(string ename, string lpath) { string xdg_folder = os__getenv(ename); string dir = ((xdg_folder).len != 0 ? (xdg_folder) : (os__join_path_single(os__home_dir(), lpath))); os__create_folder_when_it_does_not_exist(dir); return dir; } string os__cache_dir(void) { return os__xdg_home_folder(_S("XDG_CACHE_HOME"), _S(".cache")); } string os__temp_dir(void) { string path = os__getenv(_S("TMPDIR")); #if defined(_WIN32) { if ((path).len == 0) { path = os__getenv(_S("TEMP")); if ((path).len == 0) { path = os__getenv(_S("TMP")); } if ((path).len == 0) { path = _S("C:/tmp"); } } _result_string _t2 = os__get_long_path(path); if (_t2.is_error) { IError err = _t2.err; *(string*) _t2.data = path; } path = (*(string*)_t2.data); } #endif #if defined(__APPLE__) { return _S("/tmp"); } #endif #if defined(__ANDROID__) { if ((path).len == 0) { path = os__cache_dir(); } } #endif #if defined(__TERMUX__) { path = _S("/data/data/com.termux/files/usr/tmp"); } #endif if ((path).len == 0) { path = _S("/tmp"); } return path; } string os__vtmp_dir(void) { string vtmp = os__getenv(_S("VTMP")); if (vtmp.len > 0) { os__create_folder_when_it_does_not_exist(vtmp); return vtmp; } int uid = os__getuid(); vtmp = os__join_path_single(os__temp_dir(), str_intp(2, _MOV((StrIntpData[]){{_S("v_"), 0xfe07, {.d_i32 = uid}}, {_SLIT0, 0, { .d_c = 0 }}}))); os__create_folder_when_it_does_not_exist(vtmp); os__setenv(_S("VTMP"), vtmp, true); return vtmp; } VV_LOC string os__default_vmodules_path(void) { string hdir = os__home_dir(); string res = os__join_path_single(hdir, _S(".vmodules")); return res; } string os__vmodules_dir(void) { Array_string paths = os__vmodules_paths(); if (paths.len > 0) { return (*(string*)array_get(paths, 0)); } return os__default_vmodules_path(); } Array_string os__vmodules_paths(void) { bool os__vmodules_paths_defer_0 = false; bool os__vmodules_paths_defer_1 = false; string path = os__getenv(_S("VMODULES")); if ((path).len == 0) { path = os__default_vmodules_path(); } os__vmodules_paths_defer_0 = true; Array_string splitted = string_split(path, _const_os__path_delimiter); os__vmodules_paths_defer_1 = true; Array_string list = __new_array_with_default(0, splitted.len, sizeof(string), 0); for (int i = 0; i < splitted.len; ++i) { string si = (*(string*)array_get(splitted, i)); string trimmed = string_trim_right(si, _const_os__path_separator); array_push((array*)&list, _MOV((string[]){ string_clone(trimmed) })); } Array_string _t2 = list; // Defer begin if (os__vmodules_paths_defer_1) { } // Defer end // Defer begin if (os__vmodules_paths_defer_0) { } // Defer end return _t2; } os__Result os__execute_or_exit(string cmd) { os__Result res = os__execute(cmd); if (res.exit_code != 0) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("failed cmd: "), 0xfe10, {.d_s = cmd}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("failed code: "), 0xfe07, {.d_i32 = res.exit_code}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(res.output); _v_exit(1); VUNREACHABLE(); } return res; } _result_os__Result os__execute_opt(string cmd) { os__Result res = os__execute(cmd); if (res.exit_code != 0) { return (_result_os__Result){ .is_error=true, .err=_v_error(res.output), .data={E_STRUCT} }; } _result_os__Result _t2 = {0}; _result_ok(&(os__Result[]) { res }, (_result*)(&_t2), sizeof(os__Result)); return _t2; } string os__quoted_path(string path) { #if defined(_WIN32) { return (string_ends_with(path, _const_os__path_separator) ? (str_intp(2, _MOV((StrIntpData[]){{_S("\""), 0xfe10, {.d_s = string__plus(path, _const_os__path_separator)}}, {_S("\""), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("\""), 0xfe10, {.d_s = path}}, {_S("\""), 0, { .d_c = 0 }}})))); } #else { return str_intp(2, _MOV((StrIntpData[]){{_S("'"), 0xfe10, {.d_s = path}}, {_S("'"), 0, { .d_c = 0 }}})); } #endif return (string){.str=(byteptr)"", .is_lit=1}; } os__Uname os__uname(void) { os__Uname u = ((os__Uname){.sysname = (string){.str=(byteptr)"", .is_lit=1},.nodename = (string){.str=(byteptr)"", .is_lit=1},.release = (string){.str=(byteptr)"", .is_lit=1},.version = (string){.str=(byteptr)"", .is_lit=1},.machine = (string){.str=(byteptr)"", .is_lit=1},}); { // Unsafe block struct utsname* d = ((struct utsname*)(malloc_noscan(((int)(sizeof(struct utsname)))))); if (uname(d) == 0) { u.sysname = cstring_to_vstring(d->sysname); u.nodename = cstring_to_vstring(d->nodename); u.release = cstring_to_vstring(d->release); u.version = cstring_to_vstring(d->version); u.machine = cstring_to_vstring(d->machine); } _v_free(d); } return u; } _result_Array_string os__ls(string path) { if ((path).len == 0) { return (_result_Array_string){ .is_error=true, .err=_v_error(_S("ls() expects a folder, not an empty string")), .data={E_STRUCT} }; } Array_string res = __new_array_with_default(0, 50, sizeof(string), 0); DIR* dir = opendir(((char*)(path.str))); if (isnil(dir)) { return (_result_Array_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("ls() couldnt open dir \""), 0xfe10, {.d_s = path}}, {_S("\""), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } struct dirent* ent = ((struct dirent*)(((void*)0))); for (;;) { ent = readdir(dir); if (isnil(ent)) { break; } { // Unsafe block u8* bptr = ((u8*)(&ent->d_name[0])); if (bptr[0] == 0 || (bptr[0] == '.' && bptr[1] == 0) || (bptr[0] == '.' && bptr[1] == '.' && bptr[2] == 0)) { continue; } array_push((array*)&res, _MOV((string[]){ tos_clone(bptr) })); } } closedir(dir); _result_Array_string _t4 = {0}; _result_ok(&(Array_string[]) { res }, (_result*)(&_t4), sizeof(Array_string)); return _t4; } _result_void os__mkdir(string path, os__MkdirParams params) { if (_SLIT_EQ(path.str, path.len, ".")) { return (_result_void){0}; } string apath = os__real_path(path); int r = mkdir(((char*)(apath.str)), params.mode); if (r == -1) { return (_result_void){ .is_error=true, .err=_v_error(os__posix_get_error_msg(errno)), .data={E_STRUCT} }; } return (_result_void){0}; } os__Result os__execute(string cmd) { bool os__execute_defer_0 = false; string pcmd; bool os__execute_defer_1 = false; strings__Builder res; pcmd = str_intp(2, _MOV((StrIntpData[]){{_S("exec 2>&1;"), 0xfe10, {.d_s = cmd}}, {_SLIT0, 0, { .d_c = 0 }}})); os__execute_defer_0 = true; voidptr f = os__vpopen(pcmd); if (isnil(f)) { os__Result _t1 = ((os__Result){.exit_code = -1,.output = str_intp(2, _MOV((StrIntpData[]){{_S("exec(\""), 0xfe10, {.d_s = cmd}}, {_S("\") failed"), 0, { .d_c = 0 }}})),}); // Defer begin if (os__execute_defer_0) { string_free(&pcmd); } // Defer end return _t1; } int fd = os__fileno(f); res = strings__new_builder(1024); os__execute_defer_1 = true; Array_fixed_u8_4096 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; { // Unsafe block u8* pbuf = &buf[0]; for (;;) { int len = read(fd, pbuf, 4096); if (len == 0) { break; } strings__Builder_write_ptr(&res, pbuf, len); } } string soutput = strings__Builder_str(&res); int exit_code = os__vpclose(f); os__Result _t2 = ((os__Result){.exit_code = exit_code,.output = soutput,}); // Defer begin if (os__execute_defer_1) { strings__Builder_free(&res); } // Defer end // Defer begin if (os__execute_defer_0) { string_free(&pcmd); } // Defer end return _t2; } string os__get_error_msg(int code) { return os__posix_get_error_msg(code); } void os__File_close(os__File* f) { if (!f->is_opened) { return; } f->is_opened = false; fflush(f->cfile); fclose(f->cfile); } _result_void os__ensure_folder_is_writable(string folder) { bool os__ensure_folder_is_writable_defer_0 = false; string tmp_perm_check; if (!os__exists(folder)) { return (_result_void){ .is_error=true, .err=error_with_code(str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = folder}}, {_S("` does not exist"), 0, { .d_c = 0 }}})), 1), .data={E_STRUCT} }; } if (!os__is_dir(folder)) { return (_result_void){ .is_error=true, .err=error_with_code(str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = folder}}, {_S("` is not a folder"), 0, { .d_c = 0 }}})), 2), .data={E_STRUCT} }; } tmp_perm_check = os__join_path_single(folder, _S("XXXXXX")); os__ensure_folder_is_writable_defer_0 = true; { // Unsafe block int x = mkstemp(((char*)(tmp_perm_check.str))); if (-1 == x) { _result_void _t3 = (_result_void){ .is_error=true, .err=error_with_code(str_intp(2, _MOV((StrIntpData[]){{_S("folder `"), 0xfe10, {.d_s = folder}}, {_S("` is not writable"), 0, { .d_c = 0 }}})), 3), .data={E_STRUCT} }; // Defer begin if (os__ensure_folder_is_writable_defer_0) { string_free(&tmp_perm_check); } // Defer end return _t3; } close(x); } _result_void _t4 = os__rm(tmp_perm_check); if (_t4.is_error) { // Defer begin if (os__ensure_folder_is_writable_defer_0) { string_free(&tmp_perm_check); } // Defer end _result_void _t5 = {0}; _t5.is_error = true; _t5.err = _t4.err; return _t5; } ; // Defer begin if (os__ensure_folder_is_writable_defer_0) { string_free(&tmp_perm_check); } // Defer end return (_result_void){0}; } inline int os__getuid(void) { return getuid(); } VV_LOC _result_string os__get_long_path(string path) { _result_string _t1 = {0}; _result_ok(&(string[]) { path }, (_result*)(&_t1), sizeof(string)); return _t1; } void os__Process_wait(os__Process* p) { if (p->status == os__ProcessState__not_started) { os__Process__spawn(p); } if (!(p->status == os__ProcessState__running || p->status == os__ProcessState__stopped)) { return; } os__Process__wait(p); } void os__Process_close(os__Process* p) { if (p->status == os__ProcessState__not_started || p->status == os__ProcessState__closed) { return; } p->status = os__ProcessState__closed; #if !defined(_WIN32) { for (int i = 0; i < 3; ++i) { if (p->stdio_fd[v_fixed_index(i, 3)] != 0) { os__fd_close(p->stdio_fd[v_fixed_index(i, 3)]); } } } #endif } void os__Process_free(os__Process* p) { os__Process_close(p); { // Unsafe block string_free(&p->filename); string_free(&p->err); Array_string_free(&p->args); Array_string_free(&p->env); } } VV_LOC int os__Process__spawn(os__Process* p) { if (!p->env_is_custom) { p->env = __new_array_with_default(0, 0, sizeof(string), 0); Map_string_string current_environment = os__environ(); int _t2 = current_environment.key_values.len; for (int _t1 = 0; _t1 < _t2; ++_t1 ) { int _t3 = current_environment.key_values.len - _t2; _t2 = current_environment.key_values.len; if (_t3 < 0) { _t1 = -1; continue; } if (!DenseArray_has_index(¤t_environment.key_values, _t1)) {continue;} string k = *(string*)DenseArray_key(¤t_environment.key_values, _t1); k = string_clone(k); string v = (*(string*)DenseArray_value(¤t_environment.key_values, _t1)); array_push((array*)&p->env, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = k}}, {_S("="), 0xfe10, {.d_s = v}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } int pid = 0; #if defined(_WIN32) { pid = os__Process_win_spawn_process(p); } #else { pid = os__Process_unix_spawn_process(p); } #endif p->pid = pid; p->status = os__ProcessState__running; return 0; } VV_LOC void os__Process__wait(os__Process* p) { #if defined(_WIN32) { os__Process_win_wait(p); } #else { os__Process_unix_wait(p); } #endif } os__Process* os__new_process(string filename) { return ((os__Process*)memdup(&(os__Process){.filename = filename,.pid = 0,.code = -1,.status = os__ProcessState__not_started,.err = (string){.str=(byteptr)"", .is_lit=1},.args = __new_array(0, 0, sizeof(string)),.work_folder = (string){.str=(byteptr)"", .is_lit=1},.env_is_custom = 0,.env = __new_array(0, 0, sizeof(string)),.use_stdio_ctl = 0,.use_pgroup = 0,.stdio_fd = {-1, -1, -1},.wdata = 0,.create_no_window = 0,}, sizeof(os__Process))); } void os__Process_set_args(os__Process* p, Array_string pargs) { if (p->status != os__ProcessState__not_started) { return; } p->args = pargs; return; } VV_LOC int os__Process_unix_spawn_process(os__Process* p) { Array_fixed_int_6 pipeset = {0, 0, 0, 0, 0, 0}; if (p->use_stdio_ctl) { int dont_care = pipe(&pipeset[0]); dont_care = pipe(&pipeset[2]); dont_care = pipe(&pipeset[4]); {int _ = dont_care;} ; } int pid = os__fork(); if (pid != 0) { if (p->use_stdio_ctl) { p->stdio_fd[0] = pipeset[1]; p->stdio_fd[1] = pipeset[2]; p->stdio_fd[2] = pipeset[4]; os__fd_close(pipeset[0]); os__fd_close(pipeset[3]); os__fd_close(pipeset[5]); } return pid; } if (p->use_pgroup) { setpgid(0, 0); } if (p->use_stdio_ctl) { os__fd_close(pipeset[1]); os__fd_close(pipeset[2]); os__fd_close(pipeset[4]); dup2(pipeset[0], 0); dup2(pipeset[3], 1); dup2(pipeset[5], 2); os__fd_close(pipeset[0]); os__fd_close(pipeset[3]); os__fd_close(pipeset[5]); } if ((p->work_folder).len != 0) { if (!os__is_abs_path(p->filename)) { p->filename = os__abs_path(p->filename); } _result_void _t2 = os__chdir(p->work_folder); (void)_t2; ; } _result_void _t3 = os__execve(p->filename, p->args, p->env); if (_t3.is_error) { IError err = _t3.err; eprintln(IError_str(err)); _v_exit(1); VUNREACHABLE(); ; } ; return 0; } VV_LOC void os__Process_unix_wait(os__Process* p) { os__Process_impl_check_pid_status(p, false, 0); } VV_LOC bool os__Process_impl_check_pid_status(os__Process* p, bool exit_early_on_ret0, int waitpid_options) { int cstatus = 0; int ret = -1; #if !defined(CUSTOM_DEFINE_emscripten) { ret = waitpid(p->pid, &cstatus, waitpid_options); } #endif p->code = ret; if (ret == -1) { p->err = os__posix_get_error_msg(errno); return false; } if (exit_early_on_ret0 && ret == 0) { return true; } multi_return_int_bool mr_3008 = os__posix_wait4_to_exit_status(cstatus); int pret = mr_3008.arg0; bool is_signaled = mr_3008.arg1; if (is_signaled) { p->status = os__ProcessState__aborted; p->err = str_intp(3, _MOV((StrIntpData[]){{_S("Terminated by signal "), 0x4fe27, {.d_i32 = pret}}, {_S(" ("), 0xfe10, {.d_s = os__sigint_to_signal_name(pret)}}, {_S(")"), 0, { .d_c = 0 }}})); pret += 128; } else { p->status = os__ProcessState__exited; } p->code = pret; return false; } VV_LOC int os__Process_win_spawn_process(os__Process* p) { return 0; } VV_LOC void os__Process_win_wait(os__Process* p) { } _result_anon_fn_os__signal os__signal_opt(os__Signal signum, void (*handler)(os__Signal )) { errno = 0; voidptr prev_handler = signal(((int)(signum)), (voidptr)handler); if (prev_handler == SIG_ERR) { return (_result_anon_fn_os__signal){ .is_error=true, .err=error_with_code(os__posix_get_error_msg(EINVAL), EINVAL), .data={E_STRUCT} }; } _result_anon_fn_os__signal _t2 = {0}; _result_ok(&(os__SignalHandler[]) { (voidptr)((os__SignalHandler)(prev_handler)) }, (_result*)(&_t2), sizeof(os__SignalHandler)); return _t2; } VV_LOC void os__sleep_ms(i64 ms) { #if defined(_WIN32) { Sleep(((u32)(ms))); } #else { struct timespec req = ((struct timespec){.tv_sec = (i64)(ms / 1000),.tv_nsec = (i64)(1000000 * ((i64)(ms % 1000))),}); struct timespec rem = ((struct timespec){.tv_sec = 0,.tv_nsec = 0,}); for (;;) { if (!(nanosleep(&req, &rem) < 0)) break; if (errno == EINTR) { req = rem; } else { break; } } } #endif } _result_os__Stat os__stat(string path) { struct stat s; { // Unsafe block int res = stat(((char*)(path.str)), &s); if (res != 0) { return (_result_os__Stat){ .is_error=true, .err=os__error_posix(((os__SystemError){.msg = (string){.str=(byteptr)"", .is_lit=1},.code = _const_os__error_code_not_set,})), .data={E_STRUCT} }; } _result_os__Stat _t2 = {0}; _result_ok(&(os__Stat[]) { ((os__Stat){ .dev = s.st_dev, .inode = s.st_ino, .mode = s.st_mode, .nlink = s.st_nlink, .uid = s.st_uid, .gid = s.st_gid, .rdev = s.st_rdev, .size = s.st_size, .atime = s.st_atime, .mtime = s.st_mtime, .ctime = s.st_ctime, }) }, (_result*)(&_t2), sizeof(os__Stat)); return _t2; } return (_result_os__Stat){0}; } _result_os__Stat os__lstat(string path) { struct stat s; { // Unsafe block int res = lstat(((char*)(path.str)), &s); if (res != 0) { return (_result_os__Stat){ .is_error=true, .err=os__error_posix(((os__SystemError){.msg = (string){.str=(byteptr)"", .is_lit=1},.code = _const_os__error_code_not_set,})), .data={E_STRUCT} }; } _result_os__Stat _t2 = {0}; _result_ok(&(os__Stat[]) { ((os__Stat){ .dev = s.st_dev, .inode = s.st_ino, .mode = s.st_mode, .nlink = s.st_nlink, .uid = s.st_uid, .gid = s.st_gid, .rdev = s.st_rdev, .size = s.st_size, .atime = s.st_atime, .mtime = s.st_mtime, .ctime = s.st_ctime, }) }, (_result*)(&_t2), sizeof(os__Stat)); return _t2; } return (_result_os__Stat){0}; } os__FileType os__Stat_get_filetype(os__Stat st) { u32 _t1 = (st.mode & ((u32)(S_IFMT))); if (_t1 == (((u32)(S_IFREG)))) { return os__FileType__regular; } else if (_t1 == (((u32)(S_IFDIR)))) { return os__FileType__directory; } else if (_t1 == (((u32)(S_IFCHR)))) { return os__FileType__character_device; } else if (_t1 == (((u32)(S_IFBLK)))) { return os__FileType__block_device; } else if (_t1 == (((u32)(S_IFIFO)))) { return os__FileType__fifo; } else if (_t1 == (((u32)(S_IFLNK)))) { return os__FileType__symbolic_link; } else if (_t1 == (((u32)(S_IFSOCK)))) { return os__FileType__socket; } else { return os__FileType__unknown; } return 0; } bool os__is_dir(string path) { _result_os__Stat _t1 = os__stat(path); if (_t1.is_error) { IError err = _t1.err; return false; } os__Stat attr = (*(os__Stat*)_t1.data); return os__Stat_get_filetype(attr) == os__FileType__directory; } bool os__is_link(string path) { _result_os__Stat _t1 = os__lstat(path); if (_t1.is_error) { IError err = _t1.err; return false; } os__Stat attr = (*(os__Stat*)_t1.data); return os__Stat_get_filetype(attr) == os__FileType__symbolic_link; } os__filelock__FileLock os__filelock__new(string fileName) { return ((os__filelock__FileLock){.name = fileName,.fd = -1,}); } bool os__filelock__FileLock_wait_acquire(os__filelock__FileLock* l, time__Duration timeout) { time__Time fin = time__Time_add(time__now(), timeout); for (;;) { if (!(time__Time__lt(time__now(), fin))) break; if (os__filelock__FileLock_try_acquire(l)) { return true; } time__sleep(1 * _const_time__millisecond); } return false; } bool os__filelock__FileLock_release(os__filelock__FileLock* l) { if (l->fd != -1) { os__filelock__FileLock_unlink(l); return true; } return false; } void os__filelock__FileLock_unlink(os__filelock__FileLock* l) { if (l->fd != -1) { close(l->fd); l->fd = -1; } unlink(((char*)(l->name.str))); } VV_LOC int os__filelock__open_lockfile(string f) { int fd = open(((char*)(f.str)), O_CREAT, 0644); if (fd == -1) { fd = open(((char*)(f.str)), O_RDONLY, 0); } return fd; } bool os__filelock__FileLock_try_acquire(os__filelock__FileLock* l) { if (l->fd != -1) { return true; } int fd = os__filelock__open_lockfile(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = l->name}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (fd != -1) { int err = flock(fd, (LOCK_EX | LOCK_NB)); if (err == -1) { close(fd); return false; } l->fd = fd; return true; } return false; } v__depgraph__OrderedDepMap v__depgraph__new_ordered_dependency_map(void) { v__depgraph__OrderedDepMap res = ((v__depgraph__OrderedDepMap){.keys = __new_array(0, 0, sizeof(string)),.data = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}); ArrayFlags_set(&res.keys.flags, ArrayFlags__noslices); return res; } void v__depgraph__OrderedDepMap_set(v__depgraph__OrderedDepMap* o, string name, Array_string deps) { if (!_IN_MAP(ADDR(string, name), ADDR(map, o->data))) { array_push((array*)&o->keys, _MOV((string[]){ string_clone(name) })); } (*(Array_string*)map_get_and_set((map*)&o->data, &(string[]){name}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })) = deps; } void v__depgraph__OrderedDepMap_add(v__depgraph__OrderedDepMap* o, string name, Array_string deps) { Array_string d = v__depgraph__OrderedDepMap_get(o, name); for (int _t1 = 0; _t1 < deps.len; ++_t1) { string dep = ((string*)deps.data)[_t1]; if (!(Array_string_contains(d, dep))) { array_push((array*)&d, _MOV((string[]){ string_clone(dep) })); } } v__depgraph__OrderedDepMap_set(o, name, d); } Array_string v__depgraph__OrderedDepMap_get(v__depgraph__OrderedDepMap* o, string name) { Array_string* _t2 = (Array_string*)(map_get_check(ADDR(map, o->data), &(string[]){name})); _option_Array_string _t1 = {0}; if (_t2) { *((Array_string*)&_t1.data) = *((Array_string*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } ; if (_t1.state != 0) { IError err = _t1.err; *(Array_string*) _t1.data = __new_array_with_default(0, 0, sizeof(string), 0); } Array_string res = (*(Array_string*)_t1.data); return res; } void v__depgraph__OrderedDepMap_delete(v__depgraph__OrderedDepMap* o, string name) { if (!_IN_MAP(ADDR(string, name), ADDR(map, o->data))) { _v_panic(str_intp(2, _MOV((StrIntpData[]){{_S("delete: no such key: "), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } for (int i = 0; i < o->keys.len; ++i) { string item = ((string*)o->keys.data)[i]; if (item.len == name.len && string__eq(item, name)) { array_delete(&o->keys, i); break; } } map_delete(&o->data, &(string[]){name}); } void v__depgraph__OrderedDepMap_apply_diff(v__depgraph__OrderedDepMap* o, string name, Array_string deps) { Array_string diff = __new_array_with_default(0, 0, sizeof(string), 0); Array_string deps_of_name = v__depgraph__OrderedDepMap_get(o, name); for (int _t1 = 0; _t1 < deps_of_name.len; ++_t1) { string dep = ((string*)deps_of_name.data)[_t1]; if (!(Array_string_contains(deps, dep))) { array_push((array*)&diff, _MOV((string[]){ string_clone(dep) })); } } v__depgraph__OrderedDepMap_set(o, name, diff); } int v__depgraph__OrderedDepMap_size(v__depgraph__OrderedDepMap* o) { return o->data.len; } v__depgraph__DepGraph* v__depgraph__new_dep_graph(void) { return ((v__depgraph__DepGraph*)memdup(&(v__depgraph__DepGraph){.acyclic = true,.nodes = __new_array_with_default(0, 1024, sizeof(v__depgraph__DepGraphNode), 0),.values = new_map(sizeof(string), sizeof(i64), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}, sizeof(v__depgraph__DepGraph))); } void v__depgraph__DepGraph_add(v__depgraph__DepGraph* graph, string mod, Array_string deps) { v__depgraph__DepGraphNode new_node = ((v__depgraph__DepGraphNode){.name = mod,.value = 0,.deps = array_clone_to_depth(&deps, 0),}); array_push((array*)&graph->nodes, _MOV((v__depgraph__DepGraphNode[]){ new_node })); map_set(&graph->values, &(string[]){mod}, &(i64[]) { 0 }); } void v__depgraph__DepGraph_add_with_value(v__depgraph__DepGraph* graph, string mod, Array_string deps, i64 value) { v__depgraph__DepGraphNode new_node = ((v__depgraph__DepGraphNode){.name = mod,.value = value,.deps = array_clone_to_depth(&deps, 0),}); array_push((array*)&graph->nodes, _MOV((v__depgraph__DepGraphNode[]){ new_node })); map_set(&graph->values, &(string[]){mod}, &(i64[]) { value }); } v__depgraph__DepGraph* v__depgraph__DepGraph_resolve(v__depgraph__DepGraph* graph) { v__depgraph__OrderedDepMap node_names = v__depgraph__new_ordered_dependency_map(); v__depgraph__OrderedDepMap node_deps = v__depgraph__new_ordered_dependency_map(); for (int _t1 = 0; _t1 < graph->nodes.len; ++_t1) { v__depgraph__DepGraphNode node = ((v__depgraph__DepGraphNode*)graph->nodes.data)[_t1]; v__depgraph__OrderedDepMap_add(&node_names, node.name, node.deps); v__depgraph__OrderedDepMap_add(&node_deps, node.name, node.deps); } v__depgraph__DepGraph* resolved = v__depgraph__new_dep_graph(); for (;;) { if (!(v__depgraph__OrderedDepMap_size(&node_deps) != 0)) break; Array_string ready_set = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t2 = 0; _t2 < node_deps.keys.len; ++_t2) { string name = ((string*)node_deps.keys.data)[_t2]; Array_string deps = v__depgraph__OrderedDepMap_get(&node_deps, name); if (deps.len == 0) { array_push((array*)&ready_set, _MOV((string[]){ string_clone(name) })); } } if (ready_set.len == 0) { resolved->acyclic = false; for (int _t4 = 0; _t4 < node_deps.keys.len; ++_t4) { string name = ((string*)node_deps.keys.data)[_t4]; v__depgraph__DepGraph_add_with_value(resolved, name, v__depgraph__OrderedDepMap_get(&node_names, name), (*(i64*)map_get(ADDR(map, graph->values), &(string[]){name}, &(i64[]){ 0 }))); } return resolved; } for (int _t6 = 0; _t6 < ready_set.len; ++_t6) { string name = ((string*)ready_set.data)[_t6]; v__depgraph__OrderedDepMap_delete(&node_deps, name); Array_string resolved_deps = v__depgraph__OrderedDepMap_get(&node_names, name); v__depgraph__DepGraph_add_with_value(resolved, name, resolved_deps, (*(i64*)map_get(ADDR(map, graph->values), &(string[]){name}, &(i64[]){ 0 }))); } for (int _t7 = 0; _t7 < node_deps.keys.len; ++_t7) { string name = ((string*)node_deps.keys.data)[_t7]; v__depgraph__OrderedDepMap_apply_diff(&node_deps, name, ready_set); } } return resolved; } string v__depgraph__DepGraph_display(v__depgraph__DepGraph* graph) { Array_string out = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < graph->nodes.len; ++_t1) { v__depgraph__DepGraphNode node = ((v__depgraph__DepGraphNode*)graph->nodes.data)[_t1]; if (node.deps.len == 0) { array_push((array*)&out, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S(" * "), 0xfe10, {.d_s = node.name}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else { for (int _t3 = 0; _t3 < node.deps.len; ++_t3) { string dep = ((string*)node.deps.data)[_t3]; array_push((array*)&out, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_S(" * "), 0xfe10, {.d_s = node.name}}, {_S(" -> "), 0xfe10, {.d_s = dep}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } } return Array_string_join(out, _S("\n")); } string v__depgraph__DepGraph_display_cycles(v__depgraph__DepGraph* graph) { bool seen = false; Array_string out = __new_array_with_default(0, 0, sizeof(string), 0); v__depgraph__NodeNames nn = ((v__depgraph__NodeNames){.is_cycle = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.names = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}); for (int _t1 = 0; _t1 < graph->nodes.len; ++_t1) { v__depgraph__DepGraphNode node = ((v__depgraph__DepGraphNode*)graph->nodes.data)[_t1]; (*(Array_string*)map_get_and_set((map*)&nn.names, &(string[]){node.name}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })) = node.deps; } Map_string_Array_string _t2 = nn.names; int _t4 = _t2.key_values.len; for (int _t3 = 0; _t3 < _t4; ++_t3 ) { int _t5 = _t2.key_values.len - _t4; _t4 = _t2.key_values.len; if (_t5 < 0) { _t3 = -1; continue; } if (!DenseArray_has_index(&_t2.key_values, _t3)) {continue;} string k = *(string*)DenseArray_key(&_t2.key_values, _t3); k = string_clone(k); Array_string cycle_names = __new_array_with_default(0, 0, sizeof(string), 0); if (_IN_MAP(ADDR(string, k), ADDR(map, nn.is_cycle))) { continue; } multi_return_bool_Array_string mr_3778 = v__depgraph__NodeNames_is_part_of_cycle(&nn, k, cycle_names); seen = mr_3778.arg0; cycle_names = mr_3778.arg1; if (seen) { array_push((array*)&out, _MOV((string[]){ string__plus(_S(" * "), Array_string_join(cycle_names, _S(" -> "))) })); nn.is_cycle = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; } } return Array_string_join(out, _S("\n")); } VV_LOC multi_return_bool_Array_string v__depgraph__NodeNames_is_part_of_cycle(v__depgraph__NodeNames* nn, string name, Array_string already_seen) { bool seen = false; Array_string new_already_seen = array_clone_to_depth(&already_seen, 0); if (_IN_MAP(ADDR(string, name), ADDR(map, nn->is_cycle))) { return (multi_return_bool_Array_string){.arg0=(*(bool*)map_get(ADDR(map, nn->is_cycle), &(string[]){name}, &(bool[]){ 0 })), .arg1=new_already_seen}; } if ((Array_string_contains(already_seen, name))) { array_push((array*)&new_already_seen, _MOV((string[]){ string_clone(name) })); map_set(&nn->is_cycle, &(string[]){name}, &(bool[]) { true }); return (multi_return_bool_Array_string){.arg0=true, .arg1=new_already_seen}; } array_push((array*)&new_already_seen, _MOV((string[]){ string_clone(name) })); Array_string deps = (*(Array_string*)map_get(ADDR(map, nn->names), &(string[]){name}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })); if (deps.len == 0) { map_set(&nn->is_cycle, &(string[]){name}, &(bool[]) { false }); return (multi_return_bool_Array_string){.arg0=false, .arg1=new_already_seen}; } for (int _t6 = 0; _t6 < deps.len; ++_t6) { string d = ((string*)deps.data)[_t6]; Array_string d_already_seen = array_clone_to_depth(&new_already_seen, 0); multi_return_bool_Array_string mr_4511 = v__depgraph__NodeNames_is_part_of_cycle(nn, d, d_already_seen); seen = mr_4511.arg0; d_already_seen = mr_4511.arg1; if (seen) { new_already_seen = array_clone_to_depth(&d_already_seen, 0); map_set(&nn->is_cycle, &(string[]){name}, &(bool[]) { true }); return (multi_return_bool_Array_string){.arg0=true, .arg1=new_already_seen}; } } map_set(&nn->is_cycle, &(string[]){name}, &(bool[]) { false }); return (multi_return_bool_Array_string){.arg0=false, .arg1=new_already_seen}; } void v__depgraph__show(v__depgraph__DepGraph* graph, string path) { v__dotgraph__DotGraph* dg = v__dotgraph__new(_S("ModGraph"), str_intp(2, _MOV((StrIntpData[]){{_S("ModGraph for "), 0xfe10, {.d_s = path}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("blue")); string mbuiltin = _S("builtin"); for (int _t1 = 0; _t1 < graph->nodes.len; ++_t1) { v__depgraph__DepGraphNode node = ((v__depgraph__DepGraphNode*)graph->nodes.data)[_t1]; bool is_main = fast_string_eq(node.name, _S("main")); v__dotgraph__DotGraph_new_node(dg, node.name, ((v__dotgraph__NewNodeConfig){.node_name = (string){.str=(byteptr)"", .is_lit=1},.should_highlight = is_main,.tooltip = (string){.str=(byteptr)"", .is_lit=1},.ctx = ((void*)0),.name2node_fn = v__dotgraph__node_name,})); Array_string deps = array_clone_to_depth(&node.deps, 0); if (!string__eq(node.name, mbuiltin) && !(Array_string_contains(deps, mbuiltin))) { array_push((array*)&deps, _MOV((string[]){ string_clone(mbuiltin) })); } for (int _t3 = 0; _t3 < deps.len; ++_t3) { string dep = ((string*)deps.data)[_t3]; v__dotgraph__DotGraph_new_edge(dg, node.name, dep, ((v__dotgraph__NewEdgeConfig){.should_highlight = is_main,.ctx = ((void*)0),.name2node_fn = v__dotgraph__node_name,})); } } v__dotgraph__DotGraph_finish(dg); } inline VV_LOC u32 rand__seed__nr_next(u32 prev) { return (u32)((u32)(prev * 1664525U) + 1013904223U); } Array_u32 rand__seed__time_seed_array(int count) { u64 ctime = time__sys_mono_now(); u32 seed = ((u32)(((ctime >> 32U) ^ ((ctime & 0x00000000FFFFFFFFU))))); Array_u32 seed_data = __new_array_with_default(0, count, sizeof(u32), 0); for (int _t1 = 0; _t1 < count; ++_t1) { seed = rand__seed__nr_next(seed); array_push((array*)&seed_data, _MOV((u32[]){ rand__seed__nr_next(seed) })); } return seed_data; } u64 rand__seed__time_seed_64(void) { Array_u32 seed_data = rand__seed__time_seed_array(2); u64 lower = ((u64)((*(u32*)array_get(seed_data, 0)))); u64 upper = ((u64)((*(u32*)array_get(seed_data, 1)))); array_free(&seed_data); u64 res = (lower | ((upper << 32U))); return res; } string term__format(string msg, string open, string close) { return str_intp(4, _MOV((StrIntpData[]){{_S("\033["), 0xfe10, {.d_s = open}}, {_S("m"), 0xfe10, {.d_s = msg}}, {_S("\033["), 0xfe10, {.d_s = close}}, {_S("m"), 0, { .d_c = 0 }}})); } string term__bold(string msg) { return term__format(msg, _S("1"), _S("22")); } string term__red(string msg) { return term__format(msg, _S("31"), _S("39")); } string term__yellow(string msg) { return term__format(msg, _S("33"), _S("39")); } string term__magenta(string msg) { return term__format(msg, _S("35"), _S("39")); } string term__bg_cyan(string msg) { return term__format(msg, _S("46"), _S("49")); } string term__bright_blue(string msg) { return term__format(msg, _S("94"), _S("39")); } string term__bright_white(string msg) { return term__format(msg, _S("97"), _S("39")); } string term__highlight_command(string command) { return term__bright_white(term__bg_cyan(str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = command}}, {_S(" "), 0, { .d_c = 0 }}})))); } bool term__can_show_color_on_stdout(void) { _option_bool _t1; if (_t1 = can_show_color_on_stdout_cache, _t1.state == 0) { bool status = *(bool*)_t1.data; return status; } bool status = term__supports_escape_sequences(1); _option_bool _t3; _option_ok(&(bool[]) { status }, (_option*)(&_t3), sizeof(bool)); can_show_color_on_stdout_cache = _t3; return status; } bool term__can_show_color_on_stderr(void) { _option_bool _t1; if (_t1 = can_show_color_on_stderr_cache, _t1.state == 0) { bool status = *(bool*)_t1.data; return status; } bool status = term__supports_escape_sequences(2); _option_bool _t3; _option_ok(&(bool[]) { status }, (_option*)(&_t3), sizeof(bool)); can_show_color_on_stderr_cache = _t3; return status; } string term__ecolorize(string (*cfn)(string ), string s) { if (term__can_show_color_on_stderr()) { return cfn(s); } return s; } VV_LOC bool term__supports_escape_sequences(int fd) { bool term__supports_escape_sequences_defer_0 = false; string vcolors_override; bool term__supports_escape_sequences_defer_1 = false; string env_term; bool term__supports_escape_sequences_defer_2 = false; string env_conemu; vcolors_override = os__getenv(_S("VCOLORS")); term__supports_escape_sequences_defer_0 = true; if (_SLIT_EQ(vcolors_override.str, vcolors_override.len, "always")) { bool _t1 = true; // Defer begin if (term__supports_escape_sequences_defer_0) { string_free(&vcolors_override); } // Defer end return _t1; } if (_SLIT_EQ(vcolors_override.str, vcolors_override.len, "never")) { bool _t2 = false; // Defer begin if (term__supports_escape_sequences_defer_0) { string_free(&vcolors_override); } // Defer end return _t2; } env_term = os__getenv(_S("TERM")); term__supports_escape_sequences_defer_1 = true; if (_SLIT_EQ(env_term.str, env_term.len, "dumb")) { bool _t3 = false; // Defer begin if (term__supports_escape_sequences_defer_1) { string_free(&env_term); } // Defer end // Defer begin if (term__supports_escape_sequences_defer_0) { string_free(&vcolors_override); } // Defer end return _t3; } #if defined(_WIN32) { env_conemu = os__getenv(_S("ConEmuANSI")); term__supports_escape_sequences_defer_2 = true; if (_SLIT_EQ(env_conemu.str, env_conemu.len, "ON")) { bool _t5 = true; // Defer begin if (term__supports_escape_sequences_defer_2) { #if defined(_WIN32) string_free(&env_conemu); #endif } // Defer end // Defer begin if (term__supports_escape_sequences_defer_1) { string_free(&env_term); } // Defer end // Defer begin if (term__supports_escape_sequences_defer_0) { string_free(&vcolors_override); } // Defer end return _t5; } bool _t6 = ((os__is_atty(fd) & 0x0004)) > 0; // Defer begin if (term__supports_escape_sequences_defer_2) { #if defined(_WIN32) string_free(&env_conemu); #endif } // Defer end // Defer begin if (term__supports_escape_sequences_defer_1) { string_free(&env_term); } // Defer end // Defer begin if (term__supports_escape_sequences_defer_0) { string_free(&vcolors_override); } // Defer end return _t6; } #else { bool _t7 = os__is_atty(fd) > 0; // Defer begin if (term__supports_escape_sequences_defer_2) { #if defined(_WIN32) string_free(&env_conemu); #endif } // Defer end // Defer begin if (term__supports_escape_sequences_defer_1) { string_free(&env_term); } // Defer end // Defer begin if (term__supports_escape_sequences_defer_0) { string_free(&vcolors_override); } // Defer end return _t7; } #endif return 0; } VV_LOC string v__help__hdir(string base) { return os__join_path(base, new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("vlib"), _S("v"), _S("help")}))); } VV_LOC string v__help__help_dir(void) { string vexe = v__help__get_vexe(); if ((vexe).len != 0) { return v__help__hdir(os__dir(vexe)); } return v__help__hdir(_S("/home/runner/work/v/v")); } VNORETURN void v__help__print_and_exit(string topic, v__help__ExitOptions opts) { if (_SLIT_EQ(topic.str, topic.len, "topics")) { v__help__print_known_topics(); _v_exit(opts.exit_code); VUNREACHABLE(); } int fail_code = (opts.exit_code != 0 ? (opts.exit_code) : (1)); for (int _t1 = 0; _t1 < topic.len; ++_t1) { u8 c = topic.str[_t1]; if (!u8_is_letter(c) && !u8_is_digit(c) && c != '-') { v__help__print_topic_unknown(topic); _v_exit(fail_code); VUNREACHABLE(); } } if ((Array_string_contains(_const_v__help__cli_topics, topic))) { string vexe = v__help__get_vexe(); os__system(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(vexe)}}, {_S(" "), 0xfe10, {.d_s = topic}}, {_S(" --help"), 0, { .d_c = 0 }}}))); _v_exit(opts.exit_code); VUNREACHABLE(); } string topic_path = _S(""); Array_string _t2 = os__walk_ext(v__help__help_dir(), _S(".txt"), ((os__WalkParams){.hidden = 0,})); for (int _t3 = 0; _t3 < _t2.len; ++_t3) { string path = ((string*)_t2.data)[_t3]; if (string__eq(topic, string_all_before(os__file_name(path), _S(".txt")))) { topic_path = path; break; } } if ((topic_path).len == 0) { v__help__print_topic_unknown(topic); v__help__print_known_topics(); _v_exit(fail_code); VUNREACHABLE(); } _result_string _t4 = os__read_file(topic_path); if (_t4.is_error) { IError err = _t4.err; string msg = IError_str(err); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("error: failed reading topic file: "), 0xfe10, {.d_s = msg}}, {_SLIT0, 0, { .d_c = 0 }}}))); _v_exit(fail_code); VUNREACHABLE(); ; } string topic_content = (*(string*)_t4.data); string cleaned = string_trim_space(topic_content); println(cleaned); _v_exit(opts.exit_code); VUNREACHABLE(); while(1); } VV_LOC void v__help__print_topic_unknown(string topic) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("error: unknown help topic \""), 0xfe10, {.d_s = topic}}, {_S("\". Use `v help` for usage information."), 0, { .d_c = 0 }}}))); } VV_LOC void v__help__print_known_topics(void) { Array_string topic_paths = os__walk_ext(v__help__help_dir(), _S(".txt"), ((os__WalkParams){.hidden = 0,})); Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < topic_paths.len; ++_t1) { string path = ((string*)topic_paths.data)[_t1]; string topic = string_all_before(os__file_name(path), _S(".txt")); if (_SLIT_NE(topic.str, topic.len, "default")) { array_push((array*)&res, _MOV((string[]){ string_clone(topic) })); } } Array_string _t3 = array_clone_to_depth(ADDR(Array_string,res), 0); if (_t3.len > 0) { qsort(_t3.data, _t3.len, _t3.element_size, (voidptr)compare_5856511986181937489_string); } ; Array_string sorted_topics =_t3; println(str_intp(2, _MOV((StrIntpData[]){{_S("Known help topics: "), 0xfe10, {.d_s = Array_string_str(sorted_topics)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } VV_LOC string v__help__get_vexe(void) { string vexe = os__getenv(_S("VEXE")); if ((vexe).len == 0) { vexe = os__executable(); } return vexe; } string v__util__version__vhash(void) { Array_fixed_u8_50 buf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; buf[0] = 0; { // Unsafe block u8* bp = &buf[0]; snprintf(((char*)(bp)), 50, "%s", V_COMMIT_HASH); return tos_clone(bp); } return (string){.str=(byteptr)"", .is_lit=1}; } string v__util__version__full_hash(void) { string build_hash = v__util__version__vhash(); if ((vcurrent_hash()).len == 0 || string__eq(string_substr(build_hash, 0, 7), vcurrent_hash())) { return build_hash; } return str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = build_hash}}, {_S("."), 0xfe10, {.d_s = vcurrent_hash()}}, {_SLIT0, 0, { .d_c = 0 }}})); } string v__util__version__full_v_version(bool is_verbose) { if (is_verbose) { return str_intp(3, _MOV((StrIntpData[]){{_S("V "), 0xfe10, {.d_s = _const_v__util__version__v_version}}, {_S(" "), 0xfe10, {.d_s = v__util__version__full_hash()}}, {_SLIT0, 0, { .d_c = 0 }}})); } return str_intp(3, _MOV((StrIntpData[]){{_S("V "), 0xfe10, {.d_s = _const_v__util__version__v_version}}, {_S(" "), 0xfe10, {.d_s = vcurrent_hash()}}, {_SLIT0, 0, { .d_c = 0 }}})); } _result_string v__util__version__githash(string path) { string git_head_file = os__join_path(path, new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S(".git"), _S("HEAD")}))); if (!os__exists(git_head_file)) { return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("failed to find `"), 0xfe10, {.d_s = git_head_file}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } _result_string _t2 = os__read_file(git_head_file); if (_t2.is_error) { IError err = _t2.err; return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("failed to read `"), 0xfe10, {.d_s = git_head_file}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } string head_content = (*(string*)_t2.data); string _t4; /* if prepend */ if (string_starts_with(head_content, _S("ref: "))) { string rev_rel_path = string_trim_space(string_replace(head_content, _S("ref: "), _S(""))); string rev_file = os__join_path(path, new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S(".git"), rev_rel_path}))); if (!os__exists(rev_file)) { return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("failed to find revision file `"), 0xfe10, {.d_s = rev_file}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } _result_string _t6 = os__read_file(rev_file); if (_t6.is_error) { IError err = _t6.err; return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("failed to read revision file `"), 0xfe10, {.d_s = rev_file}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } _t4 = (*(string*)_t6.data); } else { _t4 = head_content; } string current_branch_hash = _t4; int desired_hash_length = 7; _result_string _t9 = string_substr_with_check(current_branch_hash, 0, desired_hash_length); if (_t9.is_error) { IError err = _t9.err; return (_result_string){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("failed to limit hash `"), 0xfe10, {.d_s = current_branch_hash}}, {_S("` to "), 0xfe07, {.d_i32 = desired_hash_length}}, {_S(" characters"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } _result_string _t8 = {0}; _result_ok(&(string[]) { *(string*)&_t9.data }, (_result*)(&_t8), sizeof(string)); return _t8; } VV_LOC void v__vcache__remove_old_cache_folder(void) { string old_cache_folder = os__join_path(os__vmodules_dir(), new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("cache")}))); if (os__exists(old_cache_folder)) { string old_readme_file = os__join_path(old_cache_folder, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("README.md")}))); if (os__file_size(old_readme_file) == 254U) { _result_void _t1 = os__rmdir_all(old_cache_folder); (void)_t1; ; ; } } } v__vcache__CacheManager v__vcache__new_cache_manager(Array_string opts) { _option_string _t1 = os__getenv_opt(_S("VCACHE")); if (_t1.state != 0) { IError err = _t1.err; *(string*) _t1.data = os__join_path(os__vmodules_dir(), new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S(".cache")}))); } string vcache_basepath = (*(string*)_t1.data); ; ; if (!os__is_dir(vcache_basepath)) { v__vcache__remove_old_cache_folder(); _result_void _t2 = os__mkdir_all(vcache_basepath, ((os__MkdirParams){.mode = 0700U,})); if (_t2.is_error) { IError err = _t2.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; ; } string readme_file = os__join_path(vcache_basepath, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("README.md")}))); if (!os__is_file(readme_file)) { string readme_content = string_strip_margin(_S("This folder contains cached build artifacts from the V build system.\n\011\011|You can safely delete it, if it is getting too large.\n\011\011|It will be recreated the next time you compile something with V.\n\011\011|You can change its location with the VCACHE environment variable.\n\011\011")); _result_void _t3 = os__write_file(readme_file, readme_content); if (_t3.is_error) { IError err = _t3.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; ; } Map_string_bool deduped_opts = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int _t4 = 0; _t4 < opts.len; ++_t4) { string o = ((string*)opts.data)[_t4]; map_set(&deduped_opts, &(string[]){o}, &(bool[]) { true }); } Array_string _t5 = {0}; Array_string _t5_orig = map_keys(&deduped_opts); int _t5_len = _t5_orig.len; _t5 = __new_array(0, _t5_len, sizeof(string)); for (int _t6 = 0; _t6 < _t5_len; ++_t6) { string it = ((string*) _t5_orig.data)[_t6]; if ((it).len != 0 && !string_starts_with(it, _S("['gcboehm', "))) { array_push((array*)&_t5, &it); } } Array_string deduped_opts_keys =_t5; string original_vopts = Array_string_join(deduped_opts_keys, _S("|")); return ((v__vcache__CacheManager){.basepath = vcache_basepath,.original_vopts = original_vopts,.vopts = original_vopts,.k2cpath = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}); } void v__vcache__CacheManager_set_temporary_options(v__vcache__CacheManager* cm, Array_string new_opts) { cm->vopts = string__plus(string__plus(cm->original_vopts, _S("#")), Array_string_join(new_opts, _S("|"))); ; } string v__vcache__CacheManager_key2cpath(v__vcache__CacheManager* cm, string key) { string* _t2 = (string*)(map_get_check(ADDR(map, cm->k2cpath), &(string[]){key})); _option_string _t1 = {0}; if (_t2) { *((string*)&_t1.data) = *((string*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } ; if (_t1.state != 0) { IError err = _t1.err; *(string*) _t1.data = _S(""); } string cpath = (*(string*)_t1.data); if ((cpath).len == 0) { string hk = string__plus(cm->vopts, key); string a = u64_hex_full(hash__sum64_string(hk, 5U)); string b = u64_hex_full(hash__sum64_string(hk, 7U)); string khash = string__plus(a, b); string prefix = string_substr(khash, 0, 2); string cprefix_folder = os__join_path(cm->basepath, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){prefix}))); cpath = os__join_path(cprefix_folder, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){khash}))); if (!os__is_dir(cprefix_folder)) { _result_void _t3 = os__mkdir_all(cprefix_folder, ((os__MkdirParams){.mode = 0777,})); if (_t3.is_error) { IError err = _t3.err; if (!os__is_dir(cprefix_folder)) { _v_panic(IError_str(err)); VUNREACHABLE(); } ; } ; } ; ; ; ; map_set(&cm->k2cpath, &(string[]){key}, &(string[]) { cpath }); } ; return cpath; } string v__vcache__CacheManager_postfix_with_key2cpath(v__vcache__CacheManager* cm, string postfix, string key) { string prefix = v__vcache__CacheManager_key2cpath(cm, key); string res = string__plus(prefix, postfix); return res; } VV_LOC string v__vcache__normalise_mod(string mod) { return string_trim(string_replace(string_replace(string_replace(mod, _S("/"), _S(".")), _S("\\"), _S(".")), _S("vlib."), _S("")), _S(".")); } string v__vcache__CacheManager_mod_postfix_with_key2cpath(v__vcache__CacheManager* cm, string mod, string postfix, string key) { string prefix = v__vcache__CacheManager_key2cpath(cm, key); string res = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = prefix}}, {_S(".module."), 0xfe10, {.d_s = v__vcache__normalise_mod(mod)}}, {_SLIT0, 0xfe10, {.d_s = postfix}}, {_SLIT0, 0, { .d_c = 0 }}})); return res; } _result_string v__vcache__CacheManager_exists(v__vcache__CacheManager* cm, string postfix, string key) { string fpath = v__vcache__CacheManager_postfix_with_key2cpath(cm, postfix, key); ; if (!os__exists(fpath)) { return (_result_string){ .is_error=true, .err=_v_error(_S("does not exist yet")), .data={E_STRUCT} }; } _result_string _t2 = {0}; _result_ok(&(string[]) { fpath }, (_result*)(&_t2), sizeof(string)); return _t2; } _result_string v__vcache__CacheManager_mod_exists(v__vcache__CacheManager* cm, string mod, string postfix, string key) { string fpath = v__vcache__CacheManager_mod_postfix_with_key2cpath(cm, mod, postfix, key); ; if (!os__exists(fpath)) { return (_result_string){ .is_error=true, .err=_v_error(_S("does not exist yet")), .data={E_STRUCT} }; } _result_string _t2 = {0}; _result_ok(&(string[]) { fpath }, (_result*)(&_t2), sizeof(string)); return _t2; } _result_string v__vcache__CacheManager_save(v__vcache__CacheManager* cm, string postfix, string key, string content) { string fpath = v__vcache__CacheManager_postfix_with_key2cpath(cm, postfix, key); _result_void _t1 = os__write_file(fpath, content); if (_t1.is_error) { _result_string _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } ; ; _result_string _t3 = {0}; _result_ok(&(string[]) { fpath }, (_result*)(&_t3), sizeof(string)); return _t3; } _result_string v__vcache__CacheManager_mod_save(v__vcache__CacheManager* cm, string mod, string postfix, string key, string content) { string fpath = v__vcache__CacheManager_mod_postfix_with_key2cpath(cm, mod, postfix, key); _result_void _t1 = os__write_file(fpath, content); if (_t1.is_error) { _result_string _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } ; ; _result_string _t3 = {0}; _result_ok(&(string[]) { fpath }, (_result*)(&_t3), sizeof(string)); return _t3; } _result_string v__vcache__CacheManager_load(v__vcache__CacheManager* cm, string postfix, string key) { _result_string _t1 = v__vcache__CacheManager_exists(cm, postfix, key); if (_t1.is_error) { _result_string _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } string fpath = (*(string*)_t1.data); _result_string _t3 = os__read_file(fpath); if (_t3.is_error) { _result_string _t4 = {0}; _t4.is_error = true; _t4.err = _t3.err; return _t4; } string content = (*(string*)_t3.data); ; _result_string _t5 = {0}; _result_ok(&(string[]) { content }, (_result*)(&_t5), sizeof(string)); return _t5; } string v__util__recompilation__disabling_file(string vroot) { string tools_folder = os__join_path(vroot, new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("cmd"), _S("tools")}))); string res = os__join_path_single(tools_folder, _S(".disable_autorecompilation")); return res; } Array_string v__util__vflags__join_env_vflags_and_os_args(void) { string vosargs = os__getenv(_S("VOSARGS")); if ((vosargs).len != 0) { return v__util__vflags__tokenize_to_args(vosargs); } string vflags = os__getenv(_S("VFLAGS")); if ((vflags).len != 0) { Array_string args = __new_array_with_default(0, 0, sizeof(string), 0); array_push((array*)&args, _MOV((string[]){ (*(string*)array_get(_const_os__args, 0)) })); _PUSH_MANY(&args, (v__util__vflags__tokenize_to_args(vflags)), _t3, Array_string); _PUSH_MANY(&args, (array_slice_ni(_const_os__args, 1, 2147483647)), _t4, Array_string); return args; } return _const_os__args; } Array_string v__util__vflags__tokenize_to_args(string s) { Array_string tokens = __new_array_with_default(0, 0, sizeof(string), 0); strings__Builder ctoken = strings__new_builder(20); bool in_quotes = false; rune quote_char = ' '; for (int i = 0; i < s.len; ++i) { u8 c = string_at(s, i); if (!in_quotes && (c == '"' || c == '\'')) { in_quotes = true; quote_char = c; } else if (in_quotes && c == quote_char) { if (i > 0 && string_at(s, (int_literal)(i - 1)) == '\\') { strings__Builder_go_back(&ctoken, 1); strings__Builder_write_rune(&ctoken, c); } else { in_quotes = false; array_push((array*)&tokens, _MOV((string[]){ strings__Builder_str(&ctoken) })); } } else if (u8_is_space(c) && !in_quotes) { if (ctoken.len > 0) { array_push((array*)&tokens, _MOV((string[]){ strings__Builder_str(&ctoken) })); } } else { strings__Builder_write_rune(&ctoken, c); } } if (ctoken.len > 0) { array_push((array*)&tokens, _MOV((string[]){ strings__Builder_str(&ctoken) })); } return tokens; } int runtime__nr_jobs(void) { #if defined(CUSTOM_DEFINE_cross) { return 1; } #endif int cpus = (int)(runtime__nr_cpus() - 1); int vjobs = string_int(os__getenv(_S("VJOBS"))); if (vjobs > 0) { cpus = vjobs; } if (cpus == 0) { return 1; } return cpus; } int runtime__nr_cpus(void) { return ((int)(sysconf(_SC_NPROCESSORS_ONLN))); } v__vmod__ModFileCacher* v__vmod__get_cache(void) { return _const_v__vmod__private_file_cacher; } v__vmod__ModFileCacher* v__vmod__new_mod_file_cacher(void) { return ((v__vmod__ModFileCacher*)memdup(&(v__vmod__ModFileCacher){.cache = new_map(sizeof(string), sizeof(v__vmod__ModFileAndFolder), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.folder_files = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.hits = 0,.misses = 0,.get_files_hits = 0,.get_files_misses = 0,}, sizeof(v__vmod__ModFileCacher))); } v__vmod__ModFileAndFolder v__vmod__ModFileCacher_get_by_file(v__vmod__ModFileCacher* mcache, string vfile) { return v__vmod__ModFileCacher_get_by_folder(mcache, os__dir(vfile)); } v__vmod__ModFileAndFolder v__vmod__ModFileCacher_get_by_folder(v__vmod__ModFileCacher* mcache, string vfolder) { string mfolder = os__real_path(vfolder); if (_IN_MAP(ADDR(string, mfolder), ADDR(map, mcache->cache))) { mcache->hits++; return (*(v__vmod__ModFileAndFolder*)map_get(ADDR(map, mcache->cache), &(string[]){mfolder}, &(v__vmod__ModFileAndFolder[]){ (v__vmod__ModFileAndFolder){.vmod_file = (string){.str=(byteptr)"", .is_lit=1},.vmod_folder = (string){.str=(byteptr)"", .is_lit=1},} })); } multi_return_Array_string_v__vmod__ModFileAndFolder mr_2647 = v__vmod__ModFileCacher_traverse(mcache, mfolder); Array_string traversed_folders = mr_2647.arg0; v__vmod__ModFileAndFolder res = mr_2647.arg1; for (int _t2 = 0; _t2 < traversed_folders.len; ++_t2) { string tfolder = ((string*)traversed_folders.data)[_t2]; v__vmod__ModFileCacher_add(mcache, tfolder, res); } mcache->misses++; return res; } VV_LOC void v__vmod__ModFileCacher_add(v__vmod__ModFileCacher* cacher, string path, v__vmod__ModFileAndFolder result) { (*(v__vmod__ModFileAndFolder*)map_get_and_set((map*)&cacher->cache, &(string[]){path}, &(v__vmod__ModFileAndFolder[]){ (v__vmod__ModFileAndFolder){.vmod_file = (string){.str=(byteptr)"", .is_lit=1},.vmod_folder = (string){.str=(byteptr)"", .is_lit=1},} })) = result; } VV_LOC multi_return_Array_string_v__vmod__ModFileAndFolder v__vmod__ModFileCacher_traverse(v__vmod__ModFileCacher* mcache, string mfolder) { string cfolder = mfolder; Array_string folders_so_far = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){string_clone(cfolder)})); int levels = 0; for (;;) { if (levels > 255) { break; } if (_SLIT_EQ(cfolder.str, cfolder.len, "/") || (cfolder).len == 0) { break; } if (_IN_MAP(ADDR(string, cfolder), ADDR(map, mcache->cache))) { mcache->hits++; v__vmod__ModFileAndFolder res = (*(v__vmod__ModFileAndFolder*)map_get(ADDR(map, mcache->cache), &(string[]){cfolder}, &(v__vmod__ModFileAndFolder[]){ (v__vmod__ModFileAndFolder){.vmod_file = (string){.str=(byteptr)"", .is_lit=1},.vmod_folder = (string){.str=(byteptr)"", .is_lit=1},} })); if (res.vmod_file.len == 0) { v__vmod__ModFileCacher_mark_folders_as_vmod_free(mcache, folders_so_far); } else { v__vmod__ModFileCacher_mark_folders_with_vmod(mcache, folders_so_far, res); } return (multi_return_Array_string_v__vmod__ModFileAndFolder){.arg0=__new_array_with_default(0, 0, sizeof(string), 0), .arg1=res}; } Array_string files = v__vmod__ModFileCacher_get_files(mcache, cfolder); if ((Array_string_contains(files, _S("v.mod")))) { v__vmod__ModFileAndFolder res = ((v__vmod__ModFileAndFolder){.vmod_file = os__join_path(cfolder, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("v.mod")}))),.vmod_folder = cfolder,}); return (multi_return_Array_string_v__vmod__ModFileAndFolder){.arg0=folders_so_far, .arg1=res}; } if (v__vmod__ModFileCacher_check_for_stop(mcache, files)) { break; } cfolder = os__dir(cfolder); array_push((array*)&folders_so_far, _MOV((string[]){ string_clone(cfolder) })); levels++; } v__vmod__ModFileCacher_mark_folders_as_vmod_free(mcache, folders_so_far); return (multi_return_Array_string_v__vmod__ModFileAndFolder){.arg0=new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){string_clone(mfolder)})), .arg1=((v__vmod__ModFileAndFolder){.vmod_file = _S(""),.vmod_folder = mfolder,})}; } VV_LOC void v__vmod__ModFileCacher_mark_folders_with_vmod(v__vmod__ModFileCacher* mcache, Array_string folders_so_far, v__vmod__ModFileAndFolder vmod) { for (int _t1 = 0; _t1 < folders_so_far.len; ++_t1) { string f = ((string*)folders_so_far.data)[_t1]; v__vmod__ModFileCacher_add(mcache, f, vmod); } } VV_LOC void v__vmod__ModFileCacher_mark_folders_as_vmod_free(v__vmod__ModFileCacher* mcache, Array_string folders_so_far) { for (int _t1 = 0; _t1 < folders_so_far.len; ++_t1) { string f = ((string*)folders_so_far.data)[_t1]; v__vmod__ModFileCacher_add(mcache, f, ((v__vmod__ModFileAndFolder){.vmod_file = _S(""),.vmod_folder = f,})); } } VV_LOC bool v__vmod__ModFileCacher_check_for_stop(v__vmod__ModFileCacher* mcache, Array_string files) { for (int _t1 = 0; _t1 < _const_v__vmod__mod_file_stop_paths.len; ++_t1) { string i = ((string*)_const_v__vmod__mod_file_stop_paths.data)[_t1]; if ((Array_string_contains(files, i))) { return true; } } return false; } VV_LOC Array_string v__vmod__ModFileCacher_get_files(v__vmod__ModFileCacher* mcache, string cfolder) { if (_IN_MAP(ADDR(string, cfolder), ADDR(map, mcache->folder_files))) { mcache->get_files_hits++; return (*(Array_string*)map_get(ADDR(map, mcache->folder_files), &(string[]){cfolder}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })); } mcache->get_files_misses++; Array_string files = __new_array_with_default(0, 0, sizeof(string), 0); if (os__exists(cfolder) && os__is_dir(cfolder)) { _result_Array_string _t2; if (_t2 = os__ls(cfolder), !_t2.is_error) { Array_string listing = *(Array_string*)_t2.data; files = array_clone_to_depth(&listing, 0); } } (*(Array_string*)map_get_and_set((map*)&mcache->folder_files, &(string[]){cfolder}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })) = files; return files; } string v__cflag__CFlag_str(v__cflag__CFlag* c) { return str_intp(6, _MOV((StrIntpData[]){{_S("CFlag{ name: \""), 0xfe10, {.d_s = c->name}}, {_S("\" value: \""), 0xfe10, {.d_s = c->value}}, {_S("\" mod: \""), 0xfe10, {.d_s = c->mod}}, {_S("\" os: \""), 0xfe10, {.d_s = c->os}}, {_S("\" cached: \""), 0xfe10, {.d_s = c->cached}}, {_S("\" }"), 0, { .d_c = 0 }}})); } VV_LOC multi_return_bool_string_int_Array_string v__cflag__find_first_existing_path(string remainder, string literal) { string sparams = string_all_before(string_substr(remainder, (int)(literal.len + 1), 2147483647), _S(")")); int delta_i = (int)((int)(sparams.len + literal.len) + 1); Array_string _t1 = {0}; Array_string _t1_orig = string_split_into_lines(string_replace(sparams, _S(","), _S("\n"))); int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { string it = ((string*) _t1_orig.data)[_t3]; string _t2 = string_trim(it, _S("\t \'\"")); array_push((array*)&_t1, &_t2); } Array_string svalues =_t1; for (int _t4 = 0; _t4 < svalues.len; ++_t4) { string spath = ((string*)svalues.data)[_t4]; if (os__exists(spath)) { return (multi_return_bool_string_int_Array_string){.arg0=true, .arg1=spath, .arg2=delta_i, .arg3=__new_array_with_default(0, 0, sizeof(string), 0)}; } } return (multi_return_bool_string_int_Array_string){.arg0=false, .arg1=_S(""), .arg2=delta_i, .arg3=svalues}; } _option_string v__cflag__CFlag_eval(v__cflag__CFlag* cf) { strings__Builder value_builder = strings__new_builder((int)(10 * cf->value.len)); cflag_eval_outer_loop: for (int i = 0; i < cf->value.len; i++) { u8 x = string_at(cf->value, i); if (x == '$') { string remainder = string_substr(cf->value, i, 2147483647); if (string_starts_with(remainder, _const_v__cflag__fexisting_literal)) { multi_return_bool_string_int_Array_string mr_1491 = v__cflag__find_first_existing_path(remainder, _const_v__cflag__fexisting_literal); bool found = mr_1491.arg0; string spath = mr_1491.arg1; int delta_i = mr_1491.arg2; Array_string svalues = mr_1491.arg3; if (found) { strings__Builder_write_string(&value_builder, spath); i += delta_i; continue; } _v_panic(str_intp(2, _MOV((StrIntpData[]){{_S(">> error: none of the paths "), 0xfe10, {.d_s = Array_string_str(svalues)}}, {_S(" exist"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } if (string_starts_with(remainder, _const_v__cflag__wexisting_literal)) { multi_return_bool_string_int_Array_string mr_1787 = v__cflag__find_first_existing_path(remainder, _const_v__cflag__wexisting_literal); bool found = mr_1787.arg0; string spath = mr_1787.arg1; int delta_i = mr_1787.arg2; if (found) { strings__Builder_write_string(&value_builder, spath); i += delta_i; continue; } return (_option_string){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } } strings__Builder_write_string(&value_builder, u8_ascii_str(x)); cflag_eval_outer_loop__continue: {} } cflag_eval_outer_loop__break: {} _option_string _t2; _option_ok(&(string[]) { strings__Builder_str(&value_builder) }, (_option*)(&_t2), sizeof(string)); return _t2; } _option_string v__cflag__CFlag_format(v__cflag__CFlag* cf) { string value = _S(""); if ((cf->cached).len != 0) { value = cf->cached; } else { _option_string _t1 = v__cflag__CFlag_eval(cf); if (_t1.state != 0) { _option_string _t2; memcpy(&_t2, &_t1, sizeof(_option)); return _t2; } value = (*(string*)_t1.data); } if ((fast_string_eq(cf->name, _S("-l")) || fast_string_eq(cf->name, _S("-Wa")) || fast_string_eq(cf->name, _S("-Wl")) || fast_string_eq(cf->name, _S("-Wp"))) && (value).len != 0) { _option_string _t3; _option_ok(&(string[]) { string_trim_space(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = cf->name}}, {_SLIT0, 0xfe10, {.d_s = value}}, {_SLIT0, 0, { .d_c = 0 }}}))) }, (_option*)(&_t3), sizeof(string)); return _t3; } if (fast_string_eq(cf->name, _S("-I")) || fast_string_eq(cf->name, _S("-L")) || string_ends_with(value, _S(".o"))) { value = string__plus(string__plus(_S("\""), os__real_path(value)), _S("\"")); } _option_string _t4; _option_ok(&(string[]) { string_trim_space(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = cf->name}}, {_S(" "), 0xfe10, {.d_s = value}}, {_SLIT0, 0, { .d_c = 0 }}}))) }, (_option*)(&_t4), sizeof(string)); return _t4; } Array_string Array_v__cflag__CFlag_c_options_before_target_msvc(Array_v__cflag__CFlag cflags) { return __new_array_with_default(0, 0, sizeof(string), 0); } Array_string Array_v__cflag__CFlag_c_options_after_target_msvc(Array_v__cflag__CFlag cflags) { return __new_array_with_default(0, 0, sizeof(string), 0); } Array_string Array_v__cflag__CFlag_c_options_before_target(Array_v__cflag__CFlag cflags) { multi_return_Array_string_Array_string_Array_string mr_2806 = Array_v__cflag__CFlag_defines_others_libs(cflags); Array_string defines = mr_2806.arg0; Array_string others = mr_2806.arg1; Array_string args = __new_array_with_default(0, (int)(defines.len + others.len), sizeof(string), 0); _PUSH_MANY(&args, (defines), _t1, Array_string); _PUSH_MANY(&args, (others), _t2, Array_string); return v__cflag__uniq_non_empty(args); } Array_string Array_v__cflag__CFlag_c_options_after_target(Array_v__cflag__CFlag cflags) { multi_return_Array_string_Array_string_Array_string mr_3028 = Array_v__cflag__CFlag_defines_others_libs(cflags); Array_string libs = mr_3028.arg2; return libs; } Array_string Array_v__cflag__CFlag_c_options_without_object_files(Array_v__cflag__CFlag cflags) { Array_string args = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < cflags.len; ++_t1) { v__cflag__CFlag flag = ((v__cflag__CFlag*)cflags.data)[_t1]; if (string_ends_with(flag.value, _S(".o")) || string_ends_with(flag.value, _S(".obj"))) { continue; } _option_string _t3 = v__cflag__CFlag_format(&flag); if (_t3.state != 0) { IError err = _t3.err; continue; } array_push((array*)&args, _MOV((string[]){ (*(string*)_t3.data) })); } return v__cflag__uniq_non_empty(args); } Array_string Array_v__cflag__CFlag_c_options_only_object_files(Array_v__cflag__CFlag cflags) { Array_string args = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < cflags.len; ++_t1) { v__cflag__CFlag flag = ((v__cflag__CFlag*)cflags.data)[_t1]; if (string_ends_with(flag.value, _S(".o")) || string_ends_with(flag.value, _S(".obj")) || (fast_string_eq(flag.name, _S("-l")) && fast_string_eq(flag.value, _S("pq")))) { _option_string _t3 = v__cflag__CFlag_format(&flag); if (_t3.state != 0) { IError err = _t3.err; continue; } array_push((array*)&args, _MOV((string[]){ (*(string*)_t3.data) })); } } return v__cflag__uniq_non_empty(args); } multi_return_Array_string_Array_string_Array_string Array_v__cflag__CFlag_defines_others_libs(Array_v__cflag__CFlag cflags) { Array_string copts_without_obj_files = Array_v__cflag__CFlag_c_options_without_object_files(cflags); Array_string defines = __new_array_with_default(0, 0, sizeof(string), 0); Array_string others = __new_array_with_default(0, 0, sizeof(string), 0); Array_string libs = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < copts_without_obj_files.len; ++_t1) { string copt = ((string*)copts_without_obj_files.data)[_t1]; if (string_ends_with(copt, _S("@START_LIBS"))) { array_insert(&libs, 0, &(string[]){string_all_before(copt, _S("@START_LIBS"))}); continue; } if (string_starts_with(copt, _S("-l"))) { array_push((array*)&libs, _MOV((string[]){ string_clone(copt) })); continue; } if (string_ends_with(copt, _S(".a"))) { array_push((array*)&libs, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("\""), 0xfe10, {.d_s = copt}}, {_S("\""), 0, { .d_c = 0 }}})) })); continue; } if (string_ends_with(copt, _S("@START_DEFINES"))) { array_insert(&defines, 0, &(string[]){string_all_before(copt, _S("@START_DEFINES"))}); continue; } if (string_starts_with(copt, _S("-D"))) { array_push((array*)&defines, _MOV((string[]){ string_clone(copt) })); continue; } if (string_ends_with(copt, _S("@START_OTHERS"))) { array_insert(&others, 0, &(string[]){string_all_before(copt, _S("@START_OTHERS"))}); continue; } array_push((array*)&others, _MOV((string[]){ string_clone(copt) })); } return (multi_return_Array_string_Array_string_Array_string){.arg0=v__cflag__uniq_non_empty(defines), .arg1=v__cflag__uniq_non_empty(others), .arg2=v__cflag__uniq_non_empty(libs)}; } VV_LOC Array_string v__cflag__uniq_non_empty(Array_string args) { Array_string uniq_args = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < args.len; ++_t1) { string a = ((string*)args.data)[_t1]; if ((a).len == 0) { continue; } if (!(Array_string_contains(uniq_args, a))) { array_push((array*)&uniq_args, _MOV((string[]){ string_clone(a) })); } } return uniq_args; } void rand__wyrand__WyRandRNG_seed(rand__wyrand__WyRandRNG* rng, Array_u32 seed_data) { if (seed_data.len != 2) { eprintln(_S("WyRandRNG needs 2 32-bit unsigned integers as the seed.")); _v_exit(1); VUNREACHABLE(); } rng->state = ((*(u32*)array_get(seed_data, 0)) | ((((u64)((*(u32*)array_get(seed_data, 1)))) << 32U))); rng->bytes_left = 0; rng->buffer = 0U; } inline u8 rand__wyrand__WyRandRNG_u8(rand__wyrand__WyRandRNG* rng) { if (rng->bytes_left >= 1) { rng->bytes_left -= 1; u8 value = ((u8)(rng->buffer)); rng->buffer >>= 8U; return value; } rng->buffer = rand__wyrand__WyRandRNG_u64(rng); rng->bytes_left = 7; u8 value = ((u8)(rng->buffer)); rng->buffer >>= 8U; return value; } inline u16 rand__wyrand__WyRandRNG_u16(rand__wyrand__WyRandRNG* rng) { if (rng->bytes_left >= 2) { rng->bytes_left -= 2; u16 value = ((u16)(rng->buffer)); rng->buffer >>= 16U; return value; } u64 ans = rand__wyrand__WyRandRNG_u64(rng); rng->buffer = (ans >> 16U); rng->bytes_left = 6; return ((u16)(ans)); } inline u32 rand__wyrand__WyRandRNG_u32(rand__wyrand__WyRandRNG* rng) { if (rng->bytes_left >= 4) { rng->bytes_left -= 4; u32 value = ((u32)(rng->buffer)); rng->buffer >>= 32U; return value; } u64 ans = rand__wyrand__WyRandRNG_u64(rng); rng->buffer = (ans >> 32U); rng->bytes_left = 4; return ((u32)(ans)); } inline u64 rand__wyrand__WyRandRNG_u64(rand__wyrand__WyRandRNG* rng) { { // Unsafe block u64 seed1 = rng->state; seed1 += _const_rand__wyrand__wyp0; rng->state = seed1; return hash__wymum((seed1 ^ _const_rand__wyrand__wyp1), seed1); } return 0U; } inline int rand__wyrand__WyRandRNG_block_size(rand__wyrand__WyRandRNG* rng) { return 64; } void rand__wyrand__WyRandRNG_free(rand__wyrand__WyRandRNG* rng) { _v_free(rng); } VV_LOC _result_string v__pkgconfig__desc(string mod) { v__pkgconfig__Options options = ((v__pkgconfig__Options){.path = (string){.str=(byteptr)"", .is_lit=1},.debug = 0,.norecurse = 0,.only_description = true,.use_default_paths = true,}); _result_v__pkgconfig__PkgConfig_ptr _t1 = v__pkgconfig__load(mod, options); if (_t1.is_error) { IError err = _t1.err; return (_result_string){ .is_error=true, .err=_v_error(_S("cannot parse")), .data={E_STRUCT} }; } v__pkgconfig__PkgConfig* pc = (*(v__pkgconfig__PkgConfig**)_t1.data); _result_string _t3 = {0}; _result_ok(&(string[]) { pc->description }, (_result*)(&_t3), sizeof(string)); return _t3; } _result_v__pkgconfig__Main_ptr v__pkgconfig__main(Array_string args) { flag__FlagParser* fp = flag__new_flag_parser(args); flag__FlagParser_application(fp, _S("pkgconfig")); flag__FlagParser_version(fp, _const_v__pkgconfig__version); v__pkgconfig__Main* m = ((v__pkgconfig__Main*)memdup(&(v__pkgconfig__Main){.opt = v__pkgconfig__parse_options(fp),.res = (string){.str=(byteptr)"", .is_lit=1},.has_actions = 0,}, sizeof(v__pkgconfig__Main))); v__pkgconfig__MainOptions* opt = m->opt; if (opt->help) { m->res = flag__FlagParser_usage(fp); } else if (opt->version) { m->res = _const_v__pkgconfig__version; } else if (opt->listall) { Array_string modules = v__pkgconfig__list(); if (modules.len > 0) { qsort(modules.data, modules.len, modules.element_size, (voidptr)compare_6984583855671780374_string); } ; if (opt->description) { for (int _t1 = 0; _t1 < modules.len; ++_t1) { string mod = ((string*)modules.data)[_t1]; _result_string _t2 = v__pkgconfig__desc(mod); if (_t2.is_error) { IError err = _t2.err; continue; } string d = (*(string*)_t2.data); string pad = strings__repeat(' ', (int)(20 - mod.len)); m->res = string__plus(m->res, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mod}}, {_S(" "), 0xfe10, {.d_s = pad}}, {_S(" "), 0xfe10, {.d_s = d}}, {_S("\n"), 0, { .d_c = 0 }}}))); } } else { m->res = Array_string_join(modules, _S("\n")); } } else if (opt->args.len == 0) { return (_result_v__pkgconfig__Main_ptr){ .is_error=true, .err=_v_error(_S("No packages given")), .data={E_STRUCT} }; } _result_v__pkgconfig__Main_ptr _t4 = {0}; _result_ok(&(v__pkgconfig__Main*[]) { m }, (_result*)(&_t4), sizeof(v__pkgconfig__Main*)); return _t4; } _result_string v__pkgconfig__Main_run(v__pkgconfig__Main* m) { v__pkgconfig__Options options = ((v__pkgconfig__Options){.path = (string){.str=(byteptr)"", .is_lit=1},.debug = m->opt->debug,.norecurse = 0,.only_description = 0,.use_default_paths = true,}); v__pkgconfig__MainOptions* opt = m->opt; v__pkgconfig__PkgConfig* pc = ((v__pkgconfig__PkgConfig*)(((void*)0))); string res = m->res; for (int _t1 = 0; _t1 < opt->args.len; ++_t1) { string arg = ((string*)opt->args.data)[_t1]; _result_v__pkgconfig__PkgConfig_ptr _t2 = v__pkgconfig__load(arg, options); if (_t2.is_error) { IError err = _t2.err; if (!opt->exists) { return (_result_string){ .is_error=true, .err=err, .data={E_STRUCT} }; } continue; } v__pkgconfig__PkgConfig* pcdep = (*(v__pkgconfig__PkgConfig**)_t2.data); if (opt->description) { if ((res).len != 0) { res = string__plus(res, _S("\n")); } res = string__plus(res, pcdep->description); } if (pc != 0) { _result_string _t4 = v__pkgconfig__PkgConfig_extend(pc, pcdep); if (_t4.is_error) { _result_string _t5 = {0}; _t5.is_error = true; _t5.err = _t4.err; return _t5; } ; } else { pc = pcdep; } } if (opt->exists) { _result_string _t6 = {0}; _result_ok(&(string[]) { res }, (_result*)(&_t6), sizeof(string)); return _t6; } if ((opt->exactversion).len != 0) { if (!string__eq(pc->version, opt->exactversion)) { return (_result_string){ .is_error=true, .err=_v_error(_S("version mismatch")), .data={E_STRUCT} }; } _result_string _t8 = {0}; _result_ok(&(string[]) { res }, (_result*)(&_t8), sizeof(string)); return _t8; } if ((opt->atleast).len != 0) { if (v__pkgconfig__PkgConfig_atleast(pc, opt->atleast)) { return (_result_string){ .is_error=true, .err=_v_error(_S("version mismatch")), .data={E_STRUCT} }; } _result_string _t10 = {0}; _result_ok(&(string[]) { res }, (_result*)(&_t10), sizeof(string)); return _t10; } if ((opt->atleastpc).len != 0) { if (v__pkgconfig__atleast(opt->atleastpc)) { return (_result_string){ .is_error=true, .err=_v_error(_S("version mismatch")), .data={E_STRUCT} }; } _result_string _t12 = {0}; _result_ok(&(string[]) { res }, (_result*)(&_t12), sizeof(string)); return _t12; } if (opt->variables) { res = Array_string_join(map_keys(&pc->vars), _S("\n")); } if (opt->__v_requires) { res = string__plus(res, Array_string_join(pc->__v_requires, _S("\n"))); } Array_string r = __new_array_with_default(0, 0, sizeof(string), 0); if (opt->cflags_only_path) { array_push((array*)&r, _MOV((string[]){ v__pkgconfig__filter(pc->cflags, _S("-I"), _S("")) })); } if (opt->cflags_only_other) { array_push((array*)&r, _MOV((string[]){ v__pkgconfig__filter(pc->cflags, _S("-I"), _S("-I")) })); } if (opt->cflags) { array_push((array*)&r, _MOV((string[]){ Array_string_join(pc->cflags, _S(" ")) })); } if (opt->libs_only_link) { array_push((array*)&r, _MOV((string[]){ v__pkgconfig__filter(pc->libs, _S("-l"), _S("")) })); } if (opt->libs_only_path) { array_push((array*)&r, _MOV((string[]){ v__pkgconfig__filter(pc->libs, _S("-L"), _S("")) })); } if (opt->libs_only_other) { array_push((array*)&r, _MOV((string[]){ v__pkgconfig__filter(pc->libs, _S("-l"), _S("-L")) })); } if (opt->libs) { if (opt->stat1c) { array_push((array*)&r, _MOV((string[]){ Array_string_join(pc->libs_private, _S(" ")) })); } else { array_push((array*)&r, _MOV((string[]){ Array_string_join(pc->libs, _S(" ")) })); } } if (opt->modversion) { array_push((array*)&r, _MOV((string[]){ string_clone(pc->version) })); } _result_string _t22 = {0}; _result_ok(&(string[]) { string__plus(res, Array_string_join(r, _S(" "))) }, (_result*)(&_t22), sizeof(string)); return _t22; } VV_LOC string v__pkgconfig__filter(Array_string libs, string prefix, string prefix2) { string res = _S(""); if ((prefix2).len != 0) { for (int _t1 = 0; _t1 < libs.len; ++_t1) { string lib = ((string*)libs.data)[_t1]; if (!string_starts_with(lib, prefix) && !string_starts_with(lib, prefix2)) { res = string__plus(res, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = lib}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } } else { for (int _t2 = 0; _t2 < libs.len; ++_t2) { string lib = ((string*)libs.data)[_t2]; if (string_starts_with(lib, prefix)) { res = string__plus(res, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = lib}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } } return res; } VV_LOC v__pkgconfig__MainOptions* v__pkgconfig__parse_options(flag__FlagParser* fp) { return ((v__pkgconfig__MainOptions*)memdup(&(v__pkgconfig__MainOptions){.modversion = flag__FlagParser_bool(fp, _S("modversion"), 'V', false, _S("show version of module"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .description = flag__FlagParser_bool(fp, _S("description"), 'd', false, _S("show pkg module description"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .help = flag__FlagParser_bool(fp, _S("help"), 'h', false, _S("show this help message"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .debug = flag__FlagParser_bool(fp, _S("debug"), 'D', false, _S("show debug information"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .listall = flag__FlagParser_bool(fp, _S("list-all"), 'p', false, _S("list all pkgmodules"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .exists = flag__FlagParser_bool(fp, _S("exists"), 'e', false, _S("return 0 if pkg exists"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .variables = flag__FlagParser_bool(fp, _S("print-variables"), 'P', false, _S("display variable names"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .__v_requires = flag__FlagParser_bool(fp, _S("print-requires"), 'r', false, _S("display requires of the module"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .atleast = flag__FlagParser_string(fp, _S("atleast-version"), 'a', _S(""), _S("return 0 if pkg version is at least the given one"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .atleastpc = flag__FlagParser_string(fp, _S("atleast-pkgconfig-version"), 'A', _S(""), _S("return 0 if pkgconfig version is at least the given one"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .exactversion = flag__FlagParser_string(fp, _S("exact-version"), ' ', _S(""), _S("return 0 if pkg version is at least the given one"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .version = flag__FlagParser_bool(fp, _S("version"), 'v', false, _S("show version of this tool"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .cflags = flag__FlagParser_bool(fp, _S("cflags"), 'c', false, _S("output all pre-processor and compiler flags"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .cflags_only_path = flag__FlagParser_bool(fp, _S("cflags-only-I"), 'I', false, _S("show only -I flags from CFLAGS"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .cflags_only_other = flag__FlagParser_bool(fp, _S("cflags-only-other"), ' ', false, _S("show cflags without -I"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .stat1c = flag__FlagParser_bool(fp, _S("static"), 's', false, _S("show --libs for static linking"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .libs = flag__FlagParser_bool(fp, _S("libs"), 'l', false, _S("output all linker flags"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .libs_only_link = flag__FlagParser_bool(fp, _S("libs-only-l"), ' ', false, _S("show only -l from ldflags"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .libs_only_path = flag__FlagParser_bool(fp, _S("libs-only-L"), 'L', false, _S("show only -L from ldflags"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .libs_only_other = flag__FlagParser_bool(fp, _S("libs-only-other"), ' ', false, _S("show flags not containing -l or -L"), ((flag__FlagConfig){.val_desc = (string){.str=(byteptr)"", .is_lit=1},})), .args = fp->args, }, sizeof(v__pkgconfig__MainOptions))); } VV_LOC Array_string v__pkgconfig__PkgConfig_parse_list_no_comma(v__pkgconfig__PkgConfig* pc, string s) { return v__pkgconfig__PkgConfig_parse_list(pc, string_replace(s, _S(","), _S(" "))); } VV_LOC Array_string v__pkgconfig__PkgConfig_parse_list(v__pkgconfig__PkgConfig* pc, string s) { Array_string operators = new_array_from_c_array(5, 5, sizeof(string), _MOV((string[5]){_S("="), _S("<"), _S(">"), _S(">="), _S("<=")})); Array_string r = string_split(v__pkgconfig__PkgConfig_parse_line(pc, string_replace(string_replace(s, _S(" "), _S(" ")), _S(", "), _S(" "))), _S(" ")); Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); bool skip = false; for (int _t1 = 0; _t1 < r.len; ++_t1) { string a = ((string*)r.data)[_t1]; string b = string_trim_space(a); if (skip) { skip = false; } else if ((Array_string_contains(operators, b))) { skip = true; } else if ((b).len != 0) { array_push((array*)&res, _MOV((string[]){ string_clone(b) })); } } return res; } VV_LOC string v__pkgconfig__PkgConfig_parse_line(v__pkgconfig__PkgConfig* pc, string s) { string r = (*(string*)array_get(string_split(s, _S("#")), 0)); for (;;) { if (!(string_contains(r, _S("${")))) break; _option_int _t1 = string_index(r, _S("${")); if (_t1.state != 0) { IError err = _t1.err; break; } int tok0 = (*(int*)_t1.data); _option_int _t2 = string_index(string_substr(r, tok0, 2147483647), _S("}")); if (_t2.state != 0) { IError err = _t2.err; break; } int tok1 = (*(int*)_t2.data); tok1 += tok0; string v = string_substr(r, (int)(tok0 + 2), tok1); r = string_replace(r, str_intp(2, _MOV((StrIntpData[]){{_S("${"), 0xfe10, {.d_s = v}}, {_S("}"), 0, { .d_c = 0 }}})), (*(string*)map_get(ADDR(map, pc->vars), &(string[]){v}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} }))); } return string_trim_space(r); } VV_LOC void v__pkgconfig__PkgConfig_setvar(v__pkgconfig__PkgConfig* pc, string line) { Array_string kv = string_split(string_trim_space(line), _S("=")); if (kv.len == 2) { string k = (*(string*)array_get(kv, 0)); string v = v__pkgconfig__PkgConfig_parse_line(pc, (*(string*)array_get(kv, 1))); map_set(&pc->vars, &(string[]){k}, &(string[]) { v__pkgconfig__PkgConfig_parse_line(pc, v) }); } } VV_LOC bool v__pkgconfig__PkgConfig_parse(v__pkgconfig__PkgConfig* pc, string file) { pc->file_path = file; _result_string _t1 = os__read_file(file); if (_t1.is_error) { IError err = _t1.err; return false; } string data = (*(string*)_t1.data); if (pc->options.debug) { eprintln(data); } Array_string lines = string_split(data, _S("\n")); if (pc->options.only_description) { for (int _t3 = 0; _t3 < lines.len; ++_t3) { string line = ((string*)lines.data)[_t3]; if (string_starts_with(line, _S("Description: "))) { pc->description = v__pkgconfig__PkgConfig_parse_line(pc, string_substr(line, 13, 2147483647)); } } } else { for (int _t4 = 0; _t4 < lines.len; ++_t4) { string oline = ((string*)lines.data)[_t4]; string line = string_trim_space(oline); if (string_starts_with(line, _S("#"))) { continue; } if (string_contains(line, _S("=")) && !string_contains(line, _S(" "))) { v__pkgconfig__PkgConfig_setvar(pc, line); continue; } if (string_starts_with(line, _S("Name:"))) { pc->name = v__pkgconfig__PkgConfig_parse_line(pc, string_substr(line, 5, 2147483647)); } else if (string_starts_with(line, _S("Description:"))) { pc->description = v__pkgconfig__PkgConfig_parse_line(pc, string_substr(line, 12, 2147483647)); } else if (string_starts_with(line, _S("Version:"))) { pc->version = v__pkgconfig__PkgConfig_parse_line(pc, string_substr(line, 8, 2147483647)); } else if (string_starts_with(line, _S("Requires:"))) { pc->__v_requires = v__pkgconfig__PkgConfig_parse_list_no_comma(pc, string_substr(line, 9, 2147483647)); } else if (string_starts_with(line, _S("Requires.private:"))) { pc->requires_private = v__pkgconfig__PkgConfig_parse_list_no_comma(pc, string_substr(line, 17, 2147483647)); } else if (string_starts_with(line, _S("Conflicts:"))) { pc->conflicts = v__pkgconfig__PkgConfig_parse_list_no_comma(pc, string_substr(line, 10, 2147483647)); } else if (string_starts_with(line, _S("Cflags:"))) { pc->cflags = v__pkgconfig__PkgConfig_parse_list(pc, string_substr(line, 7, 2147483647)); } else if (string_starts_with(line, _S("Libs:"))) { pc->libs = v__pkgconfig__PkgConfig_parse_list(pc, string_substr(line, 5, 2147483647)); } else if (string_starts_with(line, _S("Libs.private:"))) { pc->libs_private = v__pkgconfig__PkgConfig_parse_list(pc, string_substr(line, 13, 2147483647)); } else if (string_starts_with(line, _S("URL:"))) { pc->url = v__pkgconfig__PkgConfig_parse_line(pc, string_substr(line, 4, 2147483647)); } } } return true; } VV_LOC _result_string v__pkgconfig__PkgConfig_resolve(v__pkgconfig__PkgConfig* pc, string pkgname) { if (string_ends_with(pkgname, _S(".pc"))) { if (os__exists(pkgname)) { _result_string _t1 = {0}; _result_ok(&(string[]) { pkgname }, (_result*)(&_t1), sizeof(string)); return _t1; } } else { if (pc->paths.len == 0) { array_push((array*)&pc->paths, _MOV((string[]){ _S(".") })); } for (int _t3 = 0; _t3 < pc->paths.len; ++_t3) { string path = ((string*)pc->paths.data)[_t3]; string file = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = path}}, {_S("/"), 0xfe10, {.d_s = pkgname}}, {_S(".pc"), 0, { .d_c = 0 }}})); if (os__exists(file)) { _result_string _t4 = {0}; _result_ok(&(string[]) { file }, (_result*)(&_t4), sizeof(string)); return _t4; } } } return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("Cannot find \""), 0xfe10, {.d_s = pkgname}}, {_S("\" pkgconfig file"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } bool v__pkgconfig__atleast(string v) { _result_semver__Version _t1 = semver__from(_const_v__pkgconfig__version); if (_t1.is_error) { IError err = _t1.err; return false; } semver__Version v0 = (*(semver__Version*)_t1.data); _result_semver__Version _t3 = semver__from(v); if (_t3.is_error) { IError err = _t3.err; return false; } semver__Version v1 = (*(semver__Version*)_t3.data); return semver__Version__lt(v1, v0); } bool v__pkgconfig__PkgConfig_atleast(v__pkgconfig__PkgConfig* pc, string v) { _result_semver__Version _t1 = semver__from(pc->version); if (_t1.is_error) { IError err = _t1.err; return false; } semver__Version v0 = (*(semver__Version*)_t1.data); _result_semver__Version _t3 = semver__from(v); if (_t3.is_error) { IError err = _t3.err; return false; } semver__Version v1 = (*(semver__Version*)_t3.data); return semver__Version__lt(v1, v0); } _result_string v__pkgconfig__PkgConfig_extend(v__pkgconfig__PkgConfig* pc, v__pkgconfig__PkgConfig* pcdep) { for (int _t1 = 0; _t1 < pcdep->cflags.len; ++_t1) { string flag = ((string*)pcdep->cflags.data)[_t1]; if (Array_string_index(pc->cflags, flag) == -1) { array_push((array*)&pc->cflags, _MOV((string[]){ string_clone(flag) })); } } for (int _t3 = 0; _t3 < pcdep->libs.len; ++_t3) { string lib = ((string*)pcdep->libs.data)[_t3]; if (Array_string_index(pc->libs, lib) == -1) { array_push((array*)&pc->libs, _MOV((string[]){ string_clone(lib) })); } } for (int _t5 = 0; _t5 < pcdep->libs_private.len; ++_t5) { string lib = ((string*)pcdep->libs_private.data)[_t5]; if (Array_string_index(pc->libs_private, lib) == -1) { array_push((array*)&pc->libs_private, _MOV((string[]){ string_clone(lib) })); } } return (_result_string){ .is_error=true, .err=_v_error(_S("")), .data={E_STRUCT} }; } VV_LOC _result_void v__pkgconfig__PkgConfig_load_requires(v__pkgconfig__PkgConfig* pc) { for (int _t1 = 0; _t1 < pc->__v_requires.len; ++_t1) { string dep = ((string*)pc->__v_requires.data)[_t1]; _result_void _t2 = v__pkgconfig__PkgConfig_load_require(pc, dep); if (_t2.is_error) { _result_void _t3 = {0}; _t3.is_error = true; _t3.err = _t2.err; return _t3; } ; } for (int _t4 = 0; _t4 < pc->requires_private.len; ++_t4) { string dep = ((string*)pc->requires_private.data)[_t4]; _result_void _t5 = v__pkgconfig__PkgConfig_load_require(pc, dep); if (_t5.is_error) { _result_void _t6 = {0}; _t6.is_error = true; _t6.err = _t5.err; return _t6; } ; } return (_result_void){0}; } VV_LOC _result_void v__pkgconfig__PkgConfig_load_require(v__pkgconfig__PkgConfig* pc, string dep) { if ((Array_string_contains(pc->loaded, dep))) { return (_result_void){0}; } array_push((array*)&pc->loaded, _MOV((string[]){ string_clone(dep) })); v__pkgconfig__PkgConfig pcdep = ((v__pkgconfig__PkgConfig){.file_path = (string){.str=(byteptr)"", .is_lit=1},.options = ((v__pkgconfig__Options){.path = (string){.str=(byteptr)"", .is_lit=1},.debug = 0,.norecurse = 0,.only_description = 0,.use_default_paths = true,}),.name = (string){.str=(byteptr)"", .is_lit=1},.modname = (string){.str=(byteptr)"", .is_lit=1},.url = (string){.str=(byteptr)"", .is_lit=1},.version = (string){.str=(byteptr)"", .is_lit=1},.description = (string){.str=(byteptr)"", .is_lit=1},.libs = __new_array(0, 0, sizeof(string)),.libs_private = __new_array(0, 0, sizeof(string)),.cflags = __new_array(0, 0, sizeof(string)),.paths = pc->paths,.vars = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.__v_requires = __new_array(0, 0, sizeof(string)),.requires_private = __new_array(0, 0, sizeof(string)),.conflicts = __new_array(0, 0, sizeof(string)),.loaded = pc->loaded,}); _result_string _t2 = v__pkgconfig__PkgConfig_resolve(&pcdep, dep); if (_t2.is_error) { IError err = _t2.err; if (pc->options.debug) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("cannot resolve "), 0xfe10, {.d_s = dep}}, {_SLIT0, 0, { .d_c = 0 }}}))); } return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("could not resolve dependency "), 0xfe10, {.d_s = dep}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } string depfile = (*(string*)_t2.data); if (!v__pkgconfig__PkgConfig_parse(&pcdep, depfile)) { return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("required file \""), 0xfe10, {.d_s = depfile}}, {_S("\" could not be parsed"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } if (!pc->options.norecurse) { _result_void _t5 = v__pkgconfig__PkgConfig_load_requires(&pcdep); if (_t5.is_error) { _result_void _t6 = {0}; _t6.is_error = true; _t6.err = _t5.err; return _t6; } ; } _result_string _t7 = v__pkgconfig__PkgConfig_extend(pc, (voidptr)&pcdep); (void)_t7; ; return (_result_void){0}; } VV_LOC void v__pkgconfig__PkgConfig_add_path(v__pkgconfig__PkgConfig* pc, string path) { if ((path).len == 0) { return; } string p = string_trim_right(path, _S("/")); if (!os__exists(p)) { return; } #if defined(CUSTOM_DEFINE_trace_pkgconfig_add_path) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> PkgConfig.add_path path: "), 0xfe10, {.d_s = p}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif if (Array_string_index(pc->paths, p) == -1) { array_push((array*)&pc->paths, _MOV((string[]){ string_clone(p) })); } } VV_LOC void v__pkgconfig__PkgConfig_load_paths(v__pkgconfig__PkgConfig* pc) { string _t1; #if defined(_WIN32) _t1 = _S(";"); ; #else _t1 = _S(":"); ; #endif string split_c = _t1; string config_path_override = os__getenv(_S("PKG_CONFIG_PATH_DEFAULTS")); if ((config_path_override).len != 0) { Array_string _t2 = string_split(config_path_override, split_c); for (int _t3 = 0; _t3 < _t2.len; ++_t3) { string path = ((string*)_t2.data)[_t3]; v__pkgconfig__PkgConfig_add_path(pc, path); } } else { if (pc->options.use_default_paths) { for (int _t4 = 0; _t4 < _const_v__pkgconfig__default_paths.len; ++_t4) { string path = ((string*)_const_v__pkgconfig__default_paths.data)[_t4]; v__pkgconfig__PkgConfig_add_path(pc, path); } } } Array_string _t5 = string_split(pc->options.path, split_c); for (int _t6 = 0; _t6 < _t5.len; ++_t6) { string path = ((string*)_t5.data)[_t6]; v__pkgconfig__PkgConfig_add_path(pc, path); } string env_var = os__getenv(_S("PKG_CONFIG_PATH")); if ((env_var).len != 0) { Array_string env_paths = string_split(string_trim_space(env_var), split_c); for (int _t7 = 0; _t7 < env_paths.len; ++_t7) { string path = ((string*)env_paths.data)[_t7]; v__pkgconfig__PkgConfig_add_path(pc, path); } } } _result_v__pkgconfig__PkgConfig_ptr v__pkgconfig__load(string pkgname, v__pkgconfig__Options options) { v__pkgconfig__PkgConfig* pc = ((v__pkgconfig__PkgConfig*)memdup(&(v__pkgconfig__PkgConfig){.file_path = (string){.str=(byteptr)"", .is_lit=1},.options = options,.name = (string){.str=(byteptr)"", .is_lit=1},.modname = pkgname,.url = (string){.str=(byteptr)"", .is_lit=1},.version = (string){.str=(byteptr)"", .is_lit=1},.description = (string){.str=(byteptr)"", .is_lit=1},.libs = __new_array(0, 0, sizeof(string)),.libs_private = __new_array(0, 0, sizeof(string)),.cflags = __new_array(0, 0, sizeof(string)),.paths = __new_array(0, 0, sizeof(string)),.vars = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.__v_requires = __new_array(0, 0, sizeof(string)),.requires_private = __new_array(0, 0, sizeof(string)),.conflicts = __new_array(0, 0, sizeof(string)),.loaded = __new_array(0, 0, sizeof(string)),}, sizeof(v__pkgconfig__PkgConfig))); v__pkgconfig__PkgConfig_load_paths(pc); _result_string _t1 = v__pkgconfig__PkgConfig_resolve(pc, pkgname); if (_t1.is_error) { IError err = _t1.err; return (_result_v__pkgconfig__PkgConfig_ptr){ .is_error=true, .err=err, .data={E_STRUCT} }; } string file = (*(string*)_t1.data); if (!v__pkgconfig__PkgConfig_parse(pc, file)) { return (_result_v__pkgconfig__PkgConfig_ptr){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("file \""), 0xfe10, {.d_s = file}}, {_S("\" could not be parsed"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } if (!options.norecurse) { _result_void _t4 = v__pkgconfig__PkgConfig_load_requires(pc); if (_t4.is_error) { _result_v__pkgconfig__PkgConfig_ptr _t5 = {0}; _t5.is_error = true; _t5.err = _t4.err; return _t5; } ; } _result_v__pkgconfig__PkgConfig_ptr _t6 = {0}; _result_ok(&(v__pkgconfig__PkgConfig*[]) { pc }, (_result*)(&_t6), sizeof(v__pkgconfig__PkgConfig*)); return _t6; } Array_string v__pkgconfig__list(void) { v__pkgconfig__PkgConfig* pc = ((v__pkgconfig__PkgConfig*)memdup(&(v__pkgconfig__PkgConfig){.file_path = (string){.str=(byteptr)"", .is_lit=1},.options = ((v__pkgconfig__Options){.path = (string){.str=(byteptr)"", .is_lit=1},.debug = 0,.norecurse = 0,.only_description = 0,.use_default_paths = true,}),.name = (string){.str=(byteptr)"", .is_lit=1},.modname = (string){.str=(byteptr)"", .is_lit=1},.url = (string){.str=(byteptr)"", .is_lit=1},.version = (string){.str=(byteptr)"", .is_lit=1},.description = (string){.str=(byteptr)"", .is_lit=1},.libs = __new_array(0, 0, sizeof(string)),.libs_private = __new_array(0, 0, sizeof(string)),.cflags = __new_array(0, 0, sizeof(string)),.paths = __new_array(0, 0, sizeof(string)),.vars = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.__v_requires = __new_array(0, 0, sizeof(string)),.requires_private = __new_array(0, 0, sizeof(string)),.conflicts = __new_array(0, 0, sizeof(string)),.loaded = __new_array(0, 0, sizeof(string)),}, sizeof(v__pkgconfig__PkgConfig))); v__pkgconfig__PkgConfig_load_paths(pc); Array_string modules = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < pc->paths.len; ++_t1) { string path = ((string*)pc->paths.data)[_t1]; _result_Array_string _t2 = os__ls(path); if (_t2.is_error) { IError err = _t2.err; continue; } Array_string files = (*(Array_string*)_t2.data); for (int _t3 = 0; _t3 < files.len; ++_t3) { string file = ((string*)files.data)[_t3]; if (string_ends_with(file, _S(".pc"))) { string name = string_replace(file, _S(".pc"), _S("")); if (Array_string_index(modules, name) == -1) { array_push((array*)&modules, _MOV((string[]){ string_clone(name) })); } } } } return modules; } VV_LOC string rand__internal_ulid_at_millisecond(rand__PRNG* rng, u64 unix_time_milli) { int buflen = 26; u8* buf = malloc_noscan(27); u64 t = unix_time_milli; int i = 9; for (;;) { if (!(i >= 0)) break; { // Unsafe block buf[i] = _const_rand__ulid_encoding.str[ (t & 0x1FU)]; } t = (t >> 5U); i--; } u64 x = rand__PRNG_name_table[rng->_typ]._method_u64(rng->_object); i = 10; for (;;) { if (!(i < 19)) break; { // Unsafe block buf[i] = _const_rand__ulid_encoding.str[ (x & 0x1FU)]; } x = (x >> 5U); i++; } x = rand__PRNG_name_table[rng->_typ]._method_u64(rng->_object); for (;;) { if (!(i < 26)) break; { // Unsafe block buf[i] = _const_rand__ulid_encoding.str[ (x & 0x1FU)]; } x = (x >> 5U); i++; } { // Unsafe block buf[26] = 0; return u8_vstring_with_len(buf, buflen); } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC void rand__deinit(void) { { // Unsafe block rand__PRNG_name_table[default_rng->_typ]._method__v_free(default_rng->_object); _v_free(default_rng); } } VV_LOC void rand__init(void) { default_rng = rand__new_default(((rand__config__PRNGConfigStruct){.seed_ = rand__seed__time_seed_array(2),})); _result_void _t1 = at_exit((voidptr)rand__deinit); (void)_t1; ; } inline _result_u32 rand__PRNG_u32n(rand__PRNG* rng, u32 max) { if (max == 0U) { return (_result_u32){ .is_error=true, .err=_v_error(_S("max must be positive integer")), .data={E_STRUCT} }; } int bit_len = math__bits__len_32(max); if (_unlikely_(bit_len == 32)) { for (;;) { u32 value = rand__PRNG_name_table[rng->_typ]._method_u32(rng->_object); if (value < max) { _result_u32 _t2 = {0}; _result_ok(&(u32[]) { value }, (_result*)(&_t2), sizeof(u32)); return _t2; } } } else { u32 mask = (_unlikely_(bit_len == 31) ? (((u32)(0x7FFFFFFFU))) : ((u32)(((((u32)(1U)) << ((int)(bit_len + 1)))) - 1U))); for (;;) { u32 value = (rand__PRNG_name_table[rng->_typ]._method_u32(rng->_object) & mask); if (value < max) { _result_u32 _t3 = {0}; _result_ok(&(u32[]) { value }, (_result*)(&_t3), sizeof(u32)); return _t3; } } } _result_u32 _t4 = {0}; _result_ok(&(u32[]) { ((u32)(0U)) }, (_result*)(&_t4), sizeof(u32)); return _t4; } inline _result_int rand__PRNG_intn(rand__PRNG* rng, int max) { if (max <= 0) { return (_result_int){ .is_error=true, .err=_v_error(_S("max has to be positive.")), .data={E_STRUCT} }; } _result_u32 _t3 = rand__PRNG_u32n(rng, ((u32)(max))); if (_t3.is_error) { _result_int _t4 = {0}; _t4.is_error = true; _t4.err = _t3.err; return _t4; } _result_int _t2 = {0}; _result_ok(&(int[]) { ((int)((*(u32*)_t3.data))) }, (_result*)(&_t2), sizeof(int)); return _t2; } string rand__PRNG_ulid(rand__PRNG* rng) { return rand__internal_ulid_at_millisecond(rng, ((u64)(time__Time_unix_milli(time__utc())))); } rand__PRNG* rand__new_default(rand__config__PRNGConfigStruct config_) { rand__wyrand__WyRandRNG* rng = ((rand__wyrand__WyRandRNG*)memdup(&(rand__wyrand__WyRandRNG){.PRNGBuffer = ((rand__buffer__PRNGBuffer){.bytes_left = 0,.buffer = 0,}),.state = rand__seed__time_seed_64(),.bytes_left = 0,.buffer = 0,}, sizeof(rand__wyrand__WyRandRNG))); rand__wyrand__WyRandRNG_seed(rng, config_.seed_); array_free(&config_.seed_); return HEAP(rand__PRNG, I_rand__wyrand__WyRandRNG_to_Interface_rand__PRNG(rng)); } _result_int rand__intn(int max) { return rand__PRNG_intn(default_rng, max); } string rand__ulid(void) { return rand__PRNG_ulid(default_rng); } v__pref__Arch v__pref__get_host_arch(void) { if (__V_architecture <= ((int)(v__pref__Arch___auto)) || __V_architecture >= ((int)(v__pref__Arch___max))) { return v__pref__Arch__amd64; } return ((v__pref__Arch)(__V_architecture)); } _result_v__pref__Arch v__pref__arch_from_string(string arch_str) { if (_SLIT_EQ(arch_str.str, arch_str.len, "amd64") || _SLIT_EQ(arch_str.str, arch_str.len, "x86_64") || _SLIT_EQ(arch_str.str, arch_str.len, "x64") || _SLIT_EQ(arch_str.str, arch_str.len, "x86")) { _result_v__pref__Arch _t1 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__amd64 }, (_result*)(&_t1), sizeof(v__pref__Arch)); return _t1; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "aarch64") || _SLIT_EQ(arch_str.str, arch_str.len, "arm64")) { _result_v__pref__Arch _t2 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__arm64 }, (_result*)(&_t2), sizeof(v__pref__Arch)); return _t2; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "aarch32") || _SLIT_EQ(arch_str.str, arch_str.len, "arm32") || _SLIT_EQ(arch_str.str, arch_str.len, "arm")) { _result_v__pref__Arch _t3 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__arm32 }, (_result*)(&_t3), sizeof(v__pref__Arch)); return _t3; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "rv64") || _SLIT_EQ(arch_str.str, arch_str.len, "riscv64") || _SLIT_EQ(arch_str.str, arch_str.len, "risc-v64") || _SLIT_EQ(arch_str.str, arch_str.len, "riscv") || _SLIT_EQ(arch_str.str, arch_str.len, "risc-v")) { _result_v__pref__Arch _t4 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__rv64 }, (_result*)(&_t4), sizeof(v__pref__Arch)); return _t4; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "rv32") || _SLIT_EQ(arch_str.str, arch_str.len, "riscv32")) { _result_v__pref__Arch _t5 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__rv32 }, (_result*)(&_t5), sizeof(v__pref__Arch)); return _t5; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "x86_32") || _SLIT_EQ(arch_str.str, arch_str.len, "x32") || _SLIT_EQ(arch_str.str, arch_str.len, "i386") || _SLIT_EQ(arch_str.str, arch_str.len, "IA-32") || _SLIT_EQ(arch_str.str, arch_str.len, "ia-32") || _SLIT_EQ(arch_str.str, arch_str.len, "ia32")) { _result_v__pref__Arch _t6 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__i386 }, (_result*)(&_t6), sizeof(v__pref__Arch)); return _t6; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "s390x")) { _result_v__pref__Arch _t7 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__s390x }, (_result*)(&_t7), sizeof(v__pref__Arch)); return _t7; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "loongarch64")) { _result_v__pref__Arch _t8 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__loongarch64 }, (_result*)(&_t8), sizeof(v__pref__Arch)); return _t8; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "ppc64le")) { _result_v__pref__Arch _t9 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__ppc64le }, (_result*)(&_t9), sizeof(v__pref__Arch)); return _t9; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "js") || _SLIT_EQ(arch_str.str, arch_str.len, "js_node")) { _result_v__pref__Arch _t10 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__js_node }, (_result*)(&_t10), sizeof(v__pref__Arch)); return _t10; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "js_browser")) { _result_v__pref__Arch _t11 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__js_browser }, (_result*)(&_t11), sizeof(v__pref__Arch)); return _t11; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "js_freestanding")) { _result_v__pref__Arch _t12 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__js_freestanding }, (_result*)(&_t12), sizeof(v__pref__Arch)); return _t12; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "wasm32") || _SLIT_EQ(arch_str.str, arch_str.len, "wasm")) { _result_v__pref__Arch _t13 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch__wasm32 }, (_result*)(&_t13), sizeof(v__pref__Arch)); return _t13; } else if (_SLIT_EQ(arch_str.str, arch_str.len, "")) { _result_v__pref__Arch _t14 = {0}; _result_ok(&(v__pref__Arch[]) { v__pref__Arch___auto }, (_result*)(&_t14), sizeof(v__pref__Arch)); return _t14; } else { return (_result_v__pref__Arch){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("invalid arch: "), 0xfe10, {.d_s = arch_str}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } return (_result_v__pref__Arch){0}; } void v__pref__set_build_flags_and_defines(Array_string facts, Array_string defines) { string sfacts = Array_string_join(facts, _S(",")); string sdefines = Array_string_join(defines, _S(",")); os__setenv(_S("VBUILD_FACTS"), sfacts, true); os__setenv(_S("VBUILD_DEFINES"), sdefines, true); #if defined(CUSTOM_DEFINE_trace_vbuild) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> VBUILD_FACTS: "), 0xfe10, {.d_s = sfacts}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> VBUILD_DEFINES: "), 0xfe10, {.d_s = sdefines}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif string_free(&sdefines); string_free(&sfacts); } VV_LOC void v__pref__Preferences_expand_lookup_paths(v__pref__Preferences* p) { if ((p->vroot).len == 0) { p->vroot = os__dir(v__pref__vexe_path()); } p->vlib = os__join_path(p->vroot, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("vlib")}))); p->vmodules_paths = os__vmodules_paths(); if (p->lookup_path.len == 0) { p->lookup_path = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("@vlib"), _S("@vmodules")})); } Array_string expanded_paths = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < p->lookup_path.len; ++_t1) { string path = ((string*)p->lookup_path.data)[_t1]; if (_SLIT_EQ(path.str, path.len, "@vlib")) { array_push((array*)&expanded_paths, _MOV((string[]){ string_clone(p->vlib) })); } else if (_SLIT_EQ(path.str, path.len, "@vmodules")) { _PUSH_MANY(&expanded_paths, (p->vmodules_paths), _t3, Array_string); } else { array_push((array*)&expanded_paths, _MOV((string[]){ string_replace(path, _S("@vroot"), p->vroot) })); } } p->lookup_path = expanded_paths; } VV_LOC void v__pref__Preferences_expand_exclude_paths(v__pref__Preferences* p) { Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); Array_string static_replacement_list = new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S("@vroot"), string_clone(p->vroot), _S("@vlib"), string_clone(p->vlib)})); for (int _t1 = 0; _t1 < p->exclude.len; ++_t1) { string x = ((string*)p->exclude.data)[_t1]; string y = string_replace_each(x, static_replacement_list); if (string_contains(y, _S("@vmodules"))) { for (int _t2 = 0; _t2 < p->vmodules_paths.len; ++_t2) { string vmp = ((string*)p->vmodules_paths.data)[_t2]; array_push((array*)&res, _MOV((string[]){ string_replace(y, _S("@vmodules"), vmp) })); } continue; } array_push((array*)&res, _MOV((string[]){ string_clone(y) })); } p->exclude = res; } VV_LOC void v__pref__Preferences_setup_os_and_arch_when_not_explicitly_set(v__pref__Preferences* p) { if (p->os == v__pref__OS__wasm32_emscripten) { v__pref__Preferences_parse_define(p, _S("emscripten")); } v__pref__OS host_os = (p->backend == v__pref__Backend__wasm ? (v__pref__OS__wasi) : (v__pref__get_host_os())); if (p->os == v__pref__OS___auto) { p->os = host_os; array_push((array*)&p->build_options, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-os "), 0xfe10, {.d_s = v__pref__OS_lower(host_os)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if (!p->output_cross_c) { if (p->os != host_os) { if (host_os == v__pref__OS__macos && p->os == v__pref__OS__linux) { if (p->arch == v__pref__Arch___auto) { p->arch = v__pref__Arch__amd64; array_push((array*)&p->build_options, _MOV((string[]){ _S("-arch amd64") })); } v__pref__Preferences_parse_define(p, _S("use_bundled_libgc")); } } } if (p->arch == v__pref__Arch___auto) { p->arch = v__pref__get_host_arch(); array_push((array*)&p->build_options, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-arch "), 0xfe10, {.d_s = v__pref__Arch_str(p->arch)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } string v__pref__Preferences_defines_map_unique_keys(v__pref__Preferences* p) { Map_string_bool defines_map = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int _t1 = 0; _t1 < p->compile_defines.len; ++_t1) { string d = ((string*)p->compile_defines.data)[_t1]; map_set(&defines_map, &(string[]){d}, &(bool[]) { true }); } for (int _t2 = 0; _t2 < p->compile_defines_all.len; ++_t2) { string d = ((string*)p->compile_defines_all.data)[_t2]; map_set(&defines_map, &(string[]){d}, &(bool[]) { true }); } Array_string keys = map_keys(&defines_map); Array_string _t3 = array_clone_to_depth(ADDR(Array_string,keys), 0); if (_t3.len > 0) { qsort(_t3.data, _t3.len, _t3.element_size, (voidptr)compare_13857508711935328005_string); } ; Array_string skeys =_t3; return Array_string_join(skeys, _S(",")); } void v__pref__Preferences_fill_with_defaults(v__pref__Preferences* p) { v__pref__Preferences_setup_os_and_arch_when_not_explicitly_set(p); v__pref__Preferences_expand_lookup_paths(p); v__pref__Preferences_expand_exclude_paths(p); string rpath = os__real_path(p->path); if ((p->out_name).len == 0) { string filename = string_trim_space(os__file_name(rpath)); string base = string_all_before_last(filename, _S(".")); if (Array_string_contains(new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S(".c"), _S(".js"), _S(".wasm")})), os__file_ext(base))) { base = string_all_before_last(base, _S(".")); } if ((base).len == 0) { base = filename; } string target_dir = (os__is_dir(rpath) ? (rpath) : (os__dir(rpath))); if ((p->raw_vsh_tmp_prefix).len != 0) { p->out_name = os__join_path(target_dir, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){string__plus(string__plus(p->raw_vsh_tmp_prefix, _S(".")), base)}))); } else { p->out_name = os__join_path(target_dir, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){base}))); } if (string__eq(rpath, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = p->vroot}}, {_S("/cmd/v"), 0, { .d_c = 0 }}}))) && os__is_dir(_S("vlib/compiler"))) { println(_S("Saving the resulting V executable in `./v2`")); println(_S("Use `v -o v cmd/v` if you want to replace current V executable.")); p->out_name = _S("v2"); } } string rpath_name = os__file_name(rpath); p->building_v = !p->is_repl && (_SLIT_EQ(rpath_name.str, rpath_name.len, "v") || _SLIT_EQ(rpath_name.str, rpath_name.len, "vfmt.v")); if (p->os == v__pref__OS__linux) { #if !defined(__linux__) { v__pref__Preferences_parse_define(p, _S("cross_compile")); } #endif } if (p->output_cross_c) { p->gc_mode = v__pref__GarbageCollectionMode__no_gc; p->use_cache = false; p->skip_unused = false; v__pref__Preferences_parse_define(p, _S("no_backtrace")); v__pref__Preferences_parse_define(p, _S("cross")); } if (p->gc_mode == v__pref__GarbageCollectionMode__unknown) { if (p->backend != v__pref__Backend__c || p->building_v || p->is_bare || fast_string_eq(p->ccompiler, _S("msvc"))) { p->gc_mode = v__pref__GarbageCollectionMode__no_gc; _PUSH_MANY(&p->build_options, (new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("-gc"), _S("none")}))), _t2, Array_string); } else { p->gc_mode = v__pref__GarbageCollectionMode__boehm_full_opt; v__pref__Preferences_parse_define(p, _S("gcboehm")); v__pref__Preferences_parse_define(p, _S("gcboehm_full")); v__pref__Preferences_parse_define(p, _S("gcboehm_opt")); } } if (p->is_debug) { v__pref__Preferences_parse_define(p, _S("debug")); } v__pref__Preferences_try_to_use_tcc_by_default(p); if ((p->ccompiler).len == 0) { v__pref__Preferences_default_c_compiler(p); } if ((p->cppcompiler).len == 0) { v__pref__Preferences_default_cpp_compiler(p); } v__pref__Preferences_find_cc_if_cross_compiling(p); p->ccompiler_type = v__pref__cc_from_string(p->ccompiler); p->is_test = string_ends_with(p->path, _S("_test.v")) || string_ends_with(p->path, _S("_test.vv")) || string_ends_with(string_all_before_last(string_all_before_last(p->path, _S(".v")), _S(".")), _S("_test")); p->is_vsh = string_ends_with(p->path, _S(".vsh")) || (p->raw_vsh_tmp_prefix).len != 0; p->is_script = p->is_vsh || string_ends_with(p->path, _S(".v")) || string_ends_with(p->path, _S(".vv")); if ((p->third_party_option).len == 0) { p->third_party_option = p->cflags; #if !defined(_WIN32) { if (!string_contains(p->third_party_option, _S("-fPIC"))) { p->third_party_option = string__plus(p->third_party_option, _S(" -fPIC")); } } #endif } string final_os = v__pref__OS_lower(p->os); v__pref__Preferences_parse_define(p, final_os); string vhash = _S("cd94cff219b025837c31233560c388aaeca87a94"); p->cache_manager = v__vcache__new_cache_manager(new_array_from_c_array(6, 6, sizeof(string), _MOV((string[6]){string_clone(vhash), str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__pref__Backend_str(p->backend)}}, {_S(" | "), 0xfe10, {.d_s = final_os}}, {_S(" | "), 0xfe10, {.d_s = p->ccompiler}}, {_S(" | "), 0xfe10, {.d_s = p->is_prod ? _S("true") : _S("false")}}, {_S(" | "), 0xfe10, {.d_s = p->sanitize ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}})), v__pref__Preferences_defines_map_unique_keys(p), string_trim_space(p->cflags), string_trim_space(p->third_party_option), Array_string_str(p->lookup_path)}))); if (string__eq(os__user_os(), _S("windows"))) { p->use_cache = false; } if (p->build_mode == v__pref__BuildMode__build_module) { p->use_cache = false; } if (p->is_shared) { p->use_cache = false; } if ((p->bare_builtin_dir).len == 0 && p->os == v__pref__OS__wasm32) { p->bare_builtin_dir = os__join_path(p->vroot, new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("vlib"), _S("builtin"), _S("wasm_bare")}))); } else if ((p->bare_builtin_dir).len == 0) { p->bare_builtin_dir = os__join_path(p->vroot, new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("vlib"), _S("builtin"), _S("linux_bare")}))); } #if defined(_VPREALLOC) { if (!p->no_parallel && p->is_verbose) { eprintln(_S("disabling parallel cgen, since V was built with -prealloc")); } p->no_parallel = true; } #endif } VV_LOC void v__pref__Preferences_find_cc_if_cross_compiling(v__pref__Preferences* p) { if (p->os == v__pref__get_host_os()) { return; } if (p->os == v__pref__OS__windows && fast_string_eq(p->ccompiler, _S("msvc"))) { return; } p->ccompiler = v__pref__Preferences_vcross_compiler_name(p); } VV_LOC void v__pref__Preferences_try_to_use_tcc_by_default(v__pref__Preferences* p) { if (fast_string_eq(p->ccompiler, _S("tcc"))) { p->ccompiler = v__pref__default_tcc_compiler(); return; } if ((p->ccompiler).len == 0) { #if defined(__APPLE__) { return; } #endif if (p->is_prod) { return; } p->ccompiler = v__pref__default_tcc_compiler(); return; } } string v__pref__default_tcc_compiler(void) { string vexe = v__pref__vexe_path(); string vroot = os__dir(vexe); string vtccexe = os__join_path(vroot, new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("thirdparty"), _S("tcc"), _S("tcc.exe")}))); if (os__exists(vtccexe)) { return vtccexe; } return _S(""); } void v__pref__Preferences_default_c_compiler(v__pref__Preferences* p) { #if defined(_WIN32) { p->ccompiler = _S("gcc"); return; } #endif if (p->os == v__pref__OS__ios) { #if !defined(__TARGET_IOS__) { string ios_sdk = (p->is_ios_simulator ? (_S("iphonesimulator")) : (_S("iphoneos"))); os__Result ios_sdk_path_res = os__execute_or_exit(str_intp(2, _MOV((StrIntpData[]){{_S("xcrun --sdk "), 0xfe10, {.d_s = ios_sdk}}, {_S(" --show-sdk-path"), 0, { .d_c = 0 }}}))); string isysroot = string_replace(ios_sdk_path_res.output, _S("\n"), _S("")); string arch = (p->is_ios_simulator ? (_S("-arch x86_64 -arch arm64")) : (_S("-arch armv7 -arch armv7s -arch arm64"))); p->ccompiler = _S("/usr/bin/cc"); p->cflags = string__plus(str_intp(3, _MOV((StrIntpData[]){{_S("-isysroot "), 0xfe10, {.d_s = isysroot}}, {_S(" "), 0xfe10, {.d_s = arch}}, {_SLIT0, 0, { .d_c = 0 }}})), p->cflags); return; } #endif } p->ccompiler = _S("cc"); return; } void v__pref__Preferences_default_cpp_compiler(v__pref__Preferences* p) { if (string_contains(p->ccompiler, _S("clang"))) { p->cppcompiler = _S("clang++"); return; } p->cppcompiler = _S("c++"); } string v__pref__vexe_path(void) { string vexe = os__getenv(_S("VEXE")); if ((vexe).len != 0) { return vexe; } string myexe = os__executable(); string real_vexe_path = myexe; for (;;) { #if defined(__TINYC__) { #if defined(TARGET_IS_32BIT) { break; } #endif } #endif real_vexe_path = os__real_path(real_vexe_path); break; } os__setenv(_S("VEXE"), real_vexe_path, true); return real_vexe_path; } string v__pref__Preferences_vcross_linker_name(v__pref__Preferences* p) { string vlname = os__getenv(_S("VCROSS_LINKER_NAME")); if ((vlname).len != 0) { return vlname; } #if defined(__APPLE__) { return _S("/opt/homebrew/opt/llvm/bin/ld.lld"); } #endif #if defined(_WIN32) { return _S("ld.lld.exe"); } #endif return _S("ld.lld"); } string v__pref__Preferences_vcross_compiler_name(v__pref__Preferences* p) { string vccname = os__getenv(_S("VCROSS_COMPILER_NAME")); if ((vccname).len != 0) { return vccname; } if (p->os == v__pref__OS__windows) { if (p->os == v__pref__OS__freebsd) { return _S("clang"); } if (p->m64) { return _S("x86_64-w64-mingw32-gcc"); } return _S("i686-w64-mingw32-gcc"); } if (p->os == v__pref__OS__linux) { return _S("clang"); } if (p->os == v__pref__OS__freebsd) { return _S("clang"); } if (p->os == v__pref__OS__wasm32_emscripten) { if (string__eq(os__user_os(), _S("windows"))) { return _S("emcc.bat"); } return _S("emcc"); } if (p->backend == v__pref__Backend__c && !string_ends_with(p->out_name, _S(".c"))) { eprintln(_S("Note: V can only cross compile to Windows and Linux for now by default.")); eprintln(_S("It will use `cc` as a cross compiler for now, although that will probably fail.")); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("Set `VCROSS_COMPILER_NAME` to the name of your cross compiler, for your target OS: "), 0xfe10, {.d_s = v__pref__OS_str(p->os)}}, {_S(" ."), 0, { .d_c = 0 }}}))); } return _S("cc"); } VV_LOC void v__pref__Preferences_parse_line_info(v__pref__Preferences* p, string line) { string format_err = _S("wrong format, use `-line-info \"file.v:24:expr_to_look_up\""); Array_string vals = string_split(line, _S(":")); if (vals.len != 3) { eprintln(format_err); return; } string file_name = (*(string*)array_get(vals, 0)); int line_nr = (int)(string_int((*(string*)array_get(vals, 1))) - 1); string expr = (*(string*)array_get(vals, 2)); if (!string_ends_with(file_name, _S(".v")) || line_nr == -1) { eprintln(format_err); return; } p->linfo = ((v__pref__LineInfo){.line_nr = line_nr,.path = file_name,.expr = expr,.is_running = 0,.vars_printed = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}); } string v__pref__add_line_info_expr_to_program_text(string raw_text, v__pref__LineInfo linfo) { Array_string lines = string_split(raw_text, _S("\n")); string lines_before = Array_string_join(array_slice(lines, 0, linfo.line_nr), _S("\n")); string expr = linfo.expr; if (!string_contains(expr, _S("."))) { expr = string__plus(string__plus(_S("println("), expr), _S(")")); } string lines_after = Array_string_join(array_slice(lines, linfo.line_nr, 2147483647), _S("\n")); return string__plus(string__plus(string__plus(string__plus(lines_before, _S("\n")), expr), _S("\n")), lines_after); } _result_v__pref__OS v__pref__os_from_string(string os_str) { string lcased_os_str = string_to_lower_ascii(os_str); if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "")) { _result_v__pref__OS _t1 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS___auto }, (_result*)(&_t1), sizeof(v__pref__OS)); return _t1; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "linux")) { _result_v__pref__OS _t2 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__linux }, (_result*)(&_t2), sizeof(v__pref__OS)); return _t2; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "nix")) { _result_v__pref__OS _t3 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__linux }, (_result*)(&_t3), sizeof(v__pref__OS)); return _t3; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "windows")) { _result_v__pref__OS _t4 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__windows }, (_result*)(&_t4), sizeof(v__pref__OS)); return _t4; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "ios")) { _result_v__pref__OS _t5 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__ios }, (_result*)(&_t5), sizeof(v__pref__OS)); return _t5; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "macos")) { _result_v__pref__OS _t6 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__macos }, (_result*)(&_t6), sizeof(v__pref__OS)); return _t6; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "darwin")) { _result_v__pref__OS _t7 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__macos }, (_result*)(&_t7), sizeof(v__pref__OS)); return _t7; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "freebsd")) { _result_v__pref__OS _t8 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__freebsd }, (_result*)(&_t8), sizeof(v__pref__OS)); return _t8; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "openbsd")) { _result_v__pref__OS _t9 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__openbsd }, (_result*)(&_t9), sizeof(v__pref__OS)); return _t9; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "netbsd")) { _result_v__pref__OS _t10 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__netbsd }, (_result*)(&_t10), sizeof(v__pref__OS)); return _t10; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "dragonfly")) { _result_v__pref__OS _t11 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__dragonfly }, (_result*)(&_t11), sizeof(v__pref__OS)); return _t11; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "js") || _SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "js_node")) { _result_v__pref__OS _t12 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__js_node }, (_result*)(&_t12), sizeof(v__pref__OS)); return _t12; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "js_freestanding")) { _result_v__pref__OS _t13 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__js_freestanding }, (_result*)(&_t13), sizeof(v__pref__OS)); return _t13; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "js_browser")) { _result_v__pref__OS _t14 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__js_browser }, (_result*)(&_t14), sizeof(v__pref__OS)); return _t14; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "solaris")) { _result_v__pref__OS _t15 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__solaris }, (_result*)(&_t15), sizeof(v__pref__OS)); return _t15; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "serenity")) { _result_v__pref__OS _t16 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__serenity }, (_result*)(&_t16), sizeof(v__pref__OS)); return _t16; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "qnx")) { _result_v__pref__OS _t17 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__qnx }, (_result*)(&_t17), sizeof(v__pref__OS)); return _t17; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "plan9")) { _result_v__pref__OS _t18 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__plan9 }, (_result*)(&_t18), sizeof(v__pref__OS)); return _t18; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "vinix")) { _result_v__pref__OS _t19 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__vinix }, (_result*)(&_t19), sizeof(v__pref__OS)); return _t19; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "android")) { _result_v__pref__OS _t20 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__android }, (_result*)(&_t20), sizeof(v__pref__OS)); return _t20; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "termux")) { _result_v__pref__OS _t21 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__termux }, (_result*)(&_t21), sizeof(v__pref__OS)); return _t21; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "haiku")) { _result_v__pref__OS _t22 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__haiku }, (_result*)(&_t22), sizeof(v__pref__OS)); return _t22; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "raw")) { _result_v__pref__OS _t23 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__raw }, (_result*)(&_t23), sizeof(v__pref__OS)); return _t23; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "wasm32")) { _result_v__pref__OS _t24 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__wasm32 }, (_result*)(&_t24), sizeof(v__pref__OS)); return _t24; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "wasm32_wasi")) { _result_v__pref__OS _t25 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__wasm32_wasi }, (_result*)(&_t25), sizeof(v__pref__OS)); return _t25; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "wasm32_emscripten")) { _result_v__pref__OS _t26 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__wasm32_emscripten }, (_result*)(&_t26), sizeof(v__pref__OS)); return _t26; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "browser")) { _result_v__pref__OS _t27 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__browser }, (_result*)(&_t27), sizeof(v__pref__OS)); return _t27; } else if (_SLIT_EQ(lcased_os_str.str, lcased_os_str.len, "wasi")) { _result_v__pref__OS _t28 = {0}; _result_ok(&(v__pref__OS[]) { v__pref__OS__wasi }, (_result*)(&_t28), sizeof(v__pref__OS)); return _t28; } else { return (_result_v__pref__OS){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("bad OS "), 0xfe10, {.d_s = os_str}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } return (_result_v__pref__OS){0}; } string v__pref__OS_lower(v__pref__OS o) { string _t2 = (string){.str=(byteptr)"", .is_lit=1}; switch (o) { case v__pref__OS___auto: { _t2 = _S(""); break; } case v__pref__OS__linux: { _t2 = _S("linux"); break; } case v__pref__OS__windows: { _t2 = _S("windows"); break; } case v__pref__OS__macos: { _t2 = _S("macos"); break; } case v__pref__OS__ios: { _t2 = _S("ios"); break; } case v__pref__OS__freebsd: { _t2 = _S("freebsd"); break; } case v__pref__OS__openbsd: { _t2 = _S("openbsd"); break; } case v__pref__OS__netbsd: { _t2 = _S("netbsd"); break; } case v__pref__OS__dragonfly: { _t2 = _S("dragonfly"); break; } case v__pref__OS__js_node: { _t2 = _S("js"); break; } case v__pref__OS__js_freestanding: { _t2 = _S("js_freestanding"); break; } case v__pref__OS__js_browser: { _t2 = _S("js_browser"); break; } case v__pref__OS__solaris: { _t2 = _S("solaris"); break; } case v__pref__OS__serenity: { _t2 = _S("serenity"); break; } case v__pref__OS__qnx: { _t2 = _S("qnx"); break; } case v__pref__OS__plan9: { _t2 = _S("plan9"); break; } case v__pref__OS__vinix: { _t2 = _S("vinix"); break; } case v__pref__OS__android: { _t2 = _S("android"); break; } case v__pref__OS__termux: { _t2 = _S("termux"); break; } case v__pref__OS__haiku: { _t2 = _S("haiku"); break; } case v__pref__OS__raw: { _t2 = _S("raw"); break; } case v__pref__OS__wasm32: { _t2 = _S("wasm32"); break; } case v__pref__OS__wasm32_wasi: { _t2 = _S("wasm32_wasi"); break; } case v__pref__OS__wasm32_emscripten: { _t2 = _S("wasm32_emscripten"); break; } case v__pref__OS__browser: { _t2 = _S("browser"); break; } case v__pref__OS__wasi: { _t2 = _S("wasi"); break; } case v__pref__OS__all: { _t2 = _S("all"); break; } } return _t2; } string v__pref__OS_str(v__pref__OS o) { switch (o) { case v__pref__OS___auto: { return _S("RESERVED: AUTO"); } case v__pref__OS__ios: { return _S("iOS"); } case v__pref__OS__macos: { return _S("MacOS"); } case v__pref__OS__linux: { return _S("Linux"); } case v__pref__OS__windows: { return _S("Windows"); } case v__pref__OS__freebsd: { return _S("FreeBSD"); } case v__pref__OS__openbsd: { return _S("OpenBSD"); } case v__pref__OS__netbsd: { return _S("NetBSD"); } case v__pref__OS__dragonfly: { return _S("Dragonfly"); } case v__pref__OS__js_node: { return _S("NodeJS"); } case v__pref__OS__js_freestanding: { return _S("JavaScript"); } case v__pref__OS__js_browser: { return _S("JavaScript(Browser)"); } case v__pref__OS__android: { return _S("Android"); } case v__pref__OS__termux: { return _S("Termux"); } case v__pref__OS__solaris: { return _S("Solaris"); } case v__pref__OS__qnx: { return _S("QNX"); } case v__pref__OS__serenity: { return _S("SerenityOS"); } case v__pref__OS__plan9: { return _S("Plan9"); } case v__pref__OS__vinix: { return _S("Vinix"); } case v__pref__OS__haiku: { return _S("Haiku"); } case v__pref__OS__wasm32: { return _S("WebAssembly"); } case v__pref__OS__wasm32_emscripten: { return _S("WebAssembly(Emscripten)"); } case v__pref__OS__wasm32_wasi: { return _S("WebAssembly(WASI)"); } case v__pref__OS__browser: { return _S("browser"); } case v__pref__OS__wasi: { return _S("wasi"); } case v__pref__OS__raw: { return _S("Raw"); } case v__pref__OS__all: { return _S("all"); } } return (string){.str=(byteptr)"", .is_lit=1}; } v__pref__OS v__pref__get_host_os(void) { if ((os__getenv(_S("TERMUX_VERSION"))).len != 0) { return v__pref__OS__termux; } #if defined(__ANDROID__) { return v__pref__OS__android; } #endif #if defined(CUSTOM_DEFINE_emscripten) { return v__pref__OS__wasm32_emscripten; } #endif #if defined(__EMSCRIPTEN__) { return v__pref__OS__wasm32_emscripten; } #endif #if defined(__linux__) { return v__pref__OS__linux; } #endif #if defined(__TARGET_IOS__) { return v__pref__OS__ios; } #endif #if defined(__APPLE__) { return v__pref__OS__macos; } #endif #if defined(_WIN32) { return v__pref__OS__windows; } #endif #if defined(__FreeBSD__) { return v__pref__OS__freebsd; } #endif #if defined(__OpenBSD__) { return v__pref__OS__openbsd; } #endif #if defined(__NetBSD__) { return v__pref__OS__netbsd; } #endif #if defined(__DragonFly__) { return v__pref__OS__dragonfly; } #endif #if defined(__serenity__) { return v__pref__OS__serenity; } #endif #if defined(__vinix__) { return v__pref__OS__vinix; } #endif #if defined(__sun) { return v__pref__OS__solaris; } #endif #if defined(__HAIKU__) { return v__pref__OS__haiku; } #endif #if defined(true) { return v__pref__OS__js_node; } #endif #if defined(true) { return v__pref__OS__js_freestanding; } #endif #if defined(true) { return v__pref__OS__js_browser; } #endif #if defined(_VJS) { return v__pref__OS__js_node; } #endif _v_panic(_S("unknown host OS")); VUNREACHABLE(); return v__pref__OS___auto; } bool v__pref__Backend_is_js(v__pref__Backend b) { return (b == v__pref__Backend__js_node || b == v__pref__Backend__js_browser || b == v__pref__Backend__js_freestanding); } VV_LOC void v__pref__detect_musl(v__pref__Preferences* res) { res->is_glibc = true; res->is_musl = false; if (os__exists(_S("/etc/alpine-release"))) { res->is_musl = true; res->is_glibc = false; return; } Array_string _t1 = {0}; Array_string _t1_orig = os__walk_ext(_S("/proc/self/map_files/"), _S(""), ((os__WalkParams){.hidden = 0,})); int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { string it = ((string*) _t1_orig.data)[_t3]; string _t2 = os__real_path(it); array_push((array*)&_t1, &_t2); } Array_string my_libs =_t1; bool _t4 = false; Array_string _t4_orig = my_libs; int _t4_len = _t4_orig.len; for (int _t5 = 0; _t5 < _t4_len; ++_t5) { string it = ((string*) _t4_orig.data)[_t5]; if (string_contains(it, _S("musl"))) { _t4 = true; break; } } if (_t4) { res->is_musl = true; res->is_glibc = false; } } VNORETURN VV_LOC void v__pref__run_code_in_tmp_vfile_and_exit(Array_string args, v__pref__Preferences* res, string option_name, string extension, string content) { string tmp_file_path = rand__ulid(); string tmp_exe_file_path = res->out_name; string output_option = _S(""); if ((tmp_exe_file_path).len == 0) { tmp_exe_file_path = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_file_path}}, {_S(".exe"), 0, { .d_c = 0 }}})); output_option = str_intp(2, _MOV((StrIntpData[]){{_S("-o "), 0xfe10, {.d_s = os__quoted_path(tmp_exe_file_path)}}, {_S(" "), 0, { .d_c = 0 }}})); } string tmp_v_file_path = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_file_path}}, {_S("."), 0xfe10, {.d_s = extension}}, {_SLIT0, 0, { .d_c = 0 }}})); _result_void _t1 = os__write_file(tmp_v_file_path, content); if (_t1.is_error) { IError err = _t1.err; _v_panic(str_intp(2, _MOV((StrIntpData[]){{_S("Failed to create temporary file "), 0xfe10, {.d_s = tmp_v_file_path}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } ; string run_options = Array_string_join(os__cmdline__options_before(args, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){string_clone(option_name)}))), _S(" ")); string command_options = Array_string_join(array_slice_ni(os__cmdline__options_after(args, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){string_clone(option_name)}))), 1, 2147483647), _S(" ")); string vexe = v__pref__vexe_path(); string tmp_cmd = str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(vexe)}}, {_S(" "), 0xfe10, {.d_s = output_option}}, {_S(" "), 0xfe10, {.d_s = run_options}}, {_S(" run "), 0xfe10, {.d_s = os__quoted_path(tmp_v_file_path)}}, {_S(" "), 0xfe10, {.d_s = command_options}}, {_SLIT0, 0, { .d_c = 0 }}})); v__pref__Preferences_vrun_elog(res, str_intp(2, _MOV((StrIntpData[]){{_S("tmp_cmd: "), 0xfe10, {.d_s = tmp_cmd}}, {_SLIT0, 0, { .d_c = 0 }}}))); int tmp_result = os__system(tmp_cmd); v__pref__Preferences_vrun_elog(res, str_intp(2, _MOV((StrIntpData[]){{_S("exit code: "), 0xfe07, {.d_i32 = tmp_result}}, {_SLIT0, 0, { .d_c = 0 }}}))); if ((output_option).len != 0) { v__pref__Preferences_vrun_elog(res, str_intp(2, _MOV((StrIntpData[]){{_S("remove tmp exe file: "), 0xfe10, {.d_s = tmp_exe_file_path}}, {_SLIT0, 0, { .d_c = 0 }}}))); _result_void _t2 = os__rm(tmp_exe_file_path); (void)_t2; ; } v__pref__Preferences_vrun_elog(res, str_intp(2, _MOV((StrIntpData[]){{_S("remove tmp v file: "), 0xfe10, {.d_s = tmp_v_file_path}}, {_SLIT0, 0, { .d_c = 0 }}}))); _result_void _t3 = os__rm(tmp_v_file_path); (void)_t3; ; _v_exit(tmp_result); VUNREACHABLE(); while(1); } multi_return_ref_v__pref__Preferences_string v__pref__parse_args_and_show_errors(Array_string known_external_commands, Array_string args, bool show_output) { v__pref__Preferences* res = ((v__pref__Preferences*)memdup(&(v__pref__Preferences){.os = 0,.backend = 0,.backend_set_by_flag = 0,.build_mode = 0,.arch = 0,.output_mode = v__pref__OutputMode__stdout,.is_verbose = 0,.is_glibc = 0,.is_musl = 0,.is_test = 0,.is_script = 0,.is_vsh = 0,.raw_vsh_tmp_prefix = (string){.str=(byteptr)"", .is_lit=1},.is_livemain = 0,.is_liveshared = 0,.is_shared = 0,.is_o = 0,.is_prof = 0,.is_prod = 0,.no_prod_options = 0,.is_repl = 0,.is_eval_argument = 0,.is_run = 0,.is_crun = 0,.is_debug = 0,.is_vlines = 0,.is_stats = 0,.show_asserts = 0,.show_timings = 0,.is_fmt = 0,.is_vet = 0,.is_vweb = 0,.is_ios_simulator = 0,.is_apk = 0,.is_help = 0,.is_quiet = 0,.is_cstrict = 0,.is_callstack = 0,.is_trace = 0,.is_coverage = 0,.is_check_return = 0,.eval_argument = (string){.str=(byteptr)"", .is_lit=1},.test_runner = (string){.str=(byteptr)"", .is_lit=1},.profile_file = (string){.str=(byteptr)"", .is_lit=1},.coverage_dir = (string){.str=(byteptr)"", .is_lit=1},.profile_no_inline = 0,.profile_fns = __new_array(0, 0, sizeof(string)),.translated = 0,.translated_go = true,.obfuscate_removed = 0,.hide_auto_str = 0,.sanitize = 0,.sourcemap = 0,.sourcemap_inline = true,.sourcemap_src_included = 0,.show_cc = 0,.show_c_output = 0,.show_callgraph = 0,.show_depgraph = 0,.show_unused_params = 0,.dump_c_flags = (string){.str=(byteptr)"", .is_lit=1},.dump_modules = (string){.str=(byteptr)"", .is_lit=1},.dump_files = (string){.str=(byteptr)"", .is_lit=1},.dump_defines = (string){.str=(byteptr)"", .is_lit=1},.use_cache = 0,.retry_compilation = true,.use_os_system_to_run = 0,.macosx_version_min = _S("0"),.cflags = (string){.str=(byteptr)"", .is_lit=1},.ldflags = (string){.str=(byteptr)"", .is_lit=1},.m64 = 0,.ccompiler = (string){.str=(byteptr)"", .is_lit=1},.ccompiler_type = 0,.cppcompiler = (string){.str=(byteptr)"", .is_lit=1},.third_party_option = (string){.str=(byteptr)"", .is_lit=1},.building_v = 0,.no_bounds_checking = 0,.force_bounds_checking = 0,.autofree = 0,.print_autofree_vars = 0,.print_autofree_vars_in_fn = (string){.str=(byteptr)"", .is_lit=1},.trace_calls = 0,.trace_fns = __new_array(0, 0, sizeof(string)),.compress = 0,.no_builtin = 0,.enable_globals = 0,.is_bare = 0,.bare_builtin_dir = (string){.str=(byteptr)"", .is_lit=1},.no_preludes = 0,.custom_prelude = (string){.str=(byteptr)"", .is_lit=1},.cmain = (string){.str=(byteptr)"", .is_lit=1},.lookup_path = __new_array(0, 0, sizeof(string)),.output_cross_c = 0,.output_es5 = 0,.prealloc = 0,.vroot = (string){.str=(byteptr)"", .is_lit=1},.vlib = (string){.str=(byteptr)"", .is_lit=1},.vmodules_paths = __new_array(0, 0, sizeof(string)),.out_name_c = (string){.str=(byteptr)"", .is_lit=1},.out_name = (string){.str=(byteptr)"", .is_lit=1},.path = (string){.str=(byteptr)"", .is_lit=1},.line_info = (string){.str=(byteptr)"", .is_lit=1},.linfo = ((v__pref__LineInfo){.line_nr = 0,.path = (string){.str=(byteptr)"", .is_lit=1},.expr = (string){.str=(byteptr)"", .is_lit=1},.is_running = 0,.vars_printed = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}),.run_only = __new_array(0, 0, sizeof(string)),.exclude = __new_array(0, 0, sizeof(string)),.compile_defines = __new_array(0, 0, sizeof(string)),.compile_defines_all = __new_array(0, 0, sizeof(string)),.compile_values = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.run_args = __new_array(0, 0, sizeof(string)),.printfn_list = __new_array(0, 0, sizeof(string)),.print_v_files = 0,.print_watched_files = 0,.skip_running = 0,.skip_warnings = 0,.skip_notes = 0,.warn_impure_v = 0,.warns_are_errors = 0,.notes_are_errors = 0,.fatal_errors = 0,.reuse_tmpc = 0,.no_rsp = 0,.no_std = 0,.no_parallel = 0,.parallel_cc = 0,.only_check_syntax = 0,.check_only = 0,.experimental = 0,.skip_unused = 0,.use_color = 0,.cleanup_files = __new_array(0, 0, sizeof(string)),.build_options = __new_array(0, 0, sizeof(string)),.cache_manager = ((v__vcache__CacheManager){.basepath = (string){.str=(byteptr)"", .is_lit=1},.original_vopts = (string){.str=(byteptr)"", .is_lit=1},.vopts = (string){.str=(byteptr)"", .is_lit=1},.k2cpath = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}),.gc_mode = v__pref__GarbageCollectionMode__unknown,.assert_failure_mode = 0,.message_limit = 150,.nofloat = 0,.use_coroutines = 0,.fast_math = 0,.checker_match_exhaustive_cutoff_limit = 12,.thread_stack_size = 8388608,.wasm_stack_top = (int_literal)(1024 + (16384)),.wasm_validate = 0,.warn_about_allocs = 0,.div_by_zero_is_zero = 0,.relaxed_gcc14 = true,.subsystem = 0,.is_vls = 0,}, sizeof(v__pref__Preferences))); v__pref__detect_musl(res); #if defined(TARGET_IS_64BIT) { res->m64 = true; } #endif res->run_only = string_split_any(os__getenv(_S("VTEST_ONLY_FN")), _S(",")); if ((os__getenv(_S("VQUIET"))).len != 0) { res->is_quiet = true; } if ((os__getenv(_S("VNORUN"))).len != 0) { res->skip_running = true; } string coverage_dir_from_env = os__getenv(_S("VCOVDIR")); if ((coverage_dir_from_env).len != 0) { res->coverage_dir = coverage_dir_from_env; } bool no_skip_unused = false; string command = _S(""); int command_idx = 0; for (int i = 0; i < args.len; i++) { string arg = (*(string*)array_get(args, i)); if (_SLIT_EQ(arg.str, arg.len, "--")) { break; } else if (_SLIT_EQ(arg.str, arg.len, "-wasm-validate")) { res->wasm_validate = true; } else if (_SLIT_EQ(arg.str, arg.len, "-wasm-stack-top")) { res->wasm_stack_top = string_int(os__cmdline__option(array_slice(args, i, 2147483647), arg, int_str(res->wasm_stack_top))); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-apk")) { res->is_apk = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-arch")) { string target_arch = os__cmdline__option(array_slice(args, i, 2147483647), _S("-arch"), _S("")); i++; _result_v__pref__Arch _t3 = v__pref__arch_from_string(target_arch); if (_t3.is_error) { IError err = _t3.err; v__pref__eprintln_exit(str_intp(2, _MOV((StrIntpData[]){{_S("unknown architecture target `"), 0xfe10, {.d_s = target_arch}}, {_S("`"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } v__pref__Arch target_arch_kind = (*(v__pref__Arch*)_t3.data); res->arch = target_arch_kind; array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" "), 0xfe10, {.d_s = target_arch}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else if (_SLIT_EQ(arg.str, arg.len, "-assert")) { string assert_mode = os__cmdline__option(array_slice(args, i, 2147483647), _S("-assert"), _S("")); if (_SLIT_EQ(assert_mode.str, assert_mode.len, "aborts")) { res->assert_failure_mode = v__pref__AssertFailureMode__aborts; } else if (_SLIT_EQ(assert_mode.str, assert_mode.len, "backtraces")) { res->assert_failure_mode = v__pref__AssertFailureMode__backtraces; } else if (_SLIT_EQ(assert_mode.str, assert_mode.len, "continues")) { res->assert_failure_mode = v__pref__AssertFailureMode__continues; } else { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("unknown assert mode `-gc "), 0xfe10, {.d_s = assert_mode}}, {_S("`, supported modes are:`"), 0, { .d_c = 0 }}}))); eprintln(_S(" `-assert aborts` .... calls abort() after assertion failure")); eprintln(_S(" `-assert backtraces` .... calls print_backtrace() after assertion failure")); eprintln(_S(" `-assert continues` .... does not call anything, just continue after an assertion failure")); _v_exit(1); VUNREACHABLE(); } i++; } else if (_SLIT_EQ(arg.str, arg.len, "-show-timings")) { res->show_timings = true; } else if (_SLIT_EQ(arg.str, arg.len, "-show-asserts")) { res->show_asserts = true; } else if (_SLIT_EQ(arg.str, arg.len, "-check-syntax")) { res->only_check_syntax = true; } else if (_SLIT_EQ(arg.str, arg.len, "-check")) { res->check_only = true; } else if (_SLIT_EQ(arg.str, arg.len, "-?") || _SLIT_EQ(arg.str, arg.len, "-h") || _SLIT_EQ(arg.str, arg.len, "-help") || _SLIT_EQ(arg.str, arg.len, "--help")) { res->is_help = true; } else if (_SLIT_EQ(arg.str, arg.len, "-q")) { res->is_quiet = true; } else if (_SLIT_EQ(arg.str, arg.len, "-v") || _SLIT_EQ(arg.str, arg.len, "-V") || _SLIT_EQ(arg.str, arg.len, "--version") || _SLIT_EQ(arg.str, arg.len, "-version")) { if ((command).len != 0) { continue; } if (array_slice(args, i, 2147483647).len > 1 && _SLIT_EQ(arg.str, arg.len, "-v")) { res->is_verbose = true; } else { command = _S("version"); } } else if (_SLIT_EQ(arg.str, arg.len, "-progress")) { } else if (_SLIT_EQ(arg.str, arg.len, "-Wimpure-v")) { res->warn_impure_v = true; } else if (_SLIT_EQ(arg.str, arg.len, "-Wfatal-errors")) { res->fatal_errors = true; } else if (_SLIT_EQ(arg.str, arg.len, "-silent")) { res->output_mode = v__pref__OutputMode__silent; } else if (_SLIT_EQ(arg.str, arg.len, "-skip-running")) { res->skip_running = true; } else if (_SLIT_EQ(arg.str, arg.len, "-cstrict")) { res->is_cstrict = true; } else if (_SLIT_EQ(arg.str, arg.len, "-nofloat")) { res->nofloat = true; array_push((array*)&res->compile_defines_all, _MOV((string[]){ _S("nofloat") })); array_push((array*)&res->compile_defines, _MOV((string[]){ _S("nofloat") })); } else if (_SLIT_EQ(arg.str, arg.len, "-fast-math")) { res->fast_math = true; } else if (_SLIT_EQ(arg.str, arg.len, "-e")) { res->is_eval_argument = true; res->eval_argument = os__cmdline__option(array_slice(args, i, 2147483647), _S("-e"), _S("")); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-subsystem")) { string subsystem = os__cmdline__option(array_slice(args, i, 2147483647), _S("-subsystem"), _S("")); _result_v__pref__Subsystem _t7 = v__pref__Subsystem__static__from_T_string(subsystem); if (_t7.is_error) { IError err = _t7.err; Array_string valid = __new_array_with_default(0, 0, sizeof(string), 0); /* $for x in v.pref.Subsystem.values */ { EnumData x = {0}; /* enum vals 0 */ { x.name = _S("auto"); x.value = v__pref__Subsystem__auto; x.attrs = __new_array_with_default(0, 0, sizeof(string), 0); array_push((array*)&valid, _MOV((string[]){ string_clone(x.name) })); } /* enum vals 1 */ { x.name = _S("console"); x.value = v__pref__Subsystem__console; x.attrs = __new_array_with_default(0, 0, sizeof(string), 0); array_push((array*)&valid, _MOV((string[]){ string_clone(x.name) })); } /* enum vals 2 */ { x.name = _S("windows"); x.value = v__pref__Subsystem__windows; x.attrs = __new_array_with_default(0, 0, sizeof(string), 0); array_push((array*)&valid, _MOV((string[]){ string_clone(x.name) })); } }// $for eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("invalid subsystem: "), 0xfe10, {.d_s = subsystem}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("valid values are: "), 0xfe10, {.d_s = Array_string_str(valid)}}, {_SLIT0, 0, { .d_c = 0 }}}))); _v_exit(1); VUNREACHABLE(); ; } res->subsystem = (*(v__pref__Subsystem*)_t7.data); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-gc")) { string gc_mode = os__cmdline__option(array_slice(args, i, 2147483647), _S("-gc"), _S("")); if (_SLIT_EQ(gc_mode.str, gc_mode.len, "none")) { res->gc_mode = v__pref__GarbageCollectionMode__no_gc; } else if (_SLIT_EQ(gc_mode.str, gc_mode.len, "") || _SLIT_EQ(gc_mode.str, gc_mode.len, "boehm")) { res->gc_mode = v__pref__GarbageCollectionMode__boehm_full_opt; v__pref__Preferences_parse_define(res, _S("gcboehm")); v__pref__Preferences_parse_define(res, _S("gcboehm_full")); v__pref__Preferences_parse_define(res, _S("gcboehm_opt")); } else if (_SLIT_EQ(gc_mode.str, gc_mode.len, "boehm_full")) { res->gc_mode = v__pref__GarbageCollectionMode__boehm_full; v__pref__Preferences_parse_define(res, _S("gcboehm")); v__pref__Preferences_parse_define(res, _S("gcboehm_full")); } else if (_SLIT_EQ(gc_mode.str, gc_mode.len, "boehm_incr")) { res->gc_mode = v__pref__GarbageCollectionMode__boehm_incr; v__pref__Preferences_parse_define(res, _S("gcboehm")); v__pref__Preferences_parse_define(res, _S("gcboehm_incr")); } else if (_SLIT_EQ(gc_mode.str, gc_mode.len, "boehm_full_opt")) { res->gc_mode = v__pref__GarbageCollectionMode__boehm_full_opt; v__pref__Preferences_parse_define(res, _S("gcboehm")); v__pref__Preferences_parse_define(res, _S("gcboehm_full")); v__pref__Preferences_parse_define(res, _S("gcboehm_opt")); } else if (_SLIT_EQ(gc_mode.str, gc_mode.len, "boehm_incr_opt")) { res->gc_mode = v__pref__GarbageCollectionMode__boehm_incr_opt; v__pref__Preferences_parse_define(res, _S("gcboehm")); v__pref__Preferences_parse_define(res, _S("gcboehm_incr")); v__pref__Preferences_parse_define(res, _S("gcboehm_opt")); } else if (_SLIT_EQ(gc_mode.str, gc_mode.len, "boehm_leak")) { res->gc_mode = v__pref__GarbageCollectionMode__boehm_leak; v__pref__Preferences_parse_define(res, _S("gcboehm")); v__pref__Preferences_parse_define(res, _S("gcboehm_leak")); } else { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("unknown garbage collection mode `-gc "), 0xfe10, {.d_s = gc_mode}}, {_S("`, supported modes are:`"), 0, { .d_c = 0 }}}))); eprintln(_S(" `-gc boehm` ............ default GC-mode (currently `boehm_full_opt`)")); eprintln(_S(" `-gc boehm_full` ....... classic full collection")); eprintln(_S(" `-gc boehm_incr` ....... incremental collection")); eprintln(_S(" `-gc boehm_full_opt` ... optimized classic full collection")); eprintln(_S(" `-gc boehm_incr_opt` ... optimized incremental collection")); eprintln(_S(" `-gc boehm_leak` ....... leak detection (for debugging)")); eprintln(_S(" `-gc none` ............. no garbage collection")); _v_exit(1); VUNREACHABLE(); } i++; } else if (_SLIT_EQ(arg.str, arg.len, "-g") || _SLIT_EQ(arg.str, arg.len, "-debug")) { res->is_debug = true; res->is_vlines = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-cg") || _SLIT_EQ(arg.str, arg.len, "-cdebug")) { res->is_debug = true; res->is_vlines = false; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-debug-tcc")) { res->ccompiler = _S("tcc"); array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" \""), 0xfe10, {.d_s = res->ccompiler}}, {_S("\""), 0, { .d_c = 0 }}})) })); res->retry_compilation = false; res->show_cc = true; res->show_c_output = true; } else if (_SLIT_EQ(arg.str, arg.len, "-sourcemap")) { res->sourcemap = true; } else if (_SLIT_EQ(arg.str, arg.len, "-warn-about-allocs")) { res->warn_about_allocs = true; } else if (_SLIT_EQ(arg.str, arg.len, "-div-by-zero-is-zero")) { res->div_by_zero_is_zero = true; } else if (_SLIT_EQ(arg.str, arg.len, "-sourcemap-src-included")) { res->sourcemap_src_included = true; } else if (_SLIT_EQ(arg.str, arg.len, "-sourcemap-inline")) { res->sourcemap_inline = true; } else if (_SLIT_EQ(arg.str, arg.len, "-repl")) { res->is_repl = true; } else if (_SLIT_EQ(arg.str, arg.len, "-live")) { res->is_livemain = true; } else if (_SLIT_EQ(arg.str, arg.len, "-sharedlive")) { res->is_liveshared = true; res->is_shared = true; } else if (_SLIT_EQ(arg.str, arg.len, "-shared")) { res->is_shared = true; } else if (_SLIT_EQ(arg.str, arg.len, "--enable-globals")) { v__pref__eprintln_cond(show_output && !res->is_quiet, _S("`--enable-globals` flag is deprecated, please use `-enable-globals` instead")); res->enable_globals = true; } else if (_SLIT_EQ(arg.str, arg.len, "-enable-globals")) { res->enable_globals = true; } else if (_SLIT_EQ(arg.str, arg.len, "-autofree")) { res->autofree = true; res->gc_mode = v__pref__GarbageCollectionMode__no_gc; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-print_autofree_vars")) { res->print_autofree_vars = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-print_autofree_vars_in_fn")) { res->print_autofree_vars = true; string value = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("")); array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); array_push((array*)&res->build_options, _MOV((string[]){ string_clone(value) })); res->print_autofree_vars_in_fn = value; i++; } else if (_SLIT_EQ(arg.str, arg.len, "-trace-calls")) { array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); res->trace_calls = true; } else if (_SLIT_EQ(arg.str, arg.len, "-trace-fns")) { string value = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("")); array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); array_push((array*)&res->build_options, _MOV((string[]){ string_clone(value) })); Array_string trace_fns = string_split(value, _S(",")); if (trace_fns.len > 0) { _PUSH_MANY(&res->trace_fns, (trace_fns), _t21, Array_string); } i++; } else if (_SLIT_EQ(arg.str, arg.len, "-manualfree")) { res->autofree = false; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-skip-unused")) { res->skip_unused = true; } else if (_SLIT_EQ(arg.str, arg.len, "-no-skip-unused")) { no_skip_unused = true; res->skip_unused = false; } else if (_SLIT_EQ(arg.str, arg.len, "-compress")) { res->compress = true; } else if (_SLIT_EQ(arg.str, arg.len, "-freestanding")) { res->is_bare = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-no-retry-compilation")) { res->retry_compilation = false; } else if (_SLIT_EQ(arg.str, arg.len, "-musl")) { res->is_musl = true; res->is_glibc = false; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-glibc")) { res->is_musl = false; res->is_glibc = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-no-bounds-checking")) { res->no_bounds_checking = true; array_push((array*)&res->compile_defines, _MOV((string[]){ _S("no_bounds_checking") })); array_push((array*)&res->compile_defines_all, _MOV((string[]){ _S("no_bounds_checking") })); array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-force-bounds-checking")) { res->force_bounds_checking = true; } else if (_SLIT_EQ(arg.str, arg.len, "-no-builtin")) { res->no_builtin = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-no-preludes")) { res->no_preludes = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-no-relaxed-gcc14")) { res->relaxed_gcc14 = false; } else if (_SLIT_EQ(arg.str, arg.len, "-prof") || _SLIT_EQ(arg.str, arg.len, "-profile")) { res->profile_file = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("-")); res->is_prof = true; array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" "), 0xfe10, {.d_s = res->profile_file}}, {_SLIT0, 0, { .d_c = 0 }}})) })); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-cov") || _SLIT_EQ(arg.str, arg.len, "-coverage")) { res->coverage_dir = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("-")); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-profile-fns")) { Array_string profile_fns = string_split(os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("")), _S(",")); if (profile_fns.len > 0) { _PUSH_MANY(&res->profile_fns, (profile_fns), _t32, Array_string); } i++; } else if (_SLIT_EQ(arg.str, arg.len, "-profile-no-inline")) { res->profile_no_inline = true; } else if (_SLIT_EQ(arg.str, arg.len, "-prod")) { res->is_prod = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-no-prod-options")) { res->no_prod_options = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-sanitize")) { res->sanitize = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-simulator")) { res->is_ios_simulator = true; } else if (_SLIT_EQ(arg.str, arg.len, "-stats")) { res->is_stats = true; } else if (_SLIT_EQ(arg.str, arg.len, "-obf") || _SLIT_EQ(arg.str, arg.len, "-obfuscate")) { println(_S("obfuscation has been removed; use `strip` on the resulting binary instead")); res->obfuscate_removed = true; } else if (_SLIT_EQ(arg.str, arg.len, "-hide-auto-str")) { res->hide_auto_str = true; } else if (_SLIT_EQ(arg.str, arg.len, "-translated")) { res->translated = true; res->gc_mode = v__pref__GarbageCollectionMode__no_gc; } else if (_SLIT_EQ(arg.str, arg.len, "-translated-go")) { println(_S("got -translated-go")); res->translated_go = true; } else if (_SLIT_EQ(arg.str, arg.len, "-m32") || _SLIT_EQ(arg.str, arg.len, "-m64")) { res->m64 = string_at(arg, 2) == '6'; res->cflags = string__plus(res->cflags, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = arg}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else if (_SLIT_EQ(arg.str, arg.len, "-color")) { res->use_color = v__pref__ColorOutput__always; } else if (_SLIT_EQ(arg.str, arg.len, "-nocolor")) { res->use_color = v__pref__ColorOutput__never; } else if (_SLIT_EQ(arg.str, arg.len, "-showcc")) { res->show_cc = true; } else if (_SLIT_EQ(arg.str, arg.len, "-show-c-output")) { res->show_c_output = true; } else if (_SLIT_EQ(arg.str, arg.len, "-show-callgraph")) { res->show_callgraph = true; } else if (_SLIT_EQ(arg.str, arg.len, "-show-depgraph")) { res->show_depgraph = true; } else if (_SLIT_EQ(arg.str, arg.len, "-run-only")) { res->run_only = string_split_any(os__cmdline__option(array_slice(args, i, 2147483647), arg, os__getenv(_S("VTEST_ONLY_FN"))), _S(",")); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-exclude")) { Array_string patterns = string_split_any(os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("")), _S(",")); _PUSH_MANY(&res->exclude, (patterns), _t36, Array_string); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-test-runner")) { res->test_runner = os__cmdline__option(array_slice(args, i, 2147483647), arg, res->test_runner); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-dump-c-flags")) { res->dump_c_flags = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("-")); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-dump-modules")) { res->dump_modules = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("-")); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-dump-files")) { res->dump_files = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("-")); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-dump-defines")) { res->dump_defines = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("-")); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-experimental")) { res->experimental = true; } else if (_SLIT_EQ(arg.str, arg.len, "-usecache")) { res->use_cache = true; } else if (_SLIT_EQ(arg.str, arg.len, "-use-os-system-to-run")) { res->use_os_system_to_run = true; } else if (_SLIT_EQ(arg.str, arg.len, "-macosx-version-min")) { res->macosx_version_min = os__cmdline__option(array_slice(args, i, 2147483647), arg, res->macosx_version_min); array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" "), 0xfe10, {.d_s = res->macosx_version_min}}, {_SLIT0, 0, { .d_c = 0 }}})) })); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-nocache")) { res->use_cache = false; } else if (_SLIT_EQ(arg.str, arg.len, "-prealloc")) { res->prealloc = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-no-parallel")) { res->no_parallel = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-parallel-cc")) { res->parallel_cc = true; res->no_parallel = true; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-native")) { res->backend = v__pref__Backend__native; array_push((array*)&res->build_options, _MOV((string[]){ string_clone(arg) })); } else if (_SLIT_EQ(arg.str, arg.len, "-interpret")) { res->backend = v__pref__Backend__interpret; } else if (_SLIT_EQ(arg.str, arg.len, "-W")) { res->warns_are_errors = true; } else if (_SLIT_EQ(arg.str, arg.len, "-w")) { res->skip_warnings = true; res->warns_are_errors = false; } else if (_SLIT_EQ(arg.str, arg.len, "-N")) { res->notes_are_errors = true; } else if (_SLIT_EQ(arg.str, arg.len, "-n")) { res->skip_notes = true; res->notes_are_errors = false; } else if (_SLIT_EQ(arg.str, arg.len, "-no-rsp")) { res->no_rsp = true; } else if (_SLIT_EQ(arg.str, arg.len, "-no-std")) { res->no_std = true; } else if (_SLIT_EQ(arg.str, arg.len, "-keepc")) { res->reuse_tmpc = true; } else if (_SLIT_EQ(arg.str, arg.len, "-watch")) { v__pref__eprintln_exit(_S("The -watch option is deprecated. Please use the watch command `v watch file.v` instead.")); VUNREACHABLE(); } else if (_SLIT_EQ(arg.str, arg.len, "-print-v-files")) { res->print_v_files = true; } else if (_SLIT_EQ(arg.str, arg.len, "-print-watched-files")) { res->print_watched_files = true; } else if (_SLIT_EQ(arg.str, arg.len, "-http")) { string run_http_argument = _S("import net.http.file; file.serve()"); Array_string _t42 = {0}; Array_string _t42_orig = args; int _t42_len = _t42_orig.len; _t42 = __new_array(0, _t42_len, sizeof(string)); for (int _t43 = 0; _t43 < _t42_len; ++_t43) { string it = ((string*) _t42_orig.data)[_t43]; if (_SLIT_NE(it.str, it.len, "-http")) { array_push((array*)&_t42, &it); } } Array_string new_args =_t42; _PUSH_MANY(&new_args, (new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("-e"), string_clone(run_http_argument)}))), _t44, Array_string); v__pref__eprintln_cond(show_output && !res->is_quiet, str_intp(2, _MOV((StrIntpData[]){{_S("Note: use `v -e '"), 0xfe10, {.d_s = run_http_argument}}, {_S("'`, if you want to customise the http server options."), 0, { .d_c = 0 }}}))); v__pref__run_code_in_tmp_vfile_and_exit(new_args, res, _S("-e"), _S("vsh"), run_http_argument); VUNREACHABLE(); } else if (_SLIT_EQ(arg.str, arg.len, "-cross")) { res->output_cross_c = true; array_push((array*)&res->build_options, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else if (_SLIT_EQ(arg.str, arg.len, "-os")) { string target_os = string_to_lower_ascii(os__cmdline__option(array_slice(args, i, 2147483647), _S("-os"), _S(""))); i++; _result_v__pref__OS _t46 = v__pref__os_from_string(target_os); if (_t46.is_error) { IError err = _t46.err; if (_SLIT_EQ(target_os.str, target_os.len, "cross")) { res->output_cross_c = true; continue; } v__pref__eprintln_exit(str_intp(2, _MOV((StrIntpData[]){{_S("unknown operating system target `"), 0xfe10, {.d_s = target_os}}, {_S("`"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } v__pref__OS target_os_kind = (*(v__pref__OS*)_t46.data); if (target_os_kind == v__pref__OS__wasm32) { res->is_bare = true; } if (target_os_kind == v__pref__OS__wasm32 || target_os_kind == v__pref__OS__wasm32_emscripten || target_os_kind == v__pref__OS__wasm32_wasi) { res->arch = v__pref__Arch__wasm32; } if (target_os_kind == v__pref__OS__wasm32_emscripten) { res->gc_mode = v__pref__GarbageCollectionMode__no_gc; } res->os = target_os_kind; array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" "), 0xfe10, {.d_s = target_os}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else if (_SLIT_EQ(arg.str, arg.len, "-printfn")) { _PUSH_MANY(&res->printfn_list, (string_split(os__cmdline__option(array_slice(args, i, 2147483647), _S("-printfn"), _S("")), _S(","))), _t48, Array_string); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-cflags")) { res->cflags = string__plus(res->cflags, string__plus(_S(" "), os__cmdline__option(array_slice(args, i, 2147483647), _S("-cflags"), _S("")))); array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" \""), 0xfe10, {.d_s = string_trim_space(res->cflags)}}, {_S("\""), 0, { .d_c = 0 }}})) })); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-ldflags")) { res->ldflags = string__plus(res->ldflags, string__plus(_S(" "), os__cmdline__option(array_slice(args, i, 2147483647), _S("-ldflags"), _S("")))); array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" \""), 0xfe10, {.d_s = string_trim_space(res->ldflags)}}, {_S("\""), 0, { .d_c = 0 }}})) })); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-d") || _SLIT_EQ(arg.str, arg.len, "-define")) { string* _t52 = (string*)(array_get_with_check(array_slice(args, i, 2147483647), 1)); _option_string _t51 = {0}; if (_t52) { *((string*)&_t51.data) = *((string*)_t52); } else { _t51.state = 2; _t51.err = _v_error(_S("array index out of range")); } if (_t51.state == 0) { string define = (*(string*)_t51.data); v__pref__Preferences_parse_define(res, define); } i++; } else if (_SLIT_EQ(arg.str, arg.len, "-message-limit")) { res->message_limit = string_int(os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("5"))); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-thread-stack-size")) { res->thread_stack_size = string_int(os__cmdline__option(array_slice(args, i, 2147483647), arg, int_str(res->thread_stack_size))); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-cc")) { res->ccompiler = os__cmdline__option(array_slice(args, i, 2147483647), _S("-cc"), _S("cc")); array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" \""), 0xfe10, {.d_s = res->ccompiler}}, {_S("\""), 0, { .d_c = 0 }}})) })); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-c++")) { res->cppcompiler = os__cmdline__option(array_slice(args, i, 2147483647), _S("-c++"), _S("c++")); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-checker-match-exhaustive-cutoff-limit")) { res->checker_match_exhaustive_cutoff_limit = string_int(os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("10"))); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-o") || _SLIT_EQ(arg.str, arg.len, "-output")) { res->out_name = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("")); if (!os__is_abs_path(res->out_name)) { res->out_name = os__join_path(os__getwd(), new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){res->out_name}))); } i++; } else if (_SLIT_EQ(arg.str, arg.len, "-is_o")) { res->is_o = true; } else if (_SLIT_EQ(arg.str, arg.len, "-b") || _SLIT_EQ(arg.str, arg.len, "-backend")) { string sbackend = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("c")); array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" "), 0xfe10, {.d_s = sbackend}}, {_SLIT0, 0, { .d_c = 0 }}})) })); _result_v__pref__Backend _t55 = v__pref__backend_from_string(sbackend); if (_t55.is_error) { IError err = _t55.err; v__pref__eprintln_exit(str_intp(2, _MOV((StrIntpData[]){{_S("Unknown V backend: "), 0xfe10, {.d_s = sbackend}}, {_S("\nValid -backend choices are: c, go, interpret, js, js_node, js_browser, js_freestanding, native, wasm"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } v__pref__Backend b = (*(v__pref__Backend*)_t55.data); if (b == v__pref__Backend__wasm) { array_push((array*)&res->compile_defines, _MOV((string[]){ _S("wasm") })); array_push((array*)&res->compile_defines_all, _MOV((string[]){ _S("wasm") })); res->arch = v__pref__Arch__wasm32; } else if (v__pref__Backend_is_js(b)) { res->output_cross_c = true; } res->backend = b; res->backend_set_by_flag = true; i++; } else if (_SLIT_EQ(arg.str, arg.len, "-es5")) { res->output_es5 = true; } else if (_SLIT_EQ(arg.str, arg.len, "-path")) { string path = os__cmdline__option(array_slice(args, i, 2147483647), _S("-path"), _S("")); array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" \""), 0xfe10, {.d_s = path}}, {_S("\""), 0, { .d_c = 0 }}})) })); res->lookup_path = string_split(string_replace(path, _S("|"), _const_os__path_delimiter), _const_os__path_delimiter); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-bare-builtin-dir")) { string bare_builtin_dir = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("")); array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" \""), 0xfe10, {.d_s = bare_builtin_dir}}, {_S("\""), 0, { .d_c = 0 }}})) })); res->bare_builtin_dir = bare_builtin_dir; i++; } else if (_SLIT_EQ(arg.str, arg.len, "-custom-prelude")) { string path = os__cmdline__option(array_slice(args, i, 2147483647), _S("-custom-prelude"), _S("")); array_push((array*)&res->build_options, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg}}, {_S(" "), 0xfe10, {.d_s = path}}, {_SLIT0, 0, { .d_c = 0 }}})) })); _result_string _t61 = os__read_file(path); if (_t61.is_error) { IError err = _t61.err; v__pref__eprintln_exit(str_intp(2, _MOV((StrIntpData[]){{_S("cannot open custom prelude file: "), 0xfe10, {.d_s = IError_str(err)}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } string prelude = (*(string*)_t61.data); res->custom_prelude = prelude; i++; } else if (_SLIT_EQ(arg.str, arg.len, "-raw-vsh-tmp-prefix")) { res->raw_vsh_tmp_prefix = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("")); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-cmain")) { res->cmain = os__cmdline__option(array_slice(args, i, 2147483647), _S("-cmain"), _S("")); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-line-info")) { res->line_info = os__cmdline__option(array_slice(args, i, 2147483647), arg, _S("")); v__pref__Preferences_parse_line_info(res, res->line_info); i++; } else if (_SLIT_EQ(arg.str, arg.len, "-check-unused-fn-args")) { res->show_unused_params = true; } else if (_SLIT_EQ(arg.str, arg.len, "-check-return")) { res->is_check_return = true; } else if (_SLIT_EQ(arg.str, arg.len, "-use-coroutines")) { res->use_coroutines = true; #if defined(__APPLE__) || defined(__linux__) { string _t63; #if defined(__V_arm64) _t63 = _S("arm64"); ; #else _t63 = _S("amd64"); ; #endif string arch = _t63; string vexe = v__pref__vexe_path(); string vroot = os__dir(vexe); string so_path = os__join_path(vroot, new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("thirdparty"), _S("photon"), _S("photonwrapper.so")}))); string so_url = str_intp(3, _MOV((StrIntpData[]){{_S("https://github.com/vlang/photonbin/raw/master/photonwrapper_"), 0xfe10, {.d_s = os__user_os()}}, {_S("_"), 0xfe10, {.d_s = arch}}, {_S(".so"), 0, { .d_c = 0 }}})); if (!os__exists(so_path)) { println(_S("coroutines .so not found, downloading...")); _result_os__Result _t64 = os__execute_opt(str_intp(3, _MOV((StrIntpData[]){{_S("wget -O \""), 0xfe10, {.d_s = so_path}}, {_S("\" \""), 0xfe10, {.d_s = so_url}}, {_S("\""), 0, { .d_c = 0 }}}))); if (_t64.is_error) { IError err = _t64.err; _result_os__Result _t65 = os__execute_opt(str_intp(3, _MOV((StrIntpData[]){{_S("curl -o \""), 0xfe10, {.d_s = so_path}}, {_S("\" \""), 0xfe10, {.d_s = so_url}}, {_S("\""), 0, { .d_c = 0 }}}))); if (_t65.is_error) { IError err = _t65.err; _v_panic(str_intp(3, _MOV((StrIntpData[]){{_S("coroutines .so could not be downloaded with wget or curl. Download "), 0xfe10, {.d_s = so_url}}, {_S(", place it in "), 0xfe10, {.d_s = so_path}}, {_S(" then try again."), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } ; } ; println(_S("done!")); } array_push((array*)&res->compile_defines, _MOV((string[]){ _S("is_coroutine") })); array_push((array*)&res->compile_defines_all, _MOV((string[]){ _S("is_coroutine") })); #if defined(__APPLE__) { string dyld_fallback_paths = os__getenv(_S("DYLD_FALLBACK_LIBRARY_PATH")); string so_dir = os__dir(so_path); if (!string_contains(dyld_fallback_paths, so_dir)) { Array_string _t69 = {0}; Array_string _t69_orig = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){string_clone(dyld_fallback_paths), string_clone(so_dir)})); int _t69_len = _t69_orig.len; _t69 = __new_array(0, _t69_len, sizeof(string)); for (int _t70 = 0; _t70 < _t69_len; ++_t70) { string it = ((string*) _t69_orig.data)[_t70]; if (it.len != 0) { array_push((array*)&_t69, &it); } } string env = Array_string_join(_t69, _S(":")); os__setenv(_S("DYLD_FALLBACK_LIBRARY_PATH"), env, true); } } #endif } #else { println(_S("coroutines only work on macos & linux for now")); } #endif } else { if (_SLIT_EQ(command.str, command.len, "build") && v__pref__is_source_file(arg)) { v__pref__eprintln_exit(str_intp(2, _MOV((StrIntpData[]){{_S("Use `v "), 0xfe10, {.d_s = arg}}, {_S("` instead."), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } if (v__pref__is_source_file(arg) && string_ends_with(arg, _S(".vsh"))) { res->is_vsh = true; } if (!string_starts_with(arg, _S("-"))) { if ((command).len == 0) { command = arg; command_idx = i; if (res->is_eval_argument || (_SLIT_EQ(command.str, command.len, "run") || _SLIT_EQ(command.str, command.len, "crun") || _SLIT_EQ(command.str, command.len, "watch"))) { break; } } else if (v__pref__is_source_file(command) && v__pref__is_source_file(arg) && !(Array_string_contains(known_external_commands, command)) && (res->raw_vsh_tmp_prefix).len == 0) { v__pref__eprintln_exit(_S("Too many targets. Specify just one target: .")); VUNREACHABLE(); } continue; } if (!(_SLIT_EQ(command.str, command.len, "") || _SLIT_EQ(command.str, command.len, "build-module")) && !v__pref__is_source_file(command)) { continue; } if (command_idx < i && (res->is_vsh || (v__pref__is_source_file(command) && (Array_string_contains(known_external_commands, command))))) { continue; } string err_detail = ((command).len == 0 ? (_S("")) : (str_intp(2, _MOV((StrIntpData[]){{_S(" for command `"), 0xfe10, {.d_s = command}}, {_S("`"), 0, { .d_c = 0 }}})))); v__pref__eprintln_exit(str_intp(3, _MOV((StrIntpData[]){{_S("Unknown argument `"), 0xfe10, {.d_s = arg}}, {_S("`"), 0xfe10, {.d_s = err_detail}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } } if (res->force_bounds_checking) { res->no_bounds_checking = false; Array_string _t71 = {0}; Array_string _t71_orig = res->compile_defines; int _t71_len = _t71_orig.len; _t71 = __new_array(0, _t71_len, sizeof(string)); for (int _t72 = 0; _t72 < _t71_len; ++_t72) { string it = ((string*) _t71_orig.data)[_t72]; if (_SLIT_EQ(it.str, it.len, "no_bounds_checking")) { array_push((array*)&_t71, &it); } } res->compile_defines =_t71; Array_string _t73 = {0}; Array_string _t73_orig = res->compile_defines_all; int _t73_len = _t73_orig.len; _t73 = __new_array(0, _t73_len, sizeof(string)); for (int _t74 = 0; _t74 < _t73_len; ++_t74) { string it = ((string*) _t73_orig.data)[_t74]; if (_SLIT_EQ(it.str, it.len, "no_bounds_checking")) { array_push((array*)&_t73, &it); } } res->compile_defines_all =_t73; } if (res->trace_calls) { if (res->trace_fns.len == 0) { array_push((array*)&res->trace_fns, _MOV((string[]){ _S("*") })); } for (int _t76 = 0; _t76 < res->trace_fns.len; ++_t76) { string* fpattern = ((string*)res->trace_fns.data) + _t76; if (string_contains(*fpattern, _S("*"))) { continue; } *fpattern = str_intp(2, _MOV((StrIntpData[]){{_S("*"), 0xfe10, {.d_s = string_str(*fpattern)}}, {_S("*"), 0, { .d_c = 0 }}})); } } if (_SLIT_EQ(command.str, command.len, "crun")) { res->is_crun = true; } if (_SLIT_EQ(command.str, command.len, "run")) { res->is_run = true; } res->show_asserts = res->show_asserts || res->is_stats || (os__getenv(_S("VTEST_SHOW_ASSERTS"))).len != 0; if (res->os != v__pref__OS__wasm32_emscripten) { if (string_ends_with(res->out_name, _S(".js")) && !res->backend_set_by_flag) { res->backend = v__pref__Backend__js_node; res->output_cross_c = true; } } #if defined(__linux__) || defined(_WIN32) { #if defined(__V_arm64) { res->no_parallel = true; } #endif } #endif if (string_ends_with(res->out_name, _S(".o"))) { res->is_o = true; } if (_SLIT_EQ(command.str, command.len, "run") && res->is_prod && os__is_atty(1) > 0) { v__pref__eprintln_cond(show_output && !res->is_quiet, _S("Note: building an optimized binary takes much longer. It shouldn't be used with `v run`.")); v__pref__eprintln_cond(show_output && !res->is_quiet, _S("Use `v run` without optimization, or build an optimized binary with -prod first, then run it separately.")); } if ((res->os == v__pref__OS__browser || res->os == v__pref__OS__wasi) && res->backend != v__pref__Backend__wasm) { v__pref__eprintln_exit(str_intp(2, _MOV((StrIntpData[]){{_S("OS `"), 0xfe10, {.d_s = v__pref__OS_str(res->os)}}, {_S("` forbidden for backends other than wasm"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } if (res->backend == v__pref__Backend__wasm && !(res->os == v__pref__OS__browser || res->os == v__pref__OS__wasi || res->os == v__pref__OS___auto)) { v__pref__eprintln_exit(_S("Native WebAssembly backend OS must be `browser` or `wasi`")); VUNREACHABLE(); } if (_SLIT_NE(command.str, command.len, "doc") && string_ends_with(res->out_name, _S(".v"))) { v__pref__eprintln_exit(_S("Cannot save output binary in a .v file.")); VUNREACHABLE(); } if (res->fast_math) { if (res->ccompiler_type == v__pref__CompilerType__msvc) { res->cflags = string__plus(res->cflags, _S(" /fp:fast")); } else { res->cflags = string__plus(res->cflags, _S(" -ffast-math")); } } if (res->is_eval_argument) { v__pref__run_code_in_tmp_vfile_and_exit(args, res, _S("-e"), _S("vsh"), res->eval_argument); VUNREACHABLE(); } Array_string command_args = array_slice_ni(args, (int)(command_idx + 1), 2147483647); if (res->is_run || res->is_crun) { string* _t80 = (string*)(array_get_with_check(command_args, 0)); _option_string _t79 = {0}; if (_t80) { *((string*)&_t79.data) = *((string*)_t80); } else { _t79.state = 2; _t79.err = _v_error(_S("array index out of range")); } ; if (_t79.state != 0) { IError err = _t79.err; v__pref__eprintln_exit(_S("v run: no v files listed")); VUNREACHABLE(); ; } res->path = (*(string*)_t79.data); res->run_args = array_slice(command_args, 1, 2147483647); if (fast_string_eq(res->path, _S("-"))) { string contents = os__get_raw_lines_joined(); v__pref__run_code_in_tmp_vfile_and_exit(args, res, _S("run"), _S("v"), contents); VUNREACHABLE(); } v__pref__must_exist(res->path); if (!string_ends_with(res->path, _S(".v")) && os__is_executable(res->path) && os__is_file(res->path) && os__is_file(string__plus(res->path, _S(".v")))) { v__pref__eprintln_cond(show_output && !res->is_quiet, str_intp(3, _MOV((StrIntpData[]){{_S("It looks like you wanted to run \""), 0xfe10, {.d_s = res->path}}, {_S(".v\", so we went ahead and did that since \""), 0xfe10, {.d_s = res->path}}, {_S("\" is an executable."), 0, { .d_c = 0 }}}))); res->path = string__plus(res->path, _S(".v")); } } else if (v__pref__is_source_file(command)) { res->path = command; } if (!res->is_bare && (res->bare_builtin_dir).len != 0) { v__pref__eprintln_cond(show_output && !res->is_quiet, _S("`-bare-builtin-dir` must be used with `-freestanding`")); } if (string_ends_with(command, _S(".vsh")) || ((res->raw_vsh_tmp_prefix).len != 0 && !res->is_run)) { res->is_crun = true; res->path = command; res->run_args = command_args; } else if (_SLIT_EQ(command.str, command.len, "interpret")) { res->backend = v__pref__Backend__interpret; string* _t82 = (string*)(array_get_with_check(command_args, 0)); _option_string _t81 = {0}; if (_t82) { *((string*)&_t81.data) = *((string*)_t82); } else { _t81.state = 2; _t81.err = _v_error(_S("array index out of range")); } ; if (_t81.state != 0) { IError err = _t81.err; v__pref__eprintln_exit(_S("v interpret: no v files listed")); VUNREACHABLE(); ; } res->path = (*(string*)_t81.data); if ((res->path).len != 0) { v__pref__must_exist(res->path); if (!string_ends_with(res->path, _S(".v")) && os__is_executable(res->path) && os__is_file(res->path) && os__is_file(string__plus(res->path, _S(".v")))) { v__pref__eprintln_cond(show_output && !res->is_quiet, str_intp(3, _MOV((StrIntpData[]){{_S("It looks like you wanted to run \""), 0xfe10, {.d_s = res->path}}, {_S(".v\", so we went ahead and did that since \""), 0xfe10, {.d_s = res->path}}, {_S("\" is an executable."), 0, { .d_c = 0 }}}))); res->path = string__plus(res->path, _S(".v")); } } res->run_args = array_slice(command_args, 1, 2147483647); } if (_SLIT_EQ(command.str, command.len, "build-module")) { res->build_mode = v__pref__BuildMode__build_module; string* _t84 = (string*)(array_get_with_check(command_args, 0)); _option_string _t83 = {0}; if (_t84) { *((string*)&_t83.data) = *((string*)_t84); } else { _t83.state = 2; _t83.err = _v_error(_S("array index out of range")); } ; if (_t83.state != 0) { IError err = _t83.err; v__pref__eprintln_exit(_S("v build-module: no module specified")); VUNREACHABLE(); ; } res->path = (*(string*)_t83.data); } if (fast_string_eq(res->ccompiler, _S("musl-gcc"))) { res->is_musl = true; res->is_glibc = false; } if (res->is_musl) { array_push((array*)&res->compile_defines, _MOV((string[]){ _S("musl") })); array_push((array*)&res->compile_defines_all, _MOV((string[]){ _S("musl") })); } if (res->is_bare) { array_push((array*)&res->compile_defines, _MOV((string[]){ _S("freestanding") })); array_push((array*)&res->compile_defines_all, _MOV((string[]){ _S("freestanding") })); } if ((Array_string_contains(res->compile_defines_all, _S("callstack")))) { res->is_callstack = true; } if ((Array_string_contains(res->compile_defines_all, _S("trace")))) { res->is_trace = true; } if ((res->coverage_dir).len != 0) { res->is_coverage = true; array_push((array*)&res->build_options, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-coverage "), 0xfe10, {.d_s = res->coverage_dir}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } Map_string_string m = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int _t90 = 0; _t90 < res->build_options.len; ++_t90) { string x = ((string*)res->build_options.data)[_t90]; map_set(&m, &(string[]){x}, &(string[]) { _S("") }); } res->build_options = map_keys(&m); v__pref__Preferences_fill_with_defaults(res); if (res->backend == v__pref__Backend__c) { res->skip_unused = res->build_mode != v__pref__BuildMode__build_module; if (no_skip_unused) { res->skip_unused = false; } } return (multi_return_ref_v__pref__Preferences_string){.arg0=res, .arg1=command}; } VNORETURN void v__pref__eprintln_exit(string s) { eprintln(s); _v_exit(1); VUNREACHABLE(); while(1); } void v__pref__eprintln_cond(bool condition, string s) { if (!condition) { return; } eprintln(s); } void v__pref__Preferences_vrun_elog(v__pref__Preferences* pref, string s) { if (pref->is_verbose) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> v run -, "), 0xfe10, {.d_s = s}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } bool v__pref__Preferences_should_output_to_stdout(v__pref__Preferences* pref) { return string_ends_with(pref->out_name, _S("/-")) || string_ends_with(pref->out_name, _S("\\-")); } VV_LOC void v__pref__must_exist(string path) { if (!os__exists(path)) { v__pref__eprintln_exit(str_intp(2, _MOV((StrIntpData[]){{_S("v expects that `"), 0xfe10, {.d_s = path}}, {_S("` exists, but it does not"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } } inline VV_LOC bool v__pref__is_source_file(string path) { return string_ends_with(path, _S(".v")) || os__exists(path); } _result_v__pref__Backend v__pref__backend_from_string(string s) { _result_v__pref__Backend _t2 = {0}; if (_SLIT_EQ(s.str, s.len, "c")) { _result_ok(&(v__pref__Backend[]) { v__pref__Backend__c }, (_result*)(&_t2), sizeof(v__pref__Backend)); } else if (_SLIT_EQ(s.str, s.len, "interpret")) { _result_ok(&(v__pref__Backend[]) { v__pref__Backend__interpret }, (_result*)(&_t2), sizeof(v__pref__Backend)); } else if (_SLIT_EQ(s.str, s.len, "js") || _SLIT_EQ(s.str, s.len, "js_node")) { _result_ok(&(v__pref__Backend[]) { v__pref__Backend__js_node }, (_result*)(&_t2), sizeof(v__pref__Backend)); } else if (_SLIT_EQ(s.str, s.len, "js_browser")) { _result_ok(&(v__pref__Backend[]) { v__pref__Backend__js_browser }, (_result*)(&_t2), sizeof(v__pref__Backend)); } else if (_SLIT_EQ(s.str, s.len, "js_freestanding")) { _result_ok(&(v__pref__Backend[]) { v__pref__Backend__js_freestanding }, (_result*)(&_t2), sizeof(v__pref__Backend)); } else if (_SLIT_EQ(s.str, s.len, "wasm")) { _result_ok(&(v__pref__Backend[]) { v__pref__Backend__wasm }, (_result*)(&_t2), sizeof(v__pref__Backend)); } else if (_SLIT_EQ(s.str, s.len, "native")) { _result_ok(&(v__pref__Backend[]) { v__pref__Backend__native }, (_result*)(&_t2), sizeof(v__pref__Backend)); } else if (_SLIT_EQ(s.str, s.len, "go")) { _result_ok(&(v__pref__Backend[]) { v__pref__Backend__golang }, (_result*)(&_t2), sizeof(v__pref__Backend)); } else { _t2.is_error = true; _t2.err = _v_error(str_intp(2, _MOV((StrIntpData[]){{_S("Unknown backend type "), 0xfe10, {.d_s = s}}, {_SLIT0, 0, { .d_c = 0 }}}))); }return _t2; } v__pref__CompilerType v__pref__cc_from_string(string s) { if ((s).len == 0) { return v__pref__CompilerType__gcc; } string cc = string_to_lower_ascii(os__file_name(s)); bool _t3 = true; return ((_t3 == (string_contains(cc, _S("tcc")) || string_contains(cc, _S("tinyc"))))? (v__pref__CompilerType__tinyc) : (_t3 == (string_contains(cc, _S("gcc"))))? (v__pref__CompilerType__gcc) : (_t3 == (string_contains(cc, _S("clang"))))? (v__pref__CompilerType__clang) : (_t3 == (string_contains(cc, _S("emcc"))))? (v__pref__CompilerType__emcc) : (_t3 == (string_contains(cc, _S("msvc"))))? (v__pref__CompilerType__msvc) : (_t3 == (string_contains(cc, _S("mingw"))))? (v__pref__CompilerType__mingw) : (_t3 == (string_contains(cc, _S("++"))))? (v__pref__CompilerType__cplusplus) : (v__pref__CompilerType__gcc)); } VV_LOC void v__pref__Preferences_parse_define(v__pref__Preferences* prefs, string define) { if (!(prefs->is_debug && _SLIT_EQ(define.str, define.len, "debug"))) { array_push((array*)&prefs->build_options, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-d "), 0xfe10, {.d_s = define}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if (!string_contains(define, _S("="))) { map_set(&prefs->compile_values, &(string[]){define}, &(string[]) { _S("true") }); array_push((array*)&prefs->compile_defines, _MOV((string[]){ string_clone(define) })); array_push((array*)&prefs->compile_defines_all, _MOV((string[]){ string_clone(define) })); return; } string dname = string_all_before(define, _S("=")); string dvalue = string_all_after_first(define, _S("=")); map_set(&prefs->compile_values, &(string[]){dname}, &(string[]) { dvalue }); array_push((array*)&prefs->compile_defines_all, _MOV((string[]){ string_clone(dname) })); if (_SLIT_EQ(dvalue.str, dvalue.len, "")) { } else { array_push((array*)&prefs->compile_defines, _MOV((string[]){ string_clone(dname) })); } } string v__pref__supported_test_runners_list(void) { Array_string _t2 = {0}; Array_string _t2_orig = _const_v__pref__supported_test_runners; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { string it = ((string*) _t2_orig.data)[_t4]; string _t3 = str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = it}}, {_S("`"), 0, { .d_c = 0 }}})); array_push((array*)&_t2, &_t3); } return Array_string_join( _t2, _S(", ")); } bool v__pref__Preferences_should_trace_fn_name(v__pref__Preferences* pref, string fname) { bool _t2 = false; Array_string _t2_orig = pref->trace_fns; int _t2_len = _t2_orig.len; for (int _t3 = 0; _t3 < _t2_len; ++_t3) { string it = ((string*) _t2_orig.data)[_t3]; if (string_match_glob(fname, it)) { _t2 = true; break; } } return _t2; } bool v__pref__Preferences_should_use_segfault_handler(v__pref__Preferences* pref) { return !((Array_string_contains(pref->compile_defines, _S("no_segfault_handler"))) || (pref->os == v__pref__OS__wasm32 || pref->os == v__pref__OS__wasm32_emscripten)); } Array_string v__pref__Preferences_should_compile_filtered_files(v__pref__Preferences* prefs, string dir, Array_string files_) { Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); Array_string files = array_clone_to_depth(&files_, 0); if (files.len > 0) { qsort(files.data, files.len, files.element_size, (voidptr)compare_16890712418519328305_string); } ; Array_string all_v_files = __new_array_with_default(0, 0, sizeof(string), 0); files_loop: {} for (int _t1 = 0; _t1 < files.len; ++_t1) { string file = ((string*)files.data)[_t1]; if (!string_ends_with(file, _S(".v")) && !string_ends_with(file, _S(".vh"))) { continue; } if (string_ends_with(file, _S("_test.v")) || string_ends_with(string_all_before_last(string_all_before_last(file, _S(".v")), _S(".")), _S("_test"))) { continue; } bool is_d_notd_file = false; if (string_contains(file, _S("_d_"))) { is_d_notd_file = true; if (prefs->compile_defines_all.len == 0) { continue; } bool allowed = false; for (int _t2 = 0; _t2 < prefs->compile_defines.len; ++_t2) { string cdefine = ((string*)prefs->compile_defines.data)[_t2]; Array_string file_postfixes = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){str_intp(2, _MOV((StrIntpData[]){{_S("_d_"), 0xfe10, {.d_s = cdefine}}, {_S(".v"), 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S("_d_"), 0xfe10, {.d_s = cdefine}}, {_S(".c.v"), 0, { .d_c = 0 }}}))})); for (int _t3 = 0; _t3 < file_postfixes.len; ++_t3) { string file_postfix = ((string*)file_postfixes.data)[_t3]; if (string_ends_with(file, file_postfix)) { allowed = true; break; } } if (allowed) { break; } } if (!allowed) { continue; } } if (string_contains(file, _S("_notd_"))) { is_d_notd_file = true; bool allowed = true; for (int _t4 = 0; _t4 < prefs->compile_defines.len; ++_t4) { string cdefine = ((string*)prefs->compile_defines.data)[_t4]; Array_string file_postfixes = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){str_intp(2, _MOV((StrIntpData[]){{_S("_notd_"), 0xfe10, {.d_s = cdefine}}, {_S(".v"), 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S("_notd_"), 0xfe10, {.d_s = cdefine}}, {_S(".c.v"), 0, { .d_c = 0 }}}))})); for (int _t5 = 0; _t5 < file_postfixes.len; ++_t5) { string file_postfix = ((string*)file_postfixes.data)[_t5]; if (string_ends_with(file, file_postfix)) { allowed = false; break; } } if (!allowed) { break; } } if (!allowed) { continue; } } if ((prefs->backend == v__pref__Backend__c || prefs->backend == v__pref__Backend__interpret) && !is_d_notd_file && !v__pref__Preferences_should_compile_c(prefs, file)) { continue; } if (v__pref__Backend_is_js(prefs->backend) && !v__pref__Preferences_should_compile_js(prefs, file)) { continue; } if (prefs->backend == v__pref__Backend__native && !v__pref__Preferences_should_compile_native(prefs, file)) { continue; } if (!v__pref__Backend_is_js(prefs->backend) && !v__pref__Preferences_should_compile_asm(prefs, file)) { continue; } if (string_starts_with(file, _S(".#"))) { continue; } if (!prefs->prealloc && !prefs->output_cross_c && string_ends_with(file, _S("prealloc.c.v"))) { continue; } if (prefs->nofloat && string_ends_with(file, _S("float.c.v"))) { continue; } if (prefs->exclude.len > 0) { string full_file_path = os__join_path(dir, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){file}))); for (int _t6 = 0; _t6 < prefs->exclude.len; ++_t6) { string epattern = ((string*)prefs->exclude.data)[_t6]; if (string_match_glob(full_file_path, epattern)) { goto files_loop__continue; } } } array_push((array*)&all_v_files, _MOV((string[]){ os__join_path(dir, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){file}))) })); files_loop__continue: {} } files_loop__break: {} Array_string defaults = __new_array_with_default(0, 0, sizeof(string), 0); Map_string_Array_string fnames_no_postfixes = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int _t8 = 0; _t8 < all_v_files.len; ++_t8) { string file = ((string*)all_v_files.data)[_t8]; if (string_contains(file, _S("default.c.v"))) { array_push((array*)&defaults, _MOV((string[]){ string_clone(file) })); } else { array_push((array*)&res, _MOV((string[]){ string_clone(file) })); string no_postfix_key = v__pref__fname_without_platform_postfix(file); Array_string candidates = (*(Array_string*)map_get(ADDR(map, fnames_no_postfixes), &(string[]){no_postfix_key}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })); array_push((array*)&candidates, _MOV((string[]){ string_clone(file) })); (*(Array_string*)map_get_and_set((map*)&fnames_no_postfixes, &(string[]){no_postfix_key}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })) = candidates; } } for (int _t12 = 0; _t12 < defaults.len; ++_t12) { string file = ((string*)defaults.data)[_t12]; string no_postfix_key = v__pref__fname_without_platform_postfix(file); if (_IN_MAP(ADDR(string, no_postfix_key), ADDR(map, fnames_no_postfixes))) { if (prefs->is_verbose) { println(str_intp(3, _MOV((StrIntpData[]){{_S(">>> should_compile_filtered_files: skipping _default.c.v file "), 0xfe10, {.d_s = file}}, {_S(" ; the specialized versions are: "), 0xfe10, {.d_s = Array_string_str((*(Array_string*)map_get(ADDR(map, fnames_no_postfixes), &(string[]){no_postfix_key}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })))}}, {_SLIT0, 0, { .d_c = 0 }}}))); } continue; } array_push((array*)&res, _MOV((string[]){ string_clone(file) })); } if (prefs->is_verbose) { println(str_intp(2, _MOV((StrIntpData[]){{_S(">>> should_compile_filtered_files: res: "), 0xfe10, {.d_s = Array_string_str(res)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } return res; } VV_LOC string v__pref__fname_without_platform_postfix(string file) { string res = string_replace_each(file, new_array_from_c_array(32, 32, sizeof(string), _MOV((string[32]){ _S("default.c.v"), _S("_"), _S("nix.c.v"), _S("_"), _S("windows.c.v"), _S("_"), _S("linux.c.v"), _S("_"), _S("darwin.c.v"), _S("_"), _S("macos.c.v"), _S("_"), _S("android.c.v"), _S("_"), _S("termux.c.v"), _S("_"), _S("android_outside_termux.c.v"), _S("_"), _S("freebsd.c.v"), _S("_"), _S("openbsd.c.v"), _S("_"), _S("netbsd.c.v"), _S("_"), _S("dragonfly.c.v"), _S("_"), _S("solaris.c.v"), _S("_"), _S("native.v"), _S("_"), _S("wasm32_emscripten.c.v"), _S("_")}))); return res; } bool v__pref__Preferences_should_compile_native(v__pref__Preferences* prefs, string file) { return v__pref__Preferences_should_compile_c(prefs, file); } bool v__pref__Preferences_should_compile_c(v__pref__Preferences* prefs, string file) { if (string_ends_with(file, _S(".js.v"))) { return false; } if (prefs->is_bare && string_ends_with(file, _S(".freestanding.v"))) { return true; } if (prefs->os == v__pref__OS__all) { return true; } if (prefs->backend != v__pref__Backend__native && string_ends_with(file, _S("_native.v"))) { return false; } if (prefs->building_v && prefs->output_cross_c && string_ends_with(file, _S("_windows.v"))) { return true; } if (prefs->os == v__pref__OS__windows && (string_ends_with(file, _S("_nix.c.v")) || string_ends_with(file, _S("_nix.v")))) { return false; } if (prefs->os != v__pref__OS__windows && (string_ends_with(file, _S("_windows.c.v")) || string_ends_with(file, _S("_windows.v")))) { return false; } if (prefs->os != v__pref__OS__linux && (string_ends_with(file, _S("_linux.c.v")) || string_ends_with(file, _S("_linux.v")))) { return false; } if (prefs->os != v__pref__OS__macos && (string_ends_with(file, _S("_darwin.c.v")) || string_ends_with(file, _S("_darwin.v")))) { return false; } if (prefs->os != v__pref__OS__macos && (string_ends_with(file, _S("_macos.c.v")) || string_ends_with(file, _S("_macos.v")))) { return false; } if (prefs->os != v__pref__OS__ios && (string_ends_with(file, _S("_ios.c.v")) || string_ends_with(file, _S("_ios.v")))) { return false; } if (prefs->os != v__pref__OS__freebsd && string_ends_with(file, _S("_freebsd.c.v"))) { return false; } if (prefs->os != v__pref__OS__openbsd && string_ends_with(file, _S("_openbsd.c.v"))) { return false; } if (prefs->os != v__pref__OS__netbsd && string_ends_with(file, _S("_netbsd.c.v"))) { return false; } if (prefs->os != v__pref__OS__dragonfly && string_ends_with(file, _S("_dragonfly.c.v"))) { return false; } if (prefs->os != v__pref__OS__solaris && string_ends_with(file, _S("_solaris.c.v"))) { return false; } if (prefs->os != v__pref__OS__qnx && string_ends_with(file, _S("_qnx.c.v"))) { return false; } if (prefs->os != v__pref__OS__serenity && string_ends_with(file, _S("_serenity.c.v"))) { return false; } if (prefs->os != v__pref__OS__plan9 && string_ends_with(file, _S("_plan9.c.v"))) { return false; } if (prefs->os != v__pref__OS__vinix && string_ends_with(file, _S("_vinix.c.v"))) { return false; } if (prefs->os == v__pref__OS__android || prefs->os == v__pref__OS__termux) { if (string_ends_with(file, _S("_android.c.v"))) { return true; } if (string_ends_with(file, _S("_android_outside_termux.c.v"))) { return prefs->os == v__pref__OS__android; } if (string_ends_with(file, _S("_termux.c.v"))) { return prefs->os == v__pref__OS__termux; } } else if (string_ends_with(file, _S("_android.c.v")) || string_ends_with(file, _S("_termux.c.v")) || string_ends_with(file, _S("_android_outside_termux.c.v"))) { return false; } if (prefs->os != v__pref__OS__wasm32_emscripten && (string_ends_with(file, _S("_wasm32_emscripten.c.v")) || string_ends_with(file, _S("_wasm32_emscripten.v")))) { return false; } return true; } bool v__pref__Preferences_should_compile_asm(v__pref__Preferences* prefs, string path) { if (string_count(path, _S(".")) != 2 || string_ends_with(path, _S("c.v")) || string_ends_with(path, _S("js.v"))) { return true; } string file = string_all_before_last(path, _S(".v")); _result_v__pref__Arch _t2 = v__pref__arch_from_string(string_all_after_last(file, _S("."))); if (_t2.is_error) { IError err = _t2.err; *(v__pref__Arch*) _t2.data = v__pref__Arch___auto; } v__pref__Arch arch = (*(v__pref__Arch*)_t2.data); if (arch != prefs->arch && prefs->arch != v__pref__Arch___auto && arch != v__pref__Arch___auto) { return false; } _result_v__pref__OS _t4 = v__pref__os_from_string(string_all_before(string_all_after_last(file, _S("_")), _S("."))); if (_t4.is_error) { IError err = _t4.err; *(v__pref__OS*) _t4.data = v__pref__OS___auto; } v__pref__OS file_os = (*(v__pref__OS*)_t4.data); if (file_os != prefs->os && prefs->os != v__pref__OS___auto && file_os != v__pref__OS___auto) { return false; } return true; } bool v__pref__Preferences_should_compile_js(v__pref__Preferences* prefs, string file) { if (!string_ends_with(file, _S(".js.v")) && string_split(file, _S(".")).len > 2) { return false; } return true; } _result_v__pref__Subsystem v__pref__Subsystem__static__from_T_string(string input) { #if 0 { } #endif #if 1 { string val = string_str(input); if (_SLIT_EQ(val.str, val.len, "auto")) { _result_v__pref__Subsystem _t3 = {0}; _result_ok(&(v__pref__Subsystem[]) { v__pref__Subsystem__auto }, (_result*)(&_t3), sizeof(v__pref__Subsystem)); return _t3; } else if (_SLIT_EQ(val.str, val.len, "console")) { _result_v__pref__Subsystem _t4 = {0}; _result_ok(&(v__pref__Subsystem[]) { v__pref__Subsystem__console }, (_result*)(&_t4), sizeof(v__pref__Subsystem)); return _t4; } else if (_SLIT_EQ(val.str, val.len, "windows")) { _result_v__pref__Subsystem _t5 = {0}; _result_ok(&(v__pref__Subsystem[]) { v__pref__Subsystem__windows }, (_result*)(&_t5), sizeof(v__pref__Subsystem)); return _t5; } else { } } #endif return (_result_v__pref__Subsystem){ .is_error=true, .err=_v_error(_S("invalid value")), .data={E_STRUCT} }; } string sync__Channel_auto_str(sync__Channel* ch, string __v_typename) { return str_intp(4, _MOV((StrIntpData[]){{_S("chan "), 0xfe10, {.d_s = __v_typename}}, {_S("{cap: "), 0xfe06, {.d_u32 = ch->cap}}, {_S(", closed: "), 0xfe04, {.d_u16 = ch->closed}}, {_S("}"), 0, { .d_c = 0 }}})); } void sync__Channel_close(sync__Channel* ch) { u16 open_val = ((u16)(0U)); if (!atomic_compare_exchange_strong_u16(&ch->closed, &open_val, 1U)) { return; } voidptr nulladr = ((void*)0); for (;;) { if (!(!atomic_compare_exchange_weak_ptr(((voidptr)(&ch->adr_written)), ((voidptr)(&nulladr)), ((isize)(-1))))) break; nulladr = ((void*)0); } sync__Semaphore_post(&ch->readsem_im); sync__Semaphore_post(&ch->readsem); sync__SpinLock_lock(ch->read_sub_mtx); if (ch->read_subscriber != ((void*)0)) { sync__Semaphore_post(ch->read_subscriber->sem); } sync__SpinLock_unlock(ch->read_sub_mtx); sync__SpinLock_lock(ch->write_sub_mtx); if (ch->write_subscriber != ((void*)0)) { sync__Semaphore_post(ch->write_subscriber->sem); } sync__SpinLock_unlock(ch->write_sub_mtx); sync__Semaphore_post(&ch->writesem); if (ch->cap == 0U) { atomic_store_ptr(((voidptr*)(&ch->read_adr)), ((void*)0)); } sync__Semaphore_post(&ch->writesem_im); } inline int sync__Channel_len(sync__Channel* ch) { return ((int)(atomic_load_u32(&ch->read_avail))); } inline bool sync__Channel_closed(sync__Channel* ch) { return atomic_load_u16(&ch->closed) != 0U; } inline void sync__Channel_push(sync__Channel* ch, voidptr src) { if (sync__Channel_try_push_priv(ch, src, false) == ChanState__closed) { _v_panic(_S("push on closed channel")); VUNREACHABLE(); } } inline ChanState sync__Channel_try_push(sync__Channel* ch, voidptr src) { return sync__Channel_try_push_priv(ch, src, true); } VV_LOC ChanState sync__Channel_try_push_priv(sync__Channel* ch, voidptr src, bool no_block) { if (atomic_load_u16(&ch->closed) != 0U) { return ChanState__closed; } multi_return_int_int mr_4858 = (no_block ? ((multi_return_int_int){.arg0=1,.arg1=1}) : ((multi_return_int_int){.arg0=_const_sync__spinloops,.arg1=_const_sync__spinloops_sem})); int spinloops_sem_ = mr_4858.arg0; int spinloops_ = mr_4858.arg1; bool have_swapped = false; for (;;) { bool got_sem = false; voidptr wradr = atomic_load_ptr(((voidptr*)(&ch->write_adr))); for (;;) { if (!(wradr != NULL)) break; if (atomic_compare_exchange_strong_ptr(((voidptr)(&ch->write_adr)), ((voidptr)(&wradr)), ((isize)(0)))) { memcpy(wradr, src, ch->objsize); voidptr nulladr = ((void*)0); for (;;) { if (!(!atomic_compare_exchange_weak_ptr(((voidptr)(&ch->adr_written)), ((voidptr)(&nulladr)), ((isize)(wradr))))) break; nulladr = ((void*)0); } sync__Semaphore_post(&ch->readsem_im); return ChanState__success; } } if (no_block && ch->cap == 0U) { return ChanState__not_ready; } for (int _t4 = 0; _t4 < spinloops_sem_; ++_t4) { if (got_sem) { break; } got_sem = sync__Semaphore_try_wait(&ch->writesem); } if (!got_sem) { if (no_block) { return ChanState__not_ready; } sync__Semaphore_wait(&ch->writesem); } if (atomic_load_u16(&ch->closed) != 0U) { sync__Semaphore_post(&ch->writesem); return ChanState__closed; } if (ch->cap == 0U) { bool read_in_progress = false; atomic_store_ptr(((voidptr*)(&ch->read_adr)), src); wradr = atomic_load_ptr(((voidptr*)(&ch->write_adr))); if (wradr != NULL) { voidptr src2 = src; if (atomic_compare_exchange_strong_ptr(((voidptr)(&ch->read_adr)), ((voidptr)(&src2)), ((isize)(0)))) { sync__Semaphore_post(&ch->writesem); continue; } else { read_in_progress = true; } } if (!read_in_progress) { sync__SpinLock_lock(ch->read_sub_mtx); if (ch->read_subscriber != ((void*)0)) { sync__Semaphore_post(ch->read_subscriber->sem); } sync__SpinLock_unlock(ch->read_sub_mtx); } voidptr src2 = src; for (u32 sp = ((u32)(0U)); _us32_lt(sp,spinloops_) || read_in_progress; sp++) { if (atomic_compare_exchange_strong_ptr(((voidptr)(&ch->adr_read)), ((voidptr)(&src2)), ((isize)(0)))) { have_swapped = true; read_in_progress = true; break; } src2 = src; } bool got_im_sem = false; for (u32 sp = ((u32)(0U)); _us32_lt(sp,spinloops_sem_) || read_in_progress; sp++) { got_im_sem = sync__Semaphore_try_wait(&ch->writesem_im); if (got_im_sem) { break; } } for (;;) { if (got_im_sem) { got_im_sem = false; } else { sync__Semaphore_wait(&ch->writesem_im); } if (atomic_load_u16(&ch->closed) != 0U) { if (have_swapped || atomic_compare_exchange_strong_ptr(((voidptr)(&ch->adr_read)), ((voidptr)(&src2)), ((isize)(0)))) { sync__Semaphore_post(&ch->writesem); return ChanState__success; } else { return ChanState__closed; } } if (have_swapped || atomic_compare_exchange_strong_ptr(((voidptr)(&ch->adr_read)), ((voidptr)(&src2)), ((isize)(0)))) { sync__Semaphore_post(&ch->writesem); break; } else { sync__Semaphore_post(&ch->writesem_im); if (src2 == ((voidptr)(-1))) { sync__Semaphore_post(&ch->readsem); return ChanState__closed; } src2 = src; } } return ChanState__success; } else { bool space_in_queue = false; u32 wr_free = atomic_load_u32(&ch->write_free); for (;;) { if (!(wr_free > 0U)) break; space_in_queue = atomic_compare_exchange_weak_u32(&ch->write_free, &wr_free, (u32)(wr_free - 1U)); if (space_in_queue) { break; } } if (space_in_queue) { u32 wr_idx = atomic_load_u32(&ch->buf_elem_write_idx); for (;;) { u32 new_wr_idx = (u32)(wr_idx + 1U); for (;;) { if (!(new_wr_idx >= ch->cap)) break; new_wr_idx -= ch->cap; } if (atomic_compare_exchange_strong_u32(&ch->buf_elem_write_idx, &wr_idx, new_wr_idx)) { break; } } u8* wr_ptr = ch->ringbuf; u8* status_adr = ch->statusbuf; { // Unsafe block wr_ptr += ((u32)(wr_idx * ch->objsize)); status_adr += (u32)(wr_idx * sizeof(u16)); } u16 expected_status = ((u16)(sync__BufferElemStat__unused)); for (;;) { if (!(!atomic_compare_exchange_weak_u16(status_adr, &expected_status, ((u16)(sync__BufferElemStat__writing))))) break; expected_status = ((u16)(sync__BufferElemStat__unused)); } memcpy(wr_ptr, src, ch->objsize); atomic_store_u16(((u16*)(status_adr)), ((u16)(sync__BufferElemStat__written))); atomic_fetch_add_u32(((voidptr)(&ch->read_avail)), 1U); sync__Semaphore_post(&ch->readsem); sync__SpinLock_lock(ch->read_sub_mtx); if (ch->read_subscriber != ((void*)0)) { sync__Semaphore_post(ch->read_subscriber->sem); } sync__SpinLock_unlock(ch->read_sub_mtx); return ChanState__success; } else { if (no_block) { return ChanState__not_ready; } sync__Semaphore_post(&ch->writesem); } } } _v_panic(_S("unknown `try_push_priv` state")); VUNREACHABLE(); return 0; } inline bool sync__Channel_pop(sync__Channel* ch, voidptr dest) { return sync__Channel_try_pop_priv(ch, dest, false) == ChanState__success; } inline ChanState sync__Channel_try_pop(sync__Channel* ch, voidptr dest) { return sync__Channel_try_pop_priv(ch, dest, true); } VV_LOC ChanState sync__Channel_try_pop_priv(sync__Channel* ch, voidptr dest, bool no_block) { multi_return_int_int mr_9573 = (no_block ? ((multi_return_int_int){.arg0=1,.arg1=1}) : ((multi_return_int_int){.arg0=_const_sync__spinloops,.arg1=_const_sync__spinloops_sem})); int spinloops_sem_ = mr_9573.arg0; int spinloops_ = mr_9573.arg1; bool have_swapped = false; bool write_in_progress = false; for (;;) { bool got_sem = false; if (ch->cap == 0U) { voidptr rdadr = atomic_load_ptr(((voidptr*)(&ch->read_adr))); for (;;) { if (!(rdadr != NULL)) break; if (atomic_compare_exchange_strong_ptr(((voidptr)(&ch->read_adr)), ((voidptr)(&rdadr)), ((isize)(0)))) { memcpy(dest, rdadr, ch->objsize); voidptr nulladr = ((void*)0); for (;;) { if (!(!atomic_compare_exchange_weak_ptr(((voidptr)(&ch->adr_read)), ((voidptr)(&nulladr)), ((isize)(rdadr))))) break; nulladr = ((void*)0); } sync__Semaphore_post(&ch->writesem_im); return ChanState__success; } } if (no_block) { if (atomic_load_u16(&ch->closed) == 0U) { return ChanState__not_ready; } else { return ChanState__closed; } } } for (int _t4 = 0; _t4 < spinloops_sem_; ++_t4) { if (got_sem) { break; } got_sem = sync__Semaphore_try_wait(&ch->readsem); } if (!got_sem) { if (no_block) { if (atomic_load_u16(&ch->closed) == 0U) { return ChanState__not_ready; } else { return ChanState__closed; } } sync__Semaphore_wait(&ch->readsem); } if (ch->cap > 0U) { bool obj_in_queue = false; u32 rd_avail = atomic_load_u32(&ch->read_avail); for (;;) { if (!(rd_avail > 0U)) break; obj_in_queue = atomic_compare_exchange_weak_u32(&ch->read_avail, &rd_avail, (u32)(rd_avail - 1U)); if (obj_in_queue) { break; } } if (obj_in_queue) { u32 rd_idx = atomic_load_u32(&ch->buf_elem_read_idx); for (;;) { u32 new_rd_idx = (u32)(rd_idx + 1U); for (;;) { if (!(new_rd_idx >= ch->cap)) break; new_rd_idx -= ch->cap; } if (atomic_compare_exchange_weak_u32(&ch->buf_elem_read_idx, &rd_idx, new_rd_idx)) { break; } } u8* rd_ptr = ch->ringbuf; u8* status_adr = ch->statusbuf; { // Unsafe block rd_ptr += (u32)(rd_idx * ch->objsize); status_adr += (u32)(rd_idx * sizeof(u16)); } u16 expected_status = ((u16)(sync__BufferElemStat__written)); for (;;) { if (!(!atomic_compare_exchange_weak_u16(status_adr, &expected_status, ((u16)(sync__BufferElemStat__reading))))) break; expected_status = ((u16)(sync__BufferElemStat__written)); } memcpy(dest, rd_ptr, ch->objsize); atomic_store_u16(((u16*)(status_adr)), ((u16)(sync__BufferElemStat__unused))); atomic_fetch_add_u32(((voidptr)(&ch->write_free)), 1U); sync__Semaphore_post(&ch->writesem); sync__SpinLock_lock(ch->write_sub_mtx); if (ch->write_subscriber != ((void*)0)) { sync__Semaphore_post(ch->write_subscriber->sem); } sync__SpinLock_unlock(ch->write_sub_mtx); return ChanState__success; } } atomic_store_ptr(((voidptr*)(&ch->write_adr)), dest); if (ch->cap == 0U) { voidptr rdadr = atomic_load_ptr(((voidptr*)(&ch->read_adr))); if (rdadr != NULL) { voidptr dest2 = dest; if (atomic_compare_exchange_strong_ptr(((voidptr)(&ch->write_adr)), ((voidptr)(&dest2)), ((isize)(0)))) { sync__Semaphore_post(&ch->readsem); continue; } else { write_in_progress = true; } } } if (ch->cap == 0U && !write_in_progress) { sync__SpinLock_lock(ch->write_sub_mtx); if (ch->write_subscriber != ((void*)0)) { sync__Semaphore_post(ch->write_subscriber->sem); } sync__SpinLock_unlock(ch->write_sub_mtx); } voidptr dest2 = dest; for (u32 sp = ((u32)(0U)); _us32_lt(sp,spinloops_) || write_in_progress; sp++) { if (atomic_compare_exchange_strong_ptr(((voidptr)(&ch->adr_written)), ((voidptr)(&dest2)), ((isize)(0)))) { have_swapped = true; break; } else if (dest2 == ((voidptr)(-1))) { sync__Semaphore_post(&ch->readsem); return ChanState__closed; } dest2 = dest; } bool got_im_sem = false; for (u32 sp = ((u32)(0U)); _us32_lt(sp,spinloops_sem_) || write_in_progress; sp++) { got_im_sem = sync__Semaphore_try_wait(&ch->readsem_im); if (got_im_sem) { break; } } for (;;) { if (got_im_sem) { got_im_sem = false; } else { sync__Semaphore_wait(&ch->readsem_im); } if (have_swapped || atomic_compare_exchange_strong_ptr(((voidptr)(&ch->adr_written)), ((voidptr)(&dest2)), ((isize)(0)))) { sync__Semaphore_post(&ch->readsem); break; } else { sync__Semaphore_post(&ch->readsem_im); if (dest2 == ((voidptr)(-1))) { sync__Semaphore_post(&ch->readsem); return ChanState__closed; } dest2 = dest; } } break; } return ChanState__success; } string sync__Mutex_str(sync__Mutex* m) { return str_intp(2, _MOV((StrIntpData[]){{_S("Mutex("), 0xfe11, {.d_p = (void*)(((voidptr)(m)))}}, {_S(")"), 0, { .d_c = 0 }}})); } string sync__RwMutex_str(sync__RwMutex* m) { return str_intp(2, _MOV((StrIntpData[]){{_S("RwMutex("), 0xfe11, {.d_p = (void*)(((voidptr)(m)))}}, {_S(")"), 0, { .d_c = 0 }}})); } VNORETURN VV_LOC void sync__cpanic(int res) { _v_panic(tos_clone(((u8*)(strerror(res))))); VUNREACHABLE(); while(1); } VNORETURN VV_LOC void sync__cpanic_errno(void) { sync__cpanic(errno); VUNREACHABLE(); while(1); } inline void sync__SpinLock_lock(sync__SpinLock* s) { u8 expected = ((u8)(0)); int spin_count = 0; int max_spins = 100; int base_delay = 100; int max_delay = 10000; for (;;) { if (atomic_compare_exchange_weak_byte(&s->locked, &expected, 1)) { #if defined(CUSTOM_DEFINE_valgrind) { ANNOTATE_RWLOCK_ACQUIRED(&s->locked, 1); } #endif atomic_thread_fence(memory_order_acquire); return; } spin_count++; if (spin_count > max_spins) { int exponent = int_min((int)(spin_count / max_spins), 10); int delay = int_min((int)(base_delay * ((1 << exponent))), max_delay); time__sleep(delay * _const_time__nanosecond); } else { cpu_relax(); } expected = 0; } } inline void sync__SpinLock_unlock(sync__SpinLock* s) { #if defined(CUSTOM_DEFINE_valgrind) { ANNOTATE_RWLOCK_RELEASED(&s->locked, 1); } #endif atomic_thread_fence(memory_order_release); atomic_store_byte(&s->locked, 0); } void sync__WaitGroup_init(sync__WaitGroup* wg) { sync__Semaphore_init(&wg->sem, 0U); } void sync__WaitGroup_add(sync__WaitGroup* wg, int delta) { int old_nrjobs = ((int)(atomic_fetch_add_u32(((voidptr)(&wg->task_count)), ((u32)(delta))))); int new_nrjobs = (int)(old_nrjobs + delta); u32 num_waiters = atomic_load_u32(&wg->wait_count); if (new_nrjobs < 0) { _v_panic(_S("Negative number of jobs in waitgroup")); VUNREACHABLE(); } if (new_nrjobs == 0 && num_waiters > 0U) { for (;;) { if (!(!atomic_compare_exchange_weak_u32(&wg->wait_count, &num_waiters, 0U))) break; if (num_waiters == 0U) { return; } } for (;;) { if (!((num_waiters > 0U))) break; sync__Semaphore_post(&wg->sem); num_waiters--; } } } void sync__WaitGroup_done(sync__WaitGroup* wg) { sync__WaitGroup_add(wg, -1); } void sync__WaitGroup_wait(sync__WaitGroup* wg) { int nrjobs = ((int)(atomic_load_u32(&wg->task_count))); if (nrjobs == 0) { return; } atomic_fetch_add_u32(((voidptr)(&wg->wait_count)), 1U); sync__Semaphore_wait(&wg->sem); } #if !defined(__ANDROID__) #endif inline void sync__Mutex_init(sync__Mutex* m) { pthread_mutex_init(&m->mutex, NULL); } void sync__RwMutex_init(sync__RwMutex* m) { sync__RwMutexAttr a = ((sync__RwMutexAttr){E_STRUCT}); pthread_rwlockattr_init(&a.attr); pthread_rwlockattr_setkind_np(&a.attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); pthread_rwlock_init(&m->mutex, &a.attr); pthread_rwlockattr_destroy(&a.attr); } inline void sync__Mutex_lock(sync__Mutex* m) { pthread_mutex_lock(&m->mutex); } inline void sync__Mutex_unlock(sync__Mutex* m) { pthread_mutex_unlock(&m->mutex); } inline void sync__RwMutex_rlock(sync__RwMutex* m) { pthread_rwlock_rdlock(&m->mutex); } inline void sync__RwMutex_lock(sync__RwMutex* m) { pthread_rwlock_wrlock(&m->mutex); } inline void sync__RwMutex_runlock(sync__RwMutex* m) { pthread_rwlock_unlock(&m->mutex); } inline void sync__RwMutex_unlock(sync__RwMutex* m) { pthread_rwlock_unlock(&m->mutex); } inline void sync__Semaphore_init(sync__Semaphore* sem, u32 n) { sem_init(&sem->sem, 0, n); } inline void sync__Semaphore_post(sync__Semaphore* sem) { sem_post(&sem->sem); } void sync__Semaphore_wait(sync__Semaphore* sem) { for (;;) { if (sem_wait(&sem->sem) == 0) { return; } int e = errno; if (e == (EINTR)) { continue; } else { sync__cpanic_errno(); VUNREACHABLE(); } } } bool sync__Semaphore_try_wait(sync__Semaphore* sem) { #if !defined(_VDEBUG) { return sem_trywait(&sem->sem) == 0; } #else { if (sem_trywait(&sem->sem) != 0) { int e = errno; if (e == (EAGAIN)) { return false; } else { sync__cpanic_errno(); VUNREACHABLE(); } } return true; } #endif return 0; } _result_string v__util__resolve_d_value(Map_string_string compile_values, string str) { _option_int _t1 = string_index(str, _const_v__util__d_sig); if (_t1.state != 0) { IError err = _t1.err; return (_result_string){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("no \""), 0xfe10, {.d_s = _const_v__util__d_sig}}, {_S("...\')\" could be found in \""), 0xfe10, {.d_s = str}}, {_S("\""), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } int start = (*(int*)_t1.data); int i = 0; u8 ch = ((u8)('.')); Array_u8 bd_ident = __new_array_with_default(0, 20, sizeof(u8), 0); int blevel = 1; for (i = (int)(start + _const_v__util__d_sig.len); i < str.len && ch != '\''; i++) { ch = string_at(str, i); if (ch == ')') { blevel--; } else if (ch == '(') { blevel++; } if (u8_is_letter(ch) || u8_is_digit(ch) || ch == '_') { array_push((array*)&bd_ident, _MOV((u8[]){ ch })); } else { if (!(ch == '\'')) { if (ch == '$') { return (_result_string){ .is_error=true, .err=_v_error(_S("cannot use string interpolation in compile time $d() expression")), .data={E_STRUCT} }; } return (_result_string){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("invalid `$d` identifier in \""), 0xfe10, {.d_s = str}}, {_S("\", invalid character `"), 0xfe10, {.d_s = rune_str(((rune)(ch)))}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } } string d_ident = string_trim_space(Array_u8_bytestr(bd_ident)); if ((d_ident).len == 0) { return (_result_string){ .is_error=true, .err=_v_error(_S("first argument of `$d` must be a string identifier")), .data={E_STRUCT} }; } for (; i < str.len; i++) { ch = string_at(str, i); if (ch == (' ') || ch == (',')) { continue; } else if (ch == ('\'')) { i++; } else { } break; } ch = '.'; int dv_start = i; int dv_end = i; for (;;) { if (!(i < str.len)) break; ch = string_at(str, i); dv_end++; i++; if (ch == ('\'')) { break; } else if (ch == ('(')) { blevel++; } else if (ch == (')')) { blevel--; if (blevel <= 0) { break; } } else if (ch == ('$')) { return (_result_string){ .is_error=true, .err=_v_error(_S("cannot use string interpolation in compile time $d() expression")), .data={E_STRUCT} }; } else { } } if ((int)(dv_end - dv_start) == 0) { return (_result_string){ .is_error=true, .err=_v_error(_S("second argument of `$d` must be a pure literal")), .data={E_STRUCT} }; } for (; blevel > 0 && i < str.len; i++) { if (string_at(str, i) == ')') { i++; break; } } string d_default_value = string_trim_space(string_substr_ni(str, dv_start, (int)(dv_end - 1))); string* _t10 = (string*)(map_get_check(ADDR(map, compile_values), &(string[]){d_ident})); _option_string _t9 = {0}; if (_t10) { *((string*)&_t9.data) = *((string*)_t10); } else { _t9.state = 2; _t9.err = _v_error(_S("map key does not exist")); } ; if (_t9.state != 0) { IError err = _t9.err; *(string*) _t9.data = d_default_value; } string d_value = (*(string*)_t9.data); string original_expr_to_be_replaced = string_substr_ni(str, start, i); if (string_at(original_expr_to_be_replaced, (int)(original_expr_to_be_replaced.len - 1)) != ')') { _v_panic(str_intp(2, _MOV((StrIntpData[]){{_S("the last character of `"), 0xfe10, {.d_s = original_expr_to_be_replaced}}, {_S("` should be `)`"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } string rep = string_replace_once(str, original_expr_to_be_replaced, d_value); if (original_expr_to_be_replaced.len > 0 && string_contains(rep, _const_v__util__d_sig)) { return v__util__resolve_d_value(compile_values, rep); } _result_string _t12 = {0}; _result_ok(&(string[]) { rep }, (_result*)(&_t12), sizeof(string)); return _t12; } _result_string v__util__resolve_env_value(string str, bool check_for_presence) { string env_ident = _S("$env('"); _option_int _t1 = string_index(str, env_ident); if (_t1.state != 0) { IError err = _t1.err; return (_result_string){ .is_error=true, .err=_v_error(string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("no \""), 0xfe10, {.d_s = env_ident}}, {_SLIT0, 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S("...\')\" could be found in \""), 0xfe10, {.d_s = str}}, {_S("\"."), 0, { .d_c = 0 }}})))), .data={E_STRUCT} }; } int at = (*(int*)_t1.data); u8 ch = ((u8)('.')); Array_u8 benv_lit = __new_array_with_default(0, 20, sizeof(u8), 0); for (int i = (int)(at + env_ident.len); i < str.len && ch != ')'; i++) { ch = ((u8)(string_at(str, i))); if (u8_is_letter(ch) || u8_is_digit(ch) || ch == '_') { array_push((array*)&benv_lit, _MOV((u8[]){ ch })); } else { if (!(ch == '\'' || ch == ')')) { if (ch == '$') { return (_result_string){ .is_error=true, .err=_v_error(_S("cannot use string interpolation in compile time $env() expression")), .data={E_STRUCT} }; } return (_result_string){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("invalid environment variable name in \""), 0xfe10, {.d_s = str}}, {_S("\", invalid character \""), 0xfe10, {.d_s = rune_str(((rune)(ch)))}}, {_S("\""), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } } string env_lit = Array_u8_bytestr(benv_lit); if ((env_lit).len == 0) { return (_result_string){ .is_error=true, .err=_v_error(_S("supply an env variable name like HOME, PATH or USER")), .data={E_STRUCT} }; } string env_value = _S(""); if (check_for_presence) { string* _t8 = (string*)(map_get_check(ADDR(map, os__environ()), &(string[]){env_lit})); _option_string _t7 = {0}; if (_t8) { *((string*)&_t7.data) = *((string*)_t8); } else { _t7.state = 2; _t7.err = _v_error(_S("map key does not exist")); } ; if (_t7.state != 0) { IError err = _t7.err; return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("the environment variable \""), 0xfe10, {.d_s = env_lit}}, {_S("\" does not exist."), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } env_value = (*(string*)_t7.data); if ((env_value).len == 0) { return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("the environment variable \""), 0xfe10, {.d_s = env_lit}}, {_S("\" is empty."), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } else { env_value = os__getenv(env_lit); } string rep = string_replace_once(str, string__plus(string__plus(string__plus(env_ident, env_lit), _S("'")), _S(")")), env_value); if (string_contains(rep, env_ident)) { return v__util__resolve_env_value(rep, check_for_presence); } _result_string _t12 = {0}; _result_ok(&(string[]) { rep }, (_result*)(&_t12), sizeof(string)); return _t12; } v__util__EManager* v__util__new_error_manager(void) { return ((v__util__EManager*)memdup(&(v__util__EManager){.support_color = term__can_show_color_on_stderr() && term__can_show_color_on_stdout(),}, sizeof(v__util__EManager))); } void v__util__EManager_set_support_color(v__util__EManager* e, bool b) { { // Unsafe block v__util__EManager* me = e; me->support_color = b; } } string v__util__bold(string msg) { if (!_const_v__util__emanager->support_color) { return msg; } return term__bold(msg); } string v__util__color(string kind, string msg) { if (!_const_v__util__emanager->support_color) { return msg; } if (string_contains(kind, _S("error"))) { return term__red(msg); } if (string_contains(kind, _S("notice"))) { return term__yellow(msg); } if (string_contains(kind, _S("details"))) { return term__bright_blue(msg); } return term__magenta(msg); } string v__util__path_styled_for_error_messages(string path) { string rpath = os__real_path(path); rpath = string_replace(rpath, _S("\\"), _S("/")); if (_const_v__util__verror_paths_absolute) { return rpath; } if (string_starts_with(rpath, _const_v__util__normalised_workdir)) { rpath = string_replace_once(rpath, _const_v__util__normalised_workdir, _S("")); } return rpath; } string v__util__formatted_error(string kind, string omsg, string filepath, v__token__Pos pos) { string emsg = string_replace(omsg, _S("main."), _S("")); string path = v__util__path_styled_for_error_messages(filepath); string position = ((filepath).len != 0 ? (str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = path}}, {_S(":"), 0xfe07, {.d_i32 = (int)(pos.line_nr + 1)}}, {_S(":"), 0xfe07, {.d_i32 = int_max(1, (int)(pos.col + 1))}}, {_S(":"), 0, { .d_c = 0 }}}))) : (_S(""))); string scontext = Array_string_join(v__util__source_file_context(kind, filepath, pos), _S("\n")); string final_position = v__util__bold(position); string final_kind = v__util__bold(v__util__color(kind, kind)); string final_msg = emsg; string final_context = (scontext.len > 0 ? (str_intp(2, _MOV((StrIntpData[]){{_S("\n"), 0xfe10, {.d_s = scontext}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (_S(""))); return string_trim_space(str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = final_position}}, {_S(" "), 0xfe10, {.d_s = final_kind}}, {_S(" "), 0xfe10, {.d_s = final_msg}}, {_SLIT0, 0xfe10, {.d_s = final_context}}, {_SLIT0, 0, { .d_c = 0 }}}))); } Array_string v__util__cached_file2sourcelines(string path) { Array_string* _t2 = (Array_string*)(map_get_check(ADDR(map, lines_cache->lines), &(string[]){path})); _option_Array_string _t1 = {0}; if (_t2) { *((Array_string*)&_t1.data) = *((Array_string*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { Array_string res = (*(Array_string*)_t1.data); return res; } _result_string _t4 = v__util__read_file(path); if (_t4.is_error) { IError err = _t4.err; *(string*) _t4.data = _S(""); } string source = (*(string*)_t4.data); Array_string res = v__util__set_source_for_path(path, source); return res; } Array_string v__util__set_source_for_path(string path, string source) { Array_string lines = string_split_into_lines(source); (*(Array_string*)map_get_and_set((map*)&lines_cache->lines, &(string[]){path}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })) = lines; return lines; } Array_string v__util__source_file_context(string kind, string filepath, v__token__Pos pos) { Array_string clines = __new_array_with_default(0, 0, sizeof(string), 0); Array_string source_lines = v__util__cached_file2sourcelines(filepath); if (source_lines.len == 0) { return clines; } int bline = int_max(0, (int)(pos.line_nr - 2)); int aline = int_max(0, int_min((int)(source_lines.len - 1), (int)(pos.line_nr + 2))); string tab_spaces = _S(" "); for (int iline = bline; iline <= aline; iline++) { string* _t3 = (string*)(array_get_with_check(source_lines, iline)); _option_string _t2 = {0}; if (_t3) { *((string*)&_t2.data) = *((string*)_t3); } else { _t2.state = 2; _t2.err = _v_error(_S("array index out of range")); } ; if (_t2.state != 0) { IError err = _t2.err; *(string*) _t2.data = _S(""); } string sline = (*(string*)_t2.data); int start_column = int_max(0, int_min(pos.col, sline.len)); int end_column = int_max(0, int_min((int)(pos.col + int_max(0, pos.len)), sline.len)); string cline = (iline == pos.line_nr ? (string__plus(string__plus(string_substr(sline, 0, start_column), v__util__color(kind, string_substr(sline, start_column, end_column))), string_substr(sline, end_column, 2147483647))) : (sline)); array_push((array*)&clines, _MOV((string[]){ string__plus(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xafe27, {.d_i32 = (int)(iline + 1)}}, {_S(" | "), 0, { .d_c = 0 }}})), string_replace(cline, _S("\t"), tab_spaces)) })); if (iline == pos.line_nr) { strings__Builder pointerline_builder = strings__new_builder(sline.len); for (int i = 0; i < start_column; ) { if (u8_is_space(string_at(sline, i))) { strings__Builder_write_u8(&pointerline_builder, string_at(sline, i)); i++; } else { int char_len = utf8_char_len(string_at(sline, i)); string spaces = string_repeat(_S(" "), utf8_str_visible_length(string_substr_ni(sline, i, (int)(i + char_len)))); strings__Builder_write_string(&pointerline_builder, spaces); i += char_len; } } int underline_len = utf8_str_visible_length(string_substr(sline, start_column, end_column)); string underline = (underline_len > 1 ? (string_repeat(_S("~"), underline_len)) : (_S("^"))); strings__Builder_write_string(&pointerline_builder, v__util__bold(v__util__color(kind, underline))); array_push((array*)&clines, _MOV((string[]){ string__plus(_S(" | "), string_replace(strings__Builder_str(&pointerline_builder), _S("\t"), tab_spaces)) })); } } return clines; } VNORETURN void v__util__verror(string kind, string s) { string final_kind = v__util__bold(v__util__color(kind, kind)); eprintln(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = final_kind}}, {_S(": "), 0xfe10, {.d_s = s}}, {_SLIT0, 0, { .d_c = 0 }}}))); _v_exit(1); VUNREACHABLE(); while(1); } string v__util__vlines_escape_path(string path, string ccompiler) { return v__util__cescaped_path(os__real_path(path)); } void v__util__show_compiler_message(string kind, v__errors__CompilerMessage err) { string ferror = v__util__formatted_error(kind, err.message, err.file_path, err.pos); eprintln(ferror); if (err.details.len > 0) { eprintln(string__plus(v__util__bold(_S("Details: ")), v__util__color(_S("details"), err.details))); } } string v__util__qualify_import(v__pref__Preferences* pref_, string mod, string file_path) { Array_string mod_paths = array_clone_to_depth(&pref_->lookup_path, 0); _PUSH_MANY(&mod_paths, (os__vmodules_paths()), _t1, Array_string); string mod_path = string_replace(mod, _S("."), _const_os__path_separator); for (int _t2 = 0; _t2 < mod_paths.len; ++_t2) { string search_path = ((string*)mod_paths.data)[_t2]; string try_path = os__join_path_single(search_path, mod_path); if (os__is_dir(try_path)) { _result_string _t3; if (_t3 = v__util__mod_path_to_full_name(pref_, mod, try_path), !_t3.is_error) { string m1 = *(string*)_t3.data; ; return m1; } } } _result_string _t5; if (_t5 = v__util__mod_path_to_full_name(pref_, mod, file_path), !_t5.is_error) { string m1 = *(string*)_t5.data; ; return m1; } ; return mod; } string v__util__qualify_module(v__pref__Preferences* pref_, string mod, string file_path) { if (_SLIT_EQ(mod.str, mod.len, "main")) { ; return mod; } string clean_file_path = string_all_before_last(file_path, _const_os__path_separator); if (string__eq(string_replace(clean_file_path, string__plus(os__getwd(), _S("/")), _S("")), mod)) { ; return mod; } _result_string _t3; if (_t3 = v__util__mod_path_to_full_name(pref_, mod, clean_file_path), !_t3.is_error) { string m1 = *(string*)_t3.data; ; return m1; } ; return mod; } VV_LOC _result_string v__util__mod_path_to_full_name(v__pref__Preferences* pref_, string mod, string path) { Array_string vmod_folders = new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("vlib"), _S(".vmodules"), _S("modules")})); Array_string _t1 = {0}; Array_string _t1_orig = pref_->lookup_path; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { string it = ((string*) _t1_orig.data)[_t3]; string _t2 = os__base(it); array_push((array*)&_t1, &_t2); } Array_string bases =_t1; for (int _t4 = 0; _t4 < bases.len; ++_t4) { string base = ((string*)bases.data)[_t4]; if (!(Array_string_contains(vmod_folders, base))) { array_push((array*)&vmod_folders, _MOV((string[]){ string_clone(base) })); } } bool in_vmod_path = false; Array_string parts = string_split(path, _const_os__path_separator); for (int _t6 = 0; _t6 < vmod_folders.len; ++_t6) { string vmod_folder = ((string*)vmod_folders.data)[_t6]; if ((Array_string_contains(parts, vmod_folder))) { in_vmod_path = true; break; } } Array_string path_parts = string_split(path, _const_os__path_separator); string mod_path = string_replace(mod, _S("."), _const_os__path_separator); for (int i = (int)(path_parts.len - 1); i > 0; i--) { string try_path = os__join_path_single(Array_string_join(array_slice(path_parts, 0, i), _const_os__path_separator), mod_path); if (os__is_dir(try_path)) { if (in_vmod_path) { for (int j = i; j >= 0; j--) { string path_part = (*(string*)array_get(path_parts, j)); if ((Array_string_contains(vmod_folders, path_part))) { string mod_full_name = Array_string_join(array_slice(string_split(try_path, _const_os__path_separator), (int)(j + 1), 2147483647), _S(".")); _result_string _t7 = {0}; _result_ok(&(string[]) { mod_full_name }, (_result*)(&_t7), sizeof(string)); return _t7; } } } else { Array_string try_path_parts = string_split(try_path, _const_os__path_separator); int last_v_mod = -1; for (int j = try_path_parts.len; j > 0; j--) { string parent = Array_string_join(array_slice(try_path_parts, 0, j), _const_os__path_separator); _result_Array_string _t8; if (_t8 = os__ls(parent), !_t8.is_error) { Array_string ls = *(Array_string*)_t8.data; if ((Array_string_contains(ls, _S("v.mod"))) && (try_path_parts.len > i && !string__eq((*(string*)array_get(try_path_parts, i)), _S("v")) && !(Array_string_contains(ls, _S("vlib"))))) { last_v_mod = j; } continue; } break; } if (last_v_mod > -1) { string mod_full_name = Array_string_join(array_slice(try_path_parts, last_v_mod, 2147483647), _S(".")); _result_string _t10; /* if prepend */ if (mod_full_name.len < mod.len) { _result_ok(&(string[]) { mod }, (_result*)(&_t10), sizeof(string)); } else { _result_ok(&(string[]) { mod_full_name }, (_result*)(&_t10), sizeof(string)); } return _t10; } } } } if (os__is_abs_path(pref_->path) && os__is_abs_path(path) && os__is_dir(path)) { string rel_mod_path = string_replace(path, string__plus(string_all_before_last(pref_->path, _const_os__path_separator), _S("/")), _S("")); if (!string__eq(rel_mod_path, path)) { string full_mod_name = string_replace(rel_mod_path, _const_os__path_separator, _S(".")); _result_string _t11 = {0}; _result_ok(&(string[]) { full_mod_name }, (_result*)(&_t11), sizeof(string)); return _t11; } } return (_result_string){ .is_error=true, .err=_v_error(_S("module not found")), .data={E_STRUCT} }; } string v__util__smart_quote(string str, bool raw) { int len = str.len; if (len == 0) { return _S(""); } if (len < 256) { bool is_pure = true; for (int i = 0; i < len; i++) { u8 ch = ((u8)(str.str[ i])); if ((ch >= 37 && ch <= 90) || (ch >= 95 && ch <= 126) || (ch == ' ' || ch == '!' || ch == '#' || ch == '[' || ch == ']')) { continue; } is_pure = false; break; } if (is_pure) { return str; } } strings__Builder result = strings__new_builder((int)(len + 10)); int pos = -1; u8 last = ((u8)(0)); u8 current = ((u8)(0)); u8 next = ((u8)(0)); bool skip_next = false; for (;;) { pos++; if (skip_next) { skip_next = false; pos++; } if (pos >= len) { break; } last = current; current = str.str[ pos]; if ((int)(pos + 1) < len) { next = str.str[ (int)(pos + 1)]; } else { next = 0; } if (current == 34) { current = 0; strings__Builder_write_u8(&result, _const_v__util__backslash); strings__Builder_write_u8(&result, _const_v__util__double_quote); continue; } if (current == 92) { if (raw) { strings__Builder_write_string(&result, _const_v__util__double_escape); continue; } if (next == 92) { current = 0; skip_next = true; strings__Builder_write_string(&result, _const_v__util__double_escape); continue; } if (next != 0) { if (raw) { skip_next = true; strings__Builder_write_string(&result, _const_v__util__double_escape); continue; } if ((Array_u8_contains(_const_v__util__invalid_escapes, next))) { current = 0; skip_next = true; strings__Builder_write_u8(&result, next); continue; } skip_next = true; strings__Builder_write_u8(&result, current); strings__Builder_write_u8(&result, next); current = 0; continue; } } if (current == 10) { current = 0; strings__Builder_write_u8(&result, _const_v__util__backslash); strings__Builder_write_u8(&result, 'n'); continue; } if (current == 13 && next == 10) { strings__Builder_write_u8(&result, current); strings__Builder_write_u8(&result, next); current = 0; skip_next = true; continue; } if (!raw) { if (current == '$') { if (last == 92) { strings__Builder_write_u8(&result, last); strings__Builder_write_u8(&result, current); continue; } } } strings__Builder_write_u8(&result, current); } return strings__Builder_str(&result); } VV_LOC _v_Array_fixed_bool_256 v__util__get_non_white_space_table(void) { Array_fixed_bool_256 bytes = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; for (int c = 0; c < 256; ++c) { bytes[v_fixed_index(c, 256)] = !u8_is_space(((u8)(c))); } _v_Array_fixed_bool_256 _t1 = {0}; memcpy(_t1.ret_arr, bytes, sizeof(Array_fixed_bool_256)); return _t1; } VV_LOC _v_Array_fixed_bool_256 v__util__get_name_char_table(void) { Array_fixed_bool_256 res = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; for (int c = 0; c < 256; ++c) { res[v_fixed_index(c, 256)] = u8_is_letter(((u8)(c))) || c == '_'; } _v_Array_fixed_bool_256 _t1 = {0}; memcpy(_t1.ret_arr, res, sizeof(Array_fixed_bool_256)); return _t1; } VV_LOC _v_Array_fixed_bool_256 v__util__get_func_char_table(void) { Array_fixed_bool_256 res = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; for (int c = 0; c < 256; ++c) { res[v_fixed_index(c, 256)] = u8_is_letter(((u8)(c))) || u8_is_digit(((u8)(c))) || c == '_'; } _v_Array_fixed_bool_256 _t1 = {0}; memcpy(_t1.ret_arr, res, sizeof(Array_fixed_bool_256)); return _t1; } inline bool v__util__is_func_char(u8 c) { return _const_v__util__func_char_table[c]; } bool v__util__contains_capital(string s) { for (int _t1 = 0; _t1 < s.len; ++_t1) { u8 c = s.str[_t1]; if (u8_is_capital(c)) { return true; } } return false; } inline bool v__util__is_generic_type_name(string name) { return name.len == 1 && name.str[ 0] != 'C' && (name.str[ 0] >= 'A' && name.str[ 0] <= 'Z'); } string v__util__cescaped_path(string s) { return string_replace(s, _S("\\"), _S("\\\\")); } v__util__Suggestion v__util__new_suggestion(string wanted, Array_string possibilities, v__util__SuggestionParams params) { v__util__Suggestion s = ((v__util__Suggestion){.known = __new_array(0, 0, sizeof(v__util__Possibility)),.wanted = wanted,.swanted = v__util__short_module_name(wanted),.similarity_threshold = params.similarity_threshold,.similarity_fn = (voidptr)params.similarity_fn,}); v__util__Suggestion_add_many(&s, possibilities); v__util__Suggestion_sort(&s); return s; } void v__util__Suggestion_add(v__util__Suggestion* s, string val) { if (string__eq(val, s->wanted) || string__eq(val, s->swanted)) { return; } string sval = v__util__short_module_name(val); if (string__eq(sval, s->wanted) || string__eq(sval, s->swanted)) { return; } f32 similarity = (f32)(((f32)(((int)((f32)(s->similarity_fn(s->swanted, sval) * 1000))))) / 1000); array_push((array*)&s->known, _MOV((v__util__Possibility[]){ ((v__util__Possibility){.value = val,.svalue = sval,.similarity = similarity,}) })); } void v__util__Suggestion_add_many(v__util__Suggestion* s, Array_string many) { for (int _t1 = 0; _t1 < many.len; ++_t1) { string x = ((string*)many.data)[_t1]; v__util__Suggestion_add(s, x); } } void v__util__Suggestion_sort(v__util__Suggestion* s) { if (s->known.len > 0) { qsort(s->known.data, s->known.len, s->known.element_size, (voidptr)compare_6081961377856465380_v__util__Possibility_by_similarity); } ; } string v__util__Suggestion_say(v__util__Suggestion s, string msg) { string res = msg; bool found = false; if (s.known.len > 0) { v__util__Possibility top_possibility = (*(v__util__Possibility*)array_last(s.known)); if (top_possibility.similarity > s.similarity_threshold) { string val = top_possibility.value; if (!string_starts_with(val, _S("[]"))) { res = string__plus(res, str_intp(2, _MOV((StrIntpData[]){{_S(".\nDid you mean `"), 0xfe10, {.d_s = v__util__highlight_suggestion(val)}}, {_S("`?"), 0, { .d_c = 0 }}}))); found = true; } } } if (!found) { if (s.known.len > 0) { Array_string _t1 = {0}; Array_v__util__Possibility _t1_orig = s.known; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__util__Possibility it = ((v__util__Possibility*) _t1_orig.data)[_t3]; string _t2 = str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__util__highlight_suggestion(it.svalue)}}, {_S("`"), 0, { .d_c = 0 }}})); array_push((array*)&_t1, &_t2); } Array_string values =_t1; if (values.len > 0) { qsort(values.data, values.len, values.element_size, (voidptr)compare_6081961377856465380_string); } ; if (values.len == 1) { res = string__plus(res, str_intp(2, _MOV((StrIntpData[]){{_S(".\n1 possibility: "), 0xfe10, {.d_s = (*(string*)array_get(values, 0))}}, {_S("."), 0, { .d_c = 0 }}}))); } else if (values.len < 25) { res = string__plus(res, string__plus(string__plus(str_intp(2, _MOV((StrIntpData[]){{_S(".\n"), 0xfe07, {.d_i32 = values.len}}, {_S(" possibilities: "), 0, { .d_c = 0 }}})), Array_string_join(values, _S(", "))), _S("."))); } } } return res; } string v__util__short_module_name(string name) { if (!string_contains(name, _S("."))) { return name; } Array_string vals = string_split(name, _S(".")); if (vals.len < 2) { return name; } string mname = (*(string*)array_get(vals, (int)(vals.len - 2))); string symname = (*(string*)array_last(vals)); return str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mname}}, {_S("."), 0xfe10, {.d_s = symname}}, {_SLIT0, 0, { .d_c = 0 }}})); } string v__util__highlight_suggestion(string message) { return term__ecolorize((voidptr)term__bright_blue, message); } v__util__Surrounder v__util__new_surrounder(int expected_length) { return ((v__util__Surrounder){.befores = __new_array_with_default(0, expected_length, sizeof(string), 0),.afters = __new_array_with_default(0, expected_length, sizeof(string), 0),}); } void v__util__Surrounder_add(v__util__Surrounder* s, string before, string after) { array_push((array*)&s->befores, _MOV((string[]){ string_clone(before) })); array_push((array*)&s->afters, _MOV((string[]){ string_clone(after) })); } void v__util__Surrounder_builder_write_befores(v__util__Surrounder* s, strings__Builder* sb) { int len = s->befores.len; if (len > 0) { for (int i = 0; i < len; i++) { string x = (*(string*)array_get(s->befores, i)); if (x.len > 0) { strings__Builder_writeln(sb, x); } } } } void v__util__Surrounder_builder_write_afters(v__util__Surrounder* s, strings__Builder* sb) { int len = s->afters.len; if (len > 0) { for (int i = (int)(len - 1); i >= 0; i--) { string x = (*(string*)array_get(s->afters, i)); if (x.len > 0) { strings__Builder_writeln(sb, x); } } } } void v__util__Surrounder_free(v__util__Surrounder* s) { { // Unsafe block Array_string_free(&s->befores); Array_string_free(&s->afters); } } v__util__Timers* v__util__new_timers(v__util__TimerParams params) { #if defined(CUSTOM_DEFINE_trace_timers_creation) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S(">>>> new_timers, should_print: "), 0xfe10, {.d_s = params.should_print ? _S("true") : _S("false")}}, {_S(" | label: "), 0xfe10, {.d_s = params.label}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif return ((v__util__Timers*)memdup(&(v__util__Timers){.label = params.label,.swatches = (__shared__Map_string_time__StopWatch*)__dup_shared_map(&(__shared__Map_string_time__StopWatch){.mtx = {0}, .val = new_map(sizeof(string), sizeof(time__StopWatch), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) }, sizeof(__shared__Map_string_time__StopWatch)) ,.should_print = params.should_print,.already_shown = __new_array_with_default(0, 100, sizeof(string), 0),}, sizeof(v__util__Timers))); } v__util__Timers* v__util__get_timers(void) { return g_timers; } void v__util__timing_start(string label) { v__util__Timers* t = v__util__get_timers(); v__util__Timers_start(t, label); } void v__util__timing_measure(string label) { v__util__Timers_show(g_timers, label); } void v__util__timing_measure_cumulative(string label) { v__util__Timers_measure_cumulative(g_timers, label); } void v__util__timing_set_should_print(bool should_print) { g_timers->should_print = should_print; } void v__util__Timers_start(v__util__Timers* t, string name) { _option_time__StopWatch _t1 = v__util__Timers_tsafe_get_sw(t, name); if (_t1.state != 0) { IError err = _t1.err; *(time__StopWatch*) _t1.data = time__new_stopwatch(((time__StopWatchOptions){.auto_start = true,})); } time__StopWatch sw = (*(time__StopWatch*)_t1.data); time__StopWatch_start(&sw); v__util__Timers_tsafe_set_sw(t, name, sw); } i64 v__util__Timers_measure(v__util__Timers* t, string name) { _option_time__StopWatch _t1 = v__util__Timers_tsafe_get_sw(t, name); if (_t1.state != 0) { IError err = _t1.err; Array_string timer_keys = v__util__Timers_tsafe_get_keys(t); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> Timer `"), 0xfe10, {.d_s = name}}, {_S("` was NOT started."), 0, { .d_c = 0 }}}))); eprintln(_S("> Available timers:")); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> "), 0xfe10, {.d_s = Array_string_str(timer_keys)}}, {_SLIT0, 0, { .d_c = 0 }}}))); *(time__StopWatch*) _t1.data = time__new_stopwatch(((time__StopWatchOptions){.auto_start = true,})); } time__StopWatch sw = (*(time__StopWatch*)_t1.data); i64 ms = time__Duration_microseconds(time__StopWatch_elapsed(sw)); time__StopWatch_pause(&sw); v__util__Timers_tsafe_set_sw(t, name, sw); return ms; } i64 v__util__Timers_measure_cumulative(v__util__Timers* t, string name) { i64 ms = v__util__Timers_measure(t, name); _option_time__StopWatch _t1 = v__util__Timers_tsafe_get_sw(t, name); if (_t1.state != 0) { IError err = _t1.err; return ms; } time__StopWatch sw = (*(time__StopWatch*)_t1.data); time__StopWatch_pause(&sw); v__util__Timers_tsafe_set_sw(t, name, sw); return ms; } void v__util__Timers_measure_pause(v__util__Timers* t, string name) { _option_time__StopWatch _t1 = v__util__Timers_tsafe_get_sw(t, name); if (_t1.state != 0) { IError err = _t1.err; return; } time__StopWatch sw = (*(time__StopWatch*)_t1.data); time__StopWatch_pause(&sw); v__util__Timers_tsafe_set_sw(t, name, sw); } void v__util__Timers_measure_resume(v__util__Timers* t, string name) { _option_time__StopWatch _t1 = v__util__Timers_tsafe_get_sw(t, name); if (_t1.state != 0) { IError err = _t1.err; return; } time__StopWatch sw = (*(time__StopWatch*)_t1.data); time__StopWatch_start(&sw); v__util__Timers_tsafe_set_sw(t, name, sw); } string v__util__Timers_message(v__util__Timers* t, string name) { f64 ms = (f64)(((f64)(v__util__Timers_measure(t, name))) / ((f64)(1000.0))); string value = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0x10060d, {.d_f64 = ms}}, {_SLIT0, 0, { .d_c = 0 }}}))); string formatted_message = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = value}}, {_S(" ms "), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); return formatted_message; } void v__util__Timers_show(v__util__Timers* t, string label) { if (v_memory_panic) { return; } if (t->should_print) { string formatted_message = v__util__Timers_message(t, label); println(formatted_message); } array_push((array*)&t->already_shown, _MOV((string[]){ string_clone(label) })); } void v__util__Timers_show_if_exists(v__util__Timers* t, string label) { _option_time__StopWatch _t1 = v__util__Timers_tsafe_get_sw(t, label); if (_t1.state != 0) { IError err = _t1.err; return; } ; v__util__Timers_show(t, label); array_push((array*)&t->already_shown, _MOV((string[]){ string_clone(label) })); } void v__util__Timers_show_remaining(v__util__Timers* t) { Array_string keys = v__util__Timers_tsafe_get_keys(t); for (int _t1 = 0; _t1 < keys.len; ++_t1) { string k = ((string*)keys.data)[_t1]; if ((Array_string_contains(t->already_shown, k))) { continue; } v__util__Timers_show(t, k); } } VV_LOC Array_string v__util__Timers_tsafe_get_keys(v__util__Timers* t) { Array_string _t1; sync__RwMutex_rlock(&t->swatches->mtx); /*lock*/ { _t1 = map_keys(&t->swatches->val); ; } sync__RwMutex_runlock(&t->swatches->mtx); Array_string keys = _t1; return keys; } VV_LOC void v__util__Timers_tsafe_set_sw(v__util__Timers* t, string name, time__StopWatch sw) { sync__RwMutex_lock(&t->swatches->mtx); /*lock*/ { (*(time__StopWatch*)map_get_and_set((map*)&t->swatches->val, &(string[]){name}, &(time__StopWatch[]){ (time__StopWatch){.elapsed = 0,.start = 0,.end = 0,} })) = sw; } sync__RwMutex_unlock(&t->swatches->mtx);; } VV_LOC _option_time__StopWatch v__util__Timers_tsafe_get_sw(v__util__Timers* t, string name) { sync__RwMutex_rlock(&t->swatches->mtx); /*lock*/ { if (!_IN_MAP(ADDR(string, name), ADDR(map, t->swatches->val))) { _option_time__StopWatch _t1 = (_option_time__StopWatch){ .state=2, .err=_const_none__, .data={E_STRUCT} }; sync__RwMutex_runlock(&t->swatches->mtx);return _t1; } _option_time__StopWatch _t2; _option_ok(&(time__StopWatch[]) { (*(time__StopWatch*)map_get(ADDR(map, t->swatches->val), &(string[]){name}, &(time__StopWatch[]){ (time__StopWatch){.elapsed = 0,.start = 0,.end = 0,} })) }, (_option*)(&_t2), sizeof(time__StopWatch)); sync__RwMutex_runlock(&t->swatches->mtx);return _t2; } sync__RwMutex_runlock(&t->swatches->mtx);; return (_option_time__StopWatch){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } string v__util__skip_bom(string file_content) { string raw_text = file_content; if (raw_text.len >= 3) { { // Unsafe block u8* c_text = raw_text.str; if (c_text[0] == 0xEF && c_text[1] == 0xBB && c_text[2] == 0xBF) { int offset_from_begin = 3; raw_text = tos((voidptr)&c_text[offset_from_begin], (int)(vstrlen(c_text) - offset_from_begin)); } } } return raw_text; } bool v__util__module_is_builtin(string mod) { return (Array_string_contains(_const_v__util__builtin_module_parts, mod)); } string v__util__tabs(int n) { return (n >= 0 && n < 11 ? (_const_v__util__const_tabs[n]) : (string_repeat(_S("\t"), n))); } time__Time v__util__get_build_time(void) { string sde = os__getenv(_S("SOURCE_DATE_EPOCH")); if ((sde).len == 0) { return time__utc(); } return time__unix_nanosecond(string_i64(sde), 0); } void v__util__set_vroot_folder(string vroot_path) { string vexe = os__getenv(_S("VEXE")); if ((vexe).len == 0) { string vname = (string__eq(os__user_os(), _S("windows")) ? (_S("v.exe")) : (_S("v"))); os__setenv(_S("VEXE"), os__real_path(os__join_path_single(vroot_path, vname)), true); } os__setenv(_S("VCHILD"), _S("true"), true); } inline bool v__util__is_escape_sequence(u8 c) { return (c == 'x' || c == 'u' || c == 'e' || c == 'n' || c == 'r' || c == 't' || c == 'v' || c == 'a' || c == 'f' || c == 'b' || c == '\\' || c == '`' || c == '$' || c == '@' || c == '?' || c == '{' || c == '}' || c == '\'' || c == '"' || c == 'U'); } VNORETURN void v__util__launch_tool(bool is_verbose, string tool_name, Array_string args) { string vexe = v__pref__vexe_path(); string vroot = os__dir(vexe); v__util__set_vroot_folder(vroot); string tool_args = v__util__args_quote_paths(args); string tools_folder = os__join_path(vroot, new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("cmd"), _S("tools")}))); string tool_basename = os__real_path(os__join_path_single(tools_folder, tool_name)); string tool_exe = _S(""); string tool_source = _S(""); if (os__is_dir(tool_basename)) { tool_exe = v__util__path_of_executable(os__join_path_single(tool_basename, os__file_name(tool_name))); tool_source = tool_basename; } else { tool_exe = v__util__path_of_executable(tool_basename); tool_source = string__plus(tool_basename, _S(".v")); } if (is_verbose) { println(str_intp(2, _MOV((StrIntpData[]){{_S("launch_tool vexe : "), 0xfe10, {.d_s = vexe}}, {_SLIT0, 0, { .d_c = 0 }}}))); println(str_intp(2, _MOV((StrIntpData[]){{_S("launch_tool vroot : "), 0xfe10, {.d_s = vroot}}, {_SLIT0, 0, { .d_c = 0 }}}))); println(str_intp(2, _MOV((StrIntpData[]){{_S("launch_tool tool_source : "), 0xfe10, {.d_s = tool_source}}, {_SLIT0, 0, { .d_c = 0 }}}))); println(str_intp(2, _MOV((StrIntpData[]){{_S("launch_tool tool_exe : "), 0xfe10, {.d_s = tool_exe}}, {_SLIT0, 0, { .d_c = 0 }}}))); println(str_intp(2, _MOV((StrIntpData[]){{_S("launch_tool tool_args : "), 0xfe10, {.d_s = tool_args}}, {_SLIT0, 0, { .d_c = 0 }}}))); } string disabling_file = v__util__recompilation__disabling_file(vroot); bool is_recompilation_disabled = os__exists(disabling_file); bool should_compile = !is_recompilation_disabled && v__util__should_recompile_tool(vexe, tool_source, tool_name, tool_exe); if (is_verbose) { println(str_intp(2, _MOV((StrIntpData[]){{_S("launch_tool should_compile: "), 0xfe10, {.d_s = should_compile ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (should_compile) { Array_string emodules = (*(Array_string*)map_get(ADDR(map, _const_v__util__external_module_dependencies_for_tool), &(string[]){tool_name}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })); for (int _t1 = 0; _t1 < emodules.len; ++_t1) { string emodule = ((string*)emodules.data)[_t1]; _result_bool _t2 = v__util__check_module_is_installed(emodule, is_verbose, false); if (_t2.is_error) { IError err = _t2.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; } string compilation_command = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(vexe)}}, {_S(" "), 0, { .d_c = 0 }}})); if (_SLIT_EQ(tool_name.str, tool_name.len, "vself") || _SLIT_EQ(tool_name.str, tool_name.len, "vup") || _SLIT_EQ(tool_name.str, tool_name.len, "vdoctor") || _SLIT_EQ(tool_name.str, tool_name.len, "vsymlink")) { compilation_command = string__plus(compilation_command, _S(" -g ")); } if (_SLIT_EQ(tool_name.str, tool_name.len, "vfmt")) { compilation_command = string__plus(compilation_command, _S(" -d vfmt ")); } compilation_command = string__plus(compilation_command, os__quoted_path(tool_source)); if (is_verbose) { println(str_intp(3, _MOV((StrIntpData[]){{_S("Compiling "), 0xfe10, {.d_s = tool_name}}, {_S(" with: \""), 0xfe10, {.d_s = compilation_command}}, {_S("\""), 0, { .d_c = 0 }}}))); } string current_work_dir = os__getwd(); ; string lockfile = string__plus(tool_exe, _S(".lock")); ; os__filelock__FileLock l = os__filelock__new(lockfile); if (os__filelock__FileLock_try_acquire(&l)) { ; _option_string _t3 = os__getenv_opt(_S("VUTIL_RETRY_MAX_COUNT")); if (_t3.state != 0) { IError err = _t3.err; *(string*) _t3.data = _S("7"); } int tool_recompile_retry_max_count = int_max(1, string_int((*(string*)_t3.data))); for (int i = 0; i < tool_recompile_retry_max_count; ++i) { ; _result_void _t4 = os__chdir(vroot); (void)_t4; ; os__Result tool_compilation = os__execute(compilation_command); _result_void _t5 = os__chdir(current_work_dir); (void)_t5; ; ; if (tool_compilation.exit_code == 0) { break; } else { if (_SLIT_EQ(tool_name.str, tool_name.len, "vup")) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("Cannot recompile the new version of `vup`: "), 0xfe07, {.d_i32 = tool_compilation.exit_code}}, {_S("\n"), 0xfe10, {.d_s = tool_compilation.output}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (os__exists(tool_exe)) { eprintln(_S("Trying an already existing old version of the `vup` tool instead...")); break; } else { eprintln(_S("Failed compilation of the `vup` tool, using the new V source code.")); eprintln(_S("The new source code, is likely to be unsupported, by your existing older V executable.")); eprintln(_S("Try running `make` or `make.bat` manually.")); eprintln(_S("If that fails, clone V from source in a new folder, and run `make` or `make.bat` manually again there.")); os__filelock__FileLock_release(&l); _v_exit(1); VUNREACHABLE(); } } if (i == (int)(tool_recompile_retry_max_count - 1)) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("cannot compile `"), 0xfe10, {.d_s = tool_source}}, {_S("`: "), 0xfe07, {.d_i32 = tool_compilation.exit_code}}, {_S("\n"), 0xfe10, {.d_s = tool_compilation.output}}, {_SLIT0, 0, { .d_c = 0 }}}))); os__filelock__FileLock_release(&l); _v_exit(1); VUNREACHABLE(); } } _result_int _t6 = rand__intn(40); if (_t6.is_error) { IError err = _t6.err; *(int*) _t6.data = 0; } time__sleep(((int)(20 + (*(int*)_t6.data))) * _const_time__millisecond); } ; os__filelock__FileLock_release(&l); ; } else { ; if (os__filelock__FileLock_wait_acquire(&l, 10 * _const_time__second)) { ; os__filelock__FileLock_release(&l); } else { ; } _result_int _t7 = rand__intn(40); if (_t7.is_error) { IError err = _t7.err; *(int*) _t7.data = 0; } time__sleep(((int)(50 + (*(int*)_t7.data))) * _const_time__millisecond); ; } } ; #if defined(_WIN32) { v__util__cmd_system(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(tool_exe)}}, {_S(" "), 0xfe10, {.d_s = tool_args}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } #elif defined(_VJS) { v__util__cmd_system(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tool_exe}}, {_S(" "), 0xfe10, {.d_s = tool_args}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } #else { _result_void _t9 = os__execvp(tool_exe, args); if (_t9.is_error) { IError err = _t9.err; eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("> error while executing: "), 0xfe10, {.d_s = tool_exe}}, {_S(" "), 0xfe10, {.d_s = Array_string_str(args)}}, {_SLIT0, 0, { .d_c = 0 }}}))); _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; } #endif _v_exit(2); VUNREACHABLE(); while(1); } VNORETURN VV_LOC void v__util__cmd_system(string cmd) { int res = os__system(cmd); if (res != 0) { ; } _v_exit(res); VUNREACHABLE(); while(1); } bool v__util__should_recompile_tool(string vexe, string tool_source, string tool_name, string tool_exe) { if (os__is_dir(tool_source)) { Array_string source_files = os__walk_ext(tool_source, _S(".v"), ((os__WalkParams){.hidden = 0,})); string newest_sfile = _S(""); i64 newest_sfile_mtime = ((i64)(0)); for (int _t1 = 0; _t1 < source_files.len; ++_t1) { string sfile = ((string*)source_files.data)[_t1]; i64 mtime = os__file_last_mod_unix(sfile); if (mtime > newest_sfile_mtime) { newest_sfile_mtime = mtime; newest_sfile = sfile; } } bool single_file_recompile = v__util__should_recompile_tool(vexe, newest_sfile, tool_name, tool_exe); return single_file_recompile; } bool should_compile = false; if (!os__exists(tool_exe)) { should_compile = true; } else { i64 mtime_vexe = os__file_last_mod_unix(vexe); i64 mtime_tool_exe = os__file_last_mod_unix(tool_exe); i64 mtime_tool_source = os__file_last_mod_unix(tool_source); if (mtime_tool_exe <= mtime_vexe) { should_compile = true; if (_SLIT_EQ(tool_name.str, tool_name.len, "vself") || _SLIT_EQ(tool_name.str, tool_name.len, "vup")) { should_compile = false; } } if (mtime_tool_exe <= mtime_tool_source) { should_compile = true; } if (mtime_vexe < 1024 && mtime_tool_exe < 1024) { should_compile = false; } } return should_compile; } string v__util__quote_path(string s) { return os__quoted_path(s); } string v__util__args_quote_paths(Array_string args) { Array_string _t2 = {0}; Array_string _t2_orig = args; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { string it = ((string*) _t2_orig.data)[_t4]; string _t3 = v__util__quote_path(it); array_push((array*)&_t2, &_t3); } return Array_string_join( _t2, _S(" ")); } string v__util__path_of_executable(string path) { #if defined(_WIN32) { return string__plus(path, _S(".exe")); } #endif return path; } _result_string v__util__cached_read_source_file(string path) { static v__util__SourceCache* cache = ((v__util__SourceCache*)(((void*)0))); if (cache == ((void*)0)) { cache = ((v__util__SourceCache*)memdup(&(v__util__SourceCache){.sources = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}, sizeof(v__util__SourceCache))); } #if defined(CUSTOM_DEFINE_trace_cached_read_source_file) { println(str_intp(2, _MOV((StrIntpData[]){{_S("cached_read_source_file "), 0xfe10, {.d_s = path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif if ((path).len == 0) { map_free(&cache->sources); _v_free(cache); cache = ((v__util__SourceCache*)(((void*)0))); return (_result_string){ .is_error=true, .err=_v_error(_S("memory source file cache cleared")), .data={E_STRUCT} }; } string* _t4 = (string*)(map_get_check(ADDR(map, cache->sources), &(string[]){path})); _option_string _t3 = {0}; if (_t4) { *((string*)&_t3.data) = *((string*)_t4); } else { _t3.state = 2; _t3.err = _v_error(_S("map key does not exist")); } if (_t3.state == 0) { string res = (*(string*)_t3.data); #if defined(CUSTOM_DEFINE_trace_cached_read_source_file_cached) { println(str_intp(2, _MOV((StrIntpData[]){{_S("cached_read_source_file cached "), 0xfe10, {.d_s = path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif _result_string _t6 = {0}; _result_ok(&(string[]) { res }, (_result*)(&_t6), sizeof(string)); return _t6; } #if defined(CUSTOM_DEFINE_trace_cached_read_source_file_not_cached) { println(str_intp(2, _MOV((StrIntpData[]){{_S("cached_read_source_file not cached "), 0xfe10, {.d_s = path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif _result_string _t8 = os__read_file(path); if (_t8.is_error) { IError err = _t8.err; return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("failed to open "), 0xfe10, {.d_s = path}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } string raw_text = (*(string*)_t8.data); string res = v__util__skip_bom(raw_text); map_set(&cache->sources, &(string[]){path}, &(string[]) { res }); _result_string _t10 = {0}; _result_ok(&(string[]) { res }, (_result*)(&_t10), sizeof(string)); return _t10; } string v__util__replace_op(string s) { return ((_SLIT_EQ(s.str, s.len, "+"))? (_S("_plus")) : (_SLIT_EQ(s.str, s.len, "-"))? (_S("_minus")) : (_SLIT_EQ(s.str, s.len, "*"))? (_S("_mult")) : (_SLIT_EQ(s.str, s.len, "/"))? (_S("_div")) : (_SLIT_EQ(s.str, s.len, "%"))? (_S("_mod")) : (_SLIT_EQ(s.str, s.len, "<"))? (_S("_lt")) : (_SLIT_EQ(s.str, s.len, ">"))? (_S("_gt")) : (_SLIT_EQ(s.str, s.len, "=="))? (_S("_eq")) : (_S(""))); } Array_string v__util__join_env_vflags_and_os_args(void) { return v__util__vflags__join_env_vflags_and_os_args(); } _result_bool v__util__check_module_is_installed(string modulename, bool is_verbose, bool need_update) { string mpath = os__join_path_single(os__vmodules_dir(), modulename); string mod_v_file = os__join_path_single(mpath, _S("v.mod")); string murl = str_intp(2, _MOV((StrIntpData[]){{_S("https://github.com/vlang/"), 0xfe10, {.d_s = modulename}}, {_SLIT0, 0, { .d_c = 0 }}})); if (is_verbose) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("check_module_is_installed: mpath: "), 0xfe10, {.d_s = mpath}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("check_module_is_installed: mod_v_file: "), 0xfe10, {.d_s = mod_v_file}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("check_module_is_installed: murl: "), 0xfe10, {.d_s = murl}}, {_SLIT0, 0, { .d_c = 0 }}}))); } string vexe = v__pref__vexe_path(); if (os__exists(mod_v_file)) { if (need_update) { string update_cmd = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(vexe)}}, {_S(" update '"), 0xfe10, {.d_s = modulename}}, {_S("'"), 0, { .d_c = 0 }}})); if (is_verbose) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("check_module_is_installed: updating with "), 0xfe10, {.d_s = update_cmd}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } os__Result update_res = os__execute(update_cmd); if (update_res.exit_code < 0) { return (_result_bool){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("can not start "), 0xfe10, {.d_s = update_cmd}}, {_S(", error: "), 0xfe10, {.d_s = update_res.output}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } if (update_res.exit_code != 0) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("Warning: `"), 0xfe10, {.d_s = modulename}}, {_S("` exists, but is not updated.\nV will continue, since updates can fail due to temporary network problems,\nand the existing module `"), 0xfe10, {.d_s = modulename}}, {_S("` may still work."), 0, { .d_c = 0 }}}))); if (is_verbose) { eprintln(_S("Details:")); eprintln(update_res.output); } eprintln(string_repeat(_S("-"), 50)); } } _result_bool _t2 = {0}; _result_ok(&(bool[]) { true }, (_result*)(&_t2), sizeof(bool)); return _t2; } if (is_verbose) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("check_module_is_installed: cloning from "), 0xfe10, {.d_s = murl}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } os__Result cloning_res = os__execute(str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(vexe)}}, {_S(" retry -- git clone "), 0xfe10, {.d_s = os__quoted_path(murl)}}, {_S(" "), 0xfe10, {.d_s = os__quoted_path(mpath)}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (cloning_res.exit_code != 0) { return (_result_bool){ .is_error=true, .err=error_with_code(str_intp(2, _MOV((StrIntpData[]){{_S("cloning failed, details: "), 0xfe10, {.d_s = cloning_res.output}}, {_SLIT0, 0, { .d_c = 0 }}})), cloning_res.exit_code), .data={E_STRUCT} }; } if (!os__exists(mod_v_file)) { return (_result_bool){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("even after cloning, "), 0xfe10, {.d_s = mod_v_file}}, {_S(" is still missing"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } if (is_verbose) { eprintln(_S("check_module_is_installed: done")); } _result_bool _t5 = {0}; _result_ok(&(bool[]) { true }, (_result*)(&_t5), sizeof(bool)); return _t5; } inline string v__util__strip_mod_name(string name) { return string_all_after_last(name, _S(".")); } inline string v__util__strip_main_name(string name) { return string_replace(name, _S("main."), _S("")); } inline string v__util__no_dots(string s) { return string_replace(s, _S("."), _S("__")); } string v__util__no_cur_mod(string __v_typename, string cur_mod) { string res = __v_typename; string mod_prefix = string__plus(cur_mod, _S(".")); bool has_map_prefix = string_starts_with(res, _const_v__util__map_prefix); if (has_map_prefix) { res = string_replace_once(res, _const_v__util__map_prefix, _S("")); } string no_symbols = string_trim_left(res, _S("&[]")); bool should_shorten = string_starts_with(no_symbols, mod_prefix); if (should_shorten) { res = string_replace_once(res, mod_prefix, _S("")); } if (has_map_prefix) { res = string__plus(_S("map[string]"), res); } return res; } bool v__util__should_bundle_module(string mod) { return (Array_fixed_string_8_contains(_const_v__util__bundle_modules, mod)) || (string_contains(mod, _S(".")) && (Array_fixed_string_8_contains(_const_v__util__bundle_modules, string_all_before(mod, _S("."))))); } void v__util__free_caches(void) { { // Unsafe block v__util__cached_file2sourcelines(_S("")); _result_string _t1 = v__util__cached_read_source_file(_S("")); if (_t1.is_error) { IError err = _t1.err; *(string*) _t1.data = _S(""); } ; } } _result_string v__util__read_file(string file_path) { return v__util__cached_read_source_file(file_path); } _result_string v__util__resolve_vmodroot(string str, string dir) { v__vmod__ModFileCacher* mcache = v__vmod__get_cache(); v__vmod__ModFileAndFolder vmod_file_location = v__vmod__ModFileCacher_get_by_folder(mcache, dir); if (vmod_file_location.vmod_file.len == 0) { return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("To use @VMODROOT, you need to have a \"v.mod\" file in "), 0xfe10, {.d_s = dir}}, {_S(", or in one of its parent folders."), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } string vmod_path = vmod_file_location.vmod_folder; _result_string _t2 = {0}; _result_ok(&(string[]) { string_replace(str, _S("@VMODROOT"), os__real_path(vmod_path)) }, (_result*)(&_t2), sizeof(string)); return _t2; } VV_LOC voidptr sync__pool__empty_cb(sync__pool__PoolProcessor* _p, int _idx, int _task_id) { { // Unsafe block return ((void*)0); } return 0; } sync__pool__PoolProcessor* sync__pool__new_pool_processor(sync__pool__PoolProcessorConfig context) { if (context.callback == (voidptr)((void*)0)) { _v_panic(_S("You need to pass a valid callback to new_pool_processor.")); VUNREACHABLE(); } sync__pool__PoolProcessor *pool = HEAP(sync__pool__PoolProcessor, (((sync__pool__PoolProcessor){ .thread_cb = ((voidptr)(context.callback)), .njobs = context.maxjobs, .items = __new_array_with_default(0, 0, sizeof(voidptr), 0), .results = (__shared__Array_voidptr*)__dup_shared_array(&(__shared__Array_voidptr){.mtx = {0}, .val = __new_array_with_default(0, 0, sizeof(voidptr), 0)}, sizeof(__shared__Array_voidptr)) , .ntask = 0U, .waitgroup = ((sync__WaitGroup){.task_count = 0,.wait_count = 0,.sem = ((sync__Semaphore){E_STRUCT}),}), .shared_context = (voidptr)((void*)0), .thread_contexts = __new_array_with_default(0, 0, sizeof(voidptr), 0), }))); sync__WaitGroup_init(&(*(pool)).waitgroup); return &(*(pool)); } void sync__pool__PoolProcessor_set_max_jobs(sync__pool__PoolProcessor* pool, int njobs) { pool->njobs = njobs; } void sync__pool__PoolProcessor_work_on_items_T___ptr__v__ast__File(sync__pool__PoolProcessor* pool, Array_v__ast__File_ptr items) { sync__pool__PoolProcessor_work_on_pointers(pool, array_pointers(items)); } void sync__pool__PoolProcessor_work_on_items_T_string(sync__pool__PoolProcessor* pool, Array_string items) { sync__pool__PoolProcessor_work_on_pointers(pool, array_pointers(items)); } void sync__pool__PoolProcessor_work_on_pointers(sync__pool__PoolProcessor* pool, Array_voidptr items) { int njobs = runtime__nr_jobs(); if (pool->njobs > 0) { njobs = pool->njobs; } { // Unsafe block pool->thread_contexts = __new_array_with_default(items.len, 0, sizeof(voidptr), 0); sync__RwMutex_lock(&pool->results->mtx); /*lock*/ { pool->results->val = __new_array_with_default(items.len, 0, sizeof(voidptr), 0); } sync__RwMutex_unlock(&pool->results->mtx);; pool->items = __new_array_with_default(0, items.len, sizeof(voidptr), 0); _PUSH_MANY(&pool->items, (items), _t1, Array_voidptr); sync__WaitGroup_add(&pool->waitgroup, njobs); for (int i = 0; i < njobs; i++) { if (njobs > 1) { // start go thread_arg_sync__pool__process_in_thread *arg__t2 = (thread_arg_sync__pool__process_in_thread *) _v_malloc(sizeof(thread_arg_sync__pool__process_in_thread)); arg__t2->fn = sync__pool__process_in_thread; arg__t2->arg1 = pool; arg__t2->arg2 = i; pthread_t thread__t2; pthread_attr_t thread__t2_attributes; pthread_attr_init(&thread__t2_attributes); pthread_attr_setstacksize(&thread__t2_attributes, 8388608); // fn: sync.pool.process_in_thread int _t2_thr_res = pthread_create(&thread__t2, &thread__t2_attributes, (void*)sync__pool__process_in_thread_thread_wrapper, arg__t2); if (_t2_thr_res) panic_error_number(tos3("`go sync__pool__process_in_thread()`: "), _t2_thr_res); pthread_detach(thread__t2); // end go ; } else { sync__pool__process_in_thread(pool, i); } } } sync__WaitGroup_wait(&pool->waitgroup); } VV_LOC void sync__pool__process_in_thread(sync__pool__PoolProcessor* pool, int task_id) { voidptr (*cb) (sync__pool__PoolProcessor* p, int idx, int task_id) = ((sync__pool__ThreadCB)(pool->thread_cb)); int ilen = pool->items.len; for (;;) { int idx = ((int)(atomic_fetch_add_u32(((voidptr)(&pool->ntask)), 1U))); if (idx >= ilen) { break; } voidptr res = cb(pool, idx, task_id); sync__RwMutex_lock(&pool->results->mtx); /*lock*/ { array_set(&pool->results->val, idx, &(voidptr[]) { res }); } sync__RwMutex_unlock(&pool->results->mtx);; } sync__WaitGroup_done(&pool->waitgroup); } v__ast__File* sync__pool__PoolProcessor_get_item_T___ptr__v__ast__File(sync__pool__PoolProcessor* pool, int idx) { return *(((v__ast__File**)((*(voidptr*)array_get(pool->items, idx))))); } string sync__pool__PoolProcessor_get_item_T_string(sync__pool__PoolProcessor* pool, int idx) { return *(((string*)((*(voidptr*)array_get(pool->items, idx))))); } Array_os__Result sync__pool__PoolProcessor_get_results_T_os__Result(sync__pool__PoolProcessor* pool) { Array_os__Result res = __new_array_with_default(0, pool->results->val.len, sizeof(os__Result), 0); for (int i = 0; i < pool->results->val.len; ++i) { sync__RwMutex_rlock(&pool->results->mtx); /*lock*/ { array_push((array*)&res, _MOV((os__Result[]){ *(((os__Result*)((*(voidptr*)array_get(pool->results->val, i))))) })); } sync__RwMutex_runlock(&pool->results->mtx);; } return res; } Array_v__gen__c__Gen_ptr sync__pool__PoolProcessor_get_results_ref_T_v__gen__c__Gen(sync__pool__PoolProcessor* pool) { Array_v__gen__c__Gen_ptr res = __new_array_with_default(0, pool->results->val.len, sizeof(v__gen__c__Gen*), 0); for (int i = 0; i < pool->results->val.len; ++i) { sync__RwMutex_rlock(&pool->results->mtx); /*lock*/ { array_push((array*)&res, _MOV((v__gen__c__Gen*[]){ ((v__gen__c__Gen*)((*(voidptr*)array_get(pool->results->val, i)))) })); } sync__RwMutex_runlock(&pool->results->mtx);; } return res; } void sync__pool__PoolProcessor_set_shared_context(sync__pool__PoolProcessor* pool, voidptr context) { pool->shared_context = context; } voidptr sync__pool__PoolProcessor_get_shared_context(sync__pool__PoolProcessor* pool) { return pool->shared_context; } string v__ast__ComptimeType_str(v__ast__ComptimeType cty) { string _t2 = (string){.str=(byteptr)"", .is_lit=1}; switch (cty.kind) { case v__ast__ComptimeTypeKind__unknown: { _t2 = _S("$unknown"); break; } case v__ast__ComptimeTypeKind__map: { _t2 = _S("$map"); break; } case v__ast__ComptimeTypeKind__int: { _t2 = _S("$int"); break; } case v__ast__ComptimeTypeKind__float: { _t2 = _S("$float"); break; } case v__ast__ComptimeTypeKind__struct: { _t2 = _S("$struct"); break; } case v__ast__ComptimeTypeKind__iface: { _t2 = _S("$interface"); break; } case v__ast__ComptimeTypeKind__array: { _t2 = _S("$array"); break; } case v__ast__ComptimeTypeKind__array_dynamic: { _t2 = _S("$array_dynamic"); break; } case v__ast__ComptimeTypeKind__array_fixed: { _t2 = _S("$array_fixed"); break; } case v__ast__ComptimeTypeKind__sum_type: { _t2 = _S("$sumtype"); break; } case v__ast__ComptimeTypeKind__enum: { _t2 = _S("$enum"); break; } case v__ast__ComptimeTypeKind__alias: { _t2 = _S("$alias"); break; } case v__ast__ComptimeTypeKind__function: { _t2 = _S("$function"); break; } case v__ast__ComptimeTypeKind__option: { _t2 = _S("$option"); break; } case v__ast__ComptimeTypeKind__string: { _t2 = _S("$string"); break; } case v__ast__ComptimeTypeKind__pointer: { _t2 = _S("$pointer"); break; } case v__ast__ComptimeTypeKind__voidptr: { _t2 = _S("$voidptr"); break; } } return _t2; } _option_v__ast__Ident v__ast__SelectorExpr_root_ident(v__ast__SelectorExpr* e) { v__ast__Expr root = e->expr; for (;;) { if (!((root)._typ == 379 /* v.ast.SelectorExpr */)) break; root = (*root._v__ast__SelectorExpr).expr; } if ((root)._typ == 358 /* v.ast.Ident */) { _option_v__ast__Ident _t1; _option_ok(&(v__ast__Ident[]) { (*root._v__ast__Ident) }, (_option*)(&_t1), sizeof(v__ast__Ident)); return _t1; } return (_option_v__ast__Ident){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } bool v__ast__StructField_equals(v__ast__StructField* f, v__ast__StructField* o) { return string__eq(f->name, o->name) && f->typ == o->typ && f->is_pub == o->is_pub && f->is_global == o->is_global; } v__ast__FnDecl v__ast__FnDecl_new_method_with_receiver_type(v__ast__FnDecl* f, v__ast__Type new_type_) { v__ast__Type new_type = (v__ast__Type_is_ptr((*(v__ast__Param*)array_get(f->params, 0)).typ) && !v__ast__Type_is_ptr(new_type_) ? (v__ast__Type_ref(new_type_)) : (new_type_)); { // Unsafe block v__ast__FnDecl* new_method = f; new_method->params = array_clone_to_depth(&f->params, 0); for (int i = 1; i < new_method->params.len; ++i) { if ((*(v__ast__Param*)array_get(new_method->params, i)).typ == (*(v__ast__Param*)array_get(new_method->params, 0)).typ) { (*(v__ast__Param*)array_get(new_method->params, i)).typ = new_type; } } (*(v__ast__Param*)array_get(new_method->params, 0)).typ = new_type; return *new_method; } return (v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = (v__ast__StructField){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.option_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = (v__ast__StructDecl){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,},},.receiver_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_method = 0,.is_static_type_method = 0,.static_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.method_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.body_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.end_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_expand_simple_interpolation = 0,}; } VV_LOC bool v__ast__Fn_method_equals(v__ast__Fn* f, v__ast__Fn* o) { return Array_v__ast__Param_equals(array_slice(f->params, 1, 2147483647), array_slice(o->params, 1, 2147483647)) && f->return_type == o->return_type && f->is_variadic == o->is_variadic && f->language == o->language && Array_string_arr_eq(f->generic_names, o->generic_names) && f->is_pub == o->is_pub && string__eq(f->mod, o->mod) && string__eq(f->name, o->name); } string v__ast__Param_specifier(v__ast__Param* p) { bool _t2 = true; return ((_t2 == (p->is_shared))? (_S("shared")) : (_t2 == (p->is_atomic))? (_S("atomic")) : (_t2 == (p->is_mut))? (_S("mut")) : (_S(""))); } v__ast__Fn v__ast__Fn_new_method_with_receiver_type(v__ast__Fn* f, v__ast__Type new_type_) { v__ast__Type new_type = (v__ast__Type_is_ptr((*(v__ast__Param*)array_get(f->params, 0)).typ) && !v__ast__Type_is_ptr(new_type_) ? (v__ast__Type_ref(new_type_)) : (new_type_)); { // Unsafe block v__ast__Fn* new_method = f; new_method->params = array_clone_to_depth(&f->params, 0); for (int i = 1; i < new_method->params.len; ++i) { if ((*(v__ast__Param*)array_get(new_method->params, i)).typ == (*(v__ast__Param*)array_get(new_method->params, 0)).typ) { (*(v__ast__Param*)array_get(new_method->params, i)).typ = new_type; } } new_method->from_embedded_type = (f->from_embedded_type != 0 ? (f->from_embedded_type) : ((*(v__ast__Param*)array_get(f->params, 0)).typ)); (*(v__ast__Param*)array_get(new_method->params, 0)).typ = new_type; return *new_method; } return (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}; } VV_LOC bool v__ast__Param_equals(v__ast__Param* p, v__ast__Param* o) { return string__eq(p->name, o->name) && p->is_mut == o->is_mut && p->typ == o->typ && p->is_hidden == o->is_hidden; } VV_LOC bool Array_v__ast__Param_equals(Array_v__ast__Param p, Array_v__ast__Param o) { if (p.len != o.len) { return false; } for (int i = 0; i < p.len; ++i) { if (!v__ast__Param_equals(&(*(v__ast__Param*)array_get(p, i)), (voidptr)&(*(v__ast__Param*)array_get(o, i)))) { return false; } } return true; } void v__ast__File_free(v__ast__File* f) { { // Unsafe block string_free(&f->path); string_free(&f->path_base); v__ast__Scope_free(f->scope); array_free(&f->stmts); array_free(&f->imports); Array_string_free(&f->auto_imports); array_free(&f->embedded_files); map_free(&f->imported_symbols); array_free(&f->errors); array_free(&f->warnings); array_free(&f->notices); Array_string_free(&f->global_labels); } } string v__ast__Ident_full_name(v__ast__Ident* i) { if ((i->full_name).len != 0) { return i->full_name; } if (string_contains(i->name, _S("."))) { i->full_name = i->name; } else { i->full_name = string__plus(string__plus(i->mod, _S(".")), i->name); } return i->full_name; } inline bool v__ast__Ident_is_auto_heap(v__ast__Ident* i) { return ((i->obj._typ == 422 /* v.ast.Var */)? ((*i->obj._v__ast__Var).is_auto_heap) : (false)); } inline bool v__ast__Ident_is_mut(v__ast__Ident* i) { if (i->obj._typ == 422 /* v.ast.Var */) { return (*i->obj._v__ast__Var).is_mut; } else if (i->obj._typ == 420 /* v.ast.ConstField */) { return false; } else if (i->obj._typ == 418 /* v.ast.EmptyScopeObject */) { return false; } else if (i->obj._typ == 419 /* v.ast.AsmRegister */) { return true; } else if (i->obj._typ == 421 /* v.ast.GlobalField */) { return true; } return 0; } v__ast__IdentVar v__ast__Ident_var_info(v__ast__Ident* i) { if (i->info._typ == 477 /* v.ast.IdentVar */) { return (*i->info._v__ast__IdentVar); } else { _v_panic(_S("Ident.var_info(): info is not IdentVar variant")); VUNREACHABLE(); } return (v__ast__IdentVar){.typ = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_option = 0,.share = 0,}; } _result_void v__ast__ComptimeCall_resolve_compile_value(v__ast__ComptimeCall* cc, Map_string_string compile_values) { if (cc->is_d_resolved) { return (_result_void){0}; } if (cc->kind != v__ast__ComptimeCallKind__d) { return (_result_void){ .is_error=true, .err=_v_error(_S("ComptimeCall is not $d()")), .data={E_STRUCT} }; } v__ast__CallArg* _t3 = (v__ast__CallArg*)(array_get_with_check(cc->args, 0)); _option_v__ast__CallArg _t2 = {0}; if (_t3) { *((v__ast__CallArg*)&_t2.data) = *((v__ast__CallArg*)_t3); } else { _t2.state = 2; _t2.err = _v_error(_S("array index out of range")); } ; if (_t2.state != 0) { IError err = _t2.err; return (_result_void){ .is_error=true, .err=_v_error(_S("$d() takes two arguments, a string and a primitive literal")), .data={E_STRUCT} }; } v__ast__CallArg arg = (*(v__ast__CallArg*)_t2.data); if (!v__ast__Expr_is_pure_literal(arg.expr)) { return (_result_void){ .is_error=true, .err=_v_error(_S("$d() values can only be pure literals")), .data={E_STRUCT} }; } v__ast__Type typ = v__ast__Expr_get_pure_type(arg.expr); string arg_as_string = string_trim(v__ast__CallArg_str(arg), _S("`\"\'")); string* _t7 = (string*)(map_get_check(ADDR(map, compile_values), &(string[]){cc->args_var})); _option_string _t6 = {0}; if (_t7) { *((string*)&_t6.data) = *((string*)_t7); } else { _t6.state = 2; _t6.err = _v_error(_S("map key does not exist")); } ; if (_t6.state != 0) { IError err = _t6.err; *(string*) _t6.data = arg_as_string; } string value = (*(string*)_t6.data); _result_void _t8 = v__ast__validate_type_string_is_pure_literal(typ, value); if (_t8.is_error) { IError err = _t8.err; return (_result_void){ .is_error=true, .err=_v_error(IError_name_table[err._typ]._method_msg(err._object)), .data={E_STRUCT} }; } ; cc->compile_value = value; cc->result_type = typ; cc->is_d_resolved = true; return (_result_void){0}; } string v__ast__ComptimeCall_expr_str(v__ast__ComptimeCall _v_toheap_cc) { v__ast__ComptimeCall* cc = HEAP(v__ast__ComptimeCall, _v_toheap_cc); string str = _S("ast.ComptimeCall"); if ((*(cc)).kind == v__ast__ComptimeCallKind__d) { v__ast__CallArg* _t2 = (v__ast__CallArg*)(array_get_with_check((*(cc)).args, 0)); _option_v__ast__CallArg _t1 = {0}; if (_t2) { *((v__ast__CallArg*)&_t1.data) = *((v__ast__CallArg*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("array index out of range")); } ; if (_t1.state != 0) { IError err = _t1.err; return str; } v__ast__CallArg arg = (*(v__ast__CallArg*)_t1.data); if (v__ast__Expr_is_pure_literal(arg.expr)) { str = str_intp(4, _MOV((StrIntpData[]){{_S("$"), 0xfe10, {.d_s = (*(cc)).method_name}}, {_S("('"), 0xfe10, {.d_s = (*(cc)).args_var}}, {_S("', "), 0xfe10, {.d_s = v__ast__CallArg_str(arg)}}, {_S(")"), 0, { .d_c = 0 }}})); } } return str; } inline bool v__ast__Expr_is_blank_ident(v__ast__Expr expr) { if ((expr)._typ == 358 /* v.ast.Ident */) { return (*expr._v__ast__Ident).kind == v__ast__IdentKind__blank_ident; } return false; } inline bool v__ast__Expr_is_as_cast(v__ast__Expr expr) { if ((expr)._typ == 374 /* v.ast.ParExpr */) { return v__ast__Expr_is_as_cast((*expr._v__ast__ParExpr).expr); } else if ((expr)._typ == 379 /* v.ast.SelectorExpr */) { return v__ast__Expr_is_as_cast((*expr._v__ast__SelectorExpr).expr); } else { return (expr)._typ == 339 /* v.ast.AsCast */; } return 0; } v__token__Pos v__ast__Expr_pos(v__ast__Expr expr) { bool v__ast__Expr_pos_defer_0 = false; i64 pos_calls = sync__stdatomic__add_i64(&nested_expr_pos_calls, 1); if (pos_calls > 5000) { #if defined(CUSTOM_DEFINE_panic_on_deeply_nested_expr_pos_calls) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _S("/home/runner/work/v/v/vlib/v/ast/ast.v:2240, ast.Expr{}.pos")}}, {_S(": too many nested Expr.pos() calls: "), 0xfe09, {.d_i64 = pos_calls}}, {_S(", expr type: "), 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_sumtype_v__ast__Expr( (expr)._typ ))}}, {_SLIT0, 0, { .d_c = 0 }}}))); _v_exit(1); VUNREACHABLE(); } #endif return ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); } v__ast__Expr_pos_defer_0 = true; v__token__Pos _t4 = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}; if (expr._typ == 336 /* v.ast.AnonFn */) { _t4 = (*expr._v__ast__AnonFn).decl.pos; } else if (expr._typ == 343 /* v.ast.CTempVar */) { _t4 = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); } else if (expr._typ == 354 /* v.ast.EmptyExpr */) { _t4 = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); } else if (expr._typ == 335 /* v.ast.NodeError */) { _t4 = (*expr._v__ast__NodeError).pos; } else if (expr._typ == 337 /* v.ast.ArrayDecompose */) { _t4 = (*expr._v__ast__ArrayDecompose).pos; } else if (expr._typ == 338 /* v.ast.ArrayInit */) { _t4 = (*expr._v__ast__ArrayInit).pos; } else if (expr._typ == 339 /* v.ast.AsCast */) { _t4 = (*expr._v__ast__AsCast).pos; } else if (expr._typ == 340 /* v.ast.Assoc */) { _t4 = (*expr._v__ast__Assoc).pos; } else if (expr._typ == 341 /* v.ast.AtExpr */) { _t4 = (*expr._v__ast__AtExpr).pos; } else if (expr._typ == 342 /* v.ast.BoolLiteral */) { _t4 = (*expr._v__ast__BoolLiteral).pos; } else if (expr._typ == 344 /* v.ast.CallExpr */) { _t4 = (*expr._v__ast__CallExpr).pos; } else if (expr._typ == 345 /* v.ast.CastExpr */) { _t4 = (*expr._v__ast__CastExpr).pos; } else if (expr._typ == 346 /* v.ast.ChanInit */) { _t4 = (*expr._v__ast__ChanInit).pos; } else if (expr._typ == 347 /* v.ast.CharLiteral */) { _t4 = (*expr._v__ast__CharLiteral).pos; } else if (expr._typ == 352 /* v.ast.ConcatExpr */) { _t4 = (*expr._v__ast__ConcatExpr).pos; } else if (expr._typ == 348 /* v.ast.Comment */) { _t4 = (*expr._v__ast__Comment).pos; } else if (expr._typ == 349 /* v.ast.ComptimeCall */) { _t4 = (*expr._v__ast__ComptimeCall).pos; } else if (expr._typ == 350 /* v.ast.ComptimeSelector */) { _t4 = (*expr._v__ast__ComptimeSelector).pos; } else if (expr._typ == 355 /* v.ast.EnumVal */) { _t4 = (*expr._v__ast__EnumVal).pos; } else if (expr._typ == 353 /* v.ast.DumpExpr */) { _t4 = (*expr._v__ast__DumpExpr).pos; } else if (expr._typ == 356 /* v.ast.FloatLiteral */) { _t4 = (*expr._v__ast__FloatLiteral).pos; } else if (expr._typ == 357 /* v.ast.GoExpr */) { _t4 = (*expr._v__ast__GoExpr).pos; } else if (expr._typ == 381 /* v.ast.SpawnExpr */) { _t4 = (*expr._v__ast__SpawnExpr).pos; } else if (expr._typ == 358 /* v.ast.Ident */) { _t4 = (*expr._v__ast__Ident).pos; } else if (expr._typ == 359 /* v.ast.IfExpr */) { _t4 = (*expr._v__ast__IfExpr).pos; } else if (expr._typ == 363 /* v.ast.IntegerLiteral */) { _t4 = (*expr._v__ast__IntegerLiteral).pos; } else if (expr._typ == 364 /* v.ast.IsRefType */) { _t4 = (*expr._v__ast__IsRefType).pos; } else if (expr._typ == 366 /* v.ast.Likely */) { _t4 = (*expr._v__ast__Likely).pos; } else if (expr._typ == 367 /* v.ast.LockExpr */) { _t4 = (*expr._v__ast__LockExpr).pos; } else if (expr._typ == 368 /* v.ast.MapInit */) { _t4 = (*expr._v__ast__MapInit).pos; } else if (expr._typ == 369 /* v.ast.MatchExpr */) { _t4 = (*expr._v__ast__MatchExpr).pos; } else if (expr._typ == 371 /* v.ast.None */) { _t4 = (*expr._v__ast__None).pos; } else if (expr._typ == 372 /* v.ast.OffsetOf */) { _t4 = (*expr._v__ast__OffsetOf).pos; } else if (expr._typ == 373 /* v.ast.OrExpr */) { _t4 = (*expr._v__ast__OrExpr).pos; } else if (expr._typ == 374 /* v.ast.ParExpr */) { _t4 = (*expr._v__ast__ParExpr).pos; } else if (expr._typ == 375 /* v.ast.PostfixExpr */) { _t4 = (*expr._v__ast__PostfixExpr).pos; } else if (expr._typ == 376 /* v.ast.PrefixExpr */) { _t4 = (*expr._v__ast__PrefixExpr).pos; } else if (expr._typ == 377 /* v.ast.RangeExpr */) { _t4 = (*expr._v__ast__RangeExpr).pos; } else if (expr._typ == 378 /* v.ast.SelectExpr */) { _t4 = (*expr._v__ast__SelectExpr).pos; } else if (expr._typ == 379 /* v.ast.SelectorExpr */) { _t4 = (*expr._v__ast__SelectorExpr).pos; } else if (expr._typ == 380 /* v.ast.SizeOf */) { _t4 = (*expr._v__ast__SizeOf).pos; } else if (expr._typ == 382 /* v.ast.SqlExpr */) { _t4 = (*expr._v__ast__SqlExpr).pos; } else if (expr._typ == 383 /* v.ast.StringInterLiteral */) { _t4 = (*expr._v__ast__StringInterLiteral).pos; } else if (expr._typ == 384 /* v.ast.StringLiteral */) { _t4 = (*expr._v__ast__StringLiteral).pos; } else if (expr._typ == 385 /* v.ast.StructInit */) { _t4 = (*expr._v__ast__StructInit).pos; } else if (expr._typ == 386 /* v.ast.TypeNode */) { _t4 = (*expr._v__ast__TypeNode).pos; } else if (expr._typ == 387 /* v.ast.TypeOf */) { _t4 = (*expr._v__ast__TypeOf).pos; } else if (expr._typ == 388 /* v.ast.UnsafeExpr */) { _t4 = (*expr._v__ast__UnsafeExpr).pos; } else if (expr._typ == 351 /* v.ast.ComptimeType */) { _t4 = (*expr._v__ast__ComptimeType).pos; } else if (expr._typ == 365 /* v.ast.LambdaExpr */) { _t4 = (*expr._v__ast__LambdaExpr).pos; } else if (expr._typ == 370 /* v.ast.Nil */) { _t4 = (*expr._v__ast__Nil).pos; } else if (expr._typ == 361 /* v.ast.IndexExpr */) { _t4 = ((*expr._v__ast__IndexExpr).or_expr.kind != v__ast__OrKind__absent ? ((*expr._v__ast__IndexExpr).or_expr.pos) : ((*expr._v__ast__IndexExpr).pos)); } else if (expr._typ == 360 /* v.ast.IfGuardExpr */) { _t4 = v__ast__Expr_pos((*expr._v__ast__IfGuardExpr).expr); } else if (expr._typ == 362 /* v.ast.InfixExpr */) { v__token__Pos left_pos = v__ast__Expr_pos((*expr._v__ast__InfixExpr).left); v__token__Pos right_pos = v__ast__Expr_pos((*expr._v__ast__InfixExpr).right); _t4 = ((v__token__Pos){.len = (int)((int)(right_pos.pos - left_pos.pos) + right_pos.len),.line_nr = (*expr._v__ast__InfixExpr).pos.line_nr,.pos = left_pos.pos,.col = left_pos.col,.last_line = right_pos.last_line,}); } v__token__Pos _t3 = _t4; // Defer begin if (v__ast__Expr_pos_defer_0) { sync__stdatomic__sub_i64(&nested_expr_pos_calls, 1); } // Defer end return _t3; } bool v__ast__Expr_is_lvalue(v__ast__Expr expr) { return ((expr._typ == 358 /* v.ast.Ident */)? (true) : (expr._typ == 343 /* v.ast.CTempVar */)? (true) : (expr._typ == 361 /* v.ast.IndexExpr */)? (v__ast__Expr_is_lvalue((*expr._v__ast__IndexExpr).left)) : (expr._typ == 379 /* v.ast.SelectorExpr */)? (v__ast__Expr_is_lvalue((*expr._v__ast__SelectorExpr).expr)) : (expr._typ == 374 /* v.ast.ParExpr */)? (v__ast__Expr_is_lvalue((*expr._v__ast__ParExpr).expr)) : (expr._typ == 376 /* v.ast.PrefixExpr */)? (v__ast__Expr_is_lvalue((*expr._v__ast__PrefixExpr).right)) : (expr._typ == 350 /* v.ast.ComptimeSelector */)? (v__ast__Expr_is_lvalue((*expr._v__ast__ComptimeSelector).field_expr)) : (false)); } bool v__ast__Expr_is_expr(v__ast__Expr expr) { return ((expr._typ == 359 /* v.ast.IfExpr */)? ((*expr._v__ast__IfExpr).is_expr) : (expr._typ == 367 /* v.ast.LockExpr */)? ((*expr._v__ast__LockExpr).is_expr) : (expr._typ == 369 /* v.ast.MatchExpr */)? ((*expr._v__ast__MatchExpr).is_expr) : (expr._typ == 378 /* v.ast.SelectExpr */)? ((*expr._v__ast__SelectExpr).is_expr) : (true)); } v__ast__Type v__ast__Expr_get_pure_type(v__ast__Expr expr) { return ((expr._typ == 342 /* v.ast.BoolLiteral */)? (_const_v__ast__bool_type) : (expr._typ == 347 /* v.ast.CharLiteral */)? (_const_v__ast__char_type) : (expr._typ == 356 /* v.ast.FloatLiteral */)? (_const_v__ast__f64_type) : (expr._typ == 384 /* v.ast.StringLiteral */)? (_const_v__ast__string_type) : (expr._typ == 363 /* v.ast.IntegerLiteral */)? (_const_v__ast__i64_type) : (_const_v__ast__void_type)); } bool v__ast__Expr_is_pure_literal(v__ast__Expr expr) { return ((expr._typ == 342 /* v.ast.BoolLiteral */)? (true) : (expr._typ == 347 /* v.ast.CharLiteral */)? (true) : (expr._typ == 356 /* v.ast.FloatLiteral */)? (true) : (expr._typ == 384 /* v.ast.StringLiteral */)? (true) : (expr._typ == 363 /* v.ast.IntegerLiteral */)? (true) : (false)); } bool v__ast__Expr_is_auto_deref_var(v__ast__Expr expr) { return ((expr._typ == 358 /* v.ast.Ident */)? ((((*expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */ ? ((*(*expr._v__ast__Ident).obj._v__ast__Var).is_auto_deref) : (false))) : (expr._typ == 376 /* v.ast.PrefixExpr */)? ((*expr._v__ast__PrefixExpr).op == v__token__Kind__amp && v__ast__Expr_is_auto_deref_var((*expr._v__ast__PrefixExpr).right)) : (false)); } bool v__ast__Expr_is_lockable(v__ast__Expr* e) { return ((e->_typ == 358 /* v.ast.Ident */)? (true) : (e->_typ == 379 /* v.ast.SelectorExpr */)? (v__ast__Expr_is_lockable(&(*e->_v__ast__SelectorExpr).expr)) : (false)); } bool v__ast__Expr_has_fn_call(v__ast__Expr* e) { return ((e->_typ == 344 /* v.ast.CallExpr */)? (true) : (e->_typ == 379 /* v.ast.SelectorExpr */)? (v__ast__Expr_has_fn_call(&(*e->_v__ast__SelectorExpr).expr)) : (false)); } v__token__Pos v__ast__Node_pos(v__ast__Node node) { if (node._typ == 335 /* v.ast.NodeError */) { return ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); } else if (node._typ == 425 /* v.ast.EmptyNode */) { return ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); } else if (node._typ == 416 /* v.ast.Stmt */) { v__token__Pos pos = (*((*node._v__ast__Stmt).pos)); if (((*node._v__ast__Stmt))._typ == 409 /* v.ast.Import */) { for (int _t3 = 0; _t3 < (*(*node._v__ast__Stmt)._v__ast__Import).syms.len; ++_t3) { v__ast__ImportSymbol sym = ((v__ast__ImportSymbol*)(*(*node._v__ast__Stmt)._v__ast__Import).syms.data)[_t3]; pos = v__token__Pos_extend(pos, sym.pos); } } else if (((*node._v__ast__Stmt))._typ == 334 /* v.ast.TypeDecl */) { if ((*(*node._v__ast__Stmt)._v__ast__TypeDecl)._typ == 332 /* v.ast.FnTypeDecl */) { pos = v__token__Pos_extend(pos, (*(*(*node._v__ast__Stmt)._v__ast__TypeDecl)._v__ast__FnTypeDecl).type_pos); } else if ((*(*node._v__ast__Stmt)._v__ast__TypeDecl)._typ == 331 /* v.ast.AliasTypeDecl */) { pos = v__token__Pos_extend(pos, (*(*(*node._v__ast__Stmt)._v__ast__TypeDecl)._v__ast__AliasTypeDecl).type_pos); } else if ((*(*node._v__ast__Stmt)._v__ast__TypeDecl)._typ == 333 /* v.ast.SumTypeDecl */) { for (int _t4 = 0; _t4 < (*(*(*node._v__ast__Stmt)._v__ast__TypeDecl)._v__ast__SumTypeDecl).variants.len; ++_t4) { v__ast__TypeNode variant = ((v__ast__TypeNode*)(*(*(*node._v__ast__Stmt)._v__ast__TypeDecl)._v__ast__SumTypeDecl).variants.data)[_t4]; pos = v__token__Pos_extend(pos, variant.pos); } } } if (((*node._v__ast__Stmt))._typ == 392 /* v.ast.AssignStmt */) { return v__token__Pos_extend(pos, v__ast__Expr_pos((*(v__ast__Expr*)array_last((*(*node._v__ast__Stmt)._v__ast__AssignStmt).right)))); } if (((*node._v__ast__Stmt))._typ == 391 /* v.ast.AssertStmt */) { return v__token__Pos_extend(pos, v__ast__Expr_pos((*(*node._v__ast__Stmt)._v__ast__AssertStmt).expr)); } return pos; } else if (node._typ == 389 /* v.ast.Expr */) { return v__ast__Expr_pos((*node._v__ast__Expr)); } else if (node._typ == 431 /* v.ast.StructField */) { return v__token__Pos_extend((*node._v__ast__StructField).pos, (*node._v__ast__StructField).type_pos); } else if (node._typ == 428 /* v.ast.MatchBranch */) { return (*node._v__ast__MatchBranch).pos; } else if (node._typ == 430 /* v.ast.SelectBranch */) { return (*node._v__ast__SelectBranch).pos; } else if (node._typ == 426 /* v.ast.EnumField */) { return (*node._v__ast__EnumField).pos; } else if (node._typ == 420 /* v.ast.ConstField */) { return (*node._v__ast__ConstField).pos; } else if (node._typ == 432 /* v.ast.StructInitField */) { return (*node._v__ast__StructInitField).pos; } else if (node._typ == 421 /* v.ast.GlobalField */) { return (*node._v__ast__GlobalField).pos; } else if (node._typ == 424 /* v.ast.CallArg */) { return (*node._v__ast__CallArg).pos; } else if (node._typ == 429 /* v.ast.Param */) { return v__token__Pos_extend((*node._v__ast__Param).pos, (*node._v__ast__Param).type_pos); } else if (node._typ == 427 /* v.ast.IfBranch */) { return v__token__Pos_extend((*node._v__ast__IfBranch).pos, (*node._v__ast__IfBranch).body_pos); } else if (node._typ == 423 /* v.ast.ScopeObject */) { if ((*node._v__ast__ScopeObject)._typ == 420 /* v.ast.ConstField */) { return (*(*node._v__ast__ScopeObject)._v__ast__ConstField).pos; } else if ((*node._v__ast__ScopeObject)._typ == 421 /* v.ast.GlobalField */) { return (*(*node._v__ast__ScopeObject)._v__ast__GlobalField).pos; } else if ((*node._v__ast__ScopeObject)._typ == 422 /* v.ast.Var */) { return (*(*node._v__ast__ScopeObject)._v__ast__Var).pos; } else if ((*node._v__ast__ScopeObject)._typ == 418 /* v.ast.EmptyScopeObject */) { return ((v__token__Pos){.len = -1,.line_nr = -1,.pos = -1,.col = -1,.last_line = -1,}); } else if ((*node._v__ast__ScopeObject)._typ == 419 /* v.ast.AsmRegister */) { return ((v__token__Pos){.len = -1,.line_nr = -1,.pos = -1,.col = -1,.last_line = -1,}); } } else if (node._typ == 228 /* v.ast.File */) { v__token__Pos pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if ((*node._v__ast__File).stmts.len > 0) { v__token__Pos first_pos = (*((*(v__ast__Stmt*)array_first((*node._v__ast__File).stmts)).pos)); v__token__Pos last_pos = (*((*(v__ast__Stmt*)array_last((*node._v__ast__File).stmts)).pos)); pos = v__token__Pos_extend_with_last_line(first_pos, last_pos, last_pos.line_nr); } return pos; } return (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}; } Array_v__ast__Node v__ast__Node_children(v__ast__Node node) { Array_v__ast__Node children = __new_array_with_default(0, 0, sizeof(v__ast__Node), 0); if ((node)._typ == 389 /* v.ast.Expr */) { if ((*node._v__ast__Expr)._typ == 383 /* v.ast.StringInterLiteral */) { Array_v__ast__Node _t2 = {0}; Array_v__ast__Expr _t2_orig = (*(*node._v__ast__Expr)._v__ast__StringInterLiteral).exprs; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(v__ast__Node)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Expr it = ((v__ast__Expr*) _t2_orig.data)[_t4]; v__ast__Node _t3 = v__ast__Expr_to_sumtype_v__ast__Node(&it); array_push((array*)&_t2, &_t3); } return _t2; } else if ((*node._v__ast__Expr)._typ == 340 /* v.ast.Assoc */) { Array_v__ast__Node _t6 = {0}; Array_v__ast__Expr _t6_orig = (*(*node._v__ast__Expr)._v__ast__Assoc).exprs; int _t6_len = _t6_orig.len; _t6 = __new_array(0, _t6_len, sizeof(v__ast__Node)); for (int _t8 = 0; _t8 < _t6_len; ++_t8) { v__ast__Expr it = ((v__ast__Expr*) _t6_orig.data)[_t8]; v__ast__Node _t7 = v__ast__Expr_to_sumtype_v__ast__Node(&it); array_push((array*)&_t6, &_t7); } return _t6; } else if ((*node._v__ast__Expr)._typ == 338 /* v.ast.ArrayInit */) { Array_v__ast__Node _t10 = {0}; Array_v__ast__Expr _t10_orig = (*(*node._v__ast__Expr)._v__ast__ArrayInit).exprs; int _t10_len = _t10_orig.len; _t10 = __new_array(0, _t10_len, sizeof(v__ast__Node)); for (int _t12 = 0; _t12 < _t10_len; ++_t12) { v__ast__Expr it = ((v__ast__Expr*) _t10_orig.data)[_t12]; v__ast__Node _t11 = v__ast__Expr_to_sumtype_v__ast__Node(&it); array_push((array*)&_t10, &_t11); } return _t10; } else if ((*node._v__ast__Expr)._typ == 379 /* v.ast.SelectorExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__SelectorExpr).expr) })); } else if ((*node._v__ast__Expr)._typ == 375 /* v.ast.PostfixExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__PostfixExpr).expr) })); } else if ((*node._v__ast__Expr)._typ == 388 /* v.ast.UnsafeExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__UnsafeExpr).expr) })); } else if ((*node._v__ast__Expr)._typ == 339 /* v.ast.AsCast */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__AsCast).expr) })); } else if ((*node._v__ast__Expr)._typ == 374 /* v.ast.ParExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__ParExpr).expr) })); } else if ((*node._v__ast__Expr)._typ == 360 /* v.ast.IfGuardExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__IfGuardExpr).expr) })); } else if ((*node._v__ast__Expr)._typ == 380 /* v.ast.SizeOf */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__SizeOf).expr) })); } else if ((*node._v__ast__Expr)._typ == 366 /* v.ast.Likely */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__Likely).expr) })); } else if ((*node._v__ast__Expr)._typ == 387 /* v.ast.TypeOf */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__TypeOf).expr) })); } else if ((*node._v__ast__Expr)._typ == 337 /* v.ast.ArrayDecompose */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__ArrayDecompose).expr) })); } else if ((*node._v__ast__Expr)._typ == 365 /* v.ast.LambdaExpr */) { for (int _t23 = 0; _t23 < (*(*node._v__ast__Expr)._v__ast__LambdaExpr).params.len; ++_t23) { v__ast__Ident p = ((v__ast__Ident*)(*(*node._v__ast__Expr)._v__ast__LambdaExpr).params.data)[_t23]; array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(ADDR(v__ast__Expr, (v__ast__Ident_to_sumtype_v__ast__Expr(&p)))) })); } array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__LambdaExpr).expr) })); } else if ((*node._v__ast__Expr)._typ == 367 /* v.ast.LockExpr */) { Array_v__ast__Node _t27 = {0}; Array_v__ast__Stmt _t27_orig = (*(*node._v__ast__Expr)._v__ast__LockExpr).stmts; int _t27_len = _t27_orig.len; _t27 = __new_array(0, _t27_len, sizeof(v__ast__Node)); for (int _t29 = 0; _t29 < _t27_len; ++_t29) { v__ast__Stmt it = ((v__ast__Stmt*) _t27_orig.data)[_t29]; v__ast__Node _t28 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t27, &_t28); } return _t27; } else if ((*node._v__ast__Expr)._typ == 373 /* v.ast.OrExpr */) { Array_v__ast__Node _t31 = {0}; Array_v__ast__Stmt _t31_orig = (*(*node._v__ast__Expr)._v__ast__OrExpr).stmts; int _t31_len = _t31_orig.len; _t31 = __new_array(0, _t31_len, sizeof(v__ast__Node)); for (int _t33 = 0; _t33 < _t31_len; ++_t33) { v__ast__Stmt it = ((v__ast__Stmt*) _t31_orig.data)[_t33]; v__ast__Node _t32 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t31, &_t32); } return _t31; } else if ((*node._v__ast__Expr)._typ == 385 /* v.ast.StructInit */) { Array_v__ast__Node _t35 = {0}; Array_v__ast__StructInitField _t35_orig = (*(*node._v__ast__Expr)._v__ast__StructInit).init_fields; int _t35_len = _t35_orig.len; _t35 = __new_array(0, _t35_len, sizeof(v__ast__Node)); for (int _t37 = 0; _t37 < _t35_len; ++_t37) { v__ast__StructInitField it = ((v__ast__StructInitField*) _t35_orig.data)[_t37]; v__ast__Node _t36 = v__ast__StructInitField_to_sumtype_v__ast__Node(&it); array_push((array*)&_t35, &_t36); } return _t35; } else if ((*node._v__ast__Expr)._typ == 336 /* v.ast.AnonFn */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Stmt_to_sumtype_v__ast__Node(ADDR(v__ast__Stmt, (v__ast__FnDecl_to_sumtype_v__ast__Stmt(&(*(*node._v__ast__Expr)._v__ast__AnonFn).decl)))) })); } else if ((*node._v__ast__Expr)._typ == 344 /* v.ast.CallExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__CallExpr).left) })); Array_v__ast__Node _t41 = {0}; Array_v__ast__CallArg _t41_orig = (*(*node._v__ast__Expr)._v__ast__CallExpr).args; int _t41_len = _t41_orig.len; _t41 = __new_array(0, _t41_len, sizeof(v__ast__Node)); for (int _t43 = 0; _t43 < _t41_len; ++_t43) { v__ast__CallArg it = ((v__ast__CallArg*) _t41_orig.data)[_t43]; v__ast__Node _t42 = v__ast__CallArg_to_sumtype_v__ast__Node(&it); array_push((array*)&_t41, &_t42); } _PUSH_MANY(&children, (_t41), _t40, Array_v__ast__Node); array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(ADDR(v__ast__Expr, (v__ast__OrExpr_to_sumtype_v__ast__Expr(&(*(*node._v__ast__Expr)._v__ast__CallExpr).or_block)))) })); } else if ((*node._v__ast__Expr)._typ == 362 /* v.ast.InfixExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__InfixExpr).left) })); array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__InfixExpr).right) })); } else if ((*node._v__ast__Expr)._typ == 376 /* v.ast.PrefixExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__PrefixExpr).right) })); } else if ((*node._v__ast__Expr)._typ == 361 /* v.ast.IndexExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__IndexExpr).left) })); array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__IndexExpr).index) })); } else if ((*node._v__ast__Expr)._typ == 359 /* v.ast.IfExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__IfExpr).left) })); Array_v__ast__Node _t52 = {0}; Array_v__ast__IfBranch _t52_orig = (*(*node._v__ast__Expr)._v__ast__IfExpr).branches; int _t52_len = _t52_orig.len; _t52 = __new_array(0, _t52_len, sizeof(v__ast__Node)); for (int _t54 = 0; _t54 < _t52_len; ++_t54) { v__ast__IfBranch it = ((v__ast__IfBranch*) _t52_orig.data)[_t54]; v__ast__Node _t53 = v__ast__IfBranch_to_sumtype_v__ast__Node(&it); array_push((array*)&_t52, &_t53); } _PUSH_MANY(&children, (_t52), _t51, Array_v__ast__Node); } else if ((*node._v__ast__Expr)._typ == 369 /* v.ast.MatchExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__MatchExpr).cond) })); Array_v__ast__Node _t57 = {0}; Array_v__ast__MatchBranch _t57_orig = (*(*node._v__ast__Expr)._v__ast__MatchExpr).branches; int _t57_len = _t57_orig.len; _t57 = __new_array(0, _t57_len, sizeof(v__ast__Node)); for (int _t59 = 0; _t59 < _t57_len; ++_t59) { v__ast__MatchBranch it = ((v__ast__MatchBranch*) _t57_orig.data)[_t59]; v__ast__Node _t58 = v__ast__MatchBranch_to_sumtype_v__ast__Node(&it); array_push((array*)&_t57, &_t58); } _PUSH_MANY(&children, (_t57), _t56, Array_v__ast__Node); } else if ((*node._v__ast__Expr)._typ == 378 /* v.ast.SelectExpr */) { Array_v__ast__Node _t61 = {0}; Array_v__ast__SelectBranch _t61_orig = (*(*node._v__ast__Expr)._v__ast__SelectExpr).branches; int _t61_len = _t61_orig.len; _t61 = __new_array(0, _t61_len, sizeof(v__ast__Node)); for (int _t63 = 0; _t63 < _t61_len; ++_t63) { v__ast__SelectBranch it = ((v__ast__SelectBranch*) _t61_orig.data)[_t63]; v__ast__Node _t62 = v__ast__SelectBranch_to_sumtype_v__ast__Node(&it); array_push((array*)&_t61, &_t62); } return _t61; } else if ((*node._v__ast__Expr)._typ == 346 /* v.ast.ChanInit */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__ChanInit).cap_expr) })); } else if ((*node._v__ast__Expr)._typ == 368 /* v.ast.MapInit */) { Array_v__ast__Node _t66 = {0}; Array_v__ast__Expr _t66_orig = (*(*node._v__ast__Expr)._v__ast__MapInit).keys; int _t66_len = _t66_orig.len; _t66 = __new_array(0, _t66_len, sizeof(v__ast__Node)); for (int _t68 = 0; _t68 < _t66_len; ++_t68) { v__ast__Expr it = ((v__ast__Expr*) _t66_orig.data)[_t68]; v__ast__Node _t67 = v__ast__Expr_to_sumtype_v__ast__Node(&it); array_push((array*)&_t66, &_t67); } _PUSH_MANY(&children, (_t66), _t65, Array_v__ast__Node); Array_v__ast__Node _t70 = {0}; Array_v__ast__Expr _t70_orig = (*(*node._v__ast__Expr)._v__ast__MapInit).vals; int _t70_len = _t70_orig.len; _t70 = __new_array(0, _t70_len, sizeof(v__ast__Node)); for (int _t72 = 0; _t72 < _t70_len; ++_t72) { v__ast__Expr it = ((v__ast__Expr*) _t70_orig.data)[_t72]; v__ast__Node _t71 = v__ast__Expr_to_sumtype_v__ast__Node(&it); array_push((array*)&_t70, &_t71); } _PUSH_MANY(&children, (_t70), _t69, Array_v__ast__Node); } else if ((*node._v__ast__Expr)._typ == 377 /* v.ast.RangeExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__RangeExpr).low) })); array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__RangeExpr).high) })); } else if ((*node._v__ast__Expr)._typ == 345 /* v.ast.CastExpr */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__CastExpr).expr) })); array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__CastExpr).arg) })); } else if ((*node._v__ast__Expr)._typ == 352 /* v.ast.ConcatExpr */) { Array_v__ast__Node _t78 = {0}; Array_v__ast__Expr _t78_orig = (*(*node._v__ast__Expr)._v__ast__ConcatExpr).vals; int _t78_len = _t78_orig.len; _t78 = __new_array(0, _t78_len, sizeof(v__ast__Node)); for (int _t80 = 0; _t80 < _t78_len; ++_t80) { v__ast__Expr it = ((v__ast__Expr*) _t78_orig.data)[_t80]; v__ast__Node _t79 = v__ast__Expr_to_sumtype_v__ast__Node(&it); array_push((array*)&_t78, &_t79); } return _t78; } else if ((*node._v__ast__Expr)._typ == 349 /* v.ast.ComptimeCall */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__ComptimeCall).left) })); } else if ((*node._v__ast__Expr)._typ == 350 /* v.ast.ComptimeSelector */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Expr)._v__ast__ComptimeSelector).left) })); } else { } } else if ((node)._typ == 416 /* v.ast.Stmt */) { if ((*node._v__ast__Stmt)._typ == 393 /* v.ast.Block */) { Array_v__ast__Node _t84 = {0}; Array_v__ast__Stmt _t84_orig = (*(*node._v__ast__Stmt)._v__ast__Block).stmts; int _t84_len = _t84_orig.len; _t84 = __new_array(0, _t84_len, sizeof(v__ast__Node)); for (int _t86 = 0; _t86 < _t84_len; ++_t86) { v__ast__Stmt it = ((v__ast__Stmt*) _t84_orig.data)[_t86]; v__ast__Node _t85 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t84, &_t85); } return _t84; } else if ((*node._v__ast__Stmt)._typ == 398 /* v.ast.DeferStmt */) { Array_v__ast__Node _t88 = {0}; Array_v__ast__Stmt _t88_orig = (*(*node._v__ast__Stmt)._v__ast__DeferStmt).stmts; int _t88_len = _t88_orig.len; _t88 = __new_array(0, _t88_len, sizeof(v__ast__Node)); for (int _t90 = 0; _t90 < _t88_len; ++_t90) { v__ast__Stmt it = ((v__ast__Stmt*) _t88_orig.data)[_t90]; v__ast__Node _t89 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t88, &_t89); } return _t88; } else if ((*node._v__ast__Stmt)._typ == 402 /* v.ast.ForCStmt */) { Array_v__ast__Node _t92 = {0}; Array_v__ast__Stmt _t92_orig = (*(*node._v__ast__Stmt)._v__ast__ForCStmt).stmts; int _t92_len = _t92_orig.len; _t92 = __new_array(0, _t92_len, sizeof(v__ast__Node)); for (int _t94 = 0; _t94 < _t92_len; ++_t94) { v__ast__Stmt it = ((v__ast__Stmt*) _t92_orig.data)[_t94]; v__ast__Node _t93 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t92, &_t93); } return _t92; } else if ((*node._v__ast__Stmt)._typ == 403 /* v.ast.ForInStmt */) { Array_v__ast__Node _t96 = {0}; Array_v__ast__Stmt _t96_orig = (*(*node._v__ast__Stmt)._v__ast__ForInStmt).stmts; int _t96_len = _t96_orig.len; _t96 = __new_array(0, _t96_len, sizeof(v__ast__Node)); for (int _t98 = 0; _t98 < _t96_len; ++_t98) { v__ast__Stmt it = ((v__ast__Stmt*) _t96_orig.data)[_t98]; v__ast__Node _t97 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t96, &_t97); } return _t96; } else if ((*node._v__ast__Stmt)._typ == 404 /* v.ast.ForStmt */) { Array_v__ast__Node _t100 = {0}; Array_v__ast__Stmt _t100_orig = (*(*node._v__ast__Stmt)._v__ast__ForStmt).stmts; int _t100_len = _t100_orig.len; _t100 = __new_array(0, _t100_len, sizeof(v__ast__Node)); for (int _t102 = 0; _t102 < _t100_len; ++_t102) { v__ast__Stmt it = ((v__ast__Stmt*) _t100_orig.data)[_t102]; v__ast__Node _t101 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t100, &_t101); } return _t100; } else if ((*node._v__ast__Stmt)._typ == 395 /* v.ast.ComptimeFor */) { Array_v__ast__Node _t104 = {0}; Array_v__ast__Stmt _t104_orig = (*(*node._v__ast__Stmt)._v__ast__ComptimeFor).stmts; int _t104_len = _t104_orig.len; _t104 = __new_array(0, _t104_len, sizeof(v__ast__Node)); for (int _t106 = 0; _t106 < _t104_len; ++_t106) { v__ast__Stmt it = ((v__ast__Stmt*) _t104_orig.data)[_t106]; v__ast__Node _t105 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t104, &_t105); } return _t104; } else if ((*node._v__ast__Stmt)._typ == 401 /* v.ast.ExprStmt */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Stmt)._v__ast__ExprStmt).expr) })); } else if ((*node._v__ast__Stmt)._typ == 391 /* v.ast.AssertStmt */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__Stmt)._v__ast__AssertStmt).expr) })); } else if ((*node._v__ast__Stmt)._typ == 410 /* v.ast.InterfaceDecl */) { Array_v__ast__Node _t110 = {0}; Array_v__ast__FnDecl _t110_orig = (*(*node._v__ast__Stmt)._v__ast__InterfaceDecl).methods; int _t110_len = _t110_orig.len; _t110 = __new_array(0, _t110_len, sizeof(v__ast__Node)); for (int _t112 = 0; _t112 < _t110_len; ++_t112) { v__ast__FnDecl it = ((v__ast__FnDecl*) _t110_orig.data)[_t112]; v__ast__Node _t111 = v__ast__Stmt_to_sumtype_v__ast__Node(ADDR(v__ast__Stmt, (v__ast__FnDecl_to_sumtype_v__ast__Stmt(&it)))); array_push((array*)&_t110, &_t111); } _PUSH_MANY(&children, (_t110), _t109, Array_v__ast__Node); Array_v__ast__Node _t114 = {0}; Array_v__ast__StructField _t114_orig = (*(*node._v__ast__Stmt)._v__ast__InterfaceDecl).fields; int _t114_len = _t114_orig.len; _t114 = __new_array(0, _t114_len, sizeof(v__ast__Node)); for (int _t116 = 0; _t116 < _t114_len; ++_t116) { v__ast__StructField it = ((v__ast__StructField*) _t114_orig.data)[_t116]; v__ast__Node _t115 = v__ast__StructField_to_sumtype_v__ast__Node(&it); array_push((array*)&_t114, &_t115); } _PUSH_MANY(&children, (_t114), _t113, Array_v__ast__Node); } else if ((*node._v__ast__Stmt)._typ == 392 /* v.ast.AssignStmt */) { Array_v__ast__Node _t118 = {0}; Array_v__ast__Expr _t118_orig = (*(*node._v__ast__Stmt)._v__ast__AssignStmt).left; int _t118_len = _t118_orig.len; _t118 = __new_array(0, _t118_len, sizeof(v__ast__Node)); for (int _t120 = 0; _t120 < _t118_len; ++_t120) { v__ast__Expr it = ((v__ast__Expr*) _t118_orig.data)[_t120]; v__ast__Node _t119 = v__ast__Expr_to_sumtype_v__ast__Node(&it); array_push((array*)&_t118, &_t119); } _PUSH_MANY(&children, (_t118), _t117, Array_v__ast__Node); Array_v__ast__Node _t122 = {0}; Array_v__ast__Expr _t122_orig = (*(*node._v__ast__Stmt)._v__ast__AssignStmt).right; int _t122_len = _t122_orig.len; _t122 = __new_array(0, _t122_len, sizeof(v__ast__Node)); for (int _t124 = 0; _t124 < _t122_len; ++_t124) { v__ast__Expr it = ((v__ast__Expr*) _t122_orig.data)[_t124]; v__ast__Node _t123 = v__ast__Expr_to_sumtype_v__ast__Node(&it); array_push((array*)&_t122, &_t123); } _PUSH_MANY(&children, (_t122), _t121, Array_v__ast__Node); } else if ((*node._v__ast__Stmt)._typ == 412 /* v.ast.Return */) { Array_v__ast__Node _t126 = {0}; Array_v__ast__Expr _t126_orig = (*(*node._v__ast__Stmt)._v__ast__Return).exprs; int _t126_len = _t126_orig.len; _t126 = __new_array(0, _t126_len, sizeof(v__ast__Node)); for (int _t128 = 0; _t128 < _t126_len; ++_t128) { v__ast__Expr it = ((v__ast__Expr*) _t126_orig.data)[_t128]; v__ast__Node _t127 = v__ast__Expr_to_sumtype_v__ast__Node(&it); array_push((array*)&_t126, &_t127); } return _t126; } else if ((*node._v__ast__Stmt)._typ == 415 /* v.ast.StructDecl */) { Array_v__ast__Node _t130 = {0}; Array_v__ast__StructField _t130_orig = (*(*node._v__ast__Stmt)._v__ast__StructDecl).fields; int _t130_len = _t130_orig.len; _t130 = __new_array(0, _t130_len, sizeof(v__ast__Node)); for (int _t132 = 0; _t132 < _t130_len; ++_t132) { v__ast__StructField it = ((v__ast__StructField*) _t130_orig.data)[_t132]; v__ast__Node _t131 = v__ast__StructField_to_sumtype_v__ast__Node(&it); array_push((array*)&_t130, &_t131); } return _t130; } else if ((*node._v__ast__Stmt)._typ == 405 /* v.ast.GlobalDecl */) { Array_v__ast__Node _t134 = {0}; Array_v__ast__GlobalField _t134_orig = (*(*node._v__ast__Stmt)._v__ast__GlobalDecl).fields; int _t134_len = _t134_orig.len; _t134 = __new_array(0, _t134_len, sizeof(v__ast__Node)); for (int _t136 = 0; _t136 < _t134_len; ++_t136) { v__ast__GlobalField it = ((v__ast__GlobalField*) _t134_orig.data)[_t136]; v__ast__Node _t135 = v__ast__GlobalField_to_sumtype_v__ast__Node(&it); array_push((array*)&_t134, &_t135); } return _t134; } else if ((*node._v__ast__Stmt)._typ == 396 /* v.ast.ConstDecl */) { Array_v__ast__Node _t138 = {0}; Array_v__ast__ConstField _t138_orig = (*(*node._v__ast__Stmt)._v__ast__ConstDecl).fields; int _t138_len = _t138_orig.len; _t138 = __new_array(0, _t138_len, sizeof(v__ast__Node)); for (int _t140 = 0; _t140 < _t138_len; ++_t140) { v__ast__ConstField it = ((v__ast__ConstField*) _t138_orig.data)[_t140]; v__ast__Node _t139 = v__ast__ConstField_to_sumtype_v__ast__Node(&it); array_push((array*)&_t138, &_t139); } return _t138; } else if ((*node._v__ast__Stmt)._typ == 400 /* v.ast.EnumDecl */) { Array_v__ast__Node _t142 = {0}; Array_v__ast__EnumField _t142_orig = (*(*node._v__ast__Stmt)._v__ast__EnumDecl).fields; int _t142_len = _t142_orig.len; _t142 = __new_array(0, _t142_len, sizeof(v__ast__Node)); for (int _t144 = 0; _t144 < _t142_len; ++_t144) { v__ast__EnumField it = ((v__ast__EnumField*) _t142_orig.data)[_t144]; v__ast__Node _t143 = v__ast__EnumField_to_sumtype_v__ast__Node(&it); array_push((array*)&_t142, &_t143); } return _t142; } else if ((*node._v__ast__Stmt)._typ == 237 /* v.ast.FnDecl */) { if ((*(*node._v__ast__Stmt)._v__ast__FnDecl).is_method) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__StructField_to_sumtype_v__ast__Node(&(*(*node._v__ast__Stmt)._v__ast__FnDecl).receiver) })); } Array_v__ast__Node _t147 = {0}; Array_v__ast__Param _t147_orig = (*(*node._v__ast__Stmt)._v__ast__FnDecl).params; int _t147_len = _t147_orig.len; _t147 = __new_array(0, _t147_len, sizeof(v__ast__Node)); for (int _t149 = 0; _t149 < _t147_len; ++_t149) { v__ast__Param it = ((v__ast__Param*) _t147_orig.data)[_t149]; v__ast__Node _t148 = v__ast__Param_to_sumtype_v__ast__Node(&it); array_push((array*)&_t147, &_t148); } _PUSH_MANY(&children, (_t147), _t146, Array_v__ast__Node); Array_v__ast__Node _t151 = {0}; Array_v__ast__Stmt _t151_orig = (*(*node._v__ast__Stmt)._v__ast__FnDecl).stmts; int _t151_len = _t151_orig.len; _t151 = __new_array(0, _t151_len, sizeof(v__ast__Node)); for (int _t153 = 0; _t153 < _t151_len; ++_t153) { v__ast__Stmt it = ((v__ast__Stmt*) _t151_orig.data)[_t153]; v__ast__Node _t152 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t151, &_t152); } _PUSH_MANY(&children, (_t151), _t150, Array_v__ast__Node); } else if ((*node._v__ast__Stmt)._typ == 334 /* v.ast.TypeDecl */) { if (((*(*node._v__ast__Stmt)._v__ast__TypeDecl))._typ == 333 /* v.ast.SumTypeDecl */) { Array_v__ast__Node _t155 = {0}; Array_v__ast__TypeNode _t155_orig = (*(*(*node._v__ast__Stmt)._v__ast__TypeDecl)._v__ast__SumTypeDecl).variants; int _t155_len = _t155_orig.len; _t155 = __new_array(0, _t155_len, sizeof(v__ast__Node)); for (int _t157 = 0; _t157 < _t155_len; ++_t157) { v__ast__TypeNode it = ((v__ast__TypeNode*) _t155_orig.data)[_t157]; v__ast__Node _t156 = v__ast__Expr_to_sumtype_v__ast__Node(ADDR(v__ast__Expr, (v__ast__TypeNode_to_sumtype_v__ast__Expr(&it)))); array_push((array*)&_t155, &_t156); } _PUSH_MANY(&children, (_t155), _t154, Array_v__ast__Node); } } else { } } else if ((node)._typ == 423 /* v.ast.ScopeObject */) { if ((*node._v__ast__ScopeObject)._typ == 421 /* v.ast.GlobalField */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__ScopeObject)._v__ast__GlobalField).expr) })); } else if ((*node._v__ast__ScopeObject)._typ == 420 /* v.ast.ConstField */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__ScopeObject)._v__ast__ConstField).expr) })); } else if ((*node._v__ast__ScopeObject)._typ == 422 /* v.ast.Var */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*(*node._v__ast__ScopeObject)._v__ast__Var).expr) })); } else if ((*node._v__ast__ScopeObject)._typ == 419 /* v.ast.AsmRegister */) { } else if ((*node._v__ast__ScopeObject)._typ == 418 /* v.ast.EmptyScopeObject */) { } } else { if (node._typ == 421 /* v.ast.GlobalField */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*node._v__ast__GlobalField).expr) })); } else if (node._typ == 420 /* v.ast.ConstField */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*node._v__ast__ConstField).expr) })); } else if (node._typ == 426 /* v.ast.EnumField */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*node._v__ast__EnumField).expr) })); } else if (node._typ == 432 /* v.ast.StructInitField */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*node._v__ast__StructInitField).expr) })); } else if (node._typ == 424 /* v.ast.CallArg */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Expr_to_sumtype_v__ast__Node(&(*node._v__ast__CallArg).expr) })); } else if (node._typ == 430 /* v.ast.SelectBranch */) { array_push((array*)&children, _MOV((v__ast__Node[]){ v__ast__Stmt_to_sumtype_v__ast__Node(&(*node._v__ast__SelectBranch).stmt) })); Array_v__ast__Node _t168 = {0}; Array_v__ast__Stmt _t168_orig = (*node._v__ast__SelectBranch).stmts; int _t168_len = _t168_orig.len; _t168 = __new_array(0, _t168_len, sizeof(v__ast__Node)); for (int _t170 = 0; _t170 < _t168_len; ++_t170) { v__ast__Stmt it = ((v__ast__Stmt*) _t168_orig.data)[_t170]; v__ast__Node _t169 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t168, &_t169); } _PUSH_MANY(&children, (_t168), _t167, Array_v__ast__Node); } else if (node._typ == 427 /* v.ast.IfBranch */) { Array_v__ast__Node _t172 = {0}; Array_v__ast__Stmt _t172_orig = (*node._v__ast__IfBranch).stmts; int _t172_len = _t172_orig.len; _t172 = __new_array(0, _t172_len, sizeof(v__ast__Node)); for (int _t174 = 0; _t174 < _t172_len; ++_t174) { v__ast__Stmt it = ((v__ast__Stmt*) _t172_orig.data)[_t174]; v__ast__Node _t173 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t172, &_t173); } return _t172; } else if (node._typ == 228 /* v.ast.File */) { Array_v__ast__Node _t176 = {0}; Array_v__ast__Stmt _t176_orig = (*node._v__ast__File).stmts; int _t176_len = _t176_orig.len; _t176 = __new_array(0, _t176_len, sizeof(v__ast__Node)); for (int _t178 = 0; _t178 < _t176_len; ++_t178) { v__ast__Stmt it = ((v__ast__Stmt*) _t176_orig.data)[_t178]; v__ast__Node _t177 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t176, &_t177); } return _t176; } else if (node._typ == 428 /* v.ast.MatchBranch */) { Array_v__ast__Node _t180 = {0}; Array_v__ast__Stmt _t180_orig = (*node._v__ast__MatchBranch).stmts; int _t180_len = _t180_orig.len; _t180 = __new_array(0, _t180_len, sizeof(v__ast__Node)); for (int _t182 = 0; _t182 < _t180_len; ++_t182) { v__ast__Stmt it = ((v__ast__Stmt*) _t180_orig.data)[_t182]; v__ast__Node _t181 = v__ast__Stmt_to_sumtype_v__ast__Node(&it); array_push((array*)&_t180, &_t181); } _PUSH_MANY(&children, (_t180), _t179, Array_v__ast__Node); Array_v__ast__Node _t184 = {0}; Array_v__ast__Expr _t184_orig = (*node._v__ast__MatchBranch).exprs; int _t184_len = _t184_orig.len; _t184 = __new_array(0, _t184_len, sizeof(v__ast__Node)); for (int _t186 = 0; _t186 < _t184_len; ++_t186) { v__ast__Expr it = ((v__ast__Expr*) _t184_orig.data)[_t186]; v__ast__Node _t185 = v__ast__Expr_to_sumtype_v__ast__Node(&it); array_push((array*)&_t184, &_t185); } _PUSH_MANY(&children, (_t184), _t183, Array_v__ast__Node); } else { } } return children; } void v__ast__IndexExpr_recursive_mapset_is_setter(v__ast__IndexExpr* lx, bool val) { lx->is_setter = val; if ((lx->left)._typ == 361 /* v.ast.IndexExpr */ && (*(v__ast__IndexExpr*)__as_cast((lx->left)._v__ast__IndexExpr,(lx->left)._typ, 361)).is_map) { v__ast__IndexExpr_recursive_mapset_is_setter(&(*lx->left._v__ast__IndexExpr), val); } } void v__ast__IndexExpr_recursive_arraymap_set_is_setter(v__ast__IndexExpr* lx) { lx->is_setter = true; if ((lx->left)._typ == 361 /* v.ast.IndexExpr */) { v__ast__IndexExpr_recursive_arraymap_set_is_setter(&(*lx->left._v__ast__IndexExpr)); } else if ((lx->left)._typ == 379 /* v.ast.SelectorExpr */ && ((*(v__ast__SelectorExpr*)__as_cast((lx->left)._v__ast__SelectorExpr,(lx->left)._typ, 379)).expr)._typ == 361 /* v.ast.IndexExpr */) { v__ast__IndexExpr_recursive_arraymap_set_is_setter(&(*(*lx->left._v__ast__SelectorExpr).expr._v__ast__IndexExpr)); } } Map_string_v__ast__ScopeObject v__ast__all_registers(v__ast__Table* t, v__pref__Arch arch) { Map_string_v__ast__ScopeObject res = new_map(sizeof(string), sizeof(v__ast__ScopeObject), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; switch (arch) { case v__pref__Arch___auto: { return v__ast__all_registers(t, v__pref__Arch__amd64); } case v__pref__Arch__amd64: case v__pref__Arch__i386: { int _t3 = _const_v__ast__x86_no_number_register_list.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _const_v__ast__x86_no_number_register_list.key_values.len - _t3; _t3 = _const_v__ast__x86_no_number_register_list.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_const_v__ast__x86_no_number_register_list.key_values, _t2)) {continue;} int bit_size = *(int*)DenseArray_key(&_const_v__ast__x86_no_number_register_list.key_values, _t2); Array_string __v_array = (*(Array_string*)DenseArray_value(&_const_v__ast__x86_no_number_register_list.key_values, _t2)); for (int _t5 = 0; _t5 < __v_array.len; ++_t5) { string name = ((string*)__v_array.data)[_t5]; map_set(&res, &(string[]){name}, &(v__ast__ScopeObject[]) { v__ast__AsmRegister_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__AsmRegister, (((v__ast__AsmRegister){.name = name,.typ = v__ast__Table_bitsize_to_type(t, bit_size),.size = bit_size,})))) }); } } int _t7 = _const_v__ast__x86_with_number_register_list.key_values.len; for (int _t6 = 0; _t6 < _t7; ++_t6 ) { int _t8 = _const_v__ast__x86_with_number_register_list.key_values.len - _t7; _t7 = _const_v__ast__x86_with_number_register_list.key_values.len; if (_t8 < 0) { _t6 = -1; continue; } if (!DenseArray_has_index(&_const_v__ast__x86_with_number_register_list.key_values, _t6)) {continue;} int bit_size = *(int*)DenseArray_key(&_const_v__ast__x86_with_number_register_list.key_values, _t6); Map_string_int __v_array = (*(Map_string_int*)DenseArray_value(&_const_v__ast__x86_with_number_register_list.key_values, _t6)); int _t10 = __v_array.key_values.len; for (int _t9 = 0; _t9 < _t10; ++_t9 ) { int _t11 = __v_array.key_values.len - _t10; _t10 = __v_array.key_values.len; if (_t11 < 0) { _t9 = -1; continue; } if (!DenseArray_has_index(&__v_array.key_values, _t9)) {continue;} string name = *(string*)DenseArray_key(&__v_array.key_values, _t9); name = string_clone(name); int max_num = (*(int*)DenseArray_value(&__v_array.key_values, _t9)); for (int i = 0; i < max_num; ++i) { _option_int _t12 = string_index(name, _S("#")); if (_t12.state != 0) { IError err = _t12.err; _v_panic(_S("all_registers: no hashtag found")); VUNREACHABLE(); ; } int hash_index = (*(int*)_t12.data); string assembled_name = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = string_substr(name, 0, hash_index)}}, {_SLIT0, 0xfe07, {.d_i32 = i}}, {_SLIT0, 0xfe10, {.d_s = string_substr(name, (int)(hash_index + 1), 2147483647)}}, {_SLIT0, 0, { .d_c = 0 }}})); map_set(&res, &(string[]){assembled_name}, &(v__ast__ScopeObject[]) { v__ast__AsmRegister_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__AsmRegister, (((v__ast__AsmRegister){.name = assembled_name,.typ = v__ast__Table_bitsize_to_type(t, bit_size),.size = bit_size,})))) }); } } } break; } case v__pref__Arch__arm32: { Map_string_v__ast__ScopeObject arm32 = v__ast__gen_all_registers(t, _const_v__ast__arm_no_number_register_list, _const_v__ast__arm_with_number_register_list, 32); int _t14 = arm32.key_values.len; for (int _t13 = 0; _t13 < _t14; ++_t13 ) { int _t15 = arm32.key_values.len - _t14; _t14 = arm32.key_values.len; if (_t15 < 0) { _t13 = -1; continue; } if (!DenseArray_has_index(&arm32.key_values, _t13)) {continue;} string k = *(string*)DenseArray_key(&arm32.key_values, _t13); k = string_clone(k); v__ast__ScopeObject v = (*(v__ast__ScopeObject*)DenseArray_value(&arm32.key_values, _t13)); map_set(&res, &(string[]){k}, &(v__ast__ScopeObject[]) { v }); } break; } case v__pref__Arch__arm64: { Map_string_v__ast__ScopeObject arm64 = v__ast__gen_all_registers(t, _const_v__ast__arm_no_number_register_list, _const_v__ast__arm_with_number_register_list, 64); int _t17 = arm64.key_values.len; for (int _t16 = 0; _t16 < _t17; ++_t16 ) { int _t18 = arm64.key_values.len - _t17; _t17 = arm64.key_values.len; if (_t18 < 0) { _t16 = -1; continue; } if (!DenseArray_has_index(&arm64.key_values, _t16)) {continue;} string k = *(string*)DenseArray_key(&arm64.key_values, _t16); k = string_clone(k); v__ast__ScopeObject v = (*(v__ast__ScopeObject*)DenseArray_value(&arm64.key_values, _t16)); map_set(&res, &(string[]){k}, &(v__ast__ScopeObject[]) { v }); } break; } case v__pref__Arch__rv32: { Map_string_v__ast__ScopeObject rv32 = v__ast__gen_all_registers(t, _const_v__ast__riscv_no_number_register_list, _const_v__ast__riscv_with_number_register_list, 32); int _t20 = rv32.key_values.len; for (int _t19 = 0; _t19 < _t20; ++_t19 ) { int _t21 = rv32.key_values.len - _t20; _t20 = rv32.key_values.len; if (_t21 < 0) { _t19 = -1; continue; } if (!DenseArray_has_index(&rv32.key_values, _t19)) {continue;} string k = *(string*)DenseArray_key(&rv32.key_values, _t19); k = string_clone(k); v__ast__ScopeObject v = (*(v__ast__ScopeObject*)DenseArray_value(&rv32.key_values, _t19)); map_set(&res, &(string[]){k}, &(v__ast__ScopeObject[]) { v }); } break; } case v__pref__Arch__rv64: { Map_string_v__ast__ScopeObject rv64 = v__ast__gen_all_registers(t, _const_v__ast__riscv_no_number_register_list, _const_v__ast__riscv_with_number_register_list, 64); int _t23 = rv64.key_values.len; for (int _t22 = 0; _t22 < _t23; ++_t22 ) { int _t24 = rv64.key_values.len - _t23; _t23 = rv64.key_values.len; if (_t24 < 0) { _t22 = -1; continue; } if (!DenseArray_has_index(&rv64.key_values, _t22)) {continue;} string k = *(string*)DenseArray_key(&rv64.key_values, _t22); k = string_clone(k); v__ast__ScopeObject v = (*(v__ast__ScopeObject*)DenseArray_value(&rv64.key_values, _t22)); map_set(&res, &(string[]){k}, &(v__ast__ScopeObject[]) { v }); } break; } case v__pref__Arch__s390x: { Map_string_v__ast__ScopeObject s390x = v__ast__gen_all_registers(t, _const_v__ast__s390x_no_number_register_list, _const_v__ast__s390x_with_number_register_list, 64); int _t26 = s390x.key_values.len; for (int _t25 = 0; _t25 < _t26; ++_t25 ) { int _t27 = s390x.key_values.len - _t26; _t26 = s390x.key_values.len; if (_t27 < 0) { _t25 = -1; continue; } if (!DenseArray_has_index(&s390x.key_values, _t25)) {continue;} string k = *(string*)DenseArray_key(&s390x.key_values, _t25); k = string_clone(k); v__ast__ScopeObject v = (*(v__ast__ScopeObject*)DenseArray_value(&s390x.key_values, _t25)); map_set(&res, &(string[]){k}, &(v__ast__ScopeObject[]) { v }); } break; } case v__pref__Arch__ppc64le: { Map_string_v__ast__ScopeObject ppc64le = v__ast__gen_all_registers(t, _const_v__ast__ppc64le_no_number_register_list, _const_v__ast__ppc64le_with_number_register_list, 64); int _t29 = ppc64le.key_values.len; for (int _t28 = 0; _t28 < _t29; ++_t28 ) { int _t30 = ppc64le.key_values.len - _t29; _t29 = ppc64le.key_values.len; if (_t30 < 0) { _t28 = -1; continue; } if (!DenseArray_has_index(&ppc64le.key_values, _t28)) {continue;} string k = *(string*)DenseArray_key(&ppc64le.key_values, _t28); k = string_clone(k); v__ast__ScopeObject v = (*(v__ast__ScopeObject*)DenseArray_value(&ppc64le.key_values, _t28)); map_set(&res, &(string[]){k}, &(v__ast__ScopeObject[]) { v }); } break; } case v__pref__Arch__loongarch64: { Map_string_v__ast__ScopeObject loongarch64 = v__ast__gen_all_registers(t, _const_v__ast__loongarch64_no_number_register_list, _const_v__ast__loongarch64_with_number_register_list, 64); int _t32 = loongarch64.key_values.len; for (int _t31 = 0; _t31 < _t32; ++_t31 ) { int _t33 = loongarch64.key_values.len - _t32; _t32 = loongarch64.key_values.len; if (_t33 < 0) { _t31 = -1; continue; } if (!DenseArray_has_index(&loongarch64.key_values, _t31)) {continue;} string k = *(string*)DenseArray_key(&loongarch64.key_values, _t31); k = string_clone(k); v__ast__ScopeObject v = (*(v__ast__ScopeObject*)DenseArray_value(&loongarch64.key_values, _t31)); map_set(&res, &(string[]){k}, &(v__ast__ScopeObject[]) { v }); } break; } case v__pref__Arch__wasm32: { break; } case v__pref__Arch__js_node: case v__pref__Arch__js_browser: case v__pref__Arch__js_freestanding: case v__pref__Arch___max: default: { { _v_panic(str_intp(2, _MOV((StrIntpData[]){{_S("all_registers: unhandled arch: "), 0xfe10, {.d_s = v__pref__Arch_str(arch)}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); break; } } } return res; } VV_LOC Map_string_v__ast__ScopeObject v__ast__gen_all_registers(v__ast__Table* t, Array_string without_numbers, Map_string_int with_numbers, int bit_size) { Map_string_v__ast__ScopeObject res = new_map(sizeof(string), sizeof(v__ast__ScopeObject), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int _t1 = 0; _t1 < without_numbers.len; ++_t1) { string name = ((string*)without_numbers.data)[_t1]; map_set(&res, &(string[]){name}, &(v__ast__ScopeObject[]) { v__ast__AsmRegister_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__AsmRegister, (((v__ast__AsmRegister){.name = name,.typ = v__ast__Table_bitsize_to_type(t, bit_size),.size = bit_size,})))) }); } int _t3 = with_numbers.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = with_numbers.key_values.len - _t3; _t3 = with_numbers.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&with_numbers.key_values, _t2)) {continue;} string name = *(string*)DenseArray_key(&with_numbers.key_values, _t2); name = string_clone(name); int max_num = (*(int*)DenseArray_value(&with_numbers.key_values, _t2)); for (int i = 0; i < max_num; ++i) { _option_int _t5 = string_index(name, _S("#")); if (_t5.state != 0) { IError err = _t5.err; _v_panic(_S("all_registers: no hashtag found")); VUNREACHABLE(); ; } int hash_index = (*(int*)_t5.data); string assembled_name = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = string_substr(name, 0, hash_index)}}, {_SLIT0, 0xfe07, {.d_i32 = i}}, {_SLIT0, 0xfe10, {.d_s = string_substr(name, (int)(hash_index + 1), 2147483647)}}, {_SLIT0, 0, { .d_c = 0 }}})); map_set(&res, &(string[]){assembled_name}, &(v__ast__ScopeObject[]) { v__ast__AsmRegister_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__AsmRegister, (((v__ast__AsmRegister){.name = assembled_name,.typ = v__ast__Table_bitsize_to_type(t, bit_size),.size = bit_size,})))) }); } } return res; } bool v__ast__Expr_is_reference(v__ast__Expr expr) { return ((expr._typ == 376 /* v.ast.PrefixExpr */)? ((*expr._v__ast__PrefixExpr).op == v__token__Kind__amp) : (expr._typ == 388 /* v.ast.UnsafeExpr */)? (v__ast__Expr_is_reference((*expr._v__ast__UnsafeExpr).expr)) : (expr._typ == 374 /* v.ast.ParExpr */)? (v__ast__Expr_is_reference((*expr._v__ast__ParExpr).expr)) : (false)); } v__ast__Expr v__ast__Expr_remove_par(v__ast__Expr* expr) { v__ast__Expr e = *expr; for (;;) { if (!((e)._typ == 374 /* v.ast.ParExpr */)) break; e = (*e._v__ast__ParExpr).expr; } return e; } bool v__ast__Expr_is_literal(v__ast__Expr expr) { return ((expr._typ == 342 /* v.ast.BoolLiteral */)? (true) : (expr._typ == 347 /* v.ast.CharLiteral */)? (true) : (expr._typ == 356 /* v.ast.FloatLiteral */)? (true) : (expr._typ == 363 /* v.ast.IntegerLiteral */)? (true) : (expr._typ == 384 /* v.ast.StringLiteral */)? (true) : (expr._typ == 383 /* v.ast.StringInterLiteral */)? (true) : (expr._typ == 376 /* v.ast.PrefixExpr */)? (v__ast__Expr_is_literal((*expr._v__ast__PrefixExpr).right)) : (expr._typ == 362 /* v.ast.InfixExpr */)? (v__ast__Expr_is_literal((*expr._v__ast__InfixExpr).left) && v__ast__Expr_is_literal((*expr._v__ast__InfixExpr).right)) : (expr._typ == 374 /* v.ast.ParExpr */)? (v__ast__Expr_is_literal((*expr._v__ast__ParExpr).expr)) : (expr._typ == 345 /* v.ast.CastExpr */)? (!(*expr._v__ast__CastExpr).has_arg && v__ast__Expr_is_literal((*expr._v__ast__CastExpr).expr) && (v__ast__Type_is_any_kind_of_pointer((*expr._v__ast__CastExpr).typ) || ((*expr._v__ast__CastExpr).typ == _const_v__ast__i8_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__i16_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__int_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__i64_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__u8_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__u16_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__u32_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__u64_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__f32_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__f64_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__char_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__bool_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__rune_type))) : (expr._typ == 380 /* v.ast.SizeOf */)? ((*expr._v__ast__SizeOf).is_type || v__ast__Expr_is_literal((*expr._v__ast__SizeOf).expr)) : (expr._typ == 364 /* v.ast.IsRefType */)? ((*expr._v__ast__IsRefType).is_type || v__ast__Expr_is_literal((*expr._v__ast__IsRefType).expr)) : (false)); } inline bool v__ast__Expr_is_nil(v__ast__Expr e) { return (e)._typ == 370 /* v.ast.Nil */ || ((e)._typ == 388 /* v.ast.UnsafeExpr */ && ((*(v__ast__UnsafeExpr*)__as_cast((e)._v__ast__UnsafeExpr,(e)._typ, 388)).expr)._typ == 370 /* v.ast.Nil */); } bool v__ast__type_can_start_with_token(v__token__Token* tok) { return ((tok->kind == (v__token__Kind__name))? ((tok->lit.len > 0 && u8_is_capital(tok->lit.str[ 0])) || v__token__KeywordsMatcherTrie_matches(&_const_v__ast__builtin_type_names_matcher, tok->lit)) : (tok->kind == (v__token__Kind__amp) || tok->kind == (v__token__Kind__key_fn) || tok->kind == (v__token__Kind__lsbr) || tok->kind == (v__token__Kind__question))? (true) : (false)); } _result_void v__ast__validate_type_string_is_pure_literal(v__ast__Type typ, string str) { if (typ == _const_v__ast__bool_type) { if (!(_SLIT_EQ(str.str, str.len, "true") || _SLIT_EQ(str.str, str.len, "false"))) { return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("bool literal `true` or `false` expected, found \""), 0xfe10, {.d_s = str}}, {_S("\""), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } else if (typ == _const_v__ast__char_type) { if (string_starts_with(str, _S("\\"))) { if (str.len <= 1) { return (_result_void){ .is_error=true, .err=_v_error(_S("empty escape sequence found")), .data={E_STRUCT} }; } if (!v__util__is_escape_sequence(string_at(str, 1))) { return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("char literal escape sequence expected, found \""), 0xfe10, {.d_s = str}}, {_S("\""), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } else if (str.len != 1) { return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("char literal expected, found \""), 0xfe10, {.d_s = str}}, {_S("\""), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } else if (typ == _const_v__ast__f64_type) { if (string_count(str, _S(".")) != 1) { return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("f64 literal expected, found \""), 0xfe10, {.d_s = str}}, {_S("\""), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } else if (typ == _const_v__ast__string_type) { } else if (typ == _const_v__ast__i64_type) { if (!string_is_int(str)) { return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("i64 literal expected, found \""), 0xfe10, {.d_s = str}}, {_S("\""), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } else { return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("expected pure literal, found \""), 0xfe10, {.d_s = str}}, {_S("\""), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } return (_result_void){0}; } string v__ast__Attr_str(v__ast__Attr* a) { string s = _S(""); string _t1; /* if prepend */ if (a->has_arg) { s = string__plus(s, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = a->name}}, {_S(": "), 0, { .d_c = 0 }}}))); _t1 = a->arg; } else { _t1 = a->name; } string arg = _t1; s = string__plus(s, ((a->kind == (v__ast__AttrKind__plain) || a->kind == (v__ast__AttrKind__number) || a->kind == (v__ast__AttrKind__bool))? (arg) : (a->kind == (v__ast__AttrKind__string))? (str_intp(2, _MOV((StrIntpData[]){{_S("'"), 0xfe10, {.d_s = arg}}, {_S("'"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("if "), 0xfe10, {.d_s = arg}}, {_SLIT0, 0, { .d_c = 0 }}}))))); return s; } bool Array_v__ast__Attr_contains(Array_v__ast__Attr attrs, string str) { bool _t2 = false; Array_v__ast__Attr _t2_orig = attrs; int _t2_len = _t2_orig.len; for (int _t3 = 0; _t3 < _t2_len; ++_t3) { v__ast__Attr it = ((v__ast__Attr*) _t2_orig.data)[_t3]; if (string__eq(it.name, str)) { _t2 = true; break; } } return _t2; } bool Array_v__ast__Attr_contains_arg(Array_v__ast__Attr attrs, string str, string arg) { bool _t2 = false; Array_v__ast__Attr _t2_orig = attrs; int _t2_len = _t2_orig.len; for (int _t3 = 0; _t3 < _t2_len; ++_t3) { v__ast__Attr it = ((v__ast__Attr*) _t2_orig.data)[_t3]; if (it.has_arg && string__eq(it.name, str) && string__eq(it.arg, arg)) { _t2 = true; break; } } return _t2; } _option_v__ast__Attr Array_v__ast__Attr_find_first(Array_v__ast__Attr attrs, string aname) { for (int _t1 = 0; _t1 < attrs.len; ++_t1) { v__ast__Attr a = ((v__ast__Attr*)attrs.data)[_t1]; if (string__eq(a.name, aname)) { _option_v__ast__Attr _t2; _option_ok(&(v__ast__Attr[]) { a }, (_option*)(&_t2), sizeof(v__ast__Attr)); return _t2; } } return (_option_v__ast__Attr){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_int Array_v__ast__Attr_find_comptime_define(Array_v__ast__Attr attrs) { for (int idx = 0; idx < attrs.len; ++idx) { if (((v__ast__Attr*)attrs.data)[idx].kind == v__ast__AttrKind__comptime_define) { _option_int _t1; _option_ok(&(int[]) { idx }, (_option*)(&_t1), sizeof(int)); return _t1; } } return (_option_int){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } bool v__ast__Table_has_cflag(v__ast__Table* t, v__cflag__CFlag flag) { for (int _t1 = 0; _t1 < t->cflags.len; ++_t1) { v__cflag__CFlag cf = ((v__cflag__CFlag*)t->cflags.data)[_t1]; if (string__eq(cf.os, flag.os) && string__eq(cf.name, flag.name) && string__eq(cf.value, flag.value)) { return true; } } return false; } _result_void v__ast__Table_parse_cflag(v__ast__Table* t, string cflg, string mod, Array_string ctimedefines) { Array_string allowed_flags = new_array_from_c_array(9, 9, sizeof(string), _MOV((string[9]){ _S("framework"), _S("library"), _S("Wa"), _S("Wl"), _S("Wp"), _S("I"), _S("l"), _S("L"), _S("D")})); string flag_orig = string_trim_space(cflg); string flag = flag_orig; if ((flag).len == 0) { return (_result_void){ .is_error=true, .err=_v_error(_S("flag is empty")), .data={E_STRUCT} }; } string fos = _S(""); Array_string allowed_os_overrides = __new_array_with_default(0, 0, sizeof(string), 0); _PUSH_MANY(&allowed_os_overrides, (_const_v__ast__valid_comptime_not_user_defined), _t2, Array_string); _PUSH_MANY(&allowed_os_overrides, (ctimedefines), _t3, Array_string); for (int _t4 = 0; _t4 < allowed_os_overrides.len; ++_t4) { string os_override = ((string*)allowed_os_overrides.data)[_t4]; if (!string_starts_with(flag, os_override)) { continue; } _option_int _t5 = string_index(flag, _S(" ")); if (_t5.state != 0) { IError err = _t5.err; return (_result_void){ .is_error=true, .err=_v_error(_S("none")), .data={E_STRUCT} }; } int pos = (*(int*)_t5.data); fos = string_trim_space(string_substr(flag, 0, pos)); flag = string_trim_space(string_substr(flag, pos, 2147483647)); } for (;;) { string name = _S(""); string value = _S(""); if (string_at(flag, 0) == '-') { for (int _t7 = 0; _t7 < allowed_flags.len; ++_t7) { string f = ((string*)allowed_flags.data)[_t7]; int i = (int)(1 + f.len); if (i <= flag.len && string__eq(f, string_substr(flag, 1, i))) { name = string_trim_space(string_substr(flag, 0, i)); flag = string_trim_space(string_substr(flag, i, 2147483647)); break; } } } _option_int _t8 = string_index(flag, _S(" -")); if (_t8.state != 0) { IError err = _t8.err; *(int*) _t8.data = -1; } int index = (*(int*)_t8.data); if (index > -1) { value = string_trim_space(string_substr(flag, 0, index)); flag = string_trim_space(string_substr(flag, index, 2147483647)); } else { value = flag; } if ((_SLIT_EQ(name.str, name.len, "-I") || _SLIT_EQ(name.str, name.len, "-l") || _SLIT_EQ(name.str, name.len, "-L")) && (value).len == 0) { string hint = (_SLIT_EQ(name.str, name.len, "-l") ? (_S("library name")) : (_S("path"))); return (_result_void){ .is_error=true, .err=_v_error(str_intp(4, _MOV((StrIntpData[]){{_S("bad #flag `"), 0xfe10, {.d_s = flag_orig}}, {_S("`: missing "), 0xfe10, {.d_s = hint}}, {_S(" after `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } v__cflag__CFlag cf = ((v__cflag__CFlag){.mod = mod,.os = fos,.name = name,.value = value,.cached = (string){.str=(byteptr)"", .is_lit=1},}); if (!v__ast__Table_has_cflag(t, cf)) { array_push((array*)&t->cflags, _MOV((v__cflag__CFlag[]){ cf })); } if (index == -1) { break; } } return (_result_void){0}; } _option_i8 v__ast__ComptTimeConstValue_i8(v__ast__ComptTimeConstValue val) { _option_i64 _t1 = v__ast__ComptTimeConstValue_i64(val); if (_t1.state != 0) { return (_option_i8){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } i64 x = (*(i64*)_t1.data); if (x > -129 && x < 128) { _option_i8 _t2; _option_ok(&(i8[]) { ((i8)(x)) }, (_option*)(&_t2), sizeof(i8)); return _t2; } return (_option_i8){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_i16 v__ast__ComptTimeConstValue_i16(v__ast__ComptTimeConstValue val) { _option_i64 _t1 = v__ast__ComptTimeConstValue_i64(val); if (_t1.state != 0) { return (_option_i16){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } i64 x = (*(i64*)_t1.data); if (x > -32769 && x < 32768) { _option_i16 _t2; _option_ok(&(i16[]) { ((i16)(x)) }, (_option*)(&_t2), sizeof(i16)); return _t2; } return (_option_i16){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_i32 v__ast__ComptTimeConstValue_i32(v__ast__ComptTimeConstValue val) { _option_i64 _t1 = v__ast__ComptTimeConstValue_i64(val); if (_t1.state != 0) { return (_option_i32){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } i64 x = (*(i64*)_t1.data); if (x > -2147483649 && x < 2147483648) { _option_i32 _t2; _option_ok(&(i32[]) { ((i32)(x)) }, (_option*)(&_t2), sizeof(i32)); return _t2; } return (_option_i32){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_voidptr v__ast__ComptTimeConstValue_voidptr(v__ast__ComptTimeConstValue val) { if (val._typ == 5 /* i8 */) { _option_voidptr _t1; _option_ok(&(voidptr[]) { ((voidptr)(((i64)((*val._i8))))) }, (_option*)(&_t1), sizeof(voidptr)); return _t1; } else if (val._typ == 6 /* i16 */) { _option_voidptr _t2; _option_ok(&(voidptr[]) { ((voidptr)(((i64)((*val._i16))))) }, (_option*)(&_t2), sizeof(voidptr)); return _t2; } else if (val._typ == 7 /* i32 */) { _option_voidptr _t3; _option_ok(&(voidptr[]) { ((voidptr)(((i64)((*val._i32))))) }, (_option*)(&_t3), sizeof(voidptr)); return _t3; } else if (val._typ == 9 /* i64 */) { _option_voidptr _t4; _option_ok(&(voidptr[]) { ((voidptr)(((i64)((*val._i64))))) }, (_option*)(&_t4), sizeof(voidptr)); return _t4; } else if (val._typ == 11 /* u8 */) { _option_voidptr _t5; _option_ok(&(voidptr[]) { ((voidptr)(((u64)((*val._u8))))) }, (_option*)(&_t5), sizeof(voidptr)); return _t5; } else if (val._typ == 12 /* u16 */) { _option_voidptr _t6; _option_ok(&(voidptr[]) { ((voidptr)(((u64)((*val._u16))))) }, (_option*)(&_t6), sizeof(voidptr)); return _t6; } else if (val._typ == 13 /* u32 */) { _option_voidptr _t7; _option_ok(&(voidptr[]) { ((voidptr)(((u64)((*val._u32))))) }, (_option*)(&_t7), sizeof(voidptr)); return _t7; } else if (val._typ == 14 /* u64 */) { _option_voidptr _t8; _option_ok(&(voidptr[]) { ((voidptr)(((u64)((*val._u64))))) }, (_option*)(&_t8), sizeof(voidptr)); return _t8; } else if (val._typ == 22 /* rune */) { _option_voidptr _t9; _option_ok(&(voidptr[]) { ((voidptr)(((u64)((*val._rune))))) }, (_option*)(&_t9), sizeof(voidptr)); return _t9; } else if (val._typ == 2 /* voidptr */) { _option_voidptr _t10; _option_ok(&(voidptr[]) { (*val._voidptr) }, (_option*)(&_t10), sizeof(voidptr)); return _t10; } else if (val._typ == 21 /* string */) { } else if (val._typ == 354 /* v.ast.EmptyExpr */) { } else if (val._typ == 16 /* f32 */) { } else if (val._typ == 17 /* f64 */) { } return (_option_voidptr){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_i64 v__ast__ComptTimeConstValue_i64(v__ast__ComptTimeConstValue val) { if (val._typ == 5 /* i8 */) { _option_i64 _t1; _option_ok(&(i64[]) { ((i64)((*val._i8))) }, (_option*)(&_t1), sizeof(i64)); return _t1; } else if (val._typ == 6 /* i16 */) { _option_i64 _t2; _option_ok(&(i64[]) { ((i64)((*val._i16))) }, (_option*)(&_t2), sizeof(i64)); return _t2; } else if (val._typ == 7 /* i32 */) { _option_i64 _t3; _option_ok(&(i64[]) { ((i64)((*val._i32))) }, (_option*)(&_t3), sizeof(i64)); return _t3; } else if (val._typ == 9 /* i64 */) { _option_i64 _t4; _option_ok(&(i64[]) { ((i64)((*val._i64))) }, (_option*)(&_t4), sizeof(i64)); return _t4; } else if (val._typ == 11 /* u8 */) { _option_i64 _t5; _option_ok(&(i64[]) { ((i64)((*val._u8))) }, (_option*)(&_t5), sizeof(i64)); return _t5; } else if (val._typ == 12 /* u16 */) { _option_i64 _t6; _option_ok(&(i64[]) { ((i64)((*val._u16))) }, (_option*)(&_t6), sizeof(i64)); return _t6; } else if (val._typ == 13 /* u32 */) { _option_i64 _t7; _option_ok(&(i64[]) { ((i64)((*val._u32))) }, (_option*)(&_t7), sizeof(i64)); return _t7; } else if (val._typ == 14 /* u64 */) { if ((*val._u64) <= 9223372036854775807U) { _option_i64 _t8; _option_ok(&(i64[]) { ((i64)((*val._u64))) }, (_option*)(&_t8), sizeof(i64)); return _t8; } } else if (val._typ == 16 /* f32 */) { if (((f32)(-9223372036854775808.0)) <= (*val._f32) && (*val._f32) <= ((f32)(9223372036854775807.0))) { _option_i64 _t9; _option_ok(&(i64[]) { ((i64)((*val._f32))) }, (_option*)(&_t9), sizeof(i64)); return _t9; } } else if (val._typ == 17 /* f64 */) { if (((f64)(-9223372036854775808.0)) <= (*val._f64) && (*val._f64) <= ((f64)(9223372036854775807.0))) { _option_i64 _t10; _option_ok(&(i64[]) { ((i64)((*val._f64))) }, (_option*)(&_t10), sizeof(i64)); return _t10; } } else if (val._typ == 21 /* string */) { _option_i64 _t11; _option_ok(&(i64[]) { string_i64((*val._string)) }, (_option*)(&_t11), sizeof(i64)); return _t11; } else if (val._typ == 22 /* rune */) { _option_i64 _t12; _option_ok(&(i64[]) { ((int)((*val._rune))) }, (_option*)(&_t12), sizeof(i64)); return _t12; } else if (val._typ == 2 /* voidptr */) { _option_i64 _t13; _option_ok(&(i64[]) { ((i64)((*val._voidptr))) }, (_option*)(&_t13), sizeof(i64)); return _t13; } else if (val._typ == 354 /* v.ast.EmptyExpr */) { } return (_option_i64){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_u8 v__ast__ComptTimeConstValue_u8(v__ast__ComptTimeConstValue val) { _option_u64 _t1 = v__ast__ComptTimeConstValue_u64(val); if (_t1.state != 0) { return (_option_u8){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } u64 x = (*(u64*)_t1.data); if (x < 256U) { _option_u8 _t2; _option_ok(&(u8[]) { ((u8)(x)) }, (_option*)(&_t2), sizeof(u8)); return _t2; } return (_option_u8){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_u16 v__ast__ComptTimeConstValue_u16(v__ast__ComptTimeConstValue val) { _option_u64 _t1 = v__ast__ComptTimeConstValue_u64(val); if (_t1.state != 0) { return (_option_u16){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } u64 x = (*(u64*)_t1.data); if (x < 65536U) { _option_u16 _t2; _option_ok(&(u16[]) { ((u16)(x)) }, (_option*)(&_t2), sizeof(u16)); return _t2; } return (_option_u16){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_u32 v__ast__ComptTimeConstValue_u32(v__ast__ComptTimeConstValue val) { _option_u64 _t1 = v__ast__ComptTimeConstValue_u64(val); if (_t1.state != 0) { return (_option_u32){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } u64 x = (*(u64*)_t1.data); if (x < 4294967296U) { _option_u32 _t2; _option_ok(&(u32[]) { ((u32)(x)) }, (_option*)(&_t2), sizeof(u32)); return _t2; } return (_option_u32){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_u64 v__ast__ComptTimeConstValue_u64(v__ast__ComptTimeConstValue val) { if (val._typ == 5 /* i8 */) { if ((*val._i8) >= 0) { _option_u64 _t1; _option_ok(&(u64[]) { ((u64)((*val._i8))) }, (_option*)(&_t1), sizeof(u64)); return _t1; } } else if (val._typ == 6 /* i16 */) { if ((*val._i16) >= 0) { _option_u64 _t2; _option_ok(&(u64[]) { ((u64)((*val._i16))) }, (_option*)(&_t2), sizeof(u64)); return _t2; } } else if (val._typ == 7 /* i32 */) { if ((*val._i32) >= 0) { _option_u64 _t3; _option_ok(&(u64[]) { ((u64)((*val._i32))) }, (_option*)(&_t3), sizeof(u64)); return _t3; } } else if (val._typ == 9 /* i64 */) { if ((*val._i64) >= 0) { _option_u64 _t4; _option_ok(&(u64[]) { ((u64)((*val._i64))) }, (_option*)(&_t4), sizeof(u64)); return _t4; } } else if (val._typ == 11 /* u8 */) { _option_u64 _t5; _option_ok(&(u64[]) { ((u64)((*val._u8))) }, (_option*)(&_t5), sizeof(u64)); return _t5; } else if (val._typ == 12 /* u16 */) { _option_u64 _t6; _option_ok(&(u64[]) { ((u64)((*val._u16))) }, (_option*)(&_t6), sizeof(u64)); return _t6; } else if (val._typ == 13 /* u32 */) { _option_u64 _t7; _option_ok(&(u64[]) { ((u64)((*val._u32))) }, (_option*)(&_t7), sizeof(u64)); return _t7; } else if (val._typ == 14 /* u64 */) { _option_u64 _t8; _option_ok(&(u64[]) { (*val._u64) }, (_option*)(&_t8), sizeof(u64)); return _t8; } else if (val._typ == 16 /* f32 */) { if ((*val._f32) <= ((f32)(18446744073709551615.0))) { _option_u64 _t9; _option_ok(&(u64[]) { ((u64)((*val._f32))) }, (_option*)(&_t9), sizeof(u64)); return _t9; } } else if (val._typ == 17 /* f64 */) { if ((*val._f64) <= ((f64)(18446744073709551615.0))) { _option_u64 _t10; _option_ok(&(u64[]) { ((u64)((*val._f64))) }, (_option*)(&_t10), sizeof(u64)); return _t10; } } else if (val._typ == 21 /* string */) { _option_u64 _t11; _option_ok(&(u64[]) { string_u64((*val._string)) }, (_option*)(&_t11), sizeof(u64)); return _t11; } else if (val._typ == 2 /* voidptr */) { _option_u64 _t12; _option_ok(&(u64[]) { ((u64)((*val._voidptr))) }, (_option*)(&_t12), sizeof(u64)); return _t12; } else if (val._typ == 22 /* rune */) { } else if (val._typ == 354 /* v.ast.EmptyExpr */) { } return (_option_u64){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_f32 v__ast__ComptTimeConstValue_f32(v__ast__ComptTimeConstValue val) { _option_f64 _t1 = v__ast__ComptTimeConstValue_f64(val); if (_t1.state != 0) { return (_option_f32){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } f64 x = (*(f64*)_t1.data); _option_f32 _t2; _option_ok(&(f32[]) { ((f32)(x)) }, (_option*)(&_t2), sizeof(f32)); return _t2; } _option_f64 v__ast__ComptTimeConstValue_f64(v__ast__ComptTimeConstValue val) { if (val._typ == 5 /* i8 */) { _option_f64 _t1; _option_ok(&(f64[]) { ((f64)((*val._i8))) }, (_option*)(&_t1), sizeof(f64)); return _t1; } else if (val._typ == 6 /* i16 */) { _option_f64 _t2; _option_ok(&(f64[]) { ((f64)((*val._i16))) }, (_option*)(&_t2), sizeof(f64)); return _t2; } else if (val._typ == 7 /* i32 */) { _option_f64 _t3; _option_ok(&(f64[]) { ((f64)((*val._i32))) }, (_option*)(&_t3), sizeof(f64)); return _t3; } else if (val._typ == 9 /* i64 */) { _option_f64 _t4; _option_ok(&(f64[]) { ((f64)((*val._i64))) }, (_option*)(&_t4), sizeof(f64)); return _t4; } else if (val._typ == 11 /* u8 */) { _option_f64 _t5; _option_ok(&(f64[]) { ((f64)((*val._u8))) }, (_option*)(&_t5), sizeof(f64)); return _t5; } else if (val._typ == 12 /* u16 */) { _option_f64 _t6; _option_ok(&(f64[]) { ((f64)((*val._u16))) }, (_option*)(&_t6), sizeof(f64)); return _t6; } else if (val._typ == 13 /* u32 */) { _option_f64 _t7; _option_ok(&(f64[]) { ((f64)((*val._u32))) }, (_option*)(&_t7), sizeof(f64)); return _t7; } else if (val._typ == 14 /* u64 */) { _option_f64 _t8; _option_ok(&(f64[]) { ((f64)((*val._u64))) }, (_option*)(&_t8), sizeof(f64)); return _t8; } else if (val._typ == 16 /* f32 */) { _option_f64 _t9; _option_ok(&(f64[]) { ((f64)((*val._f32))) }, (_option*)(&_t9), sizeof(f64)); return _t9; } else if (val._typ == 17 /* f64 */) { _option_f64 _t10; _option_ok(&(f64[]) { (*val._f64) }, (_option*)(&_t10), sizeof(f64)); return _t10; } else if (val._typ == 21 /* string */) { _option_f64 _t11; _option_ok(&(f64[]) { string_f64((*val._string)) }, (_option*)(&_t11), sizeof(f64)); return _t11; } else if (val._typ == 2 /* voidptr */) { } else if (val._typ == 22 /* rune */) { } else if (val._typ == 354 /* v.ast.EmptyExpr */) { } return (_option_f64){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_string v__ast__ComptTimeConstValue_string(v__ast__ComptTimeConstValue val) { if (val._typ == 5 /* i8 */) { _option_string _t1; _option_ok(&(string[]) { i8_str((*val._i8)) }, (_option*)(&_t1), sizeof(string)); return _t1; } else if (val._typ == 6 /* i16 */) { _option_string _t2; _option_ok(&(string[]) { i16_str((*val._i16)) }, (_option*)(&_t2), sizeof(string)); return _t2; } else if (val._typ == 7 /* i32 */) { _option_string _t3; _option_ok(&(string[]) { i32_str((*val._i32)) }, (_option*)(&_t3), sizeof(string)); return _t3; } else if (val._typ == 9 /* i64 */) { _option_string _t4; _option_ok(&(string[]) { i64_str((*val._i64)) }, (_option*)(&_t4), sizeof(string)); return _t4; } else if (val._typ == 11 /* u8 */) { _option_string _t5; _option_ok(&(string[]) { u8_str((*val._u8)) }, (_option*)(&_t5), sizeof(string)); return _t5; } else if (val._typ == 12 /* u16 */) { _option_string _t6; _option_ok(&(string[]) { u16_str((*val._u16)) }, (_option*)(&_t6), sizeof(string)); return _t6; } else if (val._typ == 13 /* u32 */) { _option_string _t7; _option_ok(&(string[]) { u32_str((*val._u32)) }, (_option*)(&_t7), sizeof(string)); return _t7; } else if (val._typ == 14 /* u64 */) { _option_string _t8; _option_ok(&(string[]) { u64_str((*val._u64)) }, (_option*)(&_t8), sizeof(string)); return _t8; } else if (val._typ == 16 /* f32 */) { _option_string _t9; _option_ok(&(string[]) { f32_str((*val._f32)) }, (_option*)(&_t9), sizeof(string)); return _t9; } else if (val._typ == 17 /* f64 */) { _option_string _t10; _option_ok(&(string[]) { f64_str((*val._f64)) }, (_option*)(&_t10), sizeof(string)); return _t10; } else if (val._typ == 22 /* rune */) { _option_string _t11; _option_ok(&(string[]) { rune_str((*val._rune)) }, (_option*)(&_t11), sizeof(string)); return _t11; } else if (val._typ == 21 /* string */) { _option_string _t12; _option_ok(&(string[]) { (*val._string) }, (_option*)(&_t12), sizeof(string)); return _t12; } else if (val._typ == 2 /* voidptr */) { _option_string _t13; _option_ok(&(string[]) { ptr_str((*val._voidptr)) }, (_option*)(&_t13), sizeof(string)); return _t13; } else if (val._typ == 354 /* v.ast.EmptyExpr */) { } return (_option_string){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue v__ast__ConstField_comptime_expr_value(v__ast__ConstField obj) { if ((obj.comptime_expr_value)._typ != 354 /* v.ast.EmptyExpr */) { _option_v__ast__ComptTimeConstValue _t1; _option_ok(&(v__ast__ComptTimeConstValue[]) { obj.comptime_expr_value }, (_option*)(&_t1), sizeof(v__ast__ComptTimeConstValue)); return _t1; } return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } bool v__ast__ConstField_is_simple_define_const(v__ast__ConstField obj) { return ((obj.expr._typ == 347 /* v.ast.CharLiteral */)? (true) : (obj.expr._typ == 356 /* v.ast.FloatLiteral */)? (true) : (obj.expr._typ == 363 /* v.ast.IntegerLiteral */)? (true) : (false)); } bool v__ast__ScopeObject_is_simple_define_const(v__ast__ScopeObject obj) { if ((obj)._typ == 420 /* v.ast.ConstField */) { return v__ast__ConstField_is_simple_define_const((*obj._v__ast__ConstField)); } return false; } VV_LOC Array_string v__ast__all_valid_comptime_idents(void) { Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); _PUSH_MANY(&res, (_const_v__ast__valid_comptime_if_os), _t1, Array_string); _PUSH_MANY(&res, (_const_v__ast__valid_comptime_if_compilers), _t2, Array_string); _PUSH_MANY(&res, (_const_v__ast__valid_comptime_if_platforms), _t3, Array_string); _PUSH_MANY(&res, (_const_v__ast__valid_comptime_if_cpu_features), _t4, Array_string); _PUSH_MANY(&res, (_const_v__ast__valid_comptime_if_other), _t5, Array_string); return res; } u64 v__ast__EmbeddedFile_hash(v__ast__EmbeddedFile e) { return hash__fnv1a__sum64_string(str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = e.apath}}, {_S(", "), 0xfe10, {.d_s = e.compression_type}}, {_S(", "), 0xfe10, {.d_s = e.is_compressed ? _S("true") : _S("false")}}, {_S(", "), 0xfe07, {.d_i32 = e.len}}, {_SLIT0, 0, { .d_c = 0 }}}))); } v__ast__Expr v__ast__Table_resolve_init(v__ast__Table* t, v__ast__StructInit node, v__ast__Type typ) { v__ast__TypeSymbol* sym = v__ast__Table_sym(t, typ); if (sym->info._typ == 513 /* v.ast.Array */) { bool has_len = false; bool has_cap = false; bool has_init = false; v__ast__Expr len_expr = _const_v__ast__empty_expr; v__ast__Expr cap_expr = _const_v__ast__empty_expr; v__ast__Expr init_expr = _const_v__ast__empty_expr; Array_v__ast__Expr exprs = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); for (int _t1 = 0; _t1 < node.init_fields.len; ++_t1) { v__ast__StructInitField field = ((v__ast__StructInitField*)node.init_fields.data)[_t1]; if (_SLIT_EQ(field.name.str, field.name.len, "len")) { has_len = true; len_expr = field.expr; } else if (_SLIT_EQ(field.name.str, field.name.len, "cap")) { has_cap = true; cap_expr = field.expr; } else if (_SLIT_EQ(field.name.str, field.name.len, "init")) { has_init = true; init_expr = field.expr; } else { array_push((array*)&exprs, _MOV((v__ast__Expr[]){ field.expr })); } } return v__ast__ArrayInit_to_sumtype_v__ast__Expr(ADDR(v__ast__ArrayInit, (((v__ast__ArrayInit){ .pos = node.pos, .elem_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .ecmnts = __new_array(0, 0, sizeof(Array_v__ast__Comment)), .pre_cmnts = __new_array(0, 0, sizeof(v__ast__Comment)), .is_fixed = 0, .is_option = 0, .has_val = 0, .mod = (string){.str=(byteptr)"", .is_lit=1}, .has_len = has_len, .has_cap = has_cap, .has_init = has_init, .has_index = 0, .exprs = exprs, .len_expr = len_expr, .cap_expr = cap_expr, .init_expr = init_expr, .expr_types = __new_array(0, 0, sizeof(v__ast__Type)), .elem_type = (*sym->info._v__ast__Array).elem_type, .init_type = 0, .typ = typ, .alias_type = 0, .has_callexpr = 0, })))); } else if (sym->info._typ == 514 /* v.ast.Map */) { Array_v__ast__Expr keys = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); Array_v__ast__Expr vals = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); for (int _t4 = 0; _t4 < node.init_fields.len; ++_t4) { v__ast__StructInitField field = ((v__ast__StructInitField*)node.init_fields.data)[_t4]; array_push((array*)&keys, _MOV((v__ast__Expr[]){ v__ast__StringLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__StringLiteral, (((v__ast__StringLiteral){.val = field.name,.is_raw = 0,.language = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))) })); array_push((array*)&vals, _MOV((v__ast__Expr[]){ field.expr })); } return v__ast__MapInit_to_sumtype_v__ast__Expr(ADDR(v__ast__MapInit, (((v__ast__MapInit){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(Array_v__ast__Comment)),.pre_cmnts = __new_array(0, 0, sizeof(v__ast__Comment)),.keys = keys,.vals = vals,.val_types = __new_array(0, 0, sizeof(v__ast__Type)),.typ = typ,.key_type = (*sym->info._v__ast__Map).key_type,.value_type = (*sym->info._v__ast__Map).value_type,.has_update_expr = 0,.update_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_expr_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.update_expr_comments = __new_array(0, 0, sizeof(v__ast__Comment)),})))); } else { return v__ast__StructInit_to_sumtype_v__ast__Expr(ADDR(v__ast__StructInit, (((v__ast__StructInit){.pos = (node).pos,.name_pos = (node).name_pos,.no_keys = (node).no_keys,.is_short_syntax = (node).is_short_syntax,.is_anon = (node).is_anon,.unresolved = false,.pre_comments = (node).pre_comments,.typ_str = (node).typ_str,.typ = (node).typ,.update_expr = (node).update_expr,.update_expr_type = (node).update_expr_type,.update_expr_pos = (node).update_expr_pos,.update_expr_comments = (node).update_expr_comments,.is_update_embed = (node).is_update_embed,.has_update_expr = (node).has_update_expr,.init_fields = (node).init_fields,.generic_types = (node).generic_types,.language = (node).language,})))); } return (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}; } void v__ast__Scope_free(v__ast__Scope* s) { if (s == ((void*)0)) { return; } { // Unsafe block map_free(&s->objects); map_free(&s->struct_fields); for (int _t1 = 0; _t1 < s->children.len; ++_t1) { v__ast__Scope* child = ((v__ast__Scope**)s->children.data)[_t1]; v__ast__Scope_free(child); } array_free(&s->children); } } inline VV_LOC bool v__ast__Scope_dont_lookup_parent(v__ast__Scope* s) { return s->parent == ((void*)0) || s->detached_from_parent; } _option_v__ast__ScopeObject v__ast__Scope_find(v__ast__Scope* s, string name) { if (s == ((void*)0)) { return (_option_v__ast__ScopeObject){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } for (v__ast__Scope* sc = s; true; sc = sc->parent) { if (_IN_MAP(ADDR(string, name), ADDR(map, sc->objects))) { _option_v__ast__ScopeObject _t2; _option_ok(&(v__ast__ScopeObject[]) { (*(v__ast__ScopeObject*)map_get(ADDR(map, sc->objects), &(string[]){name}, &(v__ast__ScopeObject[]){ (v__ast__ScopeObject){._v__ast__EmptyScopeObject=HEAP(v__ast__EmptyScopeObject, ((v__ast__EmptyScopeObject){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,})),._typ=418} })) }, (_option*)(&_t2), sizeof(v__ast__ScopeObject)); return _t2; } if (v__ast__Scope_dont_lookup_parent(sc)) { break; } } return (_option_v__ast__ScopeObject){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } v__ast__ScopeStructField* v__ast__Scope_find_struct_field(v__ast__Scope* s, string name, v__ast__Type struct_type, string field_name) { if (s == ((void*)0)) { return ((void*)0); } string k = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = name}}, {_S("."), 0xfe10, {.d_s = field_name}}, {_SLIT0, 0, { .d_c = 0 }}})); for (v__ast__Scope* sc = s; true; sc = sc->parent) { v__ast__ScopeStructField* _t3 = (v__ast__ScopeStructField*)(map_get_check(ADDR(map, sc->struct_fields), &(string[]){k})); _option_v__ast__ScopeStructField _t2 = {0}; if (_t3) { *((v__ast__ScopeStructField*)&_t2.data) = *((v__ast__ScopeStructField*)_t3); } else { _t2.state = 2; _t2.err = _v_error(_S("map key does not exist")); } if (_t2.state == 0) { v__ast__ScopeStructField field = (*(v__ast__ScopeStructField*)_t2.data); if (field.struct_type == struct_type) { return ((v__ast__ScopeStructField*)memdup(&(v__ast__ScopeStructField){.struct_type = (field).struct_type,.name = (field).name,.pos = (field).pos,.typ = (field).typ,.orig_type = (field).orig_type,.smartcasts = (field).smartcasts,}, sizeof(v__ast__ScopeStructField))); } } if (v__ast__Scope_dont_lookup_parent(sc)) { break; } } return ((void*)0); } _option_v__ast__Var_ptr v__ast__Scope_find_var(v__ast__Scope* s, string name) { _option_v__ast__ScopeObject _t1; if (_t1 = v__ast__Scope_find(s, name), _t1.state == 0) { v__ast__ScopeObject obj = *(v__ast__ScopeObject*)_t1.data; if (obj._typ == 422 /* v.ast.Var */) { _option_v__ast__Var_ptr _t2; _option_ok(&(v__ast__Var*[]) { &(*obj._v__ast__Var) }, (_option*)(&_t2), sizeof(v__ast__Var*)); return _t2; } else { } } return (_option_v__ast__Var_ptr){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__GlobalField_ptr v__ast__Scope_find_global(v__ast__Scope* s, string name) { _option_v__ast__ScopeObject _t1; if (_t1 = v__ast__Scope_find(s, name), _t1.state == 0) { v__ast__ScopeObject obj = *(v__ast__ScopeObject*)_t1.data; if (obj._typ == 421 /* v.ast.GlobalField */) { _option_v__ast__GlobalField_ptr _t2; _option_ok(&(v__ast__GlobalField*[]) { &(*obj._v__ast__GlobalField) }, (_option*)(&_t2), sizeof(v__ast__GlobalField*)); return _t2; } else { } } return (_option_v__ast__GlobalField_ptr){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ConstField_ptr v__ast__Scope_find_const(v__ast__Scope* s, string name) { _option_v__ast__ScopeObject _t1; if (_t1 = v__ast__Scope_find(s, name), _t1.state == 0) { v__ast__ScopeObject obj = *(v__ast__ScopeObject*)_t1.data; if (obj._typ == 420 /* v.ast.ConstField */) { _option_v__ast__ConstField_ptr _t2; _option_ok(&(v__ast__ConstField*[]) { &(*obj._v__ast__ConstField) }, (_option*)(&_t2), sizeof(v__ast__ConstField*)); return _t2; } else { } } return (_option_v__ast__ConstField_ptr){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } bool v__ast__Scope_known_var(v__ast__Scope* s, string name) { if (s == ((void*)0)) { return false; } for (v__ast__Scope* sc = s; true; sc = sc->parent) { if (_IN_MAP(ADDR(string, name), ADDR(map, sc->objects))) { v__ast__ScopeObject* _t3 = (v__ast__ScopeObject*)(map_get_check(ADDR(map, sc->objects), &(string[]){name})); _option_v__ast__ScopeObject _t2 = {0}; if (_t3) { *((v__ast__ScopeObject*)&_t2.data) = *((v__ast__ScopeObject*)_t3); } else { _t2.state = 2; _t2.err = _v_error(_S("map key does not exist")); } ; if (_t2.state != 0) { IError err = _t2.err; *(v__ast__ScopeObject*) _t2.data = _const_v__ast__empty_scope_object; } v__ast__ScopeObject obj = (*(v__ast__ScopeObject*)_t2.data); if ((obj)._typ == 422 /* v.ast.Var */) { return true; } } if (v__ast__Scope_dont_lookup_parent(sc)) { break; } } return false; } bool v__ast__Scope_known_global(v__ast__Scope* s, string name) { _option_v__ast__GlobalField_ptr _t1 = v__ast__Scope_find_global(s, name); if (_t1.state != 0) { IError err = _t1.err; return false; } ; return true; } bool v__ast__Scope_known_const(v__ast__Scope* s, string name) { _option_v__ast__ConstField_ptr _t1 = v__ast__Scope_find_const(s, name); if (_t1.state != 0) { IError err = _t1.err; return false; } ; return true; } void v__ast__Scope_update_var_type(v__ast__Scope* s, string name, v__ast__Type typ) { v__ast__ScopeObject obj = (*(v__ast__ScopeObject*)map_get(ADDR(map, s->objects), &(string[]){name}, &(v__ast__ScopeObject[]){ (v__ast__ScopeObject){._v__ast__EmptyScopeObject=HEAP(v__ast__EmptyScopeObject, ((v__ast__EmptyScopeObject){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,})),._typ=418} })); if ((obj)._typ == 422 /* v.ast.Var */) { if ((*obj._v__ast__Var).typ != typ) { (*obj._v__ast__Var).typ = typ; } } } void v__ast__Scope_update_ct_var_kind(v__ast__Scope* s, string name, v__ast__ComptimeVarKind kind) { v__ast__ScopeObject obj = (*(v__ast__ScopeObject*)map_get(ADDR(map, s->objects), &(string[]){name}, &(v__ast__ScopeObject[]){ (v__ast__ScopeObject){._v__ast__EmptyScopeObject=HEAP(v__ast__EmptyScopeObject, ((v__ast__EmptyScopeObject){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,})),._typ=418} })); if ((obj)._typ == 422 /* v.ast.Var */) { (*obj._v__ast__Var).ct_type_var = kind; } } void v__ast__Scope_update_smartcasts(v__ast__Scope* s, string name, v__ast__Type typ, bool is_unwrapped) { v__ast__ScopeObject obj = (*(v__ast__ScopeObject*)map_get(ADDR(map, s->objects), &(string[]){name}, &(v__ast__ScopeObject[]){ (v__ast__ScopeObject){._v__ast__EmptyScopeObject=HEAP(v__ast__EmptyScopeObject, ((v__ast__EmptyScopeObject){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,})),._typ=418} })); if ((obj)._typ == 422 /* v.ast.Var */) { (*obj._v__ast__Var).smartcasts = new_array_from_c_array(1, 1, sizeof(v__ast__Type), _MOV((v__ast__Type[1]){typ})); (*obj._v__ast__Var).is_unwrapped = is_unwrapped; } } void v__ast__Scope_register_struct_field(v__ast__Scope* s, string name, v__ast__ScopeStructField field) { string k = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = name}}, {_S("."), 0xfe10, {.d_s = field.name}}, {_SLIT0, 0, { .d_c = 0 }}})); v__ast__ScopeStructField* _t2 = (v__ast__ScopeStructField*)(map_get_check(ADDR(map, s->struct_fields), &(string[]){k})); _option_v__ast__ScopeStructField _t1 = {0}; if (_t2) { *((v__ast__ScopeStructField*)&_t1.data) = *((v__ast__ScopeStructField*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { v__ast__ScopeStructField f = (*(v__ast__ScopeStructField*)_t1.data); if (f.struct_type == field.struct_type) { return; } } (*(v__ast__ScopeStructField*)map_get_and_set((map*)&s->struct_fields, &(string[]){k}, &(v__ast__ScopeStructField[]){ (v__ast__ScopeStructField){.struct_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),} })) = field; } void v__ast__Scope_register(v__ast__Scope* s, v__ast__ScopeObject obj) { if (!(fast_string_eq((*(obj.name)), _S("_")) || _IN_MAP(ADDR(string, (*(obj.name))), ADDR(map, s->objects)))) { map_set(&s->objects, &(string[]){(*(obj.name))}, &(v__ast__ScopeObject[]) { obj }); } } v__ast__Scope* v__ast__Scope_innermost(v__ast__Scope* s, int pos) { if (v__ast__Scope_contains(s, pos)) { int first = 0; int last = (int)(s->children.len - 1); int middle = (int)(last / 2); for (;;) { if (!(first <= last)) break; v__ast__Scope* s1 = ((v__ast__Scope**)s->children.data)[middle]; if (s1->end_pos < pos) { first = (int)(middle + 1); } else if (v__ast__Scope_contains(s1, pos)) { return v__ast__Scope_innermost(s1, pos); } else { last = (int)(middle - 1); } middle = (int)(((int)(first + last)) / 2); if (first > last) { break; } } return s; } return s; } Array_v__ast__ScopeObject v__ast__Scope_get_all_vars(v__ast__Scope* s) { if (s == ((void*)0)) { return __new_array_with_default(0, 0, sizeof(v__ast__ScopeObject), 0); } Array_v__ast__ScopeObject scope_vars = __new_array_with_default(0, 0, sizeof(v__ast__ScopeObject), 0); for (v__ast__Scope* sc = s; true; sc = sc->parent) { if (sc->objects.len > 0) { Array_v__ast__ScopeObject _t3 = {0}; Array_v__ast__ScopeObject _t3_orig = map_values(&sc->objects); int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__ScopeObject)); for (int _t4 = 0; _t4 < _t3_len; ++_t4) { v__ast__ScopeObject it = ((v__ast__ScopeObject*) _t3_orig.data)[_t4]; if ((it)._typ == 422 /* v.ast.Var */) { array_push((array*)&_t3, &it); } } _PUSH_MANY(&scope_vars, (_t3), _t2, Array_v__ast__ScopeObject); } if (v__ast__Scope_dont_lookup_parent(sc)) { break; } } return scope_vars; } inline bool v__ast__Scope_contains(v__ast__Scope* s, int pos) { return pos >= s->start_pos && pos <= s->end_pos; } bool v__ast__Scope_has_inherited_vars(v__ast__Scope* s) { Map_string_v__ast__ScopeObject _t1 = s->objects; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} v__ast__ScopeObject obj = (*(v__ast__ScopeObject*)DenseArray_value(&_t1.key_values, _t2)); if ((obj)._typ == 422 /* v.ast.Var */) { if ((*obj._v__ast__Var).is_inherited) { return true; } } } return false; } bool v__ast__Scope_is_inherited_var(v__ast__Scope* s, string var_name) { Map_string_v__ast__ScopeObject _t1 = s->objects; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} v__ast__ScopeObject obj = (*(v__ast__ScopeObject*)DenseArray_value(&_t1.key_values, _t2)); if ((obj)._typ == 422 /* v.ast.Var */) { if ((*obj._v__ast__Var).is_inherited && string__eq((*obj._v__ast__Var).name, var_name)) { return true; } } } return false; } string v__ast__Scope_show(v__ast__Scope* sc, int depth, int max_depth) { string out = _S(""); string indent = _S(""); for (int _t1 = 0; _t1 < (int)(depth * 4); ++_t1) { indent = string__plus(indent, _S(" ")); } out = string__plus(out, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("# "), 0xfe07, {.d_i32 = sc->start_pos}}, {_S(" - "), 0xfe07, {.d_i32 = sc->end_pos}}, {_S("\n"), 0, { .d_c = 0 }}}))); Map_string_v__ast__ScopeObject _t2 = sc->objects; int _t4 = _t2.key_values.len; for (int _t3 = 0; _t3 < _t4; ++_t3 ) { int _t5 = _t2.key_values.len - _t4; _t4 = _t2.key_values.len; if (_t5 < 0) { _t3 = -1; continue; } if (!DenseArray_has_index(&_t2.key_values, _t3)) {continue;} v__ast__ScopeObject obj = (*(v__ast__ScopeObject*)DenseArray_value(&_t2.key_values, _t3)); if (obj._typ == 420 /* v.ast.ConstField */) { out = string__plus(out, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S(" * const: "), 0xfe10, {.d_s = (*obj._v__ast__ConstField).name}}, {_S(" - "), 0xfe10, {.d_s = v__ast__Type_str((*obj._v__ast__ConstField).typ)}}, {_S("\n"), 0, { .d_c = 0 }}}))); } else if (obj._typ == 422 /* v.ast.Var */) { out = string__plus(out, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S(" * var: "), 0xfe10, {.d_s = (*obj._v__ast__Var).name}}, {_S(" - "), 0xfe10, {.d_s = v__ast__Type_str((*obj._v__ast__Var).typ)}}, {_S("\n"), 0, { .d_c = 0 }}}))); } else { } } Map_string_v__ast__ScopeStructField _t6 = sc->struct_fields; int _t8 = _t6.key_values.len; for (int _t7 = 0; _t7 < _t8; ++_t7 ) { int _t9 = _t6.key_values.len - _t8; _t8 = _t6.key_values.len; if (_t9 < 0) { _t7 = -1; continue; } if (!DenseArray_has_index(&_t6.key_values, _t7)) {continue;} v__ast__ScopeStructField field = (*(v__ast__ScopeStructField*)DenseArray_value(&_t6.key_values, _t7)); out = string__plus(out, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S(" * struct_field: "), 0xfe10, {.d_s = v__ast__Type_str(field.struct_type)}}, {_S(" "), 0xfe10, {.d_s = field.name}}, {_S(" - "), 0xfe10, {.d_s = v__ast__Type_str(field.typ)}}, {_S("\n"), 0, { .d_c = 0 }}}))); } if (max_depth == 0 || depth < (int)(max_depth - 1)) { for (int i = 0; i < sc->children.len; ++i) { out = string__plus(out, v__ast__Scope_show((*(v__ast__Scope**)array_get(sc->children, i)), (int)(depth + 1), max_depth)); } } return out; } bool v__ast__Scope_mark_var_as_used(v__ast__Scope* sc, string varname) { _option_v__ast__ScopeObject _t1 = v__ast__Scope_find(sc, varname); if (_t1.state != 0) { IError err = _t1.err; return false; } v__ast__ScopeObject obj = (*(v__ast__ScopeObject*)_t1.data); if ((obj)._typ == 422 /* v.ast.Var */) { (*obj._v__ast__Var).is_used = true; return true; } else if ((obj)._typ == 421 /* v.ast.GlobalField */) { return true; } return false; } string v__ast__Scope_str(v__ast__Scope* sc) { return v__ast__Scope_show(sc, 0, 0); } string v__ast__FnDecl_get_name(v__ast__FnDecl* f) { if (f->is_static_type_method) { return string_all_after_last(f->name, _S("__static__")); } else { return f->name; } return (string){.str=(byteptr)"", .is_lit=1}; } string v__ast__Table_get_anon_fn_name(v__ast__Table* table, string prefix, v__ast__Fn* func, int pos) { return str_intp(4, _MOV((StrIntpData[]){{_S("anon_fn_"), 0xfe10, {.d_s = prefix}}, {_S("_"), 0xfe10, {.d_s = v__ast__Table_fn_type_signature(table, func)}}, {_S("_"), 0xfe07, {.d_i32 = pos}}, {_SLIT0, 0, { .d_c = 0 }}})); } string v__ast__CallExpr_get_name(v__ast__CallExpr* f) { if (f->is_static_method) { return string_replace(f->name, _S("__static__"), _S(".")); } else { return f->name; } return (string){.str=(byteptr)"", .is_lit=1}; } string v__ast__FnDecl_modname(v__ast__FnDecl* node) { if ((node->mod).len != 0) { return node->mod; } string pamod = string_all_before_last(node->name, _S(".")); if (string__eq(pamod, string_after(node->name, _S(".")))) { pamod = (node->is_builtin ? (_S("builtin")) : (_S("main"))); } return pamod; } string v__ast__FnDecl_fkey(v__ast__FnDecl* node) { if (node->is_method) { return str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(node->receiver.typ))}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})); } return node->name; } string v__ast__Fn_fkey(v__ast__Fn* node) { if (node->is_method) { return str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(node->receiver_type))}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})); } return node->name; } string v__ast__CallExpr_fkey(v__ast__CallExpr* node) { if (node->is_method) { return str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(node->receiver_type))}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})); } return node->name; } string v__ast__Table_stringify_fn_decl(v__ast__Table* t, v__ast__FnDecl* node, string cur_mod, Map_string_string m2a, bool needs_wrap) { strings__Builder f = strings__new_builder(30); if (node->is_pub) { strings__Builder_write_string(&f, _S("pub ")); } strings__Builder_write_string(&f, _S("fn ")); Array_v__ast__Comment _t1 = {0}; Array_v__ast__Comment _t1_orig = node->comments; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Comment)); for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__Comment it = ((v__ast__Comment*) _t1_orig.data)[_t2]; if (it.pos.pos < node->name_pos.pos) { array_push((array*)&_t1, &it); } } Array_v__ast__Comment pre_comments =_t1; if (pre_comments.len > 0) { v__ast__write_comments(pre_comments, (voidptr)&f); if (!u8_is_space(string_at(strings__Builder_last_n(&f, 1), 0))) { strings__Builder_write_string(&f, _S(" ")); } } if (node->is_method) { strings__Builder_write_string(&f, _S("(")); string styp = v__util__no_cur_mod(v__ast__Table_type_to_code(t, v__ast__Type_clear_flag(node->receiver.typ, v__ast__TypeFlag__shared_f)), cur_mod); if (node->rec_mut) { strings__Builder_write_string(&f, string__plus(v__ast__ShareType_str(v__ast__Type_share(node->receiver.typ)), _S(" "))); styp = string_substr(styp, 1, 2147483647); } strings__Builder_write_string(&f, string__plus(node->receiver.name, _S(" "))); styp = v__util__no_cur_mod(styp, cur_mod); strings__Builder_write_string(&f, string__plus(styp, _S(") "))); } else if (node->is_static_type_method) { string styp = v__util__no_cur_mod(v__ast__Table_type_to_code(t, v__ast__Type_clear_flag(node->receiver.typ, v__ast__TypeFlag__shared_f)), cur_mod); strings__Builder_write_string(&f, string__plus(styp, _S("."))); } string name = (!node->is_method && node->language == v__ast__Language__v ? (string_all_after_last(node->name, _S("."))) : (node->name)); if (node->is_static_type_method) { name = string_after(name, _S("__static__")); } strings__Builder_write_string(&f, name); if (_SLIT_EQ(name.str, name.len, "+") || _SLIT_EQ(name.str, name.len, "-") || _SLIT_EQ(name.str, name.len, "*") || _SLIT_EQ(name.str, name.len, "/") || _SLIT_EQ(name.str, name.len, "%") || _SLIT_EQ(name.str, name.len, "<") || _SLIT_EQ(name.str, name.len, ">") || _SLIT_EQ(name.str, name.len, "==") || _SLIT_EQ(name.str, name.len, "!=") || _SLIT_EQ(name.str, name.len, ">=") || _SLIT_EQ(name.str, name.len, "<=")) { strings__Builder_write_string(&f, _S(" ")); } v__ast__Table_stringify_fn_after_name(t, node, (voidptr)&f, cur_mod, m2a); return strings__Builder_str(&f); } VV_LOC void v__ast__Table_stringify_fn_after_name(v__ast__Table* t, v__ast__FnDecl* node, strings__Builder* f, string cur_mod, Map_string_string m2a) { bool add_para_types = true; if (node->generic_names.len > 0) { if (node->is_method) { v__ast__TypeSymbol* sym = v__ast__Table_sym(t, (*(v__ast__Param*)array_get(node->params, 0)).typ); if ((sym->info)._typ == 518 /* v.ast.Struct */) { Array_string _t1 = {0}; Array_v__ast__Type _t1_orig = (*sym->info._v__ast__Struct).generic_types; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t3]; string _t2 = v__ast__Table_sym(t, it)->name; array_push((array*)&_t1, &_t2); } Array_string generic_names =_t1; if (Array_string_arr_eq(generic_names, node->generic_names)) { add_para_types = false; } } } if (add_para_types) { strings__Builder_write_string(f, _S("[")); for (int i = 0; i < node->generic_names.len; ++i) { string gname = ((string*)node->generic_names.data)[i]; strings__Builder_write_string(f, gname); if (i != (int)(node->generic_names.len - 1)) { strings__Builder_write_string(f, _S(", ")); } } strings__Builder_write_string(f, _S("]")); } } strings__Builder_write_string(f, _S("(")); int old_pline = node->pos.line_nr; int pline = node->pos.line_nr; int nparams_on_pline = 0; for (int i = 0; i < node->params.len; ++i) { v__ast__Param param = ((v__ast__Param*)node->params.data)[i]; if (node->is_method && i == 0) { continue; } if (param.is_hidden) { continue; } bool is_last_param = i == (int)(node->params.len - 1); bool is_type_only = (param.name).len == 0; if (param.on_newline) { strings__Builder_write_string(f, _S("\n\t")); pline++; nparams_on_pline = 0; } if (pline == old_pline && nparams_on_pline > 0) { strings__Builder_write_string(f, _S(" ")); } if (param.is_mut) { strings__Builder_write_string(f, string__plus(v__ast__ShareType_str(v__ast__Type_share(param.typ)), _S(" "))); } strings__Builder_write_string(f, param.name); v__ast__TypeSymbol* param_sym = v__ast__Table_sym(t, param.typ); if ((param_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((param_sym->info)._v__ast__Struct,(param_sym->info)._typ, 518)).is_anon) { if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__option)) { strings__Builder_write_string(f, _S(" ?")); } else { strings__Builder_write_string(f, _S(" ")); } strings__Builder_write_string(f, _S("struct {")); for (int _t4 = 0; _t4 < (*param_sym->info._v__ast__Struct).fields.len; ++_t4) { v__ast__StructField field = ((v__ast__StructField*)(*param_sym->info._v__ast__Struct).fields.data)[_t4]; { strings__Builder_write_string(f, _S(" ")); strings__Builder_write_string(f, field.name); strings__Builder_write_string(f, _S(" ")); strings__Builder_write_string(f, v__ast__Table_type_to_str(t, field.typ)); } if (field.has_default_expr) { strings__Builder_write_string(f, str_intp(2, _MOV((StrIntpData[]){{_S(" = "), 0xfe10, {.d_s = v__ast__Expr_str(&field.default_expr)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } if ((*param_sym->info._v__ast__Struct).fields.len > 0) { strings__Builder_write_string(f, _S(" ")); } strings__Builder_write_string(f, _S("}")); } else { string s = v__ast__Table_type_to_str(t, v__ast__Type_clear_flag(param.typ, v__ast__TypeFlag__shared_f)); if (param.is_mut) { if (string_starts_with(s, _S("&")) && ((!v__ast__TypeSymbol_is_number(param_sym) && param_sym->kind != v__ast__Kind__bool) || node->language != v__ast__Language__v || (v__ast__Type_is_ptr(param.typ) && param_sym->kind == v__ast__Kind__struct))) { s = string_substr(s, 1, 2147483647); } else if (v__ast__Type_is_ptr(param.typ) && param_sym->kind == v__ast__Kind__struct && !string_contains(s, _S("["))) { s = v__ast__Table_type_to_str(t, v__ast__Type_deref(v__ast__Type_clear_flag(param.typ, v__ast__TypeFlag__shared_f))); } } s = v__util__no_cur_mod(s, cur_mod); s = v__ast__shorten_full_name_based_on_aliases(s, m2a); if (!is_type_only) { strings__Builder_write_string(f, _S(" ")); } if (node->is_variadic && is_last_param && !node->is_c_variadic) { strings__Builder_write_string(f, _S("...")); } strings__Builder_write_string(f, s); } if (!is_last_param) { strings__Builder_write_string(f, _S(",")); } else if (node->is_c_variadic) { strings__Builder_write_string(f, _S(", ...")); } nparams_on_pline++; old_pline = pline; } strings__Builder_write_string(f, _S(")")); if (node->return_type != _const_v__ast__void_type) { string sreturn_type = v__util__no_cur_mod(v__ast__Table_type_to_str(t, node->return_type), cur_mod); string short_sreturn_type = v__ast__shorten_full_name_based_on_aliases(sreturn_type, m2a); { strings__Builder_write_string(f, _S(" ")); strings__Builder_write_string(f, short_sreturn_type); } } } VV_LOC void v__ast__write_comments(Array_v__ast__Comment comments, strings__Builder* f) { for (int i = 0; i < comments.len; ++i) { v__ast__Comment c = ((v__ast__Comment*)comments.data)[i]; v__ast__write_comment(c, f); if (i < (int)(comments.len - 1)) { strings__Builder_writeln(f, _S("")); } } } VV_LOC void v__ast__write_comment(v__ast__Comment node, strings__Builder* f) { if (node.is_multi) { string x = string_trim_space(string_trim_left(node.text, _S("\001"))); strings__Builder_writeln(f, _S("/*")); strings__Builder_writeln(f, x); strings__Builder_write_string(f, _S("*/")); } else { string s = string_trim_right(string_trim_left(node.text, _S("\001")), _S(" ")); string out_s = _S("//"); if ((s).len != 0) { if (u8_is_letter(string_at(s, 0)) || u8_is_digit(string_at(s, 0))) { out_s = string__plus(out_s, _S(" ")); } out_s = string__plus(out_s, s); } strings__Builder_writeln(f, out_s); } } VV_LOC string v__ast__shorten_full_name_based_on_aliases(string input, Map_string_string m2a) { if (m2a.len == 0 || -1 == string_index_u8(input, '.')) { return input; } Array_v__ast__StringifyModReplacement replacements = __new_array_with_default(0, m2a.len, sizeof(v__ast__StringifyModReplacement), 0); int _t3 = m2a.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = m2a.key_values.len - _t3; _t3 = m2a.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&m2a.key_values, _t2)) {continue;} string mod = *(string*)DenseArray_key(&m2a.key_values, _t2); mod = string_clone(mod); string alias = (*(string*)DenseArray_value(&m2a.key_values, _t2)); if (string__eq(mod, alias)) { continue; } if (!string_contains(input, mod)) { continue; } array_push((array*)&replacements, _MOV((v__ast__StringifyModReplacement[]){ ((v__ast__StringifyModReplacement){.mod = mod,.alias = alias,.weight = (int)((int)(string_count(mod, _S(".")) * 100) + mod.len),}) })); } if (replacements.len == 0) { return input; } string res = input; if (replacements.len > 1) { if (replacements.len > 0) { qsort(replacements.data, replacements.len, replacements.element_size, (voidptr)compare_13857757049580525278_v__ast__StringifyModReplacement_by_weight_reverse); } ; } for (int _t7 = 0; _t7 < replacements.len; ++_t7) { v__ast__StringifyModReplacement r = ((v__ast__StringifyModReplacement*)replacements.data)[_t7]; if (-1 == string_index_u8(res, '.')) { break; } if (!string_contains(res, r.mod)) { continue; } res = string_replace(res, r.mod, r.alias); } return res; } multi_return_string_bool v__ast__StringInterLiteral_get_fspec_braces(v__ast__StringInterLiteral* lit, int i) { Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); bool needs_fspec = (*(bool*)array_get(lit->need_fmts, i)) || (*(bool*)array_get(lit->pluss, i)) || ((*(bool*)array_get(lit->fills, i)) && (*(int*)array_get(lit->fwidths, i)) >= 0) || (*(int*)array_get(lit->fwidths, i)) != 0 || (*(int*)array_get(lit->precisions, i)) != 987698; bool needs_braces = needs_fspec; string sx = v__ast__Expr_str(&(*(v__ast__Expr*)array_get(lit->exprs, i))); if (string_contains(sx, _S("\"")) || string_contains(sx, _S("'"))) { needs_braces = true; } if (!needs_braces) { if ((int)(i + 1) < lit->vals.len && (*(string*)array_get(lit->vals, (int)(i + 1))).len > 0) { u8 next_char = string_at((*(string*)array_get(lit->vals, (int)(i + 1))), 0); if (v__util__is_func_char(next_char) || next_char == '.' || next_char == '(') { needs_braces = true; } } } if (!needs_braces) { v__ast__Expr sub_expr = (*(v__ast__Expr*)array_get(lit->exprs, i)); for (;;) { if (sub_expr._typ == 358 /* v.ast.Ident */) { if (string_at((*sub_expr._v__ast__Ident).name, 0) == '@') { needs_braces = true; } break; } else { needs_braces = true; break; } } } if (needs_fspec) { array_push((array*)&res, _MOV((string[]){ _S(":") })); if ((*(bool*)array_get(lit->pluss, i))) { array_push((array*)&res, _MOV((string[]){ _S("+") })); } if ((*(bool*)array_get(lit->fills, i)) && (*(int*)array_get(lit->fwidths, i)) >= 0) { array_push((array*)&res, _MOV((string[]){ _S("0") })); } if ((*(int*)array_get(lit->fwidths, i)) != 0) { array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = (*(int*)array_get(lit->fwidths, i))}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if ((*(int*)array_get(lit->precisions, i)) != 987698) { array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("."), 0xfe07, {.d_i32 = (*(int*)array_get(lit->precisions, i))}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if ((*(bool*)array_get(lit->need_fmts, i))) { array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe01, {.d_c = (*(u8*)array_get(lit->fmts, i))}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } return (multi_return_string_bool){.arg0=Array_string_join(res, _S("")), .arg1=needs_braces}; } string v__ast__Expr_str(v__ast__Expr* x) { bool v__ast__Expr_str_defer_0 = false; i64 str_calls = sync__stdatomic__add_i64(&nested_expr_str_calls, 1); if (str_calls > 300) { #if defined(CUSTOM_DEFINE_panic_on_deeply_nested_expr_str_calls) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _S("/home/runner/work/v/v/vlib/v/ast/str.v:407, &ast.Expr{}.str")}}, {_S(": too many nested Expr.str() calls: "), 0xfe09, {.d_i64 = str_calls}}, {_S(", expr type: "), 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_sumtype_v__ast__Expr( (x)->_typ ))}}, {_SLIT0, 0, { .d_c = 0 }}}))); _v_exit(1); VUNREACHABLE(); } #endif return _S("{expression too deep}"); } v__ast__Expr_str_defer_0 = true; if (x->_typ == 336 /* v.ast.AnonFn */) { string _t3 = _S("anon_fn"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t3; } else if (x->_typ == 351 /* v.ast.ComptimeType */) { string _t4 = v__ast__ComptimeType_str((*x->_v__ast__ComptimeType)); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t4; } else if (x->_typ == 353 /* v.ast.DumpExpr */) { string _t5 = str_intp(2, _MOV((StrIntpData[]){{_S("dump("), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__DumpExpr).expr)}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t5; } else if (x->_typ == 338 /* v.ast.ArrayInit */) { Array_string fields = __new_array_with_default(0, 0, sizeof(string), 0); if ((*x->_v__ast__ArrayInit).has_len) { array_push((array*)&fields, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("len: "), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__ArrayInit).len_expr)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if ((*x->_v__ast__ArrayInit).has_cap) { array_push((array*)&fields, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("cap: "), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__ArrayInit).cap_expr)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if ((*x->_v__ast__ArrayInit).has_init) { array_push((array*)&fields, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("init: "), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__ArrayInit).init_expr)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } string typ_str = v__ast__Table_type_to_str(global_table, (*x->_v__ast__ArrayInit).elem_type); if (fields.len > 0) { if ((*x->_v__ast__ArrayInit).is_fixed) { string _t9 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = Array_v__ast__Expr_str((*x->_v__ast__ArrayInit).exprs)}}, {_SLIT0, 0xfe10, {.d_s = typ_str}}, {_S("{"), 0xfe10, {.d_s = Array_string_join(fields, _S(", "))}}, {_S("}"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t9; } else { string _t10 = str_intp(3, _MOV((StrIntpData[]){{_S("[]"), 0xfe10, {.d_s = typ_str}}, {_S("{"), 0xfe10, {.d_s = Array_string_join(fields, _S(", "))}}, {_S("}"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t10; } } else { if ((*x->_v__ast__ArrayInit).is_fixed) { string _t11 = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = Array_v__ast__Expr_str((*x->_v__ast__ArrayInit).exprs)}}, {_SLIT0, 0xfe10, {.d_s = typ_str}}, {_S("{}"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t11; } else { string _t12 = Array_v__ast__Expr_str((*x->_v__ast__ArrayInit).exprs); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t12; } } } else if (x->_typ == 339 /* v.ast.AsCast */) { string _t13 = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__AsCast).expr)}}, {_S(" as "), 0xfe10, {.d_s = v__ast__Table_type_to_str(global_table, (*x->_v__ast__AsCast).typ)}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t13; } else if (x->_typ == 341 /* v.ast.AtExpr */) { string _t14 = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*x->_v__ast__AtExpr).name}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t14; } else if (x->_typ == 343 /* v.ast.CTempVar */) { string _t15 = v__ast__Expr_str(&(*x->_v__ast__CTempVar).orig); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t15; } else if (x->_typ == 342 /* v.ast.BoolLiteral */) { string _t16 = bool_str((*x->_v__ast__BoolLiteral).val); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t16; } else if (x->_typ == 345 /* v.ast.CastExpr */) { string type_name = v__util__strip_main_name(v__ast__Table_type_to_str(global_table, (*x->_v__ast__CastExpr).typ)); string _t17 = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_name}}, {_S("("), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__CastExpr).expr)}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t17; } else if (x->_typ == 344 /* v.ast.CallExpr */) { string sargs = v__ast__args2str((*x->_v__ast__CallExpr).args); string propagate_suffix = ((*x->_v__ast__CallExpr).or_block.kind == v__ast__OrKind__propagate_option ? (_S("?")) : (*x->_v__ast__CallExpr).or_block.kind == v__ast__OrKind__propagate_result ? (_S("!")) : (_S(""))); if ((*x->_v__ast__CallExpr).is_method) { string _t18 = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__CallExpr).left)}}, {_S("."), 0xfe10, {.d_s = (*x->_v__ast__CallExpr).name}}, {_S("("), 0xfe10, {.d_s = sargs}}, {_S(")"), 0xfe10, {.d_s = propagate_suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t18; } if (string_starts_with((*x->_v__ast__CallExpr).name, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*x->_v__ast__CallExpr).mod}}, {_S("."), 0, { .d_c = 0 }}})))) { string _t19 = v__util__strip_main_name(str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__CallExpr_get_name(&(*x->_v__ast__CallExpr))}}, {_S("("), 0xfe10, {.d_s = sargs}}, {_S(")"), 0xfe10, {.d_s = propagate_suffix}}, {_SLIT0, 0, { .d_c = 0 }}}))); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t19; } if (((*x->_v__ast__CallExpr).mod).len == 0 && ((*x->_v__ast__CallExpr).name).len == 0) { string _t20 = string__plus(v__ast__Expr_str(&(*x->_v__ast__CallExpr).left), str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = sargs}}, {_S(")"), 0xfe10, {.d_s = propagate_suffix}}, {_SLIT0, 0, { .d_c = 0 }}}))); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t20; } if (string_contains((*x->_v__ast__CallExpr).name, _S("."))) { string _t21 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__CallExpr_get_name(&(*x->_v__ast__CallExpr))}}, {_S("("), 0xfe10, {.d_s = sargs}}, {_S(")"), 0xfe10, {.d_s = propagate_suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t21; } if ((*x->_v__ast__CallExpr).is_static_method) { string _t22 = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*x->_v__ast__CallExpr).mod}}, {_S("."), 0xfe10, {.d_s = v__ast__CallExpr_get_name(&(*x->_v__ast__CallExpr))}}, {_S("("), 0xfe10, {.d_s = sargs}}, {_S(")"), 0xfe10, {.d_s = propagate_suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t22; } if (fast_string_eq((*x->_v__ast__CallExpr).mod, _S("main"))) { string _t23 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__CallExpr_get_name(&(*x->_v__ast__CallExpr))}}, {_S("("), 0xfe10, {.d_s = sargs}}, {_S(")"), 0xfe10, {.d_s = propagate_suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t23; } else { string _t24 = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*x->_v__ast__CallExpr).mod}}, {_S("."), 0xfe10, {.d_s = v__ast__CallExpr_get_name(&(*x->_v__ast__CallExpr))}}, {_S("("), 0xfe10, {.d_s = sargs}}, {_S(")"), 0xfe10, {.d_s = propagate_suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t24; } } else if (x->_typ == 347 /* v.ast.CharLiteral */) { string _t25 = str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = (*x->_v__ast__CharLiteral).val}}, {_S("`"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t25; } else if (x->_typ == 348 /* v.ast.Comment */) { if ((*x->_v__ast__Comment).is_multi) { Array_string lines = string_split_into_lines((*x->_v__ast__Comment).text); string _t26 = str_intp(2, _MOV((StrIntpData[]){{_S("/* "), 0xfe07, {.d_i32 = lines.len}}, {_S(" lines comment */"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t26; } else { string text = string_trim_space(string_trim((*x->_v__ast__Comment).text, _S("\001"))); string _t27 = str_intp(2, _MOV((StrIntpData[]){{_S("\302\264// "), 0xfe10, {.d_s = text}}, {_S("\302\264"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t27; } } else if (x->_typ == 350 /* v.ast.ComptimeSelector */) { string _t28 = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__ComptimeSelector).left)}}, {_S(".$("), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__ComptimeSelector).field_expr)}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t28; } else if (x->_typ == 352 /* v.ast.ConcatExpr */) { Array_string _t30 = {0}; Array_v__ast__Expr _t30_orig = (*x->_v__ast__ConcatExpr).vals; int _t30_len = _t30_orig.len; _t30 = __new_array(0, _t30_len, sizeof(string)); for (int _t32 = 0; _t32 < _t30_len; ++_t32) { v__ast__Expr it = ((v__ast__Expr*) _t30_orig.data)[_t32]; string _t31 = v__ast__Expr_str(&it); array_push((array*)&_t30, &_t31); } string _t29 = Array_string_join( _t30, _S(",")); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t29; } else if (x->_typ == 355 /* v.ast.EnumVal */) { string _t33 = str_intp(2, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = (*x->_v__ast__EnumVal).val}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t33; } else if (x->_typ == 356 /* v.ast.FloatLiteral */) { string _t34 = string_clone((*x->_v__ast__FloatLiteral).val); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t34; } else if (x->_typ == 363 /* v.ast.IntegerLiteral */) { string _t35 = string_clone((*x->_v__ast__IntegerLiteral).val); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t35; } else if (x->_typ == 357 /* v.ast.GoExpr */) { string _t36 = str_intp(2, _MOV((StrIntpData[]){{_S("go "), 0xfe10, {.d_s = v__ast__CallExpr_str((*x->_v__ast__GoExpr).call_expr)}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t36; } else if (x->_typ == 381 /* v.ast.SpawnExpr */) { string _t37 = str_intp(2, _MOV((StrIntpData[]){{_S("spawn "), 0xfe10, {.d_s = v__ast__CallExpr_str((*x->_v__ast__SpawnExpr).call_expr)}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t37; } else if (x->_typ == 358 /* v.ast.Ident */) { if (((*x->_v__ast__Ident).cached_name).len != 0) { string _t38 = (*x->_v__ast__Ident).cached_name; // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t38; } { // Unsafe block (*x->_v__ast__Ident).cached_name = v__util__strip_main_name(string_clone((*x->_v__ast__Ident).name)); } string _t39 = (*x->_v__ast__Ident).cached_name; // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t39; } else if (x->_typ == 359 /* v.ast.IfExpr */) { Array_string parts = __new_array_with_default(0, 0, sizeof(string), 0); string dollar = ((*x->_v__ast__IfExpr).is_comptime ? (_S("$")) : (_S(""))); for (int i = 0; i < (*x->_v__ast__IfExpr).branches.len; ++i) { v__ast__IfBranch branch = ((v__ast__IfBranch*)(*x->_v__ast__IfExpr).branches.data)[i]; if (i != 0) { array_push((array*)&parts, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S(" } "), 0xfe10, {.d_s = dollar}}, {_S("else "), 0, { .d_c = 0 }}})) })); } if (i < (int)((*x->_v__ast__IfExpr).branches.len - 1) || !(*x->_v__ast__IfExpr).has_else) { array_push((array*)&parts, _MOV((string[]){ string__plus(string__plus(str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = dollar}}, {_S("if "), 0, { .d_c = 0 }}})), v__ast__Expr_str(&branch.cond)), _S(" { ")) })); } else if ((*x->_v__ast__IfExpr).has_else && i == (int)((*x->_v__ast__IfExpr).branches.len - 1)) { array_push((array*)&parts, _MOV((string[]){ _S("{ ") })); } for (int _t43 = 0; _t43 < branch.stmts.len; ++_t43) { v__ast__Stmt stmt = ((v__ast__Stmt*)branch.stmts.data)[_t43]; array_push((array*)&parts, _MOV((string[]){ v__ast__Stmt_str(stmt) })); } } array_push((array*)&parts, _MOV((string[]){ _S(" }") })); string _t46 = Array_string_join(parts, _S("")); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t46; } else if (x->_typ == 361 /* v.ast.IndexExpr */) { string _t47 = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__IndexExpr).left)}}, {_S("["), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__IndexExpr).index)}}, {_S("]"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t47; } else if (x->_typ == 362 /* v.ast.InfixExpr */) { string _t48 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__InfixExpr).left)}}, {_S(" "), 0xfe10, {.d_s = v__token__Kind_str((*x->_v__ast__InfixExpr).op)}}, {_S(" "), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__InfixExpr).right)}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t48; } else if (x->_typ == 368 /* v.ast.MapInit */) { Array_string pairs = __new_array_with_default(0, 0, sizeof(string), 0); for (int ik = 0; ik < (*x->_v__ast__MapInit).keys.len; ++ik) { v__ast__Expr kv = ((v__ast__Expr*)(*x->_v__ast__MapInit).keys.data)[ik]; string mv = v__ast__Expr_str(&(*(v__ast__Expr*)array_get((*x->_v__ast__MapInit).vals, ik))); array_push((array*)&pairs, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&kv)}}, {_S(": "), 0xfe10, {.d_s = mv}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if ((*x->_v__ast__MapInit).has_update_expr) { string _t50 = str_intp(3, _MOV((StrIntpData[]){{_S("map{ ..."), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__MapInit).update_expr)}}, {_S(" "), 0xfe10, {.d_s = Array_string_join(pairs, _S(" "))}}, {_S(" }"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t50; } string _t51 = str_intp(2, _MOV((StrIntpData[]){{_S("map{ "), 0xfe10, {.d_s = Array_string_join(pairs, _S(" "))}}, {_S(" }"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t51; } else if (x->_typ == 370 /* v.ast.Nil */) { string _t52 = _S("nil"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t52; } else if (x->_typ == 374 /* v.ast.ParExpr */) { string _t53 = str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__ParExpr).expr)}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t53; } else if (x->_typ == 375 /* v.ast.PostfixExpr */) { if ((*x->_v__ast__PostfixExpr).op == v__token__Kind__question) { string _t54 = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__PostfixExpr).expr)}}, {_S(" ?"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t54; } string _t55 = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__PostfixExpr).expr)}}, {_SLIT0, 0xfe10, {.d_s = v__token__Kind_str((*x->_v__ast__PostfixExpr).op)}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t55; } else if (x->_typ == 376 /* v.ast.PrefixExpr */) { string _t56 = string__plus(v__token__Kind_str((*x->_v__ast__PrefixExpr).op), v__ast__Expr_str(&(*x->_v__ast__PrefixExpr).right)); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t56; } else if (x->_typ == 377 /* v.ast.RangeExpr */) { string s = _S(".."); if ((*x->_v__ast__RangeExpr).has_low) { s = string__plus(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__RangeExpr).low)}}, {_S(" "), 0, { .d_c = 0 }}})), s); } if ((*x->_v__ast__RangeExpr).has_high) { s = string__plus(s, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__RangeExpr).high)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } string _t57 = s; // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t57; } else if (x->_typ == 378 /* v.ast.SelectExpr */) { string _t58 = _S("ast.SelectExpr"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t58; } else if (x->_typ == 379 /* v.ast.SelectorExpr */) { string propagate_suffix = ((*x->_v__ast__SelectorExpr).or_block.kind == v__ast__OrKind__propagate_option ? (_S("?")) : (*x->_v__ast__SelectorExpr).or_block.kind == v__ast__OrKind__propagate_result ? (_S("!")) : (_S(""))); string _t59 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__SelectorExpr).expr)}}, {_S("."), 0xfe10, {.d_s = (*x->_v__ast__SelectorExpr).field_name}}, {_SLIT0, 0xfe10, {.d_s = propagate_suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t59; } else if (x->_typ == 380 /* v.ast.SizeOf */) { if ((*x->_v__ast__SizeOf).is_type) { string _t60 = str_intp(2, _MOV((StrIntpData[]){{_S("sizeof("), 0xfe10, {.d_s = v__ast__Table_type_to_str(global_table, (*x->_v__ast__SizeOf).typ)}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t60; } string _t61 = str_intp(2, _MOV((StrIntpData[]){{_S("sizeof("), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__SizeOf).expr)}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t61; } else if (x->_typ == 372 /* v.ast.OffsetOf */) { string _t62 = str_intp(3, _MOV((StrIntpData[]){{_S("__offsetof("), 0xfe10, {.d_s = v__ast__Table_type_to_str(global_table, (*x->_v__ast__OffsetOf).struct_type)}}, {_S(", "), 0xfe10, {.d_s = (*x->_v__ast__OffsetOf).field}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t62; } else if (x->_typ == 383 /* v.ast.StringInterLiteral */) { strings__Builder res = strings__new_builder(50); strings__Builder_write_string(&res, _S("'")); for (int i = 0; i < (*x->_v__ast__StringInterLiteral).vals.len; ++i) { string val = ((string*)(*x->_v__ast__StringInterLiteral).vals.data)[i]; strings__Builder_write_string(&res, val); if (i >= (*x->_v__ast__StringInterLiteral).exprs.len) { break; } strings__Builder_write_string(&res, _S("$")); multi_return_string_bool mr_16201 = v__ast__StringInterLiteral_get_fspec_braces(&(*x->_v__ast__StringInterLiteral), i); string fspec_str = mr_16201.arg0; bool needs_braces = mr_16201.arg1; if (needs_braces) { strings__Builder_write_string(&res, _S("{")); strings__Builder_write_string(&res, v__ast__Expr_str(&(*(v__ast__Expr*)array_get((*x->_v__ast__StringInterLiteral).exprs, i)))); strings__Builder_write_string(&res, fspec_str); strings__Builder_write_string(&res, _S("}")); } else { strings__Builder_write_string(&res, v__ast__Expr_str(&(*(v__ast__Expr*)array_get((*x->_v__ast__StringInterLiteral).exprs, i)))); } } strings__Builder_write_string(&res, _S("'")); string _t63 = strings__Builder_str(&res); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t63; } else if (x->_typ == 384 /* v.ast.StringLiteral */) { string _t64 = str_intp(2, _MOV((StrIntpData[]){{_S("'"), 0xfe10, {.d_s = (*x->_v__ast__StringLiteral).val}}, {_S("'"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t64; } else if (x->_typ == 386 /* v.ast.TypeNode */) { string opt_prefix = (v__ast__Type_has_flag((*x->_v__ast__TypeNode).typ, v__ast__TypeFlag__option) ? (_S("?")) : (_S(""))); string _t65 = str_intp(3, _MOV((StrIntpData[]){{_S("TypeNode("), 0xfe10, {.d_s = opt_prefix}}, {_SLIT0, 0xfe10, {.d_s = v__ast__Table_type_str(global_table, (*x->_v__ast__TypeNode).typ)}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t65; } else if (x->_typ == 387 /* v.ast.TypeOf */) { if ((*x->_v__ast__TypeOf).is_type) { string _t66 = str_intp(2, _MOV((StrIntpData[]){{_S("typeof["), 0xfe10, {.d_s = v__ast__Table_type_to_str(global_table, (*x->_v__ast__TypeOf).typ)}}, {_S("]()"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t66; } string _t67 = str_intp(2, _MOV((StrIntpData[]){{_S("typeof("), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__TypeOf).expr)}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t67; } else if (x->_typ == 365 /* v.ast.LambdaExpr */) { Array_string _t68 = {0}; Array_v__ast__Ident _t68_orig = (*x->_v__ast__LambdaExpr).params; int _t68_len = _t68_orig.len; _t68 = __new_array(0, _t68_len, sizeof(string)); for (int _t70 = 0; _t70 < _t68_len; ++_t70) { v__ast__Ident it = ((v__ast__Ident*) _t68_orig.data)[_t70]; string _t69 = it.name; array_push((array*)&_t68, &_t69); } string ilist = Array_string_join(_t68, _S(", ")); string _t71 = str_intp(3, _MOV((StrIntpData[]){{_S("|"), 0xfe10, {.d_s = ilist}}, {_S("| "), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__LambdaExpr).expr)}}, {_SLIT0, 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t71; } else if (x->_typ == 366 /* v.ast.Likely */) { string _t72 = str_intp(2, _MOV((StrIntpData[]){{_S("_likely_("), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__Likely).expr)}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t72; } else if (x->_typ == 388 /* v.ast.UnsafeExpr */) { string _t73 = str_intp(2, _MOV((StrIntpData[]){{_S("unsafe { "), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__UnsafeExpr).expr)}}, {_S(" }"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t73; } else if (x->_typ == 371 /* v.ast.None */) { string _t74 = _S("none"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t74; } else if (x->_typ == 364 /* v.ast.IsRefType */) { if ((*x->_v__ast__IsRefType).is_type) { string _t75 = str_intp(2, _MOV((StrIntpData[]){{_S("isreftype("), 0xfe10, {.d_s = v__ast__Table_type_to_str(global_table, (*x->_v__ast__IsRefType).typ)}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t75; } string _t76 = str_intp(2, _MOV((StrIntpData[]){{_S("isreftype("), 0xfe10, {.d_s = v__ast__Expr_str(&(*x->_v__ast__IsRefType).expr)}}, {_S(")"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t76; } else if (x->_typ == 360 /* v.ast.IfGuardExpr */) { string s = _S(""); for (int i = 0; i < (*x->_v__ast__IfGuardExpr).vars.len; ++i) { v__ast__IfGuardVar var = ((v__ast__IfGuardVar*)(*x->_v__ast__IfGuardExpr).vars.data)[i]; s = string__plus(s, var.name); if (i != (int)((*x->_v__ast__IfGuardExpr).vars.len - 1)) { s = string__plus(s, _S(", ")); } } string _t77 = string__plus(string__plus(s, _S(" := ")), v__ast__Expr_str(&(*x->_v__ast__IfGuardExpr).expr)); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t77; } else if (x->_typ == 385 /* v.ast.StructInit */) { string sname = v__ast__Table_sym(global_table, (*x->_v__ast__StructInit).typ)->name; string _t78 = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sname}}, {_S("{....}"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t78; } else if (x->_typ == 337 /* v.ast.ArrayDecompose */) { string _t79 = _S("ast.ArrayDecompose"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t79; } else if (x->_typ == 340 /* v.ast.Assoc */) { string _t80 = _S("ast.Assoc"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t80; } else if (x->_typ == 346 /* v.ast.ChanInit */) { string _t81 = _S("ast.ChanInit"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t81; } else if (x->_typ == 349 /* v.ast.ComptimeCall */) { string _t82 = v__ast__ComptimeCall_expr_str((*x->_v__ast__ComptimeCall)); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t82; } else if (x->_typ == 354 /* v.ast.EmptyExpr */) { string _t83 = _S("ast.EmptyExpr"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t83; } else if (x->_typ == 367 /* v.ast.LockExpr */) { string _t84 = _S("ast.LockExpr"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t84; } else if (x->_typ == 369 /* v.ast.MatchExpr */) { string _t85 = _S("ast.MatchExpr"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t85; } else if (x->_typ == 335 /* v.ast.NodeError */) { string _t86 = _S("ast.NodeError"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t86; } else if (x->_typ == 373 /* v.ast.OrExpr */) { string _t87 = _S("ast.OrExpr"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t87; } else if (x->_typ == 382 /* v.ast.SqlExpr */) { string _t88 = _S("ast.SqlExpr"); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t88; } string _t89 = str_intp(2, _MOV((StrIntpData[]){{_S("[unhandled expr type "), 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_sumtype_v__ast__Expr( (x)->_typ ))}}, {_S("]"), 0, { .d_c = 0 }}})); // Defer begin if (v__ast__Expr_str_defer_0) { sync__stdatomic__sub_i64(&nested_expr_str_calls, 1); } // Defer end return _t89; } string v__ast__CallArg_str(v__ast__CallArg a) { if (a.is_mut) { return str_intp(2, _MOV((StrIntpData[]){{_S("mut "), 0xfe10, {.d_s = v__ast__Expr_str(&a.expr)}}, {_SLIT0, 0, { .d_c = 0 }}})); } return str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&a.expr)}}, {_SLIT0, 0, { .d_c = 0 }}})); } string v__ast__args2str(Array_v__ast__CallArg args) { Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < args.len; ++_t1) { v__ast__CallArg a = ((v__ast__CallArg*)args.data)[_t1]; array_push((array*)&res, _MOV((string[]){ v__ast__CallArg_str(a) })); } return Array_string_join(res, _S(", ")); } string v__ast__BranchStmt_str(v__ast__BranchStmt* node) { string s = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__token__Kind_str(node->kind)}}, {_SLIT0, 0, { .d_c = 0 }}})); if (node->label.len > 0) { s = string__plus(s, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = node->label}}, {_SLIT0, 0, { .d_c = 0 }}}))); } return s; } string v__ast__Stmt_str(v__ast__Stmt node) { if (node._typ == 391 /* v.ast.AssertStmt */) { return str_intp(2, _MOV((StrIntpData[]){{_S("assert "), 0xfe10, {.d_s = v__ast__Expr_str(&(*node._v__ast__AssertStmt).expr)}}, {_SLIT0, 0, { .d_c = 0 }}})); } else if (node._typ == 392 /* v.ast.AssignStmt */) { string out = _S(""); for (int i = 0; i < (*node._v__ast__AssignStmt).left.len; ++i) { v__ast__Expr left = ((v__ast__Expr*)(*node._v__ast__AssignStmt).left.data)[i]; if ((left)._typ == 358 /* v.ast.Ident */) { v__ast__IdentVar var_info = v__ast__Ident_var_info(&(*left._v__ast__Ident)); if (var_info.is_mut) { out = string__plus(out, _S("mut ")); } } out = string__plus(out, v__ast__Expr_str(&left)); if (i < (int)((*node._v__ast__AssignStmt).left.len - 1)) { out = string__plus(out, _S(",")); } } out = string__plus(out, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = v__token__Kind_str((*node._v__ast__AssignStmt).op)}}, {_S(" "), 0, { .d_c = 0 }}}))); for (int i = 0; i < (*node._v__ast__AssignStmt).right.len; ++i) { v__ast__Expr val = ((v__ast__Expr*)(*node._v__ast__AssignStmt).right.data)[i]; out = string__plus(out, v__ast__Expr_str(&val)); if (i < (int)((*node._v__ast__AssignStmt).right.len - 1)) { out = string__plus(out, _S(",")); } } return out; } else if (node._typ == 393 /* v.ast.Block */) { string res = _S(""); res = string__plus(res, _S("{")); for (int _t3 = 0; _t3 < (*node._v__ast__Block).stmts.len; ++_t3) { v__ast__Stmt s = ((v__ast__Stmt*)(*node._v__ast__Block).stmts.data)[_t3]; res = string__plus(res, v__ast__Stmt_str(s)); res = string__plus(res, _S(";")); } res = string__plus(res, _S("}")); return res; } else if (node._typ == 394 /* v.ast.BranchStmt */) { return v__ast__BranchStmt_str(&(*node._v__ast__BranchStmt)); } else if (node._typ == 396 /* v.ast.ConstDecl */) { Array_string _t7 = {0}; Array_v__ast__ConstField _t7_orig = (*node._v__ast__ConstDecl).fields; int _t7_len = _t7_orig.len; _t7 = __new_array(0, _t7_len, sizeof(string)); for (int _t9 = 0; _t9 < _t7_len; ++_t9) { v__ast__ConstField it = ((v__ast__ConstField*) _t7_orig.data)[_t9]; string _t8 = v__ast__field_to_string(it); array_push((array*)&_t7, &_t8); } return Array_string_join( _t7, _S("")); } else if (node._typ == 398 /* v.ast.DeferStmt */) { string res = _S(""); res = string__plus(res, _S("defer {")); for (int _t10 = 0; _t10 < (*node._v__ast__DeferStmt).stmts.len; ++_t10) { v__ast__Stmt s = ((v__ast__Stmt*)(*node._v__ast__DeferStmt).stmts.data)[_t10]; res = string__plus(res, v__ast__Stmt_str(s)); res = string__plus(res, _S(";")); } res = string__plus(res, _S("}")); return res; } else if (node._typ == 400 /* v.ast.EnumDecl */) { return str_intp(3, _MOV((StrIntpData[]){{_S("enum "), 0xfe10, {.d_s = (*node._v__ast__EnumDecl).name}}, {_S(" { "), 0xfe07, {.d_i32 = (*node._v__ast__EnumDecl).fields.len}}, {_S(" fields }"), 0, { .d_c = 0 }}})); } else if (node._typ == 401 /* v.ast.ExprStmt */) { return v__ast__Expr_str(&(*node._v__ast__ExprStmt).expr); } else if (node._typ == 237 /* v.ast.FnDecl */) { return str_intp(4, _MOV((StrIntpData[]){{_S("fn "), 0xfe10, {.d_s = (*node._v__ast__FnDecl).name}}, {_S("( "), 0xfe07, {.d_i32 = (*node._v__ast__FnDecl).params.len}}, {_S(" params ) { "), 0xfe07, {.d_i32 = (*node._v__ast__FnDecl).stmts.len}}, {_S(" stmts }"), 0, { .d_c = 0 }}})); } else if (node._typ == 403 /* v.ast.ForInStmt */) { string res = _S(""); if ((*node._v__ast__ForInStmt).label.len > 0) { res = string__plus(res, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*node._v__ast__ForInStmt).label}}, {_S(": "), 0, { .d_c = 0 }}}))); } res = string__plus(res, _S("for ")); if (((*node._v__ast__ForInStmt).key_var).len != 0) { res = string__plus(res, (*node._v__ast__ForInStmt).key_var); } if (((*node._v__ast__ForInStmt).key_var).len != 0 && ((*node._v__ast__ForInStmt).val_var).len != 0) { res = string__plus(res, _S(", ")); } if (((*node._v__ast__ForInStmt).val_var).len != 0) { if ((*node._v__ast__ForInStmt).val_is_mut) { res = string__plus(res, _S("mut ")); } res = string__plus(res, (*node._v__ast__ForInStmt).val_var); } res = string__plus(res, _S(" in ")); res = string__plus(res, v__ast__Expr_str(&(*node._v__ast__ForInStmt).cond)); if ((*node._v__ast__ForInStmt).is_range) { res = string__plus(res, _S(" .. ")); res = string__plus(res, v__ast__Expr_str(&(*node._v__ast__ForInStmt).high)); } res = string__plus(res, _S(" {")); return res; } else if (node._typ == 404 /* v.ast.ForStmt */) { if ((*node._v__ast__ForStmt).is_inf) { return _S("for {"); } return str_intp(2, _MOV((StrIntpData[]){{_S("for "), 0xfe10, {.d_s = v__ast__Expr_str(&(*node._v__ast__ForStmt).cond)}}, {_S(" {"), 0, { .d_c = 0 }}})); } else if (node._typ == 405 /* v.ast.GlobalDecl */) { string res = _S(""); if ((*node._v__ast__GlobalDecl).fields.len == 0 && (*node._v__ast__GlobalDecl).pos.line_nr == (*node._v__ast__GlobalDecl).pos.last_line) { return _S("__global ()"); } res = string__plus(res, _S("__global ")); if ((*node._v__ast__GlobalDecl).is_block) { res = string__plus(res, _S("( ")); } for (int _t19 = 0; _t19 < (*node._v__ast__GlobalDecl).fields.len; ++_t19) { v__ast__GlobalField field = ((v__ast__GlobalField*)(*node._v__ast__GlobalDecl).fields.data)[_t19]; if (field.is_volatile) { res = string__plus(res, _S("volatile ")); } res = string__plus(res, field.name); res = string__plus(res, _S(" ")); if (field.has_expr) { res = string__plus(res, _S("= ")); res = string__plus(res, v__ast__Expr_str(&field.expr)); } else { res = string__plus(res, v__ast__Table_type_to_str(global_table, field.typ)); } res = string__plus(res, _S(";")); } if ((*node._v__ast__GlobalDecl).is_block) { res = string__plus(res, _S(" )")); } return res; } else if (node._typ == 409 /* v.ast.Import */) { string out = str_intp(2, _MOV((StrIntpData[]){{_S("import "), 0xfe10, {.d_s = (*node._v__ast__Import).mod}}, {_SLIT0, 0, { .d_c = 0 }}})); if ((*node._v__ast__Import).alias.len > 0) { out = string__plus(out, str_intp(2, _MOV((StrIntpData[]){{_S(" as "), 0xfe10, {.d_s = (*node._v__ast__Import).alias}}, {_SLIT0, 0, { .d_c = 0 }}}))); } return out; } else if (node._typ == 411 /* v.ast.Module */) { return str_intp(2, _MOV((StrIntpData[]){{_S("module "), 0xfe10, {.d_s = (*node._v__ast__Module).name}}, {_SLIT0, 0, { .d_c = 0 }}})); } else if (node._typ == 412 /* v.ast.Return */) { string out = _S("return"); for (int i = 0; i < (*node._v__ast__Return).exprs.len; ++i) { v__ast__Expr val = ((v__ast__Expr*)(*node._v__ast__Return).exprs.data)[i]; out = string__plus(out, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = v__ast__Expr_str(&val)}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (i < (int)((*node._v__ast__Return).exprs.len - 1)) { out = string__plus(out, _S(",")); } } return out; } else if (node._typ == 415 /* v.ast.StructDecl */) { return str_intp(3, _MOV((StrIntpData[]){{_S("struct "), 0xfe10, {.d_s = (*node._v__ast__StructDecl).name}}, {_S(" { "), 0xfe07, {.d_i32 = (*node._v__ast__StructDecl).fields.len}}, {_S(" fields }"), 0, { .d_c = 0 }}})); } else { return str_intp(2, _MOV((StrIntpData[]){{_S("[unhandled stmt str type: "), 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_sumtype_v__ast__Stmt( (node)._typ ))}}, {_S(" ]"), 0, { .d_c = 0 }}})); } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC string v__ast__field_to_string(v__ast__ConstField f) { string x = string_trim_string_left(f.name, string__plus(f.mod, _S("."))); return str_intp(3, _MOV((StrIntpData[]){{_S("const "), 0xfe10, {.d_s = x}}, {_S(" = "), 0xfe10, {.d_s = v__ast__Expr_str(&f.expr)}}, {_S(";"), 0, { .d_c = 0 }}})); } string v__ast__ComptimeForKind_str(v__ast__ComptimeForKind e) { switch (e) { case v__ast__ComptimeForKind__methods: { return _S("methods"); } case v__ast__ComptimeForKind__fields: { return _S("fields"); } case v__ast__ComptimeForKind__attributes: { return _S("attributes"); } case v__ast__ComptimeForKind__values: { return _S("values"); } case v__ast__ComptimeForKind__variants: { return _S("variants"); } case v__ast__ComptimeForKind__params: { return _S("params"); } } return (string){.str=(byteptr)"", .is_lit=1}; } void v__ast__UsedFeatures_free(v__ast__UsedFeatures* uf) { { // Unsafe block map_free(&uf->print_types); map_free(&uf->used_fns); map_free(&uf->used_consts); map_free(&uf->used_globals); array_free(&uf->used_veb_types); } } void v__ast__Table_free(v__ast__Table* t) { { // Unsafe block for (int _t1 = 0; _t1 < t->type_symbols.len; ++_t1) { v__ast__TypeSymbol* s = ((v__ast__TypeSymbol**)t->type_symbols.data)[_t1]; v__ast__TypeSymbol_free(s); } array_free(&t->type_symbols); map_free(&t->type_idxs); map_free(&t->fns); map_free(&t->dumps); Array_string_free(&t->imports); Array_string_free(&t->modules); array_free(&t->cflags); Array_string_free(&t->redefined_fns); map_free(&t->fn_generic_types); string_free(&t->cmod_prefix); v__ast__UsedFeatures_free(t->used_features); } } VV_LOC void v__ast__default_table_panic_handler(v__ast__Table* _t, string message) { _v_panic(message); VUNREACHABLE(); } void v__ast__Table_panic(v__ast__Table* t, string message) { v__ast__Table* mt = ((v__ast__Table*)(t)); mt->panic_npanics++; t->panic_handler(t, message); } v__ast__Table* v__ast__new_table(void) { v__ast__Table* t = ((v__ast__Table*)memdup(&(v__ast__Table){.parsing_type = (string){.str=(byteptr)"", .is_lit=1},.type_symbols = __new_array(0, 0, sizeof(v__ast__TypeSymbol*)),.type_idxs = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.fns = new_map(sizeof(string), sizeof(v__ast__Fn), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.iface_types = new_map(sizeof(string), sizeof(Array_v__ast__Type), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.dumps = new_map(sizeof(int), sizeof(string), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.imports = __new_array(0, 0, sizeof(string)),.modules = __new_array(0, 0, sizeof(string)),.global_scope = ((v__ast__Scope*)memdup(&(v__ast__Scope){.objects = new_map(sizeof(string), sizeof(v__ast__ScopeObject), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.struct_fields = new_map(sizeof(string), sizeof(v__ast__ScopeStructField), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.parent = ((void*)0),.detached_from_parent = 0,.children = __new_array(0, 0, sizeof(v__ast__Scope*)),.start_pos = 0,.end_pos = 0,}, sizeof(v__ast__Scope))),.cflags = __new_array(0, 0, sizeof(v__cflag__CFlag)),.redefined_fns = __new_array(0, 0, sizeof(string)),.fn_generic_types = new_map(sizeof(string), sizeof(Array_Array_v__ast__Type), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.interfaces = new_map(sizeof(int), sizeof(v__ast__InterfaceDecl), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.sumtypes = new_map(sizeof(int), sizeof(v__ast__SumTypeDecl), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.cmod_prefix = (string){.str=(byteptr)"", .is_lit=1},.is_fmt = 0,.used_features = ((v__ast__UsedFeatures*)memdup(&(v__ast__UsedFeatures){.dump = 0,.index = 0,.range_index = 0,.cast_ptr = 0,.anon_fn = 0,.auto_str = 0,.auto_str_ptr = 0,.arr_prepend = 0,.arr_insert = 0,.arr_first = 0,.arr_last = 0,.arr_pop = 0,.arr_delete = 0,.arr_reverse = 0,.arr_map = 0,.type_name = 0,.print_options = 0,.print_types = new_map(sizeof(int), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.used_fns = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.used_consts = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.used_globals = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.used_syms = new_map(sizeof(int), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.used_veb_types = __new_array(0, 0, sizeof(v__ast__Type)),.used_maps = 0,.used_none = 0,.comptime_calls = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.comptime_syms = new_map(sizeof(v__ast__Type), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),}, sizeof(v__ast__UsedFeatures))),.veb_res_idx_cache = 0,.veb_ctx_idx_cache = 0,.panic_handler = v__ast__default_table_panic_handler,.panic_userdata = ((void*)0),.panic_npanics = 0,.cur_fn = ((void*)0),.cur_lambda = ((void*)0),.cur_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.gostmts = 0,.enum_decls = new_map(sizeof(string), sizeof(v__ast__EnumDecl), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.module_deprecated = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.module_attrs = new_map(sizeof(string), sizeof(Array_v__ast__Attr), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.builtin_pub_fns = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.pointer_size = 0,.cached_type_to_str = (__shared__Map_u64_string*)__dup__shared__Map_u64_string(&(__shared__Map_u64_string){.mtx= {0}, .val=new_map(sizeof(u64), sizeof(string), &map_hash_int_8, &map_eq_int_8, &map_clone_int_8, &map_free_nop)}, sizeof(__shared__Map_u64_string)),.anon_struct_names = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.anon_struct_counter = 0,.anon_union_names = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.anon_union_counter = 0,}, sizeof(v__ast__Table))); v__ast__Table_register_builtin_type_symbols(t); t->is_fmt = true; global_table = t; return t; } string v__ast__Table_fn_type_signature(v__ast__Table* t, v__ast__Fn* f) { string sig = _S(""); for (int i = 0; i < f->params.len; ++i) { v__ast__Param arg = ((v__ast__Param*)f->params.data)[i]; v__ast__Type typ = v__ast__Type_set_nr_muls(arg.typ, 0); if (arg.is_mut) { sig = string__plus(sig, _S("mut_")); } sig = string__plus(sig, string_to_lower_ascii(v__ast__Table_sym(t, typ)->cname)); if (i < (int)(f->params.len - 1)) { sig = string__plus(sig, _S("_")); } } if (f->return_type != 0 && f->return_type != _const_v__ast__void_type) { v__ast__TypeSymbol* sym = v__ast__Table_sym(t, f->return_type); string opt = (v__ast__Type_has_flag(f->return_type, v__ast__TypeFlag__option) ? (_S("option_")) : (_S(""))); string res = (v__ast__Type_has_flag(f->return_type, v__ast__TypeFlag__result) ? (_S("result_")) : (_S(""))); sig = string__plus(sig, str_intp(4, _MOV((StrIntpData[]){{_S("__"), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}}))); } return sig; } string v__ast__Table_fn_type_source_signature(v__ast__Table* t, v__ast__Fn* f) { string sig = _S("("); for (int i = 0; i < f->params.len; ++i) { v__ast__Param arg = ((v__ast__Param*)f->params.data)[i]; if (arg.is_mut) { sig = string__plus(sig, _S("mut ")); } if (t->is_fmt && (arg.name).len != 0) { sig = string__plus(sig, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg.name}}, {_S(" "), 0, { .d_c = 0 }}}))); } v__ast__TypeSymbol* arg_type_sym = v__ast__Table_sym(t, arg.typ); sig = string__plus(sig, arg_type_sym->name); if (i < (int)(f->params.len - 1)) { sig = string__plus(sig, _S(", ")); } } sig = string__plus(sig, _S(")")); if (f->return_type == _const_v__ast__ovoid_type) { sig = string__plus(sig, _S(" ?")); } else if (f->return_type == _const_v__ast__rvoid_type) { sig = string__plus(sig, _S(" !")); } else if (f->return_type != _const_v__ast__void_type && f->return_type != 0) { v__ast__TypeSymbol* return_type_sym = v__ast__Table_sym(t, f->return_type); if (v__ast__Type_has_flag(f->return_type, v__ast__TypeFlag__option)) { sig = string__plus(sig, str_intp(2, _MOV((StrIntpData[]){{_S(" ?"), 0xfe10, {.d_s = return_type_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else if (v__ast__Type_has_flag(f->return_type, v__ast__TypeFlag__result)) { sig = string__plus(sig, str_intp(2, _MOV((StrIntpData[]){{_S(" !"), 0xfe10, {.d_s = return_type_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else { sig = string__plus(sig, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = return_type_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } return sig; } string v__ast__Table_is_same_method(v__ast__Table* t, v__ast__Fn* f, v__ast__Fn* func) { if (f->return_type != func->return_type) { string s = v__ast__Table_type_to_str(t, f->return_type); return str_intp(2, _MOV((StrIntpData[]){{_S("expected return type `"), 0xfe10, {.d_s = s}}, {_S("`"), 0, { .d_c = 0 }}})); } if (f->params.len != func->params.len) { return str_intp(3, _MOV((StrIntpData[]){{_S("expected "), 0xfe07, {.d_i32 = f->params.len}}, {_S(" parameter(s), not "), 0xfe07, {.d_i32 = func->params.len}}, {_SLIT0, 0, { .d_c = 0 }}})); } for (int i = 0; i < f->params.len; ++i) { bool has_unexpected_type = i > 0 && (*(v__ast__Param*)array_get(f->params, i)).typ != (*(v__ast__Param*)array_get(func->params, i)).typ; v__ast__TypeSymbol* lsym = v__ast__Table_sym(t, (*(v__ast__Param*)array_get(f->params, i)).typ); v__ast__TypeSymbol* rsym = v__ast__Table_sym(t, (*(v__ast__Param*)array_get(func->params, i)).typ); if (lsym->language == v__ast__Language__js && rsym->language == v__ast__Language__js) { return _S(""); } bool has_unexpected_mutability = !(*(v__ast__Param*)array_get(f->params, i)).is_mut && (*(v__ast__Param*)array_get(func->params, i)).is_mut; if (has_unexpected_type || has_unexpected_mutability) { string exps = v__ast__Table_type_to_str(t, (*(v__ast__Param*)array_get(f->params, i)).typ); string gots = v__ast__Table_type_to_str(t, (*(v__ast__Param*)array_get(func->params, i)).typ); if (has_unexpected_type) { return str_intp(4, _MOV((StrIntpData[]){{_S("expected `"), 0xfe10, {.d_s = exps}}, {_S("`, not `"), 0xfe10, {.d_s = gots}}, {_S("` for parameter "), 0xfe07, {.d_i32 = i}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { return str_intp(3, _MOV((StrIntpData[]){{_S("expected `"), 0xfe10, {.d_s = exps}}, {_S("` which is immutable, not `mut "), 0xfe10, {.d_s = gots}}, {_S("`"), 0, { .d_c = 0 }}})); } } } return _S(""); } _option_v__ast__Fn v__ast__Table_find_fn(v__ast__Table* t, string name) { v__ast__Fn* _t2 = (v__ast__Fn*)(map_get_check(ADDR(map, t->fns), &(string[]){name})); _option_v__ast__Fn _t1 = {0}; if (_t2) { *((v__ast__Fn*)&_t1.data) = *((v__ast__Fn*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { v__ast__Fn f = (*(v__ast__Fn*)_t1.data); _option_v__ast__Fn _t3; _option_ok(&(v__ast__Fn[]) { f }, (_option*)(&_t3), sizeof(v__ast__Fn)); return _t3; } return (_option_v__ast__Fn){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } bool v__ast__Table_known_fn(v__ast__Table* t, string name) { _option_v__ast__Fn _t1 = v__ast__Table_find_fn(t, name); if (_t1.state != 0) { IError err = _t1.err; return false; } ; return true; } void v__ast__Table_register_fn(v__ast__Table* t, v__ast__Fn new_fn) { (*(v__ast__Fn*)map_get_and_set((map*)&t->fns, &(string[]){new_fn.name}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })) = new_fn; if (new_fn.is_pub && fast_string_eq(new_fn.mod, _S("builtin"))) { map_set(&t->builtin_pub_fns, &(string[]){new_fn.name}, &(bool[]) { true }); } } void v__ast__Table_register_interface(v__ast__Table* t, v__ast__InterfaceDecl idecl) { (*(v__ast__InterfaceDecl*)map_get_and_set((map*)&t->interfaces, &(int[]){idecl.typ}, &(v__ast__InterfaceDecl[]){ (v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,} })) = idecl; } void v__ast__Table_register_sumtype(v__ast__Table* t, v__ast__SumTypeDecl sumtyp) { (*(v__ast__SumTypeDecl*)map_get_and_set((map*)&t->sumtypes, &(int[]){sumtyp.typ}, &(v__ast__SumTypeDecl[]){ (v__ast__SumTypeDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.variants = __new_array(0, 0, sizeof(v__ast__TypeNode)),.is_markused = 0,} })) = sumtyp; } int v__ast__TypeSymbol_register_method(v__ast__TypeSymbol* t, v__ast__Fn new_fn) { array_push((array*)&t->methods, _MOV((v__ast__Fn[]){ new_fn })); return (int)(t->methods.len - 1); } int v__ast__TypeSymbol_update_method(v__ast__TypeSymbol* t, v__ast__Fn f) { for (int i = 0; i < t->methods.len; ++i) { v__ast__Fn m = ((v__ast__Fn*)t->methods.data)[i]; if (string__eq(m.name, f.name)) { array_set(&t->methods, i, &(v__ast__Fn[]) { f }); return i; } } return -1; } _result_v__ast__Fn v__ast__Table_register_aggregate_method(v__ast__Table* t, v__ast__TypeSymbol* sym, string name) { if (sym->kind != v__ast__Kind__aggregate) { v__ast__Table_panic(t, str_intp(4, _MOV((StrIntpData[]){{_S("table.register_aggregate_method: sym.name: "), 0xfe10, {.d_s = sym->name}}, {_S(", sym.kind: "), 0xfe10, {.d_s = v__ast__Kind_str(sym->kind)}}, {_S(" is not an aggregate, name: "), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } v__ast__Aggregate agg_info = *(v__ast__Aggregate*)__as_cast((sym->info)._v__ast__Aggregate,(sym->info)._typ, 537); bool found_once = false; v__ast__Fn new_fn = ((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); for (int _t1 = 0; _t1 < agg_info.types.len; ++_t1) { v__ast__Type typ = ((v__ast__Type*)agg_info.types.data)[_t1]; v__ast__TypeSymbol* ts = v__ast__Table_sym(t, typ); _option_v__ast__Fn _t2; if (_t2 = v__ast__TypeSymbol_find_method(ts, name), _t2.state == 0) { v__ast__Fn type_method = *(v__ast__Fn*)_t2.data; if (!found_once) { found_once = true; new_fn = type_method; } else if (!v__ast__Fn_method_equals(&new_fn, (voidptr)&type_method)) { return (_result_v__ast__Fn){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("method `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(t, typ)}}, {_S("."), 0xfe10, {.d_s = name}}, {_S("` signature is different"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } else { IError err = _t2.err; return (_result_v__ast__Fn){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("unknown method: `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(t, typ)}}, {_S("."), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } v__ast__TypeSymbol_register_method(sym, new_fn); _result_v__ast__Fn _t5 = {0}; _result_ok(&(v__ast__Fn[]) { new_fn }, (_result*)(&_t5), sizeof(v__ast__Fn)); return _t5; } _result_v__ast__Fn v__ast__Table_find_method(v__ast__Table* t, v__ast__TypeSymbol* s, string name) { v__ast__TypeSymbol* ts = s; for (;;) { _option_v__ast__Fn _t1; if (_t1 = v__ast__TypeSymbol_find_method(ts, name), _t1.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t1.data; _result_v__ast__Fn _t2 = {0}; _result_ok(&(v__ast__Fn[]) { method }, (_result*)(&_t2), sizeof(v__ast__Fn)); return _t2; } if (ts->kind == v__ast__Kind__aggregate) { _result_v__ast__Fn _t3; if (_t3 = v__ast__Table_register_aggregate_method(t, ts, name), !_t3.is_error) { v__ast__Fn method = *(v__ast__Fn*)_t3.data; _result_v__ast__Fn _t4 = {0}; _result_ok(&(v__ast__Fn[]) { method }, (_result*)(&_t4), sizeof(v__ast__Fn)); return _t4; } else { IError err = _t3.err; return (_result_v__ast__Fn){ .is_error=true, .err=err, .data={E_STRUCT} }; } } if (ts->parent_idx == 0) { break; } ts = (*(v__ast__TypeSymbol**)array_get(t->type_symbols, ts->parent_idx)); } return (_result_v__ast__Fn){ .is_error=true, .err=_v_error(_S("unknown method")), .data={E_STRUCT} }; } Array_Array_v__ast__Type v__ast__Table_get_embeds(v__ast__Table* t, v__ast__TypeSymbol* sym, v__ast__GetEmbedsOptions options) { Array_Array_v__ast__Type embeds = __new_array_with_default(0, 0, sizeof(Array_v__ast__Type), 0); v__ast__TypeSymbol* unalias_sym = ((sym->info)._typ == 539 /* v.ast.Alias */ ? (v__ast__Table_sym(t, (*sym->info._v__ast__Alias).parent_type)) : (sym)); if ((unalias_sym->info)._typ == 518 /* v.ast.Struct */) { for (int _t1 = 0; _t1 < (*unalias_sym->info._v__ast__Struct).embeds.len; ++_t1) { v__ast__Type embed = ((v__ast__Type*)(*unalias_sym->info._v__ast__Struct).embeds.data)[_t1]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(t, embed); Array_v__ast__Type preceding = array_clone_to_depth(&options.preceding, 0); array_push((array*)&preceding, _MOV((v__ast__Type[]){ embed })); _PUSH_MANY(&embeds, (v__ast__Table_get_embeds(t, embed_sym, ((v__ast__GetEmbedsOptions){.preceding = preceding,}))), _t3, Array_Array_v__ast__Type); } if ((*unalias_sym->info._v__ast__Struct).embeds.len == 0 && options.preceding.len > 0) { array_push((array*)&embeds, _MOV((Array_v__ast__Type[]){ options.preceding })); } } return embeds; } _result_multi_return_v__ast__Fn_Array_v__ast__Type v__ast__Table_find_method_from_embeds(v__ast__Table* t, v__ast__TypeSymbol* sym, string method_name) { if ((sym->info)._typ == 518 /* v.ast.Struct */) { Array_v__ast__Fn found_methods = __new_array_with_default(0, 0, sizeof(v__ast__Fn), 0); Array_v__ast__Type embed_of_found_methods = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t1 = 0; _t1 < (*sym->info._v__ast__Struct).embeds.len; ++_t1) { v__ast__Type embed = ((v__ast__Type*)(*sym->info._v__ast__Struct).embeds.data)[_t1]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(t, embed); _option_v__ast__Fn _t2; if (_t2 = v__ast__TypeSymbol_find_method_with_generic_parent(embed_sym, method_name), _t2.state == 0) { v__ast__Fn m = *(v__ast__Fn*)_t2.data; array_push((array*)&found_methods, _MOV((v__ast__Fn[]){ m })); array_push((array*)&embed_of_found_methods, _MOV((v__ast__Type[]){ embed })); } else { IError err = _t2.err; _result_multi_return_v__ast__Fn_Array_v__ast__Type _t5 = v__ast__Table_find_method_from_embeds(t, embed_sym, method_name); if (_t5.is_error) { IError err = _t5.err; continue; } multi_return_v__ast__Fn_Array_v__ast__Type mr_11518 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t5.data); v__ast__Fn method = mr_11518.arg0; Array_v__ast__Type types = mr_11518.arg1; array_push((array*)&found_methods, _MOV((v__ast__Fn[]){ method })); array_push((array*)&embed_of_found_methods, _MOV((v__ast__Type[]){ embed })); _PUSH_MANY(&embed_of_found_methods, (types), _t8, Array_v__ast__Type); } } if (found_methods.len == 1) { _result_multi_return_v__ast__Fn_Array_v__ast__Type _t9; _result_ok(&(multi_return_v__ast__Fn_Array_v__ast__Type[]) { (multi_return_v__ast__Fn_Array_v__ast__Type){.arg0=(*(v__ast__Fn*)array_get(found_methods, 0)), .arg1=embed_of_found_methods} }, (_result*)(&_t9), sizeof(multi_return_v__ast__Fn_Array_v__ast__Type)); return _t9; } else if (found_methods.len > 1) { return (_result_multi_return_v__ast__Fn_Array_v__ast__Type){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("ambiguous method `"), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } else if ((sym->info)._typ == 542 /* v.ast.Interface */) { Array_v__ast__Fn found_methods = __new_array_with_default(0, 0, sizeof(v__ast__Fn), 0); Array_v__ast__Type embed_of_found_methods = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t11 = 0; _t11 < (*sym->info._v__ast__Interface).embeds.len; ++_t11) { v__ast__Type embed = ((v__ast__Type*)(*sym->info._v__ast__Interface).embeds.data)[_t11]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(t, embed); _option_v__ast__Fn _t12; if (_t12 = v__ast__TypeSymbol_find_method_with_generic_parent(embed_sym, method_name), _t12.state == 0) { v__ast__Fn m = *(v__ast__Fn*)_t12.data; array_push((array*)&found_methods, _MOV((v__ast__Fn[]){ m })); array_push((array*)&embed_of_found_methods, _MOV((v__ast__Type[]){ embed })); } else { IError err = _t12.err; _result_multi_return_v__ast__Fn_Array_v__ast__Type _t15 = v__ast__Table_find_method_from_embeds(t, embed_sym, method_name); if (_t15.is_error) { IError err = _t15.err; continue; } multi_return_v__ast__Fn_Array_v__ast__Type mr_12195 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t15.data); v__ast__Fn method = mr_12195.arg0; Array_v__ast__Type types = mr_12195.arg1; array_push((array*)&found_methods, _MOV((v__ast__Fn[]){ method })); array_push((array*)&embed_of_found_methods, _MOV((v__ast__Type[]){ embed })); _PUSH_MANY(&embed_of_found_methods, (types), _t18, Array_v__ast__Type); } } if (found_methods.len == 1) { _result_multi_return_v__ast__Fn_Array_v__ast__Type _t19; _result_ok(&(multi_return_v__ast__Fn_Array_v__ast__Type[]) { (multi_return_v__ast__Fn_Array_v__ast__Type){.arg0=(*(v__ast__Fn*)array_get(found_methods, 0)), .arg1=embed_of_found_methods} }, (_result*)(&_t19), sizeof(multi_return_v__ast__Fn_Array_v__ast__Type)); return _t19; } else if (found_methods.len > 1) { return (_result_multi_return_v__ast__Fn_Array_v__ast__Type){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("ambiguous method `"), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } else if ((sym->info)._typ == 537 /* v.ast.Aggregate */) { for (int _t21 = 0; _t21 < (*sym->info._v__ast__Aggregate).types.len; ++_t21) { v__ast__Type typ = ((v__ast__Type*)(*sym->info._v__ast__Aggregate).types.data)[_t21]; v__ast__TypeSymbol* agg_sym = v__ast__Table_sym(t, typ); _result_multi_return_v__ast__Fn_Array_v__ast__Type _t22 = v__ast__Table_find_method_from_embeds(t, agg_sym, method_name); if (_t22.is_error) { IError err = _t22.err; continue; } multi_return_v__ast__Fn_Array_v__ast__Type mr_12660 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t22.data); v__ast__Fn method = mr_12660.arg0; Array_v__ast__Type embed_types = mr_12660.arg1; if (embed_types.len != 0) { _result_multi_return_v__ast__Fn_Array_v__ast__Type _t23; _result_ok(&(multi_return_v__ast__Fn_Array_v__ast__Type[]) { (multi_return_v__ast__Fn_Array_v__ast__Type){.arg0=method, .arg1=embed_types} }, (_result*)(&_t23), sizeof(multi_return_v__ast__Fn_Array_v__ast__Type)); return _t23; } } } return (_result_multi_return_v__ast__Fn_Array_v__ast__Type){ .is_error=true, .err=_v_error(_S("")), .data={E_STRUCT} }; } _result_v__ast__Fn v__ast__Table_find_method_with_embeds(v__ast__Table* t, v__ast__TypeSymbol* sym, string method_name) { _result_v__ast__Fn _t1; if (_t1 = v__ast__Table_find_method(t, sym, method_name), !_t1.is_error) { v__ast__Fn func = *(v__ast__Fn*)_t1.data; _result_v__ast__Fn _t2 = {0}; _result_ok(&(v__ast__Fn[]) { func }, (_result*)(&_t2), sizeof(v__ast__Fn)); return _t2; } else { IError err = _t1.err; _result_multi_return_v__ast__Fn_Array_v__ast__Type _t3 = v__ast__Table_find_method_from_embeds(t, sym, method_name); if (_t3.is_error) { IError err = _t3.err; return (_result_v__ast__Fn){ .is_error=true, .err=err, .data={E_STRUCT} }; } multi_return_v__ast__Fn_Array_v__ast__Type mr_13107 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t3.data); v__ast__Fn func = mr_13107.arg0; _result_v__ast__Fn _t5 = {0}; _result_ok(&(v__ast__Fn[]) { func }, (_result*)(&_t5), sizeof(v__ast__Fn)); return _t5; } return (_result_v__ast__Fn){0}; } _option_i64 v__ast__Table_find_enum_field_val(v__ast__Table* t, string name, string field_) { i64 val = ((i64)(0)); v__ast__EnumDecl enum_decl = (*(v__ast__EnumDecl*)map_get(ADDR(map, t->enum_decls), &(string[]){name}, &(v__ast__EnumDecl[]){ (v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},} })); Array_i64 enum_vals = __new_array_with_default(0, 0, sizeof(i64), 0); for (int _t1 = 0; _t1 < enum_decl.fields.len; ++_t1) { v__ast__EnumField field = ((v__ast__EnumField*)enum_decl.fields.data)[_t1]; if (string__eq(field.name, field_)) { if (field.has_expr) { if ((field.expr)._typ == 363 /* v.ast.IntegerLiteral */) { val = string_i64((*field.expr._v__ast__IntegerLiteral).val); break; } return (_option_i64){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } else { if (enum_vals.len > 0) { val = (i64)((*(i64*)array_last(enum_vals)) + 1); } else { val = 0; } break; } } else { if (field.has_expr) { if ((field.expr)._typ == 363 /* v.ast.IntegerLiteral */) { array_push((array*)&enum_vals, _MOV((i64[]){ string_i64((*field.expr._v__ast__IntegerLiteral).val) })); } else { return (_option_i64){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } } else { if (enum_vals.len > 0) { array_push((array*)&enum_vals, _MOV((i64[]){ (i64)((*(i64*)array_last(enum_vals)) + 1) })); } else { array_push((array*)&enum_vals, _MOV((i64[]){ 0 })); } } } } _option_i64 _t8; /* if prepend */ if (enum_decl.is_flag) { _option_ok(&(i64[]) { ((i64)((((u64)(1U)) << ((u64)(val))))) }, (_option*)(&_t8), sizeof(i64)); } else { _option_ok(&(i64[]) { val }, (_option*)(&_t8), sizeof(i64)); } return _t8; } Array_string v__ast__Table_get_enum_field_names(v__ast__Table* t, string name) { v__ast__EnumDecl enum_decl = (*(v__ast__EnumDecl*)map_get(ADDR(map, t->enum_decls), &(string[]){name}, &(v__ast__EnumDecl[]){ (v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},} })); Array_string field_names = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < enum_decl.fields.len; ++_t1) { v__ast__EnumField field = ((v__ast__EnumField*)enum_decl.fields.data)[_t1]; array_push((array*)&field_names, _MOV((string[]){ string_clone(field.name) })); } return field_names; } Array_i64 v__ast__Table_get_enum_field_vals(v__ast__Table* t, string name) { v__ast__EnumDecl enum_decl = (*(v__ast__EnumDecl*)map_get(ADDR(map, t->enum_decls), &(string[]){name}, &(v__ast__EnumDecl[]){ (v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},} })); Array_i64 enum_vals = __new_array_with_default(0, 0, sizeof(i64), 0); i64 last_val = ((i64)(0)); for (int _t1 = 0; _t1 < enum_decl.fields.len; ++_t1) { v__ast__EnumField field = ((v__ast__EnumField*)enum_decl.fields.data)[_t1]; if (field.has_expr) { if ((field.expr)._typ == 363 /* v.ast.IntegerLiteral */) { array_push((array*)&enum_vals, _MOV((i64[]){ string_i64((*field.expr._v__ast__IntegerLiteral).val) })); last_val = string_i64((*field.expr._v__ast__IntegerLiteral).val); } } else { if (enum_vals.len > 0) { array_push((array*)&enum_vals, _MOV((i64[]){ (i64)(last_val + 1) })); last_val++; } else { array_push((array*)&enum_vals, _MOV((i64[]){ 0 })); } } } return enum_vals; } Array_v__ast__Fn v__ast__Table_get_embed_methods(v__ast__Table* t, v__ast__TypeSymbol* sym) { Array_v__ast__Fn methods = __new_array_with_default(0, 0, sizeof(v__ast__Fn), 0); if ((sym->info)._typ == 518 /* v.ast.Struct */) { for (int _t1 = 0; _t1 < (*sym->info._v__ast__Struct).embeds.len; ++_t1) { v__ast__Type embed = ((v__ast__Type*)(*sym->info._v__ast__Struct).embeds.data)[_t1]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(t, embed); _PUSH_MANY(&methods, (embed_sym->methods), _t2, Array_v__ast__Fn); _PUSH_MANY(&methods, (v__ast__Table_get_embed_methods(t, embed_sym)), _t3, Array_v__ast__Fn); } } return methods; } VV_LOC _result_v__ast__StructField v__ast__Table_register_aggregate_field(v__ast__Table* t, v__ast__TypeSymbol* sym, string name) { if (sym->kind != v__ast__Kind__aggregate) { v__ast__Table_panic(t, str_intp(4, _MOV((StrIntpData[]){{_S("table.register_aggregate_field: sym.name: "), 0xfe10, {.d_s = sym->name}}, {_S(", sym.kind: "), 0xfe10, {.d_s = v__ast__Kind_str(sym->kind)}}, {_S(" is not an aggregate, name: "), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } v__ast__Aggregate agg_info = *(v__ast__Aggregate*)__as_cast((sym->info)._v__ast__Aggregate,(sym->info)._typ, 537); bool found_once = false; v__ast__StructField new_field = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}); for (int _t1 = 0; _t1 < agg_info.types.len; ++_t1) { v__ast__Type typ = ((v__ast__Type*)agg_info.types.data)[_t1]; v__ast__TypeSymbol* ts = v__ast__Table_sym(t, typ); _result_v__ast__StructField _t2; if (_t2 = v__ast__Table_find_field(t, ts, name), !_t2.is_error) { v__ast__StructField type_field = *(v__ast__StructField*)_t2.data; if (!found_once) { found_once = true; new_field = type_field; } else if (new_field.typ != type_field.typ) { return (_result_v__ast__StructField){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(t, typ)}}, {_S("."), 0xfe10, {.d_s = name}}, {_S("` type is different"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } new_field = ((v__ast__StructField){.pos = (new_field).pos,.type_pos = (new_field).type_pos,.option_pos = (new_field).option_pos,.pre_comments = (new_field).pre_comments,.comments = (new_field).comments,.i = (new_field).i,.has_default_expr = (new_field).has_default_expr,.has_prev_newline = (new_field).has_prev_newline,.has_break_line = (new_field).has_break_line,.attrs = (new_field).attrs,.is_pub = new_field.is_pub && type_field.is_pub,.default_val = (new_field).default_val,.is_mut = new_field.is_mut && type_field.is_mut,.is_global = (new_field).is_global,.is_volatile = (new_field).is_volatile,.is_deprecated = (new_field).is_deprecated,.is_embed = (new_field).is_embed,.next_comments = (new_field).next_comments,.is_recursive = (new_field).is_recursive,.is_part_of_union = (new_field).is_part_of_union,.container_typ = (new_field).container_typ,.default_expr = (new_field).default_expr,.default_expr_typ = (new_field).default_expr_typ,.name = (new_field).name,.typ = (new_field).typ,.unaliased_typ = (new_field).unaliased_typ,.anon_struct_decl = (new_field).anon_struct_decl,}); } else { IError err = _t2.err; return (_result_v__ast__StructField){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("type `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(t, typ)}}, {_S("` has no field or method `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } array_push((array*)&agg_info.fields, _MOV((v__ast__StructField[]){ new_field })); _result_v__ast__StructField _t6 = {0}; _result_ok(&(v__ast__StructField[]) { new_field }, (_result*)(&_t6), sizeof(v__ast__StructField)); return _t6; } bool v__ast__Table_struct_has_field(v__ast__Table* t, v__ast__TypeSymbol* struct_, string name) { _result_v__ast__StructField _t1 = v__ast__Table_find_field(t, struct_, name); if (_t1.is_error) { IError err = _t1.err; return false; } ; return true; } Array_v__ast__StructField v__ast__Table_struct_fields(v__ast__Table* t, v__ast__TypeSymbol* sym) { Array_v__ast__StructField fields = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); if ((sym->info)._typ == 518 /* v.ast.Struct */) { _PUSH_MANY(&fields, ((*sym->info._v__ast__Struct).fields), _t1, Array_v__ast__StructField); for (int _t2 = 0; _t2 < (*sym->info._v__ast__Struct).embeds.len; ++_t2) { v__ast__Type embed = ((v__ast__Type*)(*sym->info._v__ast__Struct).embeds.data)[_t2]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(t, embed); _PUSH_MANY(&fields, (v__ast__Table_struct_fields(t, embed_sym)), _t3, Array_v__ast__StructField); } } return fields; } _result_v__ast__StructField v__ast__Table_find_field(v__ast__Table* t, v__ast__TypeSymbol* s, string name) { v__ast__TypeSymbol* ts = s; for (;;) { if (ts->info._typ == 518 /* v.ast.Struct */) { _option_v__ast__StructField _t1; if (_t1 = v__ast__Struct_find_field((*ts->info._v__ast__Struct), name), _t1.state == 0) { v__ast__StructField field = *(v__ast__StructField*)_t1.data; _result_v__ast__StructField _t2 = {0}; _result_ok(&(v__ast__StructField[]) { field }, (_result*)(&_t2), sizeof(v__ast__StructField)); return _t2; } } else if (ts->info._typ == 537 /* v.ast.Aggregate */) { _option_v__ast__StructField _t3; if (_t3 = v__ast__Aggregate_find_field(&(*ts->info._v__ast__Aggregate), name), _t3.state == 0) { v__ast__StructField field = *(v__ast__StructField*)_t3.data; _result_v__ast__StructField _t4 = {0}; _result_ok(&(v__ast__StructField[]) { field }, (_result*)(&_t4), sizeof(v__ast__StructField)); return _t4; } _result_v__ast__StructField _t5 = v__ast__Table_register_aggregate_field(t, ts, name); if (_t5.is_error) { IError err = _t5.err; return (_result_v__ast__StructField){ .is_error=true, .err=err, .data={E_STRUCT} }; } v__ast__StructField field = (*(v__ast__StructField*)_t5.data); _result_v__ast__StructField _t7 = {0}; _result_ok(&(v__ast__StructField[]) { field }, (_result*)(&_t7), sizeof(v__ast__StructField)); return _t7; } else if (ts->info._typ == 542 /* v.ast.Interface */) { _option_v__ast__StructField _t8; if (_t8 = v__ast__Interface_find_field(&(*ts->info._v__ast__Interface), name), _t8.state == 0) { v__ast__StructField field = *(v__ast__StructField*)_t8.data; _result_v__ast__StructField _t9 = {0}; _result_ok(&(v__ast__StructField[]) { field }, (_result*)(&_t9), sizeof(v__ast__StructField)); return _t9; } } else if (ts->info._typ == 544 /* v.ast.SumType */) { v__ast__Table_resolve_common_sumtype_fields(t, ts); _option_v__ast__StructField _t10; if (_t10 = v__ast__SumType_find_sum_type_field(&(*ts->info._v__ast__SumType), name), _t10.state == 0) { v__ast__StructField field = *(v__ast__StructField*)_t10.data; _result_v__ast__StructField _t11 = {0}; _result_ok(&(v__ast__StructField[]) { field }, (_result*)(&_t11), sizeof(v__ast__StructField)); return _t11; } string missing_variants = v__ast__Table_find_missing_variants(t, (voidptr)&(*ts->info._v__ast__SumType), name); return (_result_v__ast__StructField){ .is_error=true, .err=_v_error(str_intp(4, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = name}}, {_S("` does not exist or have the same type in these sumtype `"), 0xfe10, {.d_s = ts->name}}, {_S("` variants: "), 0xfe10, {.d_s = missing_variants}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } else { } if (ts->parent_idx == 0) { break; } ts = (*(v__ast__TypeSymbol**)array_get(t->type_symbols, ts->parent_idx)); } return (_result_v__ast__StructField){ .is_error=true, .err=_v_error(_S("")), .data={E_STRUCT} }; } _result_multi_return_v__ast__StructField_Array_v__ast__Type v__ast__Table_find_field_from_embeds(v__ast__Table* t, v__ast__TypeSymbol* sym, string field_name) { if ((sym->info)._typ == 518 /* v.ast.Struct */) { Array_v__ast__StructField found_fields = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); Array_v__ast__Type embeds_of_found_fields = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t1 = 0; _t1 < (*sym->info._v__ast__Struct).embeds.len; ++_t1) { v__ast__Type embed = ((v__ast__Type*)(*sym->info._v__ast__Struct).embeds.data)[_t1]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(t, embed); _result_v__ast__StructField _t2; if (_t2 = v__ast__Table_find_field(t, embed_sym, field_name), !_t2.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t2.data; array_push((array*)&found_fields, _MOV((v__ast__StructField[]){ field })); array_push((array*)&embeds_of_found_fields, _MOV((v__ast__Type[]){ embed })); } else { IError err = _t2.err; _result_multi_return_v__ast__StructField_Array_v__ast__Type _t5 = v__ast__Table_find_field_from_embeds(t, embed_sym, field_name); if (_t5.is_error) { IError err = _t5.err; continue; } multi_return_v__ast__StructField_Array_v__ast__Type mr_18081 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t5.data); v__ast__StructField field = mr_18081.arg0; Array_v__ast__Type types = mr_18081.arg1; array_push((array*)&found_fields, _MOV((v__ast__StructField[]){ field })); array_push((array*)&embeds_of_found_fields, _MOV((v__ast__Type[]){ embed })); _PUSH_MANY(&embeds_of_found_fields, (types), _t8, Array_v__ast__Type); } } if (found_fields.len == 1) { _result_multi_return_v__ast__StructField_Array_v__ast__Type _t9; _result_ok(&(multi_return_v__ast__StructField_Array_v__ast__Type[]) { (multi_return_v__ast__StructField_Array_v__ast__Type){.arg0=(*(v__ast__StructField*)array_get(found_fields, 0)), .arg1=embeds_of_found_fields} }, (_result*)(&_t9), sizeof(multi_return_v__ast__StructField_Array_v__ast__Type)); return _t9; } else if (found_fields.len > 1) { return (_result_multi_return_v__ast__StructField_Array_v__ast__Type){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("ambiguous field `"), 0xfe10, {.d_s = field_name}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } else if ((sym->info)._typ == 537 /* v.ast.Aggregate */) { for (int _t11 = 0; _t11 < (*sym->info._v__ast__Aggregate).types.len; ++_t11) { v__ast__Type typ = ((v__ast__Type*)(*sym->info._v__ast__Aggregate).types.data)[_t11]; v__ast__TypeSymbol* agg_sym = v__ast__Table_sym(t, typ); _result_multi_return_v__ast__StructField_Array_v__ast__Type _t12 = v__ast__Table_find_field_from_embeds(t, agg_sym, field_name); if (_t12.is_error) { IError err = _t12.err; continue; } multi_return_v__ast__StructField_Array_v__ast__Type mr_18536 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t12.data); v__ast__StructField field = mr_18536.arg0; Array_v__ast__Type embed_types = mr_18536.arg1; if (embed_types.len > 0) { _result_multi_return_v__ast__StructField_Array_v__ast__Type _t13; _result_ok(&(multi_return_v__ast__StructField_Array_v__ast__Type[]) { (multi_return_v__ast__StructField_Array_v__ast__Type){.arg0=field, .arg1=embed_types} }, (_result*)(&_t13), sizeof(multi_return_v__ast__StructField_Array_v__ast__Type)); return _t13; } } } else if ((sym->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* unalias_sym = v__ast__Table_sym(t, (*sym->info._v__ast__Alias).parent_type); return v__ast__Table_find_field_from_embeds(t, unalias_sym, field_name); } return (_result_multi_return_v__ast__StructField_Array_v__ast__Type){ .is_error=true, .err=_v_error(_S("")), .data={E_STRUCT} }; } _result_v__ast__StructField v__ast__Table_find_field_with_embeds(v__ast__Table* t, v__ast__TypeSymbol* sym, string field_name) { _result_v__ast__StructField _t1; if (_t1 = v__ast__Table_find_field(t, sym, field_name), !_t1.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t1.data; _result_v__ast__StructField _t2 = {0}; _result_ok(&(v__ast__StructField[]) { field }, (_result*)(&_t2), sizeof(v__ast__StructField)); return _t2; } else { IError err = _t1.err; IError first_err = err; _result_multi_return_v__ast__StructField_Array_v__ast__Type _t3 = v__ast__Table_find_field_from_embeds(t, sym, field_name); if (_t3.is_error) { IError err = _t3.err; return (_result_v__ast__StructField){ .is_error=true, .err=first_err, .data={E_STRUCT} }; } multi_return_v__ast__StructField_Array_v__ast__Type mr_19139 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t3.data); v__ast__StructField field = mr_19139.arg0; _result_v__ast__StructField _t5 = {0}; _result_ok(&(v__ast__StructField[]) { field }, (_result*)(&_t5), sizeof(v__ast__StructField)); return _t5; } return (_result_v__ast__StructField){0}; } void v__ast__Table_resolve_common_sumtype_fields(v__ast__Table* t, v__ast__TypeSymbol* sym) { v__ast__SumType info = *(v__ast__SumType*)__as_cast((sym->info)._v__ast__SumType,(sym->info)._typ, 544); if (info.found_fields) { return; } Map_string_v__ast__StructField field_map = new_map(sizeof(string), sizeof(v__ast__StructField), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_int field_usages = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int _t1 = 0; _t1 < info.variants.len; ++_t1) { v__ast__Type variant = ((v__ast__Type*)info.variants.data)[_t1]; v__ast__TypeSymbol* v_sym = v__ast__Table_final_sym(t, variant); Array_v__ast__StructField _t2 = __new_array(0, 0, sizeof(v__ast__StructField)); if (v_sym->info._typ == 518 /* v.ast.Struct */) { _t2 = v__ast__Table_struct_fields(t, v_sym); } else if (v_sym->info._typ == 544 /* v.ast.SumType */) { v__ast__Table_resolve_common_sumtype_fields(t, v_sym); _t2 = (*v_sym->info._v__ast__SumType).fields; } else { _t2 = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); } Array_v__ast__StructField fields = _t2; for (int _t3 = 0; _t3 < fields.len; ++_t3) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t3]; if (!_IN_MAP(ADDR(string, field.name), ADDR(map, field_map))) { (*(v__ast__StructField*)map_get_and_set((map*)&field_map, &(string[]){field.name}, &(v__ast__StructField[]){ (v__ast__StructField){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.option_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = (v__ast__StructDecl){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,},} })) = field; (*(int*)map_get_and_set((map*)&field_usages, &(string[]){field.name}, &(int[]){ 0 }))++; } else if (v__ast__StructField_equals(&field, (voidptr)&(*(v__ast__StructField*)map_get(ADDR(map, field_map), &(string[]){field.name}, &(v__ast__StructField[]){ (v__ast__StructField){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.option_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = (v__ast__StructDecl){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,},} })))) { (*(int*)map_get_and_set((map*)&field_usages, &(string[]){field.name}, &(int[]){ 0 }))++; } } } int _t5 = field_usages.key_values.len; for (int _t4 = 0; _t4 < _t5; ++_t4 ) { int _t6 = field_usages.key_values.len - _t5; _t5 = field_usages.key_values.len; if (_t6 < 0) { _t4 = -1; continue; } if (!DenseArray_has_index(&field_usages.key_values, _t4)) {continue;} string field = *(string*)DenseArray_key(&field_usages.key_values, _t4); field = string_clone(field); int nr_definitions = (*(int*)DenseArray_value(&field_usages.key_values, _t4)); if (nr_definitions == info.variants.len) { array_push((array*)&info.fields, _MOV((v__ast__StructField[]){ (*(v__ast__StructField*)map_get((map*)&field_map, &(string[]){field}, &(v__ast__StructField[]){ (v__ast__StructField){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.option_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = (v__ast__StructDecl){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,},} })) })); } } info.found_fields = true; sym->info = v__ast__SumType_to_sumtype_v__ast__TypeInfo(&info); } inline v__ast__Type v__ast__Table_find_type(v__ast__Table* t, string name) { return v__ast__idx_to_type((*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 }))); } inline int v__ast__Table_find_type_idx(v__ast__Table* t, string name) { return (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); } inline int v__ast__Table_find_type_idx_fn_scoped(v__ast__Table* t, string name, v__ast__Scope* scope) { if (scope != ((void*)0)) { int idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){str_intp(3, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = name}}, {_S("_"), 0xfe07, {.d_i32 = scope->start_pos}}, {_SLIT0, 0, { .d_c = 0 }}}))}, &(int[]){ 0 })); if (idx != 0) { return idx; } } return (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); } inline _option_v__ast__TypeSymbol_ptr v__ast__Table_find_sym(v__ast__Table* t, string name) { int idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (idx > 0) { _option_v__ast__TypeSymbol_ptr _t1; _option_ok(&(v__ast__TypeSymbol*[]) { (*(v__ast__TypeSymbol**)array_get(t->type_symbols, idx)) }, (_option*)(&_t1), sizeof(v__ast__TypeSymbol*)); return _t1; } return (_option_v__ast__TypeSymbol_ptr){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } inline multi_return_ref_v__ast__TypeSymbol_int v__ast__Table_find_sym_and_type_idx(v__ast__Table* t, string name) { int idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (idx > 0) { return (multi_return_ref_v__ast__TypeSymbol_int){.arg0=(*(v__ast__TypeSymbol**)array_get(t->type_symbols, idx)), .arg1=idx}; } return (multi_return_ref_v__ast__TypeSymbol_int){.arg0=_const_v__ast__invalid_type_symbol, .arg1=idx}; } inline v__ast__TypeSymbol* v__ast__Table_sym_by_idx(v__ast__Table* t, int idx) { return (*(v__ast__TypeSymbol**)array_get(t->type_symbols, idx)); } v__ast__TypeSymbol* v__ast__Table_sym(v__ast__Table* t, v__ast__Type typ) { int idx = v__ast__Type_idx(typ); if (idx > 0 && idx < t->type_symbols.len) { return ((v__ast__TypeSymbol**)t->type_symbols.data)[idx]; } v__ast__Table_panic(t, str_intp(3, _MOV((StrIntpData[]){{_S("table.sym: invalid type (typ="), 0xfe10, {.d_s = v__ast__Type_str(typ)}}, {_S(" idx="), 0xfe07, {.d_i32 = idx}}, {_S("). Compiler bug. This should never happen. Please report the bug using `v bug file.v`.\n"), 0, { .d_c = 0 }}}))); return _const_v__ast__invalid_type_symbol; } v__ast__TypeSymbol* v__ast__Table_final_sym(v__ast__Table* t, v__ast__Type typ) { int idx = v__ast__Type_idx(typ); if (idx > 0 && idx < t->type_symbols.len) { v__ast__TypeSymbol* cur_sym = ((v__ast__TypeSymbol**)t->type_symbols.data)[idx]; if ((cur_sym->info)._typ == 539 /* v.ast.Alias */) { idx = v__ast__Type_idx((*cur_sym->info._v__ast__Alias).parent_type); } return ((v__ast__TypeSymbol**)t->type_symbols.data)[idx]; } v__ast__Table_panic(t, str_intp(3, _MOV((StrIntpData[]){{_S("table.final_sym: invalid type (typ="), 0xfe10, {.d_s = v__ast__Type_str(typ)}}, {_S(" idx="), 0xfe07, {.d_i32 = idx}}, {_S("). Compiler bug. This should never happen. Please report the bug using `v bug file.v`."), 0, { .d_c = 0 }}}))); return _const_v__ast__invalid_type_symbol; } v__ast__Type v__ast__Table_final_type(v__ast__Table* t, v__ast__Type typ) { int idx = v__ast__Type_idx(typ); if (idx > 0 && idx < t->type_symbols.len) { v__ast__TypeSymbol* cur_sym = (*(v__ast__TypeSymbol**)array_get(t->type_symbols, idx)); if ((cur_sym->info)._typ == 539 /* v.ast.Alias */) { idx = v__ast__Type_idx((*cur_sym->info._v__ast__Alias).parent_type); v__ast__TypeSymbol* aliased_sym = (*(v__ast__TypeSymbol**)array_get(t->type_symbols, idx)); if ((aliased_sym->info)._typ == 548 /* v.ast.Enum */) { return (*aliased_sym->info._v__ast__Enum).typ; } return (*cur_sym->info._v__ast__Alias).parent_type; } else if ((cur_sym->info)._typ == 548 /* v.ast.Enum */) { return (*cur_sym->info._v__ast__Enum).typ; } } return typ; } inline string v__ast__Table_get_type_name(v__ast__Table* t, v__ast__Type typ) { return v__ast__Table_sym(t, typ)->name; } inline v__ast__Type v__ast__Table_unalias_num_type(v__ast__Table* t, v__ast__Type typ) { v__ast__TypeSymbol* sym = v__ast__Table_sym(t, typ); if ((sym->info)._typ == 539 /* v.ast.Alias */) { if ((*sym->info._v__ast__Alias).parent_type <= _const_v__ast__char_type && (*sym->info._v__ast__Alias).parent_type >= _const_v__ast__void_type) { return (*sym->info._v__ast__Alias).parent_type; } } return typ; } inline v__ast__Type v__ast__Table_unaliased_type(v__ast__Table* t, v__ast__Type typ) { v__ast__TypeSymbol* sym = v__ast__Table_sym(t, typ); if ((sym->info)._typ == 539 /* v.ast.Alias */) { return (*sym->info._v__ast__Alias).parent_type; } return typ; } VV_LOC int v__ast__Table_rewrite_already_registered_symbol(v__ast__Table* t, v__ast__TypeSymbol typ, int existing_idx) { v__ast__TypeSymbol* existing_symbol = (*(v__ast__TypeSymbol**)array_get(t->type_symbols, existing_idx)); #if defined(CUSTOM_DEFINE_trace_rewrite_already_registered_symbol) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S(">> rewrite_already_registered_symbol sym: "), 0xfe10, {.d_s = typ.name}}, {_S(" | existing_idx: "), 0xfe07, {.d_i32 = existing_idx}}, {_S(" | existing_symbol: "), 0xfe10, {.d_s = existing_symbol->name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif if (existing_symbol->kind == v__ast__Kind__placeholder) { array_set(&t->type_symbols, existing_idx, &(v__ast__TypeSymbol*[]) { ((v__ast__TypeSymbol*)memdup(&(v__ast__TypeSymbol){.parent_idx = (typ).parent_idx,.info = (typ).info,.kind = (typ).kind,.name = (typ).name,.cname = (typ).cname,.rname = (typ).rname,.methods = existing_symbol->methods,.generic_types = (typ).generic_types,.mod = (typ).mod,.is_pub = (typ).is_pub,.is_builtin = existing_symbol->is_builtin,.language = (typ).language,.idx = existing_idx,.size = (typ).size,.align = (typ).align,}, sizeof(v__ast__TypeSymbol))) }); return existing_idx; } if ((existing_idx >= 21 && existing_idx <= 24) || existing_idx == 30) { if (existing_idx == 21) { { // Unsafe block *existing_symbol = ((v__ast__TypeSymbol){.parent_idx = (typ).parent_idx,.info = (typ).info,.kind = existing_symbol->kind,.name = (typ).name,.cname = (typ).cname,.rname = (typ).rname,.methods = (typ).methods,.generic_types = (typ).generic_types,.mod = (typ).mod,.is_pub = (typ).is_pub,.is_builtin = existing_symbol->is_builtin,.language = (typ).language,.idx = existing_idx,.size = (typ).size,.align = (typ).align,}); } } else { array_set(&t->type_symbols, existing_idx, &(v__ast__TypeSymbol*[]) { ((v__ast__TypeSymbol*)memdup(&(v__ast__TypeSymbol){.parent_idx = (typ).parent_idx,.info = (typ).info,.kind = (typ).kind,.name = (typ).name,.cname = (typ).cname,.rname = (typ).rname,.methods = (typ).methods,.generic_types = (typ).generic_types,.mod = (typ).mod,.is_pub = (typ).is_pub,.is_builtin = existing_symbol->is_builtin,.language = (typ).language,.idx = existing_idx,.size = (typ).size,.align = (typ).align,}, sizeof(v__ast__TypeSymbol))) }); } return existing_idx; } return _const_v__ast__invalid_type_idx; } inline int v__ast__Table_register_sym(v__ast__Table* t, v__ast__TypeSymbol sym) { bool v__ast__Table_register_sym_defer_0 = false; int idx; idx = -2; #if defined(CUSTOM_DEFINE_trace_register_sym) { v__ast__Table_register_sym_defer_0 = true; } #endif string sym_name = ((sym.info)._typ == 518 /* v.ast.Struct */ && ((*(v__ast__Struct*)__as_cast((sym.info)._v__ast__Struct,(sym.info)._typ, 518)).scoped_name).len != 0 ? ((*sym.info._v__ast__Struct).scoped_name) : (sym.name)); int existing_idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){sym_name}, &(int[]){ 0 })); if (existing_idx > 0) { idx = v__ast__Table_rewrite_already_registered_symbol(t, sym, existing_idx); if (idx != -2) { int _t2 = idx; // Defer begin if (v__ast__Table_register_sym_defer_0) { #if defined(CUSTOM_DEFINE_trace_register_sym) eprintln(str_intp(3, _MOV((StrIntpData[]){{_S(">> register_sym: "), 0x78fe10, {.d_s = sym.name}}, {_S(" | idx: "), 0xfe07, {.d_i32 = idx}}, {_SLIT0, 0, { .d_c = 0 }}}))); #endif } // Defer end return _t2; } } if (fast_string_eq(sym.mod, _S("main"))) { existing_idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){string_trim_string_left(sym_name, _S("main."))}, &(int[]){ 0 })); if (existing_idx > 0) { idx = v__ast__Table_rewrite_already_registered_symbol(t, sym, existing_idx); if (idx != -2) { int _t3 = idx; // Defer begin if (v__ast__Table_register_sym_defer_0) { #if defined(CUSTOM_DEFINE_trace_register_sym) eprintln(str_intp(3, _MOV((StrIntpData[]){{_S(">> register_sym: "), 0x78fe10, {.d_s = sym.name}}, {_S(" | idx: "), 0xfe07, {.d_i32 = idx}}, {_SLIT0, 0, { .d_c = 0 }}}))); #endif } // Defer end return _t3; } } } idx = t->type_symbols.len; array_push((array*)&t->type_symbols, _MOV((v__ast__TypeSymbol*[]){ ((v__ast__TypeSymbol*)memdup(&(v__ast__TypeSymbol){.parent_idx = (sym).parent_idx,.info = (sym).info,.kind = (sym).kind,.name = (sym).name,.cname = (sym).cname,.rname = (sym).rname,.methods = (sym).methods,.generic_types = (sym).generic_types,.mod = (sym).mod,.is_pub = (sym).is_pub,.is_builtin = (sym).is_builtin,.language = (sym).language,.idx = (sym).idx,.size = (sym).size,.align = (sym).align,}, sizeof(v__ast__TypeSymbol))) })); (*(v__ast__TypeSymbol**)array_get(t->type_symbols, idx))->idx = idx; map_set(&t->type_idxs, &(string[]){sym_name}, &(int[]) { idx }); int _t5 = idx; // Defer begin if (v__ast__Table_register_sym_defer_0) { #if defined(CUSTOM_DEFINE_trace_register_sym) eprintln(str_intp(3, _MOV((StrIntpData[]){{_S(">> register_sym: "), 0x78fe10, {.d_s = sym.name}}, {_S(" | idx: "), 0xfe07, {.d_i32 = idx}}, {_SLIT0, 0, { .d_c = 0 }}}))); #endif } // Defer end return _t5; } inline void v__ast__Table_register_enum_decl(v__ast__Table* t, v__ast__EnumDecl enum_decl) { (*(v__ast__EnumDecl*)map_get_and_set((map*)&t->enum_decls, &(string[]){enum_decl.name}, &(v__ast__EnumDecl[]){ (v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},} })) = enum_decl; } inline void v__ast__Table_register_anon_struct(v__ast__Table* t, string name, int sym_idx) { map_set(&t->anon_struct_names, &(string[]){name}, &(int[]) { sym_idx }); } inline void v__ast__Table_register_anon_union(v__ast__Table* t, string name, int sym_idx) { map_set(&t->anon_union_names, &(string[]){name}, &(int[]) { sym_idx }); } bool v__ast__Table_known_type(v__ast__Table* t, string name) { return (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })) != 0 || string__eq(t->parsing_type, name) || (_SLIT_EQ(name.str, name.len, "i32") || _SLIT_EQ(name.str, name.len, "byte")); } void v__ast__Table_start_parsing_type(v__ast__Table* t, string type_name) { t->parsing_type = type_name; } void v__ast__Table_reset_parsing_type(v__ast__Table* t) { t->parsing_type = _S(""); } bool v__ast__Table_known_type_idx(v__ast__Table* t, v__ast__Type typ) { if (typ == 0) { return false; } v__ast__TypeSymbol* sym = v__ast__Table_sym(t, typ); if (sym->kind == (v__ast__Kind__placeholder)) { return sym->language != v__ast__Language__v || string_starts_with(sym->name, _S("C.")); } else if (sym->kind == (v__ast__Kind__array)) { return v__ast__Table_known_type_idx(t, (*(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513)).elem_type); } else if (sym->kind == (v__ast__Kind__array_fixed)) { return v__ast__Table_known_type_idx(t, (*(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549)).elem_type); } else if (sym->kind == (v__ast__Kind__map)) { v__ast__Map info = *(v__ast__Map*)__as_cast((sym->info)._v__ast__Map,(sym->info)._typ, 514); return v__ast__Table_known_type_idx(t, info.key_type) && v__ast__Table_known_type_idx(t, info.value_type); } else { } return true; } inline string v__ast__Table_array_name(v__ast__Table* t, v__ast__Type elem_type) { v__ast__TypeSymbol* elem_type_sym = v__ast__Table_sym(t, elem_type); string ptr = (v__ast__Type_is_ptr(elem_type) ? (string_repeat(_S("&"), v__ast__Type_nr_muls(elem_type))) : (_S(""))); string opt = (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__option) ? (_S("?")) : (_S(""))); string res = (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__result) ? (_S("!")) : (_S(""))); string name = elem_type_sym->name; if ((elem_type_sym->info)._typ == 518 /* v.ast.Struct */ && ((*(v__ast__Struct*)__as_cast((elem_type_sym->info)._v__ast__Struct,(elem_type_sym->info)._typ, 518)).scoped_name).len != 0) { name = (*elem_type_sym->info._v__ast__Struct).scoped_name; } return str_intp(5, _MOV((StrIntpData[]){{_S("[]"), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = ptr}}, {_SLIT0, 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); } inline string v__ast__Table_array_cname(v__ast__Table* t, v__ast__Type elem_type) { v__ast__TypeSymbol* elem_type_sym = v__ast__Table_sym(t, elem_type); string suffix = (v__ast__Type_is_ptr(elem_type) ? (string_repeat(_S("_ptr"), v__ast__Type_nr_muls(elem_type))) : (_S(""))); string opt = (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__option) ? (_S("_option_")) : (_S(""))); string res = (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__result) ? (_S("_result_")) : (_S(""))); if (string_contains(elem_type_sym->cname, _S("["))) { string type_name = string_replace_each(elem_type_sym->cname, _const_v__ast__map_cname_escape_seq); return str_intp(5, _MOV((StrIntpData[]){{_S("Array_"), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = type_name}}, {_SLIT0, 0xfe10, {.d_s = suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { return str_intp(5, _MOV((StrIntpData[]){{_S("Array_"), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = elem_type_sym->cname}}, {_SLIT0, 0xfe10, {.d_s = suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); } return (string){.str=(byteptr)"", .is_lit=1}; } inline string v__ast__Table_array_fixed_name(v__ast__Table* t, v__ast__Type elem_type, int size, v__ast__Expr size_expr) { v__ast__TypeSymbol* elem_type_sym = v__ast__Table_sym(t, elem_type); string ptr = (v__ast__Type_is_ptr(elem_type) ? (string_repeat(_S("&"), v__ast__Type_nr_muls(elem_type))) : (_S(""))); string opt = (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__option) ? (_S("?")) : (_S(""))); string res = (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__result) ? (_S("!")) : (_S(""))); string size_str = ((size_expr)._typ == 354 /* v.ast.EmptyExpr */ || !(size == 0 || size == 987654321) ? (int_str(size)) : (v__ast__Expr_str(&size_expr))); return str_intp(6, _MOV((StrIntpData[]){{_S("["), 0xfe10, {.d_s = size_str}}, {_S("]"), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = ptr}}, {_SLIT0, 0xfe10, {.d_s = elem_type_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}})); } inline string v__ast__Table_array_fixed_cname(v__ast__Table* t, v__ast__Type elem_type, int size) { v__ast__TypeSymbol* elem_type_sym = v__ast__Table_sym(t, elem_type); string suffix = (v__ast__Type_is_ptr(elem_type) ? (str_intp(2, _MOV((StrIntpData[]){{_S("_ptr"), 0xfe07, {.d_i32 = v__ast__Type_nr_muls(elem_type)}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (_S(""))); string opt = (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__option) ? (_S("_option_")) : (_S(""))); string res = (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__result) ? (_S("_result_")) : (_S(""))); if (string_contains(elem_type_sym->cname, _S("["))) { string type_name = string_replace_each(elem_type_sym->cname, _const_v__ast__map_cname_escape_seq); return str_intp(6, _MOV((StrIntpData[]){{_S("Array_fixed_"), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = type_name}}, {_SLIT0, 0xfe10, {.d_s = suffix}}, {_S("_"), 0xfe07, {.d_i32 = size}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { return str_intp(6, _MOV((StrIntpData[]){{_S("Array_fixed_"), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = elem_type_sym->cname}}, {_SLIT0, 0xfe10, {.d_s = suffix}}, {_S("_"), 0xfe07, {.d_i32 = size}}, {_SLIT0, 0, { .d_c = 0 }}})); } return (string){.str=(byteptr)"", .is_lit=1}; } inline string v__ast__Table_chan_name(v__ast__Table* t, v__ast__Type elem_type, bool is_mut) { v__ast__TypeSymbol* elem_type_sym = v__ast__Table_sym(t, elem_type); string ptr = _S(""); if (is_mut) { ptr = _S("mut "); } else if (v__ast__Type_is_ptr(elem_type)) { ptr = _S("&"); } return str_intp(3, _MOV((StrIntpData[]){{_S("chan "), 0xfe10, {.d_s = ptr}}, {_SLIT0, 0xfe10, {.d_s = elem_type_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}})); } inline string v__ast__Table_chan_cname(v__ast__Table* t, v__ast__Type elem_type, bool is_mut) { v__ast__TypeSymbol* elem_type_sym = v__ast__Table_sym(t, elem_type); string suffix = _S(""); if (is_mut) { suffix = _S("_mut"); } else if (v__ast__Type_is_ptr(elem_type)) { suffix = _S("_ptr"); } string type_name = (string_contains(elem_type_sym->cname, _S("[")) ? (string_replace_each(elem_type_sym->cname, _const_v__ast__map_cname_escape_seq)) : (elem_type_sym->cname)); return string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("chan_"), 0xfe10, {.d_s = type_name}}, {_SLIT0, 0, { .d_c = 0 }}})), suffix); } inline string v__ast__Table_promise_name(v__ast__Table* t, v__ast__Type return_type) { if (v__ast__Type_idx(return_type) == 1) { return _S("Promise[JS.Any, JS.Any]"); } v__ast__TypeSymbol* return_type_sym = v__ast__Table_sym(t, return_type); return str_intp(2, _MOV((StrIntpData[]){{_S("Promise["), 0xfe10, {.d_s = return_type_sym->name}}, {_S(", JS.Any]"), 0, { .d_c = 0 }}})); } inline string v__ast__Table_promise_cname(v__ast__Table* t, v__ast__Type return_type) { if (return_type == _const_v__ast__void_type) { return _S("Promise_Any_Any"); } v__ast__TypeSymbol* return_type_sym = v__ast__Table_sym(t, return_type); return str_intp(2, _MOV((StrIntpData[]){{_S("Promise_"), 0xfe10, {.d_s = return_type_sym->name}}, {_S("_Any"), 0, { .d_c = 0 }}})); } inline string v__ast__Table_thread_name(v__ast__Table* t, v__ast__Type return_type) { if (v__ast__Type_idx(return_type) == 1) { if (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__option)) { return _S("thread ?"); } else if (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__result)) { return _S("thread !"); } else { return _S("thread"); } } v__ast__TypeSymbol* return_type_sym = v__ast__Table_sym(t, return_type); string ptr = (v__ast__Type_is_ptr(return_type) ? (_S("&")) : (_S(""))); string opt = (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__option) ? (_S("?")) : (_S(""))); string res = (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__result) ? (_S("!")) : (_S(""))); return str_intp(5, _MOV((StrIntpData[]){{_S("thread "), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = ptr}}, {_SLIT0, 0xfe10, {.d_s = return_type_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}})); } inline string v__ast__Table_thread_cname(v__ast__Table* t, v__ast__Type return_type) { if (return_type == _const_v__ast__void_type) { if (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__option)) { return _S("__v_thread_Option_void"); } else if (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__result)) { return _S("__v_thread_Result_void"); } else { return _S("__v_thread"); } } v__ast__TypeSymbol* return_type_sym = v__ast__Table_sym(t, return_type); string suffix = (v__ast__Type_is_ptr(return_type) ? (_S("_ptr")) : (_S(""))); string opt = (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__option) ? (_S("_option_")) : (_S(""))); string res = (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__result) ? (_S("_result_")) : (_S(""))); return str_intp(5, _MOV((StrIntpData[]){{_S("__v_thread_"), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = return_type_sym->cname}}, {_SLIT0, 0xfe10, {.d_s = suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); } inline string v__ast__Table_map_name(v__ast__Table* t, v__ast__Type key_type, v__ast__Type value_type) { v__ast__TypeSymbol* key_type_sym = v__ast__Table_sym(t, key_type); v__ast__TypeSymbol* value_type_sym = v__ast__Table_sym(t, value_type); string ptr = (v__ast__Type_is_ptr(value_type) ? (string_repeat(_S("&"), v__ast__Type_nr_muls(value_type))) : (_S(""))); string opt = (v__ast__Type_has_flag(value_type, v__ast__TypeFlag__option) ? (_S("?")) : (_S(""))); string res = (v__ast__Type_has_flag(value_type, v__ast__TypeFlag__result) ? (_S("!")) : (_S(""))); return str_intp(6, _MOV((StrIntpData[]){{_S("map["), 0xfe10, {.d_s = key_type_sym->name}}, {_S("]"), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = ptr}}, {_SLIT0, 0xfe10, {.d_s = value_type_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}})); } inline string v__ast__Table_map_cname(v__ast__Table* t, v__ast__Type key_type, v__ast__Type value_type) { v__ast__TypeSymbol* key_type_sym = v__ast__Table_sym(t, key_type); v__ast__TypeSymbol* value_type_sym = v__ast__Table_sym(t, value_type); string suffix = (v__ast__Type_is_ptr(value_type) ? (string_repeat(_S("_ptr"), v__ast__Type_nr_muls(value_type))) : (_S(""))); string opt = (v__ast__Type_has_flag(value_type, v__ast__TypeFlag__option) ? (_S("_option_")) : (_S(""))); string res = (v__ast__Type_has_flag(value_type, v__ast__TypeFlag__result) ? (_S("_result_")) : (_S(""))); if (string_contains(value_type_sym->cname, _S("["))) { string type_name = string_replace_each(value_type_sym->cname, _const_v__ast__map_cname_escape_seq); return str_intp(6, _MOV((StrIntpData[]){{_S("Map_"), 0xfe10, {.d_s = key_type_sym->cname}}, {_S("_"), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = type_name}}, {_SLIT0, 0xfe10, {.d_s = suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { return str_intp(6, _MOV((StrIntpData[]){{_S("Map_"), 0xfe10, {.d_s = key_type_sym->cname}}, {_S("_"), 0xfe10, {.d_s = opt}}, {_SLIT0, 0xfe10, {.d_s = res}}, {_SLIT0, 0xfe10, {.d_s = value_type_sym->cname}}, {_SLIT0, 0xfe10, {.d_s = suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); } return (string){.str=(byteptr)"", .is_lit=1}; } int v__ast__Table_find_or_register_chan(v__ast__Table* t, v__ast__Type elem_type, bool is_mut) { string name = v__ast__Table_chan_name(t, elem_type, is_mut); string cname = v__ast__Table_chan_cname(t, elem_type, is_mut); int existing_idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (existing_idx > 0) { return existing_idx; } v__ast__TypeSymbol chan_typ = ((v__ast__TypeSymbol){.parent_idx = _const_v__ast__chan_type_idx,.info = v__ast__Chan_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Chan, (((v__ast__Chan){.elem_type = elem_type,.is_mut = is_mut,})))),.kind = v__ast__Kind__chan,.name = name,.cname = cname,.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,}); return v__ast__Table_register_sym(t, chan_typ); } int v__ast__Table_find_or_register_map(v__ast__Table* t, v__ast__Type key_type, v__ast__Type value_type) { string name = v__ast__Table_map_name(t, key_type, value_type); string cname = v__ast__Table_map_cname(t, key_type, value_type); int existing_idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (existing_idx > 0) { return existing_idx; } v__ast__TypeSymbol map_typ = ((v__ast__TypeSymbol){.parent_idx = _const_v__ast__map_type_idx,.info = v__ast__Map_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Map, (((v__ast__Map){.key_type = key_type,.value_type = value_type,})))),.kind = v__ast__Kind__map,.name = name,.cname = cname,.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,}); return v__ast__Table_register_sym(t, map_typ); } int v__ast__Table_find_or_register_thread(v__ast__Table* t, v__ast__Type return_type) { string name = v__ast__Table_thread_name(t, return_type); string cname = v__ast__Table_thread_cname(t, return_type); int existing_idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (existing_idx > 0) { return existing_idx; } v__ast__TypeSymbol thread_typ = ((v__ast__TypeSymbol){.parent_idx = _const_v__ast__thread_type_idx,.info = v__ast__Thread_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Thread, (((v__ast__Thread){.return_type = return_type,})))),.kind = v__ast__Kind__thread,.name = name,.cname = cname,.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,}); return v__ast__Table_register_sym(t, thread_typ); } int v__ast__Table_find_or_register_promise(v__ast__Table* t, v__ast__Type return_type) { string name = v__ast__Table_promise_name(t, return_type); string cname = v__ast__Table_promise_cname(t, return_type); int existing_idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (existing_idx > 0) { return existing_idx; } v__ast__TypeSymbol promise_type = ((v__ast__TypeSymbol){.parent_idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){_S("Promise")}, &(int[]){ 0 })),.info = v__ast__Struct_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Struct, (((v__ast__Struct){.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.embeds = __new_array(0, 0, sizeof(v__ast__Type)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.is_typedef = 0,.is_union = 0,.is_heap = 0,.is_minify = 0,.is_anon = 0,.is_generic = 0,.is_shared = 0,.is_markused = 0,.has_option = 0,.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.concrete_types = new_array_from_c_array(2, 2, sizeof(v__ast__Type), _MOV((v__ast__Type[2]){return_type, (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){_S("JS.Any")}, &(int[]){ 0 }))})),.parent_type = 0,})))),.kind = v__ast__Kind__struct,.name = name,.cname = cname,.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,}); return v__ast__Table_register_sym(t, promise_type); } int v__ast__Table_find_or_register_array(v__ast__Table* t, v__ast__Type elem_type) { string name = v__ast__Table_array_name(t, elem_type); int existing_idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (existing_idx > 0) { return existing_idx; } string cname = v__ast__Table_array_cname(t, elem_type); v__ast__TypeSymbol array_type_ = ((v__ast__TypeSymbol){.parent_idx = _const_v__ast__array_type_idx,.info = v__ast__Array_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Array, (((v__ast__Array){.nr_dims = 1,.elem_type = elem_type,})))),.kind = v__ast__Kind__array,.name = name,.cname = cname,.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,}); return v__ast__Table_register_sym(t, array_type_); } int v__ast__Table_find_or_register_array_with_dims(v__ast__Table* t, v__ast__Type elem_type, int nr_dims) { if (nr_dims == 1) { return v__ast__Table_find_or_register_array(t, elem_type); } return v__ast__Table_find_or_register_array(t, v__ast__idx_to_type(v__ast__Table_find_or_register_array_with_dims(t, elem_type, (int)(nr_dims - 1)))); } int v__ast__Table_find_or_register_array_fixed(v__ast__Table* t, v__ast__Type elem_type, int size, v__ast__Expr size_expr, bool is_fn_ret) { string prefix = (is_fn_ret ? (_S("_v_")) : (_S(""))); string name = string__plus(prefix, v__ast__Table_array_fixed_name(t, elem_type, size, size_expr)); int existing_idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (existing_idx > 0) { return existing_idx; } string cname = string__plus(prefix, v__ast__Table_array_fixed_cname(t, elem_type, size)); v__ast__TypeSymbol array_fixed_type = ((v__ast__TypeSymbol){.parent_idx = 0,.info = v__ast__ArrayFixed_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__ArrayFixed, (((v__ast__ArrayFixed){.size = size,.size_expr = size_expr,.elem_type = elem_type,.is_fn_ret = is_fn_ret,})))),.kind = v__ast__Kind__array_fixed,.name = name,.cname = cname,.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,}); return v__ast__Table_register_sym(t, array_fixed_type); } int v__ast__Table_find_or_register_multi_return(v__ast__Table* t, Array_v__ast__Type mr_typs) { string name = _S("("); string cname = _S("multi_return"); for (int i = 0; i < mr_typs.len; ++i) { v__ast__Type mr_typ = ((v__ast__Type*)mr_typs.data)[i]; v__ast__TypeSymbol* mr_type_sym = v__ast__Table_sym(t, v__ast__mktyp(mr_typ)); multi_return_string_string mr_35983 = (v__ast__Type_is_ptr(mr_typ) ? ((multi_return_string_string){.arg0=_S("&"),.arg1=_S("ref_")}) : ((multi_return_string_string){.arg0=_S(""),.arg1=_S("")})); string ref = mr_35983.arg0; string cref = mr_35983.arg1; name = string__plus(name, (v__ast__Type_has_flag(mr_typ, v__ast__TypeFlag__option) ? (_S("?")) : (_S("")))); name = string__plus(name, (v__ast__Type_has_flag(mr_typ, v__ast__TypeFlag__result) ? (_S("!")) : (_S("")))); name = string__plus(name, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ref}}, {_SLIT0, 0xfe10, {.d_s = mr_type_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}}))); cname = string__plus(cname, (v__ast__Type_has_flag(mr_typ, v__ast__TypeFlag__option) ? (_S("_option")) : (_S("")))); cname = string__plus(cname, (v__ast__Type_has_flag(mr_typ, v__ast__TypeFlag__result) ? (_S("_result")) : (_S("")))); cname = string__plus(cname, str_intp(3, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = cref}}, {_SLIT0, 0xfe10, {.d_s = mr_type_sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (i < (int)(mr_typs.len - 1)) { name = string__plus(name, _S(", ")); } } name = string__plus(name, _S(")")); int existing_idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (existing_idx > 0) { return existing_idx; } v__ast__TypeSymbol mr_type = ((v__ast__TypeSymbol){.parent_idx = 0,.info = v__ast__MultiReturn_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__MultiReturn, (((v__ast__MultiReturn){.types = mr_typs,})))),.kind = v__ast__Kind__multi_return,.name = name,.cname = cname,.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,}); return v__ast__Table_register_sym(t, mr_type); } int v__ast__Table_find_or_register_fn_type(v__ast__Table* t, v__ast__Fn f, bool is_anon, bool has_decl) { string name = ((f.name).len == 0 ? (str_intp(2, _MOV((StrIntpData[]){{_S("fn "), 0xfe10, {.d_s = v__ast__Table_fn_type_source_signature(t, (voidptr)&f)}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (string_clone(f.name))); string cname = ((f.name).len == 0 ? (str_intp(2, _MOV((StrIntpData[]){{_S("anon_fn_"), 0xfe10, {.d_s = v__ast__Table_fn_type_signature(t, (voidptr)&f)}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (string_replace_each(v__util__no_dots(string_clone(f.name)), _const_v__ast__fn_type_escape_seq))); bool anon = (f.name).len == 0 || is_anon; int existing_idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (existing_idx > 0 && (*(v__ast__TypeSymbol**)array_get(t->type_symbols, existing_idx))->kind != v__ast__Kind__placeholder) { if (((*(v__ast__TypeSymbol**)array_get(t->type_symbols, existing_idx))->info)._typ == 553 /* v.ast.FnType */ && !has_decl) { (*(*(v__ast__TypeSymbol**)array_get(t->type_symbols, existing_idx))->info._v__ast__FnType).has_decl = has_decl; } return existing_idx; } return v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = v__ast__FnType_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__FnType, (((v__ast__FnType){.is_anon = anon,.has_decl = has_decl,.func = f,})))),.kind = v__ast__Kind__function,.name = name,.cname = cname,.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = f.mod,.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); } int v__ast__Table_add_placeholder_type(v__ast__Table* t, string name, v__ast__Language language) { string modname = _S(""); if (string_contains(name, _S("."))) { modname = string_all_before_last(name, _S(".")); } v__ast__TypeSymbol ph_type = ((v__ast__TypeSymbol){ .parent_idx = 0, .info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557}, .kind = v__ast__Kind__placeholder, .name = name, .cname = string_replace_each(v__util__no_dots(name), new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("&"), _S("")}))), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = modname, .is_pub = true, .is_builtin = (Array_string_contains(_const_v__ast__builtins, name)), .language = language, .idx = 0, .size = -1, .align = -1, }); return v__ast__Table_register_sym(t, ph_type); } inline v__ast__Type v__ast__Table_value_type(v__ast__Table* t, v__ast__Type typ) { v__ast__TypeSymbol* sym = v__ast__Table_final_sym(t, typ); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__variadic)) { v__ast__Array array_info = *(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513); return array_info.elem_type; } if (sym->kind == v__ast__Kind__array) { v__ast__Array info = *(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513); return info.elem_type; } if (sym->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549); return info.elem_type; } if (sym->kind == v__ast__Kind__map) { v__ast__Map info = *(v__ast__Map*)__as_cast((sym->info)._v__ast__Map,(sym->info)._typ, 514); return info.value_type; } if (sym->kind == v__ast__Kind__string && v__ast__Type_is_ptr(typ)) { return _const_v__ast__string_type; } if (sym->kind == v__ast__Kind__byteptr || sym->kind == v__ast__Kind__string) { return _const_v__ast__u8_type; } if (v__ast__Type_is_ptr(typ)) { return v__ast__Type_deref(typ); } return _const_v__ast__void_type; } void v__ast__Table_register_fn_generic_types(v__ast__Table* t, string fn_name) { (*(Array_Array_v__ast__Type*)map_get_and_set((map*)&t->fn_generic_types, &(string[]){fn_name}, &(Array_Array_v__ast__Type[]){ __new_array(0, 0, sizeof(Array_v__ast__Type)) })) = __new_array_with_default(0, 0, sizeof(Array_v__ast__Type), 0); } bool v__ast__Table_register_fn_concrete_types(v__ast__Table* t, string fn_name, Array_v__ast__Type types) { Array_Array_v__ast__Type* _t2 = (Array_Array_v__ast__Type*)(map_get_check(ADDR(map, t->fn_generic_types), &(string[]){fn_name})); _option_Array_Array_v__ast__Type _t1 = {0}; if (_t2) { *((Array_Array_v__ast__Type*)&_t1.data) = *((Array_Array_v__ast__Type*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } ; if (_t1.state != 0) { IError err = _t1.err; return false; } Array_Array_v__ast__Type a = (*(Array_Array_v__ast__Type*)_t1.data); if ((Array_Array_v__ast__Type_contains(a, types))) { return false; } array_push((array*)&a, &types); (*(Array_Array_v__ast__Type*)map_get_and_set((map*)&t->fn_generic_types, &(string[]){fn_name}, &(Array_Array_v__ast__Type[]){ __new_array(0, 0, sizeof(Array_v__ast__Type)) })) = a; return true; } bool v__ast__Table_sumtype_has_variant(v__ast__Table* t, v__ast__Type parent, v__ast__Type variant, bool is_as) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(t, parent); if (parent_sym->kind == v__ast__Kind__sum_type) { v__ast__SumType parent_info = *(v__ast__SumType*)__as_cast((parent_sym->info)._v__ast__SumType,(parent_sym->info)._typ, 544); v__ast__TypeSymbol* var_sym = v__ast__Table_sym(t, variant); if (var_sym->kind == (v__ast__Kind__aggregate)) { return v__ast__Table_sumtype_check_aggregate_variant(t, parent, (voidptr)&variant, is_as); } else if (var_sym->kind == (v__ast__Kind__alias)) { return v__ast__Table_sumtype_check_alias_variant(t, parent, variant, is_as); } else if (var_sym->kind == (v__ast__Kind__function)) { return v__ast__Table_sumtype_check_function_variant(t, parent_info, variant, is_as); } else { return v__ast__Table_sumtype_check_variant_in_type(t, parent_info, variant, is_as); } } return false; } VV_LOC bool v__ast__Table_sumtype_check_function_variant(v__ast__Table* t, v__ast__SumType parent_info, v__ast__Type variant, bool is_as) { v__ast__Fn variant_fn = (({ v__ast__TypeInfo _t1 = v__ast__Table_sym(t, variant)->info; *(v__ast__FnType*)__as_cast(_t1._v__ast__FnType,_t1._typ, 553); })).func; string variant_fn_sig = v__ast__Table_fn_type_source_signature(t, (voidptr)&variant_fn); for (int _t2 = 0; _t2 < parent_info.variants.len; ++_t2) { v__ast__Type v = ((v__ast__Type*)parent_info.variants.data)[_t2]; v__ast__TypeSymbol* v_sym = v__ast__Table_sym(t, v); if ((v_sym->info)._typ == 553 /* v.ast.FnType */) { if (string__eq(v__ast__Table_fn_type_source_signature(t, (voidptr)&(*v_sym->info._v__ast__FnType).func), variant_fn_sig) && (!is_as || v__ast__Type_nr_muls(v) == v__ast__Type_nr_muls(variant))) { return true; } } } return false; } VV_LOC bool v__ast__Table_sumtype_check_variant_in_type(v__ast__Table* t, v__ast__SumType parent_info, v__ast__Type variant, bool is_as) { for (int _t1 = 0; _t1 < parent_info.variants.len; ++_t1) { v__ast__Type v = ((v__ast__Type*)parent_info.variants.data)[_t1]; if (v__ast__Type_idx(v) == v__ast__Type_idx(variant) && v__ast__Type_has_flag(variant, v__ast__TypeFlag__option) == v__ast__Type_has_flag(v, v__ast__TypeFlag__option) && (!is_as || v__ast__Type_nr_muls(v) == v__ast__Type_nr_muls(variant))) { return true; } } return false; } VV_LOC bool v__ast__Table_sumtype_check_aggregate_variant(v__ast__Table* t, v__ast__Type parent_type, v__ast__Type* aggregate_type, bool is_as) { v__ast__Aggregate aggregate_sym = ({ v__ast__TypeInfo _t1 = v__ast__Table_sym(t, *aggregate_type)->info; *(v__ast__Aggregate*)__as_cast(_t1._v__ast__Aggregate,_t1._typ, 537); }); for (int _t2 = 0; _t2 < aggregate_sym.types.len; ++_t2) { v__ast__Type var_type = ((v__ast__Type*)aggregate_sym.types.data)[_t2]; if (!v__ast__Table_sumtype_has_variant(t, parent_type, var_type, is_as)) { return false; } } return true; } VV_LOC bool v__ast__Table_sumtype_check_alias_variant(v__ast__Table* t, v__ast__Type parent_type, v__ast__Type alias_type, bool is_as) { v__ast__SumType parent_sym = ({ v__ast__TypeInfo _t1 = v__ast__Table_sym(t, parent_type)->info; *(v__ast__SumType*)__as_cast(_t1._v__ast__SumType,_t1._typ, 544); }); if (!v__ast__Table_sumtype_check_variant_in_type(t, parent_sym, alias_type, is_as)) { v__ast__Alias alias_info = ({ v__ast__TypeInfo _t2 = v__ast__Table_sym(t, alias_type)->info; *(v__ast__Alias*)__as_cast(_t2._v__ast__Alias,_t2._typ, 539); }); return parent_type == alias_info.parent_type || v__ast__Table_sumtype_has_variant(t, parent_type, alias_info.parent_type, is_as); } return true; } bool v__ast__Table_is_sumtype_or_in_variant(v__ast__Table* t, v__ast__Type parent, v__ast__Type typ) { if (typ == 0) { return false; } if (v__ast__Table_sym(t, typ)->kind == v__ast__Kind__sum_type && v__ast__Type_idx(parent) == v__ast__Type_idx(typ) && v__ast__Type_nr_muls(parent) == v__ast__Type_nr_muls(typ)) { return true; } return v__ast__Table_sumtype_has_variant(t, parent, typ, false); } inline bool v__ast__Table_is_interface_var(v__ast__Table* t, v__ast__ScopeObject var) { bool _t2 = ((var)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast((var)._v__ast__Var,(var)._typ, 422)).orig_type != 0 && v__ast__Table_sym(t, (*(v__ast__Var*)__as_cast((var)._v__ast__Var,(var)._typ, 422)).orig_type)->kind == v__ast__Kind__interface); return _t2 && v__ast__Table_sym(t, (*(v__ast__Type*)array_last((*(v__ast__Var*)__as_cast((var)._v__ast__Var,(var)._typ, 422)).smartcasts)))->kind != v__ast__Kind__interface; } inline bool v__ast__Table_is_interface_smartcast(v__ast__Table* t, v__ast__ScopeObject var) { return (var)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast((var)._v__ast__Var,(var)._typ, 422)).orig_type != 0 && v__ast__Table_sym(t, (*(v__ast__Var*)__as_cast((var)._v__ast__Var,(var)._typ, 422)).orig_type)->kind == v__ast__Kind__interface && (*(v__ast__Var*)__as_cast((var)._v__ast__Var,(var)._typ, 422)).smartcasts.len > 0; } Array_string v__ast__Table_known_type_names(v__ast__Table* t) { Array_string res = __new_array_with_default(0, t->type_idxs.len, sizeof(string), 0); Map_string_int _t1 = t->type_idxs; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} int idx = (*(int*)DenseArray_value(&_t1.key_values, _t2)); v__ast__Type typ = v__ast__idx_to_type(idx); if (!(idx == 0 || idx == _const_v__ast__int_literal_type_idx || idx == _const_v__ast__float_literal_type_idx) && v__ast__Table_known_type_idx(t, typ)) { v__ast__TypeSymbol* tsym = v__ast__Table_sym(t, typ); if (!(tsym->kind == v__ast__Kind__function || tsym->kind == v__ast__Kind__chan)) { array_push((array*)&res, _MOV((string[]){ v__ast__Table_type_to_str(t, typ) })); } else if ((tsym->info)._typ == 550 /* v.ast.Chan */ && v__ast__Table_sym(t, (*(v__ast__Chan*)__as_cast((tsym->info)._v__ast__Chan,(tsym->info)._typ, 550)).elem_type)->kind != v__ast__Kind__placeholder) { array_push((array*)&res, _MOV((string[]){ v__ast__Table_type_to_str(t, (*tsym->info._v__ast__Chan).elem_type) })); } } } return res; } bool v__ast__Table_has_deep_child_no_ref(v__ast__Table* t, v__ast__TypeSymbol* ts, string name) { if ((ts->info)._typ == 518 /* v.ast.Struct */) { for (int _t1 = 0; _t1 < (*ts->info._v__ast__Struct).fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)(*ts->info._v__ast__Struct).fields.data)[_t1]; v__ast__TypeSymbol* sym = v__ast__Table_sym(t, field.typ); if (!v__ast__Type_is_ptr(field.typ) && !v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option) && (string__eq(sym->name, name) || v__ast__Table_has_deep_child_no_ref(t, sym, name))) { return true; } } } return false; } void v__ast__Table_complete_interface_check(v__ast__Table* t) { bool v__ast__Table_complete_interface_check_defer_0 = false; v__util__timing_start(_S("Table.complete_interface_check")); v__ast__Table_complete_interface_check_defer_0 = true; for (int tk = 0; tk < t->type_symbols.len; ++tk) { v__ast__TypeSymbol** tsym = ((v__ast__TypeSymbol**)t->type_symbols.data) + tk; v__ast__Type tk_typ = v__ast__idx_to_type(tk); if ((*tsym)->kind != v__ast__Kind__struct) { continue; } Map_int_v__ast__InterfaceDecl _t1 = t->interfaces; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} v__ast__InterfaceDecl* idecl = &(*(v__ast__InterfaceDecl*)DenseArray_value(&_t1.key_values, _t2)); if (idecl->typ == 0) { continue; } if (idecl->methods.len == 0 && idecl->fields.len == 0 && !string__eq((*tsym)->mod, v__ast__Table_sym(t, idecl->typ)->mod)) { continue; } if (v__ast__Table_does_type_implement_interface(t, tk_typ, idecl->typ)) { #if defined(CUSTOM_DEFINE_trace_types_implementing_each_interface) { eprintln(str_intp(6, _MOV((StrIntpData[]){{_S(">>> tsym.mod: "), 0xfe10, {.d_s = (*tsym)->mod}}, {_S(" | tsym.name: "), 0xfe10, {.d_s = (*tsym)->name}}, {_S(" | tk: "), 0xfe07, {.d_i32 = tk}}, {_S(" | idecl.name: "), 0xfe10, {.d_s = idecl->name}}, {_S(" | idecl.typ: "), 0xfe10, {.d_s = v__ast__Type_str(idecl->typ)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif array_push((array*)&(*(Array_v__ast__Type*)map_get_and_set((map*)&t->iface_types, &(string[]){idecl->name}, &(Array_v__ast__Type[]){ __new_array(0, 0, sizeof(v__ast__Type)) })), _MOV((v__ast__Type[]){ tk_typ })); } } } // Defer begin if (v__ast__Table_complete_interface_check_defer_0) { v__util__timing_measure(_S("Table.complete_interface_check")); } // Defer end } v__ast__Type v__ast__Table_bitsize_to_type(v__ast__Table* t, int bit_size) { switch (bit_size) { case 8: { return _const_v__ast__i8_type; } case 16: { return _const_v__ast__i16_type; } case 32: { return _const_v__ast__int_type; } case 64: { return _const_v__ast__i64_type; } default: { { if ((int)(bit_size % 8) != 0) { v__ast__Table_panic(t, str_intp(2, _MOV((StrIntpData[]){{_S("table.bitsize_to_type: compiler bug: bitsizes must be multiples of 8, but passed bit_size is "), 0xfe07, {.d_i32 = bit_size}}, {_SLIT0, 0, { .d_c = 0 }}}))); } return v__ast__new_type(v__ast__Table_find_or_register_array_fixed(t, _const_v__ast__u8_type, (int)(bit_size / 8), _const_v__ast__empty_expr, false)); } } } return 0; } bool v__ast__Table_does_type_implement_interface(v__ast__Table* t, v__ast__Type typ, v__ast__Type inter_typ) { if (v__ast__Type_idx(typ) == v__ast__Type_idx(inter_typ)) { return true; } if (v__ast__Type_idx(inter_typ) == 30 && v__ast__Type_idx(typ) == 20) { return true; } v__ast__TypeSymbol* sym = v__ast__Table_sym(t, typ); if (sym->language != v__ast__Language__v) { return false; } if ((sym->info)._typ == 518 /* v.ast.Struct */) { if ((*sym->info._v__ast__Struct).is_generic) { return false; } } v__ast__TypeSymbol* inter_sym = v__ast__Table_sym(t, inter_typ); if (sym->kind == v__ast__Kind__interface && inter_sym->kind == v__ast__Kind__interface) { return false; } if ((inter_sym->info)._typ == 542 /* v.ast.Interface */) { Array_v__ast__Attr attrs = (*(v__ast__InterfaceDecl*)map_get(ADDR(map, t->interfaces), &(int[]){inter_typ}, &(v__ast__InterfaceDecl[]){ (v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,} })).attrs; for (int _t6 = 0; _t6 < attrs.len; ++_t6) { v__ast__Attr attr = ((v__ast__Attr*)attrs.data)[_t6]; if (fast_string_eq(attr.name, _S("single_impl"))) { return false; } } for (int _t8 = 0; _t8 < (*inter_sym->info._v__ast__Interface).types.len; ++_t8) { v__ast__Type tt = ((v__ast__Type*)(*inter_sym->info._v__ast__Interface).types.data)[_t8]; if (v__ast__Type_idx(tt) == v__ast__Type_idx(typ)) { return true; } } for (int _t10 = 0; _t10 < (*inter_sym->info._v__ast__Interface).methods.len; ++_t10) { v__ast__Fn imethod = ((v__ast__Fn*)(*inter_sym->info._v__ast__Interface).methods.data)[_t10]; _result_v__ast__Fn _t11; if (_t11 = v__ast__Table_find_method_with_embeds(t, sym, imethod.name), !_t11.is_error) { v__ast__Fn method = *(v__ast__Fn*)_t11.data; string msg = v__ast__Table_is_same_method(t, (voidptr)&imethod, (voidptr)&method); if (msg.len > 0) { return false; } continue; } if (sym->info._typ == 544 /* v.ast.SumType */) { _option_v__ast__Fn _t13; if (_t13 = v__ast__TypeSymbol_find_method_with_generic_parent(sym, imethod.name), _t13.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t13.data; string msg = v__ast__Table_is_same_method(t, (voidptr)&imethod, (voidptr)&method); if (msg.len > 0) { return false; } continue; } } else if (sym->info._typ == 518 /* v.ast.Struct */) { _option_v__ast__Fn _t15; if (_t15 = v__ast__TypeSymbol_find_method_with_generic_parent(sym, imethod.name), _t15.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t15.data; string msg = v__ast__Table_is_same_method(t, (voidptr)&imethod, (voidptr)&method); if (msg.len > 0) { return false; } continue; } } else if (sym->info._typ == 542 /* v.ast.Interface */) { _option_v__ast__Fn _t17; if (_t17 = v__ast__TypeSymbol_find_method_with_generic_parent(sym, imethod.name), _t17.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t17.data; string msg = v__ast__Table_is_same_method(t, (voidptr)&imethod, (voidptr)&method); if (msg.len > 0) { return false; } continue; } } else { } return false; } for (int _t20 = 0; _t20 < (*inter_sym->info._v__ast__Interface).fields.len; ++_t20) { v__ast__StructField ifield = ((v__ast__StructField*)(*inter_sym->info._v__ast__Interface).fields.data)[_t20]; if (ifield.typ == _const_v__ast__voidptr_type || ifield.typ == _const_v__ast__nil_type) { if (v__ast__Table_struct_has_field(t, sym, ifield.name)) { continue; } else { return false; } } _result_v__ast__StructField _t22; if (_t22 = v__ast__Table_find_field_with_embeds(t, sym, ifield.name), !_t22.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t22.data; if (ifield.typ != field.typ) { return false; } else if (ifield.is_mut && !(field.is_mut || field.is_global)) { return false; } continue; } return false; } bool _t26 = (typ != _const_v__ast__voidptr_type && typ != _const_v__ast__nil_type && typ != _const_v__ast__none_type); if ( _t26 && !Array_v__ast__Type_contains((*inter_sym->info._v__ast__Interface).types, typ)) { array_push((array*)&(*inter_sym->info._v__ast__Interface).types, _MOV((v__ast__Type[]){ typ })); } if (!Array_v__ast__Type_contains((*inter_sym->info._v__ast__Interface).types, _const_v__ast__voidptr_type)) { array_push((array*)&(*inter_sym->info._v__ast__Interface).types, _MOV((v__ast__Type[]){ _const_v__ast__voidptr_type })); } return true; } return false; } multi_return_v__ast__Type_string v__ast__Table_convert_generic_static_type_name(v__ast__Table* t, string fn_name, Array_string generic_names, Array_v__ast__Type concrete_types) { _option_int _t1; if (_t1 = string_index(fn_name, _S("__static__")), _t1.state == 0) { int index = *(int*)_t1.data; if (index > 0) { string generic_name = string_substr(fn_name, 0, index); bool valid_generic = v__util__is_generic_type_name(generic_name) && (Array_string_contains(generic_names, generic_name)); if (valid_generic) { v__ast__Type name_type = v__ast__Type_set_flag(v__ast__Table_find_type(t, generic_name), v__ast__TypeFlag__generic); _option_v__ast__Type _t2; if (_t2 = v__ast__Table_convert_generic_type(t, name_type, generic_names, concrete_types), _t2.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t2.data; return (multi_return_v__ast__Type_string){.arg0=name_type, .arg1=str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Table_type_to_str(t, typ)}}, {_SLIT0, 0xfe10, {.d_s = string_substr(fn_name, index, 2147483647)}}, {_SLIT0, 0, { .d_c = 0 }}}))}; } } } } return (multi_return_v__ast__Type_string){.arg0=_const_v__ast__void_type, .arg1=fn_name}; } _option_v__ast__Type v__ast__Table_convert_generic_type(v__ast__Table* t, v__ast__Type generic_type, Array_string generic_names, Array_v__ast__Type to_types) { if (generic_names.len != to_types.len) { return (_option_v__ast__Type){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } v__ast__TypeSymbol* sym = v__ast__Table_sym(t, generic_type); if ((Array_string_contains(generic_names, sym->name))) { int index = Array_string_index(generic_names, sym->name); if (index >= to_types.len) { return (_option_v__ast__Type){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } v__ast__Type typ = (*(v__ast__Type*)array_get(to_types, index)); if (typ == 0) { return (_option_v__ast__Type){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t4; _option_ok(&(v__ast__Type[]) { v__ast__Type_set_flag(v__ast__Type_derive_add_muls(typ, generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t4), sizeof(v__ast__Type)); return _t4; } else { _option_v__ast__Type _t5; _option_ok(&(v__ast__Type[]) { v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(typ, generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t5), sizeof(v__ast__Type)); return _t5; } } if (sym->info._typ == 513 /* v.ast.Array */) { multi_return_int_v__ast__Type mr_48709 = v__ast__Table_get_array_dims(t, (*sym->info._v__ast__Array)); int dims = mr_48709.arg0; v__ast__Type elem_type = mr_48709.arg1; _option_v__ast__Type _t6; if (_t6 = v__ast__Table_convert_generic_type(t, elem_type, generic_names, to_types), _t6.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t6.data; int idx = v__ast__Table_find_or_register_array_with_dims(t, typ, dims); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t7; _option_ok(&(v__ast__Type[]) { v__ast__Type_set_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t7), sizeof(v__ast__Type)); return _t7; } else { _option_v__ast__Type _t8; _option_ok(&(v__ast__Type[]) { v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t8), sizeof(v__ast__Type)); return _t8; } } } else if (sym->info._typ == 549 /* v.ast.ArrayFixed */) { _option_v__ast__Type _t9; if (_t9 = v__ast__Table_convert_generic_type(t, (*sym->info._v__ast__ArrayFixed).elem_type, generic_names, to_types), _t9.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t9.data; int idx = v__ast__Table_find_or_register_array_fixed(t, typ, (*sym->info._v__ast__ArrayFixed).size, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))), false); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t10; _option_ok(&(v__ast__Type[]) { v__ast__Type_set_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t10), sizeof(v__ast__Type)); return _t10; } else { _option_v__ast__Type _t11; _option_ok(&(v__ast__Type[]) { v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t11), sizeof(v__ast__Type)); return _t11; } } } else if (sym->info._typ == 550 /* v.ast.Chan */) { _option_v__ast__Type _t12; if (_t12 = v__ast__Table_convert_generic_type(t, (*sym->info._v__ast__Chan).elem_type, generic_names, to_types), _t12.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t12.data; int idx = v__ast__Table_find_or_register_chan(t, typ, v__ast__Type_nr_muls(typ) > 0); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t13; _option_ok(&(v__ast__Type[]) { v__ast__Type_set_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t13), sizeof(v__ast__Type)); return _t13; } else { _option_v__ast__Type _t14; _option_ok(&(v__ast__Type[]) { v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t14), sizeof(v__ast__Type)); return _t14; } } } else if (sym->info._typ == 551 /* v.ast.Thread */) { _option_v__ast__Type _t15; if (_t15 = v__ast__Table_convert_generic_type(t, (*sym->info._v__ast__Thread).return_type, generic_names, to_types), _t15.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t15.data; int idx = v__ast__Table_find_or_register_thread(t, typ); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t16; _option_ok(&(v__ast__Type[]) { v__ast__Type_set_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t16), sizeof(v__ast__Type)); return _t16; } else { _option_v__ast__Type _t17; _option_ok(&(v__ast__Type[]) { v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t17), sizeof(v__ast__Type)); return _t17; } } } else if (sym->info._typ == 553 /* v.ast.FnType */) { v__ast__Fn func = (*sym->info._v__ast__FnType).func; bool has_generic = false; if (v__ast__Type_has_flag(func.return_type, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t18; if (_t18 = v__ast__Table_convert_generic_type(t, func.return_type, generic_names, to_types), _t18.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t18.data; func.return_type = typ; if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { has_generic = true; } } } func.params = array_clone_to_depth(&func.params, 0); for (int _t19 = 0; _t19 < func.params.len; ++_t19) { v__ast__Param* param = ((v__ast__Param*)func.params.data) + _t19; if (v__ast__Type_has_flag(param->typ, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t20; if (_t20 = v__ast__Table_convert_generic_type(t, param->typ, generic_names, to_types), _t20.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t20.data; param->typ = typ; if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { has_generic = true; } } } } func.name = _S(""); func.generic_names = __new_array_with_default(0, 0, sizeof(string), 0); int idx = v__ast__Table_find_or_register_fn_type(t, func, true, false); if (has_generic) { _option_v__ast__Type _t21; _option_ok(&(v__ast__Type[]) { v__ast__Type_set_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t21), sizeof(v__ast__Type)); return _t21; } else { _option_v__ast__Type _t22; _option_ok(&(v__ast__Type[]) { v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t22), sizeof(v__ast__Type)); return _t22; } } else if (sym->info._typ == 552 /* v.ast.MultiReturn */) { Array_v__ast__Type types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); bool type_changed = false; for (int _t23 = 0; _t23 < (*sym->info._v__ast__MultiReturn).types.len; ++_t23) { v__ast__Type ret_type = ((v__ast__Type*)(*sym->info._v__ast__MultiReturn).types.data)[_t23]; _option_v__ast__Type _t24; if (_t24 = v__ast__Table_convert_generic_type(t, ret_type, generic_names, to_types), _t24.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t24.data; array_push((array*)&types, _MOV((v__ast__Type[]){ typ })); type_changed = true; } else { IError err = _t24.err; array_push((array*)&types, _MOV((v__ast__Type[]){ ret_type })); } } if (type_changed) { int idx = v__ast__Table_find_or_register_multi_return(t, types); bool _t28 = false; Array_v__ast__Type _t28_orig = types; int _t28_len = _t28_orig.len; for (int _t29 = 0; _t29 < _t28_len; ++_t29) { v__ast__Type it = ((v__ast__Type*) _t28_orig.data)[_t29]; if (v__ast__Type_has_flag(it, v__ast__TypeFlag__generic)) { _t28 = true; break; } } bool _t27 =_t28; if (_t27) { _option_v__ast__Type _t30; _option_ok(&(v__ast__Type[]) { v__ast__Type_set_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t30), sizeof(v__ast__Type)); return _t30; } else { _option_v__ast__Type _t31; _option_ok(&(v__ast__Type[]) { v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t31), sizeof(v__ast__Type)); return _t31; } } } else if (sym->info._typ == 514 /* v.ast.Map */) { bool type_changed = false; v__ast__Type unwrapped_key_type = (*sym->info._v__ast__Map).key_type; v__ast__Type unwrapped_value_type = (*sym->info._v__ast__Map).value_type; _option_v__ast__Type _t32; if (_t32 = v__ast__Table_convert_generic_type(t, (*sym->info._v__ast__Map).key_type, generic_names, to_types), _t32.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t32.data; unwrapped_key_type = typ; type_changed = true; } _option_v__ast__Type _t33; if (_t33 = v__ast__Table_convert_generic_type(t, (*sym->info._v__ast__Map).value_type, generic_names, to_types), _t33.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t33.data; unwrapped_value_type = typ; type_changed = true; } if (type_changed) { int idx = v__ast__Table_find_or_register_map(t, unwrapped_key_type, unwrapped_value_type); if (v__ast__Type_has_flag(unwrapped_key_type, v__ast__TypeFlag__generic) || v__ast__Type_has_flag(unwrapped_value_type, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t34; _option_ok(&(v__ast__Type[]) { v__ast__Type_set_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t34), sizeof(v__ast__Type)); return _t34; } else { _option_v__ast__Type _t35; _option_ok(&(v__ast__Type[]) { v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t35), sizeof(v__ast__Type)); return _t35; } } } else if (sym->info._typ == 518 /* v.ast.Struct */) { if ((*sym->info._v__ast__Struct).is_generic) { string nrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sym->name}}, {_S("["), 0, { .d_c = 0 }}})); string rnrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sym->rname}}, {_S("["), 0, { .d_c = 0 }}})); Array_string t_generic_names = array_clone_to_depth(&generic_names, 0); Array_v__ast__Type t_to_types = array_clone_to_depth(&to_types, 0); if (sym->generic_types.len > 0 && sym->generic_types.len == (*sym->info._v__ast__Struct).generic_types.len && !Array_v__ast__Type_arr_eq(sym->generic_types, (*sym->info._v__ast__Struct).generic_types)) { Array_string _t36 = {0}; Array_v__ast__Type _t36_orig = (*sym->info._v__ast__Struct).generic_types; int _t36_len = _t36_orig.len; _t36 = __new_array(0, _t36_len, sizeof(string)); for (int _t38 = 0; _t38 < _t36_len; ++_t38) { v__ast__Type it = ((v__ast__Type*) _t36_orig.data)[_t38]; string _t37 = v__ast__Table_sym(t, it)->name; array_push((array*)&_t36, &_t37); } t_generic_names =_t36; t_to_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t39 = 0; _t39 < sym->generic_types.len; ++_t39) { v__ast__Type t_typ = ((v__ast__Type*)sym->generic_types.data)[_t39]; if (!v__ast__Type_has_flag(t_typ, v__ast__TypeFlag__generic)) { array_push((array*)&t_to_types, _MOV((v__ast__Type[]){ t_typ })); } else if (v__ast__Table_sym(t, t_typ)->kind == v__ast__Kind__any) { string tname = v__ast__Table_sym(t, t_typ)->name; int index = Array_string_index(generic_names, tname); if (index >= 0 && index < to_types.len) { array_push((array*)&t_to_types, _MOV((v__ast__Type[]){ (*(v__ast__Type*)array_get(to_types, index)) })); } } else { _option_v__ast__Type _t42; if (_t42 = v__ast__Table_convert_generic_type(t, t_typ, generic_names, to_types), _t42.state == 0) { v__ast__Type tt = *(v__ast__Type*)_t42.data; array_push((array*)&t_to_types, _MOV((v__ast__Type[]){ tt })); } } } } for (int i = 0; i < (*sym->info._v__ast__Struct).generic_types.len; ++i) { _option_v__ast__Type _t44; if (_t44 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*sym->info._v__ast__Struct).generic_types, i)), t_generic_names, t_to_types), _t44.state == 0) { v__ast__Type ct = *(v__ast__Type*)_t44.data; v__ast__TypeSymbol* gts = v__ast__Table_sym(t, ct); if (v__ast__Type_is_ptr(ct)) { nrt = string__plus(nrt, string_repeat(_S("&"), v__ast__Type_nr_muls(ct))); } nrt = string__plus(nrt, gts->name); rnrt = string__plus(rnrt, gts->name); if (i != (int)((*sym->info._v__ast__Struct).generic_types.len - 1)) { nrt = string__plus(nrt, _S(", ")); rnrt = string__plus(rnrt, _S(", ")); } } else { IError err = _t44.err; return (_option_v__ast__Type){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } } nrt = string__plus(nrt, _S("]")); rnrt = string__plus(rnrt, _S("]")); int idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){nrt}, &(int[]){ 0 })); if (idx == 0) { idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){rnrt}, &(int[]){ 0 })); if (idx == 0) { idx = v__ast__Table_add_placeholder_type(t, nrt, v__ast__Language__v); } } _option_v__ast__Type _t46; _option_ok(&(v__ast__Type[]) { v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t46), sizeof(v__ast__Type)); return _t46; } } else if (sym->info._typ == 542 /* v.ast.Interface */) { if ((*sym->info._v__ast__Interface).is_generic) { string nrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sym->name}}, {_S("["), 0, { .d_c = 0 }}})); string rnrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sym->rname}}, {_S("["), 0, { .d_c = 0 }}})); Array_string t_generic_names = array_clone_to_depth(&generic_names, 0); Array_v__ast__Type t_to_types = array_clone_to_depth(&to_types, 0); if (sym->generic_types.len > 0 && sym->generic_types.len == (*sym->info._v__ast__Interface).generic_types.len && !Array_v__ast__Type_arr_eq(sym->generic_types, (*sym->info._v__ast__Interface).generic_types)) { Array_string _t47 = {0}; Array_v__ast__Type _t47_orig = (*sym->info._v__ast__Interface).generic_types; int _t47_len = _t47_orig.len; _t47 = __new_array(0, _t47_len, sizeof(string)); for (int _t49 = 0; _t49 < _t47_len; ++_t49) { v__ast__Type it = ((v__ast__Type*) _t47_orig.data)[_t49]; string _t48 = v__ast__Table_sym(t, it)->name; array_push((array*)&_t47, &_t48); } t_generic_names =_t47; t_to_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t50 = 0; _t50 < sym->generic_types.len; ++_t50) { v__ast__Type t_typ = ((v__ast__Type*)sym->generic_types.data)[_t50]; if (!v__ast__Type_has_flag(t_typ, v__ast__TypeFlag__generic)) { array_push((array*)&t_to_types, _MOV((v__ast__Type[]){ t_typ })); } else if (v__ast__Table_sym(t, t_typ)->kind == v__ast__Kind__any) { string tname = v__ast__Table_sym(t, t_typ)->name; int index = Array_string_index(generic_names, tname); if (index >= 0 && index < to_types.len) { array_push((array*)&t_to_types, _MOV((v__ast__Type[]){ (*(v__ast__Type*)array_get(to_types, index)) })); } } else { _option_v__ast__Type _t53; if (_t53 = v__ast__Table_convert_generic_type(t, t_typ, generic_names, to_types), _t53.state == 0) { v__ast__Type tt = *(v__ast__Type*)_t53.data; array_push((array*)&t_to_types, _MOV((v__ast__Type[]){ tt })); } } } } for (int i = 0; i < (*sym->info._v__ast__Interface).generic_types.len; ++i) { _option_v__ast__Type _t55; if (_t55 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*sym->info._v__ast__Interface).generic_types, i)), t_generic_names, t_to_types), _t55.state == 0) { v__ast__Type ct = *(v__ast__Type*)_t55.data; v__ast__TypeSymbol* gts = v__ast__Table_sym(t, ct); if (v__ast__Type_is_ptr(ct)) { nrt = string__plus(nrt, string_repeat(_S("&"), v__ast__Type_nr_muls(ct))); } nrt = string__plus(nrt, gts->name); rnrt = string__plus(rnrt, gts->name); if (i != (int)((*sym->info._v__ast__Interface).generic_types.len - 1)) { nrt = string__plus(nrt, _S(", ")); rnrt = string__plus(rnrt, _S(", ")); } } else { IError err = _t55.err; return (_option_v__ast__Type){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } } nrt = string__plus(nrt, _S("]")); rnrt = string__plus(rnrt, _S("]")); int idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){nrt}, &(int[]){ 0 })); if (idx == 0) { idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){rnrt}, &(int[]){ 0 })); if (idx == 0) { idx = v__ast__Table_add_placeholder_type(t, nrt, v__ast__Language__v); } } _option_v__ast__Type _t57; _option_ok(&(v__ast__Type[]) { v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t57), sizeof(v__ast__Type)); return _t57; } } else if (sym->info._typ == 544 /* v.ast.SumType */) { if ((*sym->info._v__ast__SumType).is_generic) { string nrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sym->name}}, {_S("["), 0, { .d_c = 0 }}})); string rnrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sym->rname}}, {_S("["), 0, { .d_c = 0 }}})); Array_string t_generic_names = array_clone_to_depth(&generic_names, 0); Array_v__ast__Type t_to_types = array_clone_to_depth(&to_types, 0); if (sym->generic_types.len > 0 && sym->generic_types.len == (*sym->info._v__ast__SumType).generic_types.len && !Array_v__ast__Type_arr_eq(sym->generic_types, (*sym->info._v__ast__SumType).generic_types)) { Array_string _t58 = {0}; Array_v__ast__Type _t58_orig = (*sym->info._v__ast__SumType).generic_types; int _t58_len = _t58_orig.len; _t58 = __new_array(0, _t58_len, sizeof(string)); for (int _t60 = 0; _t60 < _t58_len; ++_t60) { v__ast__Type it = ((v__ast__Type*) _t58_orig.data)[_t60]; string _t59 = v__ast__Table_sym(t, it)->name; array_push((array*)&_t58, &_t59); } t_generic_names =_t58; t_to_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t61 = 0; _t61 < sym->generic_types.len; ++_t61) { v__ast__Type t_typ = ((v__ast__Type*)sym->generic_types.data)[_t61]; if (!v__ast__Type_has_flag(t_typ, v__ast__TypeFlag__generic)) { array_push((array*)&t_to_types, _MOV((v__ast__Type[]){ t_typ })); } else if (v__ast__Table_sym(t, t_typ)->kind == v__ast__Kind__any) { string tname = v__ast__Table_sym(t, t_typ)->name; int index = Array_string_index(generic_names, tname); if (index >= 0 && index < to_types.len) { array_push((array*)&t_to_types, _MOV((v__ast__Type[]){ (*(v__ast__Type*)array_get(to_types, index)) })); } } else { _option_v__ast__Type _t64; if (_t64 = v__ast__Table_convert_generic_type(t, t_typ, generic_names, to_types), _t64.state == 0) { v__ast__Type tt = *(v__ast__Type*)_t64.data; array_push((array*)&t_to_types, _MOV((v__ast__Type[]){ tt })); } } } } for (int i = 0; i < (*sym->info._v__ast__SumType).generic_types.len; ++i) { _option_v__ast__Type _t66; if (_t66 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*sym->info._v__ast__SumType).generic_types, i)), t_generic_names, t_to_types), _t66.state == 0) { v__ast__Type ct = *(v__ast__Type*)_t66.data; v__ast__TypeSymbol* gts = v__ast__Table_sym(t, ct); if (v__ast__Type_is_ptr(ct)) { nrt = string__plus(nrt, string_repeat(_S("&"), v__ast__Type_nr_muls(ct))); } nrt = string__plus(nrt, gts->name); rnrt = string__plus(rnrt, gts->name); if (i != (int)((*sym->info._v__ast__SumType).generic_types.len - 1)) { nrt = string__plus(nrt, _S(", ")); rnrt = string__plus(rnrt, _S(", ")); } } else { IError err = _t66.err; return (_option_v__ast__Type){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } } nrt = string__plus(nrt, _S("]")); rnrt = string__plus(rnrt, _S("]")); int idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){nrt}, &(int[]){ 0 })); if (idx == 0) { idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){rnrt}, &(int[]){ 0 })); if (idx == 0) { idx = v__ast__Table_add_placeholder_type(t, nrt, v__ast__Language__v); } } _option_v__ast__Type _t68; _option_ok(&(v__ast__Type[]) { v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), generic_type), v__ast__TypeFlag__generic) }, (_option*)(&_t68), sizeof(v__ast__Type)); return _t68; } } else { } return (_option_v__ast__Type){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } VV_LOC void v__ast__generic_names_push_with_filter(Array_string* to_names, Array_string from_names) { for (int _t1 = 0; _t1 < from_names.len; ++_t1) { string name = ((string*)from_names.data)[_t1]; if (!(Array_string_contains(*to_names, name))) { array_push((array*)to_names, _MOV((string[]){ string_clone(name) })); } } } Array_string v__ast__Table_generic_type_names(v__ast__Table* t, v__ast__Type generic_type) { Array_string names = __new_array_with_default(0, 0, sizeof(string), 0); v__ast__TypeSymbol* sym = v__ast__Table_sym(t, generic_type); if (sym->name.len == 1 && u8_is_capital(string_at(sym->name, 0))) { array_push((array*)&names, _MOV((string[]){ string_clone(sym->name) })); return names; } if (sym->info._typ == 513 /* v.ast.Array */) { multi_return_int_v__ast__Type mr_54468 = v__ast__Table_get_array_dims(t, (*sym->info._v__ast__Array)); v__ast__Type elem_type = mr_54468.arg1; _PUSH_MANY(&names, (v__ast__Table_generic_type_names(t, elem_type)), _t3, Array_string); } else if (sym->info._typ == 549 /* v.ast.ArrayFixed */) { _PUSH_MANY(&names, (v__ast__Table_generic_type_names(t, (*sym->info._v__ast__ArrayFixed).elem_type)), _t4, Array_string); } else if (sym->info._typ == 550 /* v.ast.Chan */) { _PUSH_MANY(&names, (v__ast__Table_generic_type_names(t, (*sym->info._v__ast__Chan).elem_type)), _t5, Array_string); } else if (sym->info._typ == 553 /* v.ast.FnType */) { _PUSH_MANY(&names, ((*sym->info._v__ast__FnType).func.generic_names), _t6, Array_string); } else if (sym->info._typ == 552 /* v.ast.MultiReturn */) { for (int _t7 = 0; _t7 < (*sym->info._v__ast__MultiReturn).types.len; ++_t7) { v__ast__Type ret_type = ((v__ast__Type*)(*sym->info._v__ast__MultiReturn).types.data)[_t7]; v__ast__generic_names_push_with_filter(&names, v__ast__Table_generic_type_names(t, ret_type)); } } else if (sym->info._typ == 514 /* v.ast.Map */) { _PUSH_MANY(&names, (v__ast__Table_generic_type_names(t, (*sym->info._v__ast__Map).key_type)), _t8, Array_string); v__ast__generic_names_push_with_filter(&names, v__ast__Table_generic_type_names(t, (*sym->info._v__ast__Map).value_type)); } else if (sym->info._typ == 518 /* v.ast.Struct */) { if ((*sym->info._v__ast__Struct).is_generic) { if (sym->generic_types.len > 0) { for (int _t9 = 0; _t9 < sym->generic_types.len; ++_t9) { v__ast__Type typ = ((v__ast__Type*)sym->generic_types.data)[_t9]; if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic) && v__ast__Table_sym(t, typ)->kind == v__ast__Kind__any) { array_push((array*)&names, _MOV((string[]){ string_clone(v__ast__Table_sym(t, typ)->name) })); } } } else { Array_string _t12 = {0}; Array_v__ast__Type _t12_orig = (*sym->info._v__ast__Struct).generic_types; int _t12_len = _t12_orig.len; _t12 = __new_array(0, _t12_len, sizeof(string)); for (int _t14 = 0; _t14 < _t12_len; ++_t14) { v__ast__Type it = ((v__ast__Type*) _t12_orig.data)[_t14]; string _t13 = v__ast__Table_sym(t, it)->name; array_push((array*)&_t12, &_t13); } _PUSH_MANY(&names, (_t12), _t11, Array_string); } } } else if (sym->info._typ == 542 /* v.ast.Interface */) { if ((*sym->info._v__ast__Interface).is_generic) { if (sym->generic_types.len > 0) { for (int _t15 = 0; _t15 < sym->generic_types.len; ++_t15) { v__ast__Type typ = ((v__ast__Type*)sym->generic_types.data)[_t15]; if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic) && v__ast__Table_sym(t, typ)->kind == v__ast__Kind__any) { array_push((array*)&names, _MOV((string[]){ string_clone(v__ast__Table_sym(t, typ)->name) })); } } } else { Array_string _t18 = {0}; Array_v__ast__Type _t18_orig = (*sym->info._v__ast__Interface).generic_types; int _t18_len = _t18_orig.len; _t18 = __new_array(0, _t18_len, sizeof(string)); for (int _t20 = 0; _t20 < _t18_len; ++_t20) { v__ast__Type it = ((v__ast__Type*) _t18_orig.data)[_t20]; string _t19 = v__ast__Table_sym(t, it)->name; array_push((array*)&_t18, &_t19); } _PUSH_MANY(&names, (_t18), _t17, Array_string); } } } else if (sym->info._typ == 544 /* v.ast.SumType */) { if ((*sym->info._v__ast__SumType).is_generic) { if (sym->generic_types.len > 0) { for (int _t21 = 0; _t21 < sym->generic_types.len; ++_t21) { v__ast__Type typ = ((v__ast__Type*)sym->generic_types.data)[_t21]; if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic) && v__ast__Table_sym(t, typ)->kind == v__ast__Kind__any) { array_push((array*)&names, _MOV((string[]){ string_clone(v__ast__Table_sym(t, typ)->name) })); } } } else { Array_string _t24 = {0}; Array_v__ast__Type _t24_orig = (*sym->info._v__ast__SumType).generic_types; int _t24_len = _t24_orig.len; _t24 = __new_array(0, _t24_len, sizeof(string)); for (int _t26 = 0; _t26 < _t24_len; ++_t26) { v__ast__Type it = ((v__ast__Type*) _t24_orig.data)[_t26]; string _t25 = v__ast__Table_sym(t, it)->name; array_push((array*)&_t24, &_t25); } _PUSH_MANY(&names, (_t24), _t23, Array_string); } } } else { } return names; } v__ast__Type v__ast__Table_unwrap_generic_type(v__ast__Table* t, v__ast__Type typ, Array_string generic_names, Array_v__ast__Type concrete_types) { return v__ast__Table_unwrap_generic_type_ex(t, typ, generic_names, concrete_types, false); } v__ast__Type v__ast__Table_unwrap_generic_type_ex(v__ast__Table* t, v__ast__Type typ, Array_string generic_names, Array_v__ast__Type concrete_types, bool recheck_concrete_types) { Array_v__ast__Type final_concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); Array_v__ast__StructField fields = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); string nrt = _S(""); string c_nrt = _S(""); v__ast__TypeSymbol* ts = v__ast__Table_sym(t, typ); if (ts->info._typ == 513 /* v.ast.Array */) { multi_return_int_v__ast__Type mr_55906 = v__ast__Table_get_array_dims(t, (*ts->info._v__ast__Array)); int dims = mr_55906.arg0; v__ast__Type elem_type = mr_55906.arg1; v__ast__Type unwrap_typ = v__ast__Table_unwrap_generic_type_ex(t, elem_type, generic_names, concrete_types, recheck_concrete_types); int idx = v__ast__Table_find_or_register_array_with_dims(t, unwrap_typ, dims); return v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), typ), v__ast__TypeFlag__generic); } else if (ts->info._typ == 549 /* v.ast.ArrayFixed */) { v__ast__Type unwrap_typ = v__ast__Table_unwrap_generic_type_ex(t, (*ts->info._v__ast__ArrayFixed).elem_type, generic_names, concrete_types, recheck_concrete_types); int idx = v__ast__Table_find_or_register_array_fixed(t, unwrap_typ, (*ts->info._v__ast__ArrayFixed).size, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))), false); return v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), typ), v__ast__TypeFlag__generic); } else if (ts->info._typ == 550 /* v.ast.Chan */) { v__ast__Type unwrap_typ = v__ast__Table_unwrap_generic_type(t, (*ts->info._v__ast__Chan).elem_type, generic_names, concrete_types); int idx = v__ast__Table_find_or_register_chan(t, unwrap_typ, v__ast__Type_nr_muls(unwrap_typ) > 0); return v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), typ), v__ast__TypeFlag__generic); } else if (ts->info._typ == 551 /* v.ast.Thread */) { v__ast__Type unwrap_typ = v__ast__Table_unwrap_generic_type_ex(t, (*ts->info._v__ast__Thread).return_type, generic_names, concrete_types, recheck_concrete_types); int idx = v__ast__Table_find_or_register_thread(t, unwrap_typ); return v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), typ), v__ast__TypeFlag__generic); } else if (ts->info._typ == 514 /* v.ast.Map */) { v__ast__Type unwrap_key_type = v__ast__Table_unwrap_generic_type_ex(t, (*ts->info._v__ast__Map).key_type, generic_names, concrete_types, recheck_concrete_types); v__ast__Type unwrap_value_type = v__ast__Table_unwrap_generic_type_ex(t, (*ts->info._v__ast__Map).value_type, generic_names, concrete_types, recheck_concrete_types); int idx = v__ast__Table_find_or_register_map(t, unwrap_key_type, unwrap_value_type); return v__ast__Type_clear_flag(v__ast__Type_derive_add_muls(v__ast__new_type(idx), typ), v__ast__TypeFlag__generic); } else if (ts->info._typ == 518 /* v.ast.Struct */) { if (!(*ts->info._v__ast__Struct).is_generic) { return typ; } Array_string t_generic_names = array_clone_to_depth(&generic_names, 0); Array_v__ast__Type t_concrete_types = array_clone_to_depth(&concrete_types, 0); if (ts->generic_types.len > 0 && ts->generic_types.len == (*ts->info._v__ast__Struct).generic_types.len && !Array_v__ast__Type_arr_eq(ts->generic_types, (*ts->info._v__ast__Struct).generic_types)) { Array_string _t7 = {0}; Array_v__ast__Type _t7_orig = (*ts->info._v__ast__Struct).generic_types; int _t7_len = _t7_orig.len; _t7 = __new_array(0, _t7_len, sizeof(string)); for (int _t9 = 0; _t9 < _t7_len; ++_t9) { v__ast__Type it = ((v__ast__Type*) _t7_orig.data)[_t9]; string _t8 = v__ast__Table_sym(t, it)->name; array_push((array*)&_t7, &_t8); } t_generic_names =_t7; t_concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t10 = 0; _t10 < ts->generic_types.len; ++_t10) { v__ast__Type t_typ = ((v__ast__Type*)ts->generic_types.data)[_t10]; if (!v__ast__Type_has_flag(t_typ, v__ast__TypeFlag__generic)) { array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ t_typ })); } else if (v__ast__Table_sym(t, t_typ)->kind == v__ast__Kind__any) { string tname = v__ast__Table_sym(t, t_typ)->name; int index = Array_string_index(generic_names, tname); if (index >= 0 && index < concrete_types.len) { array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ (*(v__ast__Type*)array_get(concrete_types, index)) })); } } else { array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ v__ast__Table_unwrap_generic_type(t, t_typ, generic_names, concrete_types) })); } } } nrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ts->name}}, {_S("["), 0, { .d_c = 0 }}})); c_nrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ts->cname}}, {_S("_T_"), 0, { .d_c = 0 }}})); for (int i = 0; i < (*ts->info._v__ast__Struct).generic_types.len; ++i) { _option_v__ast__Type _t14; if (_t14 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*ts->info._v__ast__Struct).generic_types, i)), t_generic_names, t_concrete_types), _t14.state == 0) { v__ast__Type ct = *(v__ast__Type*)_t14.data; v__ast__TypeSymbol* gts = v__ast__Table_sym(t, ct); if (v__ast__Type_is_ptr(ct)) { nrt = string__plus(nrt, string_repeat(_S("&"), v__ast__Type_nr_muls(ct))); } nrt = string__plus(nrt, gts->name); c_nrt = string__plus(c_nrt, gts->cname); if (i != (int)((*ts->info._v__ast__Struct).generic_types.len - 1)) { nrt = string__plus(nrt, _S(", ")); c_nrt = string__plus(c_nrt, _S("_")); } } else { IError err = _t14.err; return typ; } } nrt = string__plus(nrt, _S("]")); int idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){nrt}, &(int[]){ 0 })); if (idx != 0 && (*(v__ast__TypeSymbol**)array_get(t->type_symbols, idx))->kind != v__ast__Kind__placeholder) { if (recheck_concrete_types) { fields = array_clone_to_depth(&(*ts->info._v__ast__Struct).fields, 0); for (int i = 0; i < fields.len; ++i) { if (!v__ast__Type_has_flag((*(v__ast__StructField*)array_get(fields, i)).typ, v__ast__TypeFlag__generic)) { continue; } if ((Array_v__ast__Kind_contains(new_array_from_c_array(3, 3, sizeof(v__ast__Kind), _MOV((v__ast__Kind[3]){v__ast__Kind__array, v__ast__Kind__array_fixed, v__ast__Kind__map})), v__ast__Table_type_kind(t, (*(v__ast__StructField*)array_get(fields, i)).typ))) && v__ast__Table_check_if_elements_need_unwrap(t, typ, (*(v__ast__StructField*)array_get(fields, i)).typ)) { v__ast__Table_unwrap_generic_type_ex(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types, recheck_concrete_types); } } for (int i = 0; i < (*ts->info._v__ast__Struct).generic_types.len; ++i) { _option_v__ast__Type _t16; if (_t16 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*ts->info._v__ast__Struct).generic_types, i)), t_generic_names, t_concrete_types), _t16.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t16.data; array_push((array*)&final_concrete_types, _MOV((v__ast__Type[]){ t_typ })); } } if (final_concrete_types.len > 0) { v__ast__Table_unwrap_method_types(t, ts, generic_names, concrete_types, final_concrete_types); } } return v__ast__Type_clear_flag(v__ast__Type_derive(v__ast__new_type(idx), typ), v__ast__TypeFlag__generic); } else { fields = array_clone_to_depth(&(*ts->info._v__ast__Struct).fields, 0); for (int i = 0; i < fields.len; ++i) { if (v__ast__Type_has_flag((*(v__ast__StructField*)array_get(fields, i)).typ, v__ast__TypeFlag__generic)) { v__ast__Type orig_type = (*(v__ast__StructField*)array_get(fields, i)).typ; v__ast__TypeSymbol* sym = v__ast__Table_sym(t, (*(v__ast__StructField*)array_get(fields, i)).typ); if (sym->kind == v__ast__Kind__struct && v__ast__Type_idx((*(v__ast__StructField*)array_get(fields, i)).typ) != v__ast__Type_idx(typ)) { (*(v__ast__StructField*)array_get(fields, i)).typ = v__ast__Table_unwrap_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types); } else { _option_v__ast__Type _t19; if (_t19 = v__ast__Table_convert_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types), _t19.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t19.data; (*(v__ast__StructField*)array_get(fields, i)).typ = t_typ; } if (v__ast__Type_has_flag((*(v__ast__StructField*)array_get(fields, i)).typ, v__ast__TypeFlag__generic) && (sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__array_fixed || sym->kind == v__ast__Kind__map) && v__ast__Table_check_if_elements_need_unwrap(t, typ, (*(v__ast__StructField*)array_get(fields, i)).typ)) { (*(v__ast__StructField*)array_get(fields, i)).typ = v__ast__Table_unwrap_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types); } } if ((*(v__ast__StructField*)array_get(fields, i)).is_embed) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(t, typ); v__ast__TypeInfo parent_info = parent_sym->info; if ((parent_info)._typ == 518 /* v.ast.Struct */) { for (int _t20 = 0; _t20 < (*parent_info._v__ast__Struct).embeds.len; ++_t20) { v__ast__Type* embed = ((v__ast__Type*)(*parent_info._v__ast__Struct).embeds.data) + _t20; if (*embed == orig_type) { *embed = (*(v__ast__StructField*)array_get(fields, i)).typ; break; } } } } } } for (int i = 0; i < (*ts->info._v__ast__Struct).generic_types.len; ++i) { _option_v__ast__Type _t21; if (_t21 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*ts->info._v__ast__Struct).generic_types, i)), t_generic_names, t_concrete_types), _t21.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t21.data; array_push((array*)&final_concrete_types, _MOV((v__ast__Type[]){ t_typ })); } } } } else if (ts->info._typ == 542 /* v.ast.Interface */) { if (!(*ts->info._v__ast__Interface).is_generic) { return typ; } Array_string t_generic_names = array_clone_to_depth(&generic_names, 0); Array_v__ast__Type t_concrete_types = array_clone_to_depth(&concrete_types, 0); if (ts->generic_types.len > 0 && ts->generic_types.len == (*ts->info._v__ast__Interface).generic_types.len && !Array_v__ast__Type_arr_eq(ts->generic_types, (*ts->info._v__ast__Interface).generic_types)) { Array_string _t24 = {0}; Array_v__ast__Type _t24_orig = (*ts->info._v__ast__Interface).generic_types; int _t24_len = _t24_orig.len; _t24 = __new_array(0, _t24_len, sizeof(string)); for (int _t26 = 0; _t26 < _t24_len; ++_t26) { v__ast__Type it = ((v__ast__Type*) _t24_orig.data)[_t26]; string _t25 = v__ast__Table_sym(t, it)->name; array_push((array*)&_t24, &_t25); } t_generic_names =_t24; t_concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t27 = 0; _t27 < ts->generic_types.len; ++_t27) { v__ast__Type t_typ = ((v__ast__Type*)ts->generic_types.data)[_t27]; if (!v__ast__Type_has_flag(t_typ, v__ast__TypeFlag__generic)) { array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ t_typ })); } else if (v__ast__Table_sym(t, t_typ)->kind == v__ast__Kind__any) { string tname = v__ast__Table_sym(t, t_typ)->name; int index = Array_string_index(generic_names, tname); if (index >= 0 && index < concrete_types.len) { array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ (*(v__ast__Type*)array_get(concrete_types, index)) })); } } else { array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ v__ast__Table_unwrap_generic_type(t, t_typ, generic_names, concrete_types) })); } } } nrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ts->name}}, {_S("["), 0, { .d_c = 0 }}})); c_nrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ts->cname}}, {_S("_T_"), 0, { .d_c = 0 }}})); for (int i = 0; i < (*ts->info._v__ast__Interface).generic_types.len; ++i) { _option_v__ast__Type _t31; if (_t31 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*ts->info._v__ast__Interface).generic_types, i)), t_generic_names, t_concrete_types), _t31.state == 0) { v__ast__Type ct = *(v__ast__Type*)_t31.data; v__ast__TypeSymbol* gts = v__ast__Table_sym(t, ct); if (v__ast__Type_is_ptr(ct)) { nrt = string__plus(nrt, string_repeat(_S("&"), v__ast__Type_nr_muls(ct))); } nrt = string__plus(nrt, gts->name); c_nrt = string__plus(c_nrt, gts->cname); if (i != (int)((*ts->info._v__ast__Interface).generic_types.len - 1)) { nrt = string__plus(nrt, _S(", ")); c_nrt = string__plus(c_nrt, _S("_")); } } else { IError err = _t31.err; return typ; } } nrt = string__plus(nrt, _S("]")); int idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){nrt}, &(int[]){ 0 })); if (idx != 0 && (*(v__ast__TypeSymbol**)array_get(t->type_symbols, idx))->kind != v__ast__Kind__placeholder) { if (recheck_concrete_types) { fields = array_clone_to_depth(&(*ts->info._v__ast__Interface).fields, 0); for (int i = 0; i < fields.len; ++i) { if (!v__ast__Type_has_flag((*(v__ast__StructField*)array_get(fields, i)).typ, v__ast__TypeFlag__generic)) { continue; } if ((Array_v__ast__Kind_contains(new_array_from_c_array(3, 3, sizeof(v__ast__Kind), _MOV((v__ast__Kind[3]){v__ast__Kind__array, v__ast__Kind__array_fixed, v__ast__Kind__map})), v__ast__Table_type_kind(t, (*(v__ast__StructField*)array_get(fields, i)).typ))) && v__ast__Table_check_if_elements_need_unwrap(t, typ, (*(v__ast__StructField*)array_get(fields, i)).typ)) { v__ast__Table_unwrap_generic_type_ex(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types, recheck_concrete_types); } } for (int i = 0; i < (*ts->info._v__ast__Interface).generic_types.len; ++i) { _option_v__ast__Type _t33; if (_t33 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*ts->info._v__ast__Interface).generic_types, i)), t_generic_names, t_concrete_types), _t33.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t33.data; array_push((array*)&final_concrete_types, _MOV((v__ast__Type[]){ t_typ })); } } if (final_concrete_types.len > 0) { v__ast__Table_unwrap_method_types(t, ts, generic_names, concrete_types, final_concrete_types); } } return v__ast__Type_clear_flag(v__ast__Type_derive(v__ast__new_type(idx), typ), v__ast__TypeFlag__generic); } else { fields = array_clone_to_depth(&(*ts->info._v__ast__Interface).fields, 0); for (int i = 0; i < fields.len; ++i) { if (v__ast__Type_has_flag((*(v__ast__StructField*)array_get(fields, i)).typ, v__ast__TypeFlag__generic)) { v__ast__Type orig_type = (*(v__ast__StructField*)array_get(fields, i)).typ; v__ast__TypeSymbol* sym = v__ast__Table_sym(t, (*(v__ast__StructField*)array_get(fields, i)).typ); if (sym->kind == v__ast__Kind__struct && v__ast__Type_idx((*(v__ast__StructField*)array_get(fields, i)).typ) != v__ast__Type_idx(typ)) { (*(v__ast__StructField*)array_get(fields, i)).typ = v__ast__Table_unwrap_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types); } else { _option_v__ast__Type _t36; if (_t36 = v__ast__Table_convert_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types), _t36.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t36.data; (*(v__ast__StructField*)array_get(fields, i)).typ = t_typ; } if (v__ast__Type_has_flag((*(v__ast__StructField*)array_get(fields, i)).typ, v__ast__TypeFlag__generic) && (sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__array_fixed || sym->kind == v__ast__Kind__map) && v__ast__Table_check_if_elements_need_unwrap(t, typ, (*(v__ast__StructField*)array_get(fields, i)).typ)) { (*(v__ast__StructField*)array_get(fields, i)).typ = v__ast__Table_unwrap_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types); } } if ((*(v__ast__StructField*)array_get(fields, i)).is_embed) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(t, typ); v__ast__TypeInfo parent_info = parent_sym->info; if ((parent_info)._typ == 518 /* v.ast.Struct */) { for (int _t37 = 0; _t37 < (*parent_info._v__ast__Struct).embeds.len; ++_t37) { v__ast__Type* embed = ((v__ast__Type*)(*parent_info._v__ast__Struct).embeds.data) + _t37; if (*embed == orig_type) { *embed = (*(v__ast__StructField*)array_get(fields, i)).typ; break; } } } } } } for (int i = 0; i < (*ts->info._v__ast__Interface).generic_types.len; ++i) { _option_v__ast__Type _t38; if (_t38 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*ts->info._v__ast__Interface).generic_types, i)), t_generic_names, t_concrete_types), _t38.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t38.data; array_push((array*)&final_concrete_types, _MOV((v__ast__Type[]){ t_typ })); } } } } else if (ts->info._typ == 544 /* v.ast.SumType */) { if (!(*ts->info._v__ast__SumType).is_generic) { return typ; } Array_string t_generic_names = array_clone_to_depth(&generic_names, 0); Array_v__ast__Type t_concrete_types = array_clone_to_depth(&concrete_types, 0); if (ts->generic_types.len > 0 && ts->generic_types.len == (*ts->info._v__ast__SumType).generic_types.len && !Array_v__ast__Type_arr_eq(ts->generic_types, (*ts->info._v__ast__SumType).generic_types)) { Array_string _t41 = {0}; Array_v__ast__Type _t41_orig = (*ts->info._v__ast__SumType).generic_types; int _t41_len = _t41_orig.len; _t41 = __new_array(0, _t41_len, sizeof(string)); for (int _t43 = 0; _t43 < _t41_len; ++_t43) { v__ast__Type it = ((v__ast__Type*) _t41_orig.data)[_t43]; string _t42 = v__ast__Table_sym(t, it)->name; array_push((array*)&_t41, &_t42); } t_generic_names =_t41; t_concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t44 = 0; _t44 < ts->generic_types.len; ++_t44) { v__ast__Type t_typ = ((v__ast__Type*)ts->generic_types.data)[_t44]; if (!v__ast__Type_has_flag(t_typ, v__ast__TypeFlag__generic)) { array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ t_typ })); } else if (v__ast__Table_sym(t, t_typ)->kind == v__ast__Kind__any) { string tname = v__ast__Table_sym(t, t_typ)->name; int index = Array_string_index(generic_names, tname); if (index >= 0 && index < concrete_types.len) { array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ (*(v__ast__Type*)array_get(concrete_types, index)) })); } } else { array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ v__ast__Table_unwrap_generic_type(t, t_typ, generic_names, concrete_types) })); } } } nrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ts->name}}, {_S("["), 0, { .d_c = 0 }}})); c_nrt = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ts->cname}}, {_S("_T_"), 0, { .d_c = 0 }}})); for (int i = 0; i < (*ts->info._v__ast__SumType).generic_types.len; ++i) { _option_v__ast__Type _t48; if (_t48 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*ts->info._v__ast__SumType).generic_types, i)), t_generic_names, t_concrete_types), _t48.state == 0) { v__ast__Type ct = *(v__ast__Type*)_t48.data; v__ast__TypeSymbol* gts = v__ast__Table_sym(t, ct); if (v__ast__Type_is_ptr(ct)) { nrt = string__plus(nrt, string_repeat(_S("&"), v__ast__Type_nr_muls(ct))); } nrt = string__plus(nrt, gts->name); c_nrt = string__plus(c_nrt, gts->cname); if (i != (int)((*ts->info._v__ast__SumType).generic_types.len - 1)) { nrt = string__plus(nrt, _S(", ")); c_nrt = string__plus(c_nrt, _S("_")); } } else { IError err = _t48.err; return typ; } } nrt = string__plus(nrt, _S("]")); int idx = (*(int*)map_get(ADDR(map, t->type_idxs), &(string[]){nrt}, &(int[]){ 0 })); if (idx != 0 && (*(v__ast__TypeSymbol**)array_get(t->type_symbols, idx))->kind != v__ast__Kind__placeholder) { if (recheck_concrete_types) { fields = array_clone_to_depth(&(*ts->info._v__ast__SumType).fields, 0); for (int i = 0; i < fields.len; ++i) { if (!v__ast__Type_has_flag((*(v__ast__StructField*)array_get(fields, i)).typ, v__ast__TypeFlag__generic)) { continue; } if ((Array_v__ast__Kind_contains(new_array_from_c_array(3, 3, sizeof(v__ast__Kind), _MOV((v__ast__Kind[3]){v__ast__Kind__array, v__ast__Kind__array_fixed, v__ast__Kind__map})), v__ast__Table_type_kind(t, (*(v__ast__StructField*)array_get(fields, i)).typ))) && v__ast__Table_check_if_elements_need_unwrap(t, typ, (*(v__ast__StructField*)array_get(fields, i)).typ)) { v__ast__Table_unwrap_generic_type_ex(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types, recheck_concrete_types); } } for (int i = 0; i < (*ts->info._v__ast__SumType).generic_types.len; ++i) { _option_v__ast__Type _t50; if (_t50 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*ts->info._v__ast__SumType).generic_types, i)), t_generic_names, t_concrete_types), _t50.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t50.data; array_push((array*)&final_concrete_types, _MOV((v__ast__Type[]){ t_typ })); } } if (final_concrete_types.len > 0) { v__ast__Table_unwrap_method_types(t, ts, generic_names, concrete_types, final_concrete_types); } } return v__ast__Type_clear_flag(v__ast__Type_derive(v__ast__new_type(idx), typ), v__ast__TypeFlag__generic); } else { fields = array_clone_to_depth(&(*ts->info._v__ast__SumType).fields, 0); for (int i = 0; i < fields.len; ++i) { if (v__ast__Type_has_flag((*(v__ast__StructField*)array_get(fields, i)).typ, v__ast__TypeFlag__generic)) { v__ast__Type orig_type = (*(v__ast__StructField*)array_get(fields, i)).typ; v__ast__TypeSymbol* sym = v__ast__Table_sym(t, (*(v__ast__StructField*)array_get(fields, i)).typ); if (sym->kind == v__ast__Kind__struct && v__ast__Type_idx((*(v__ast__StructField*)array_get(fields, i)).typ) != v__ast__Type_idx(typ)) { (*(v__ast__StructField*)array_get(fields, i)).typ = v__ast__Table_unwrap_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types); } else { _option_v__ast__Type _t53; if (_t53 = v__ast__Table_convert_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types), _t53.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t53.data; (*(v__ast__StructField*)array_get(fields, i)).typ = t_typ; } if (v__ast__Type_has_flag((*(v__ast__StructField*)array_get(fields, i)).typ, v__ast__TypeFlag__generic) && (sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__array_fixed || sym->kind == v__ast__Kind__map) && v__ast__Table_check_if_elements_need_unwrap(t, typ, (*(v__ast__StructField*)array_get(fields, i)).typ)) { (*(v__ast__StructField*)array_get(fields, i)).typ = v__ast__Table_unwrap_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, t_generic_names, t_concrete_types); } } if ((*(v__ast__StructField*)array_get(fields, i)).is_embed) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(t, typ); v__ast__TypeInfo parent_info = parent_sym->info; if ((parent_info)._typ == 518 /* v.ast.Struct */) { for (int _t54 = 0; _t54 < (*parent_info._v__ast__Struct).embeds.len; ++_t54) { v__ast__Type* embed = ((v__ast__Type*)(*parent_info._v__ast__Struct).embeds.data) + _t54; if (*embed == orig_type) { *embed = (*(v__ast__StructField*)array_get(fields, i)).typ; break; } } } } } } for (int i = 0; i < (*ts->info._v__ast__SumType).generic_types.len; ++i) { _option_v__ast__Type _t55; if (_t55 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get((*ts->info._v__ast__SumType).generic_types, i)), t_generic_names, t_concrete_types), _t55.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t55.data; array_push((array*)&final_concrete_types, _MOV((v__ast__Type[]){ t_typ })); } } } } else { } if (ts->info._typ == 518 /* v.ast.Struct */) { v__ast__Struct info = (*ts->info._v__ast__Struct); info.is_generic = false; info.concrete_types = final_concrete_types; info.parent_type = v__ast__Type_set_flag(typ, v__ast__TypeFlag__generic); info.fields = fields; int new_idx = v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){ .parent_idx = 0, .info = v__ast__Struct_to_sumtype_v__ast__TypeInfo(&info), .kind = v__ast__Kind__struct, .name = nrt, .cname = v__util__no_dots(c_nrt), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = ts->mod, .is_pub = ts->is_pub, .is_builtin = 0, .language = 0, .idx = 0, .size = -1, .align = -1, })); if (final_concrete_types.len > 0) { v__ast__Table_unwrap_method_types(t, ts, generic_names, concrete_types, final_concrete_types); } return v__ast__Type_clear_flag(v__ast__Type_derive(v__ast__new_type(new_idx), typ), v__ast__TypeFlag__generic); } else if (ts->info._typ == 544 /* v.ast.SumType */) { Array_v__ast__Type variants = array_clone_to_depth(&(*ts->info._v__ast__SumType).variants, 0); for (int i = 0; i < variants.len; ++i) { if (v__ast__Type_has_flag((*(v__ast__Type*)array_get(variants, i)), v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* sym = v__ast__Table_sym(t, (*(v__ast__Type*)array_get(variants, i))); if (sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__sum_type || sym->kind == v__ast__Kind__interface) { array_set(&variants, i, &(v__ast__Type[]) { v__ast__Table_unwrap_generic_type(t, (*(v__ast__Type*)array_get(variants, i)), generic_names, concrete_types) }); } else { _option_v__ast__Type _t58; if (_t58 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get(variants, i)), generic_names, concrete_types), _t58.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t58.data; array_set(&variants, i, &(v__ast__Type[]) { t_typ }); } } } } v__ast__SumType info = (*ts->info._v__ast__SumType); info.is_generic = false; info.concrete_types = final_concrete_types; info.parent_type = v__ast__Type_set_flag(typ, v__ast__TypeFlag__generic); info.fields = fields; info.variants = variants; int new_idx = v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){ .parent_idx = 0, .info = v__ast__SumType_to_sumtype_v__ast__TypeInfo(&info), .kind = v__ast__Kind__sum_type, .name = nrt, .cname = v__util__no_dots(c_nrt), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = ts->mod, .is_pub = ts->is_pub, .is_builtin = 0, .language = 0, .idx = 0, .size = -1, .align = -1, })); if (final_concrete_types.len > 0) { v__ast__Table_unwrap_method_types(t, ts, generic_names, concrete_types, final_concrete_types); } return v__ast__Type_clear_flag(v__ast__Type_derive(v__ast__new_type(new_idx), typ), v__ast__TypeFlag__generic); } else if (ts->info._typ == 542 /* v.ast.Interface */) { Array_v__ast__Fn imethods = array_clone_to_depth(&(*ts->info._v__ast__Interface).methods, 0); for (int _t60 = 0; _t60 < imethods.len; ++_t60) { v__ast__Fn* method = ((v__ast__Fn*)imethods.data) + _t60; _option_v__ast__Type _t61; if (_t61 = v__ast__Table_convert_generic_type(t, method->return_type, generic_names, concrete_types), _t61.state == 0) { v__ast__Type unwrap_typ = *(v__ast__Type*)_t61.data; method->return_type = unwrap_typ; } for (int _t62 = 0; _t62 < method->params.len; ++_t62) { v__ast__Param* param = ((v__ast__Param*)method->params.data) + _t62; _option_v__ast__Type _t63; if (_t63 = v__ast__Table_convert_generic_type(t, param->typ, generic_names, concrete_types), _t63.state == 0) { v__ast__Type unwrap_typ = *(v__ast__Type*)_t63.data; param->typ = unwrap_typ; } } } Array_v__ast__Fn all_methods = ts->methods; for (int _t64 = 0; _t64 < imethods.len; ++_t64) { v__ast__Fn imethod = ((v__ast__Fn*)imethods.data)[_t64]; for (int _t65 = 0; _t65 < all_methods.len; ++_t65) { v__ast__Fn* method = ((v__ast__Fn*)all_methods.data) + _t65; if (string__eq(imethod.name, method->name)) { *method = imethod; } } } v__ast__Interface info = (*ts->info._v__ast__Interface); bool _t66 = false; Array_v__ast__Type _t66_orig = final_concrete_types; int _t66_len = _t66_orig.len; for (int _t67 = 0; _t67 < _t66_len; ++_t67) { v__ast__Type it = ((v__ast__Type*) _t66_orig.data)[_t67]; if (v__ast__Type_has_flag(it, v__ast__TypeFlag__generic)) { _t66 = true; break; } } info.is_generic =_t66; info.concrete_types = final_concrete_types; info.parent_type = v__ast__Type_set_flag(typ, v__ast__TypeFlag__generic); info.fields = fields; info.methods = imethods; int new_idx = v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){ .parent_idx = 0, .info = v__ast__Interface_to_sumtype_v__ast__TypeInfo(&info), .kind = v__ast__Kind__interface, .name = nrt, .cname = v__util__no_dots(c_nrt), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = ts->mod, .is_pub = ts->is_pub, .is_builtin = 0, .language = 0, .idx = 0, .size = -1, .align = -1, })); v__ast__TypeSymbol* ts_copy = v__ast__Table_sym(t, v__ast__idx_to_type(new_idx)); for (int _t68 = 0; _t68 < all_methods.len; ++_t68) { v__ast__Fn method = ((v__ast__Fn*)all_methods.data)[_t68]; v__ast__TypeSymbol_register_method(ts_copy, method); } return v__ast__Type_clear_flag(v__ast__Type_derive(v__ast__new_type(new_idx), typ), v__ast__TypeFlag__generic); } else { } return typ; } VV_LOC void v__ast__Table_unwrap_method_types(v__ast__Table* t, v__ast__TypeSymbol* ts, Array_string generic_names, Array_v__ast__Type concrete_types, Array_v__ast__Type final_concrete_types) { Array_v__ast__Type needs_unwrap_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); Array_v__ast__Fn _t1 = v__ast__TypeSymbol_get_methods(ts); for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__ast__Fn method = ((v__ast__Fn*)_t1.data)[_t2]; for (int i = 1; i < method.params.len; ++i) { if (v__ast__Type_has_flag((*(v__ast__Param*)array_get(method.params, i)).typ, v__ast__TypeFlag__generic) && (*(v__ast__Param*)array_get(method.params, i)).typ != (*(v__ast__Param*)array_get(method.params, 0)).typ) { if (!(Array_v__ast__Type_contains(needs_unwrap_types, (*(v__ast__Param*)array_get(method.params, i)).typ))) { array_push((array*)&needs_unwrap_types, _MOV((v__ast__Type[]){ (*(v__ast__Param*)array_get(method.params, i)).typ })); } } if (v__ast__Type_has_flag(method.return_type, v__ast__TypeFlag__generic) && method.return_type != (*(v__ast__Param*)array_get(method.params, 0)).typ) { if (!(Array_v__ast__Type_contains(needs_unwrap_types, method.return_type))) { array_push((array*)&needs_unwrap_types, _MOV((v__ast__Type[]){ method.return_type })); } } } if (final_concrete_types.len == method.generic_names.len) { v__ast__Table_register_fn_concrete_types(t, v__ast__Fn_fkey(&method), final_concrete_types); } } for (int _t5 = 0; _t5 < needs_unwrap_types.len; ++_t5) { v__ast__Type typ_ = ((v__ast__Type*)needs_unwrap_types.data)[_t5]; v__ast__Table_unwrap_generic_type(t, typ_, generic_names, concrete_types); } } void v__ast__Table_generic_insts_to_concrete(v__ast__Table* t) { for (int _t1 = 0; _t1 < t->type_symbols.len; ++_t1) { v__ast__TypeSymbol** sym = ((v__ast__TypeSymbol**)t->type_symbols.data) + _t1; if ((*sym)->kind == v__ast__Kind__generic_inst) { v__ast__GenericInst info = *(v__ast__GenericInst*)__as_cast(((*sym)->info)._v__ast__GenericInst,((*sym)->info)._typ, 555); v__ast__TypeSymbol* parent = (*(v__ast__TypeSymbol**)array_get(t->type_symbols, info.parent_idx)); if (parent->kind == v__ast__Kind__placeholder) { (*sym)->kind = v__ast__Kind__placeholder; continue; } if (parent->info._typ == 518 /* v.ast.Struct */) { v__ast__Struct parent_info = (*parent->info._v__ast__Struct); if (!parent_info.is_generic) { v__util__verror(_S("generic error"), str_intp(2, _MOV((StrIntpData[]){{_S("struct `"), 0xfe10, {.d_s = parent->name}}, {_S("` is not a generic struct, cannot instantiate to the concrete types"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); continue; } Array_v__ast__StructField fields = array_clone_to_depth(&parent_info.fields, 0); if (parent_info.generic_types.len == info.concrete_types.len) { Array_string generic_names = v__ast__Table_get_generic_names(t, parent_info.generic_types); for (int i = 0; i < fields.len; ++i) { if (v__ast__Type_has_flag((*(v__ast__StructField*)array_get(fields, i)).typ, v__ast__TypeFlag__generic)) { v__ast__Type orig_type = (*(v__ast__StructField*)array_get(fields, i)).typ; if (v__ast__Type_idx((*(v__ast__StructField*)array_get(fields, i)).typ) != info.parent_idx) { (*(v__ast__StructField*)array_get(fields, i)).typ = v__ast__Table_unwrap_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, generic_names, info.concrete_types); } _option_v__ast__Type _t2; if (_t2 = v__ast__Table_convert_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, generic_names, info.concrete_types), _t2.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t2.data; (*(v__ast__StructField*)array_get(fields, i)).typ = t_typ; } if ((*(v__ast__StructField*)array_get(fields, i)).is_embed) { for (int _t3 = 0; _t3 < parent_info.embeds.len; ++_t3) { v__ast__Type* embed = ((v__ast__Type*)parent_info.embeds.data) + _t3; if (*embed == orig_type) { *embed = (*(v__ast__StructField*)array_get(fields, i)).typ; break; } } } } } parent_info.is_generic = false; parent_info.concrete_types = array_clone_to_depth(&info.concrete_types, 0); parent_info.fields = fields; parent_info.parent_type = v__ast__Type_set_flag(v__ast__new_type(info.parent_idx), v__ast__TypeFlag__generic); (*sym)->info = v__ast__Struct_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Struct, (((v__ast__Struct){.attrs = (parent_info).attrs,.scoped_name = (parent_info).scoped_name,.embeds = (parent_info).embeds,.fields = (parent_info).fields,.is_typedef = (parent_info).is_typedef,.is_union = (parent_info).is_union,.is_heap = (parent_info).is_heap,.is_minify = (parent_info).is_minify,.is_anon = (parent_info).is_anon,.is_generic = false,.is_shared = (parent_info).is_shared,.is_markused = (parent_info).is_markused,.has_option = (parent_info).has_option,.generic_types = (parent_info).generic_types,.concrete_types = array_clone_to_depth(&info.concrete_types, 0),.parent_type = (parent_info).parent_type,})))); (*sym)->is_pub = true; (*sym)->kind = parent->kind; v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(t, parent_info.parent_type); for (int _t4 = 0; _t4 < parent_sym->methods.len; ++_t4) { v__ast__Fn method = ((v__ast__Fn*)parent_sym->methods.data)[_t4]; if (method.generic_names.len == info.concrete_types.len) { v__ast__Table_register_fn_concrete_types(t, v__ast__Fn_fkey(&method), info.concrete_types); } } } else { v__util__verror(_S("generic error"), str_intp(2, _MOV((StrIntpData[]){{_S("the number of generic types of struct `"), 0xfe10, {.d_s = parent->name}}, {_S("` is inconsistent with the concrete types"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } } else if (parent->info._typ == 542 /* v.ast.Interface */) { v__ast__Interface parent_info = (*parent->info._v__ast__Interface); if (!parent_info.is_generic) { v__util__verror(_S("generic error"), str_intp(2, _MOV((StrIntpData[]){{_S("interface `"), 0xfe10, {.d_s = parent->name}}, {_S("` is not a generic interface, cannot instantiate to the concrete types"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); continue; } if (parent_info.generic_types.len == info.concrete_types.len) { Array_v__ast__StructField fields = array_clone_to_depth(&parent_info.fields, 0); Array_string generic_names = v__ast__Table_get_generic_names(t, parent_info.generic_types); for (int i = 0; i < fields.len; ++i) { _option_v__ast__Type _t5; if (_t5 = v__ast__Table_convert_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, generic_names, info.concrete_types), _t5.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t5.data; (*(v__ast__StructField*)array_get(fields, i)).typ = t_typ; } } Array_v__ast__Fn imethods = array_clone_to_depth(&parent_info.methods, 0); for (int _t6 = 0; _t6 < imethods.len; ++_t6) { v__ast__Fn* method = ((v__ast__Fn*)imethods.data) + _t6; array_clear(&method->generic_names); _option_v__ast__Type _t7; if (_t7 = v__ast__Table_convert_generic_type(t, method->return_type, generic_names, info.concrete_types), _t7.state == 0) { v__ast__Type pt = *(v__ast__Type*)_t7.data; method->return_type = pt; } method->params = array_clone_to_depth(&method->params, 0); for (int _t8 = 0; _t8 < method->params.len; ++_t8) { v__ast__Param* param = ((v__ast__Param*)method->params.data) + _t8; _option_v__ast__Type _t9; if (_t9 = v__ast__Table_convert_generic_type(t, param->typ, generic_names, info.concrete_types), _t9.state == 0) { v__ast__Type pt = *(v__ast__Type*)_t9.data; param->typ = pt; } } v__ast__TypeSymbol_register_method(*sym, *method); } Array_v__ast__Fn all_methods = parent->methods; for (int _t10 = 0; _t10 < imethods.len; ++_t10) { v__ast__Fn imethod = ((v__ast__Fn*)imethods.data)[_t10]; for (int _t11 = 0; _t11 < all_methods.len; ++_t11) { v__ast__Fn* method = ((v__ast__Fn*)all_methods.data) + _t11; if (string__eq(imethod.name, method->name)) { *method = imethod; } } } (*sym)->info = v__ast__Interface_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Interface, (((v__ast__Interface){.types = (parent_info).types,.fields = fields,.methods = imethods,.embeds = (parent_info).embeds,.conversions = (parent_info).conversions,.is_generic = false,.is_markused = (parent_info).is_markused,.generic_types = (parent_info).generic_types,.concrete_types = array_clone_to_depth(&info.concrete_types, 0),.parent_type = v__ast__Type_set_flag(v__ast__new_type(info.parent_idx), v__ast__TypeFlag__generic),})))); (*sym)->is_pub = true; (*sym)->kind = parent->kind; (*sym)->methods = all_methods; } else { v__util__verror(_S("generic error"), str_intp(2, _MOV((StrIntpData[]){{_S("the number of generic types of interface `"), 0xfe10, {.d_s = parent->name}}, {_S("` is inconsistent with the concrete types"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } } else if (parent->info._typ == 544 /* v.ast.SumType */) { v__ast__SumType parent_info = (*parent->info._v__ast__SumType); if (!parent_info.is_generic) { v__util__verror(_S("generic error"), str_intp(2, _MOV((StrIntpData[]){{_S("sumtype `"), 0xfe10, {.d_s = parent->name}}, {_S("` is not a generic sumtype, cannot instantiate to the concrete types"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); continue; } if (parent_info.generic_types.len == info.concrete_types.len) { Array_v__ast__StructField fields = array_clone_to_depth(&parent_info.fields, 0); Array_v__ast__Type variants = array_clone_to_depth(&parent_info.variants, 0); Array_string generic_names = v__ast__Table_get_generic_names(t, parent_info.generic_types); for (int i = 0; i < fields.len; ++i) { _option_v__ast__Type _t12; if (_t12 = v__ast__Table_convert_generic_type(t, (*(v__ast__StructField*)array_get(fields, i)).typ, generic_names, info.concrete_types), _t12.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t12.data; (*(v__ast__StructField*)array_get(fields, i)).typ = t_typ; } } for (int i = 0; i < variants.len; ++i) { if (v__ast__Type_has_flag((*(v__ast__Type*)array_get(variants, i)), v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* t_sym = v__ast__Table_sym(t, (*(v__ast__Type*)array_get(variants, i))); if (t_sym->kind == v__ast__Kind__struct && v__ast__Type_idx((*(v__ast__Type*)array_get(variants, i))) != info.parent_idx) { array_set(&variants, i, &(v__ast__Type[]) { v__ast__Table_unwrap_generic_type(t, (*(v__ast__Type*)array_get(variants, i)), generic_names, info.concrete_types) }); } else { _option_v__ast__Type _t13; if (_t13 = v__ast__Table_convert_generic_type(t, (*(v__ast__Type*)array_get(variants, i)), generic_names, info.concrete_types), _t13.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t13.data; array_set(&variants, i, &(v__ast__Type[]) { t_typ }); } } } } (*sym)->info = v__ast__SumType_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__SumType, (((v__ast__SumType){.fields = fields,.found_fields = (parent_info).found_fields,.is_anon = (parent_info).is_anon,.is_generic = false,.variants = variants,.generic_types = (parent_info).generic_types,.concrete_types = array_clone_to_depth(&info.concrete_types, 0),.parent_type = v__ast__Type_set_flag(v__ast__new_type(info.parent_idx), v__ast__TypeFlag__generic),})))); (*sym)->is_pub = true; (*sym)->kind = parent->kind; } else { v__util__verror(_S("generic error"), str_intp(2, _MOV((StrIntpData[]){{_S("the number of generic types of sumtype `"), 0xfe10, {.d_s = parent->name}}, {_S("` is inconsistent with the concrete types"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } } else if (parent->info._typ == 553 /* v.ast.FnType */) { v__ast__FnType parent_info = (*parent->info._v__ast__FnType); v__ast__Fn function = parent_info.func; function.params = array_clone_to_depth(&function.params, 0); for (int _t14 = 0; _t14 < function.params.len; ++_t14) { v__ast__Param* param = ((v__ast__Param*)function.params.data) + _t14; if (v__ast__Type_has_flag(param->typ, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t15; if (_t15 = v__ast__Table_convert_generic_type(t, param->typ, function.generic_names, info.concrete_types), _t15.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t15.data; param->typ = t_typ; } } } if (v__ast__Type_has_flag(function.return_type, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t16; if (_t16 = v__ast__Table_convert_generic_type(t, function.return_type, function.generic_names, info.concrete_types), _t16.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t16.data; function.return_type = t_typ; } } function.generic_names = __new_array_with_default(0, 0, sizeof(string), 0); (*sym)->info = v__ast__FnType_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__FnType, (((v__ast__FnType){.is_anon = (parent_info).is_anon,.has_decl = (parent_info).has_decl,.func = function,})))); (*sym)->is_pub = true; (*sym)->kind = parent->kind; } else { } } } } Array_string v__ast__Table_get_generic_names(v__ast__Table* t, Array_v__ast__Type generic_types) { Array_string generic_names = __new_array_with_default(0, generic_types.len, sizeof(string), 0); for (int _t1 = 0; _t1 < generic_types.len; ++_t1) { v__ast__Type typ = ((v__ast__Type*)generic_types.data)[_t1]; if (!v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { continue; } v__ast__TypeSymbol* sym = v__ast__Table_sym(t, typ); v__ast__TypeInfo info = sym->info; if (info._typ == 552 /* v.ast.MultiReturn */) { _PUSH_MANY(&generic_names, (v__ast__Table_get_generic_names(t, (*info._v__ast__MultiReturn).types)), _t2, Array_string); } else { array_push((array*)&generic_names, _MOV((string[]){ string_clone(sym->name) })); } } return generic_names; } bool v__ast__Table_check_if_elements_need_unwrap(v__ast__Table* t, v__ast__Type root_typ, v__ast__Type typ) { v__ast__TypeSymbol* sym = v__ast__Table_sym(t, typ); if (!(sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__array_fixed || sym->kind == v__ast__Kind__map)) { return false; } Array_v__ast__Type typs = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); if (sym->info._typ == 513 /* v.ast.Array */) { array_push((array*)&typs, _MOV((v__ast__Type[]){ ((*sym->info._v__ast__Array)).elem_type })); } else if (sym->info._typ == 549 /* v.ast.ArrayFixed */) { array_push((array*)&typs, _MOV((v__ast__Type[]){ ((*sym->info._v__ast__ArrayFixed)).elem_type })); } else if (sym->info._typ == 514 /* v.ast.Map */) { array_push((array*)&typs, _MOV((v__ast__Type[]){ ((*sym->info._v__ast__Map)).key_type })); array_push((array*)&typs, _MOV((v__ast__Type[]){ ((*sym->info._v__ast__Map)).value_type })); } else { } for (int _t6 = 0; _t6 < typs.len; ++_t6) { v__ast__Type typ_ = ((v__ast__Type*)typs.data)[_t6]; if (v__ast__Type_has_flag(typ_, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* t_sym = v__ast__Table_sym(t, typ_); if (t_sym->info._typ == 518 /* v.ast.Struct */) { if ((*t_sym->info._v__ast__Struct).is_generic && (*t_sym->info._v__ast__Struct).generic_types.len > 0 && (*t_sym->info._v__ast__Struct).concrete_types.len == 0 && v__ast__Type_idx(typ_) != v__ast__Type_idx(root_typ)) { return true; } } else if (t_sym->info._typ == 542 /* v.ast.Interface */) { if ((*t_sym->info._v__ast__Interface).is_generic && (*t_sym->info._v__ast__Interface).generic_types.len > 0 && (*t_sym->info._v__ast__Interface).concrete_types.len == 0 && v__ast__Type_idx(typ_) != v__ast__Type_idx(root_typ)) { return true; } } else if (t_sym->info._typ == 544 /* v.ast.SumType */) { if ((*t_sym->info._v__ast__SumType).is_generic && (*t_sym->info._v__ast__SumType).generic_types.len > 0 && (*t_sym->info._v__ast__SumType).concrete_types.len == 0 && v__ast__Type_idx(typ_) != v__ast__Type_idx(root_typ)) { return true; } } else { } } if (v__ast__Table_check_if_elements_need_unwrap(t, root_typ, typ_)) { return true; } } return false; } Array_string v__ast__Table_dependent_names_in_expr(v__ast__Table* t, v__ast__Expr expr) { Array_string names = __new_array_with_default(0, 0, sizeof(string), 0); if (expr._typ == 338 /* v.ast.ArrayInit */) { for (int _t1 = 0; _t1 < (*expr._v__ast__ArrayInit).exprs.len; ++_t1) { v__ast__Expr elem_expr = ((v__ast__Expr*)(*expr._v__ast__ArrayInit).exprs.data)[_t1]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, elem_expr)), _t2, Array_string); } _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__ArrayInit).len_expr)), _t3, Array_string); _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__ArrayInit).cap_expr)), _t4, Array_string); _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__ArrayInit).init_expr)), _t5, Array_string); } else if (expr._typ == 344 /* v.ast.CallExpr */) { if ((*expr._v__ast__CallExpr).is_method) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__CallExpr).left)), _t6, Array_string); } for (int _t7 = 0; _t7 < (*expr._v__ast__CallExpr).args.len; ++_t7) { v__ast__CallArg arg = ((v__ast__CallArg*)(*expr._v__ast__CallExpr).args.data)[_t7]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, arg.expr)), _t8, Array_string); } _option_v__ast__Fn _t9; if (_t9 = v__ast__Table_find_fn(t, (*expr._v__ast__CallExpr).name), _t9.state == 0) { v__ast__Fn func = *(v__ast__Fn*)_t9.data; _PUSH_MANY(&names, (func.dep_names), _t10, Array_string); } } else if (expr._typ == 345 /* v.ast.CastExpr */) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__CastExpr).expr)), _t11, Array_string); _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__CastExpr).arg)), _t12, Array_string); } else if (expr._typ == 358 /* v.ast.Ident */) { if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__global || (*expr._v__ast__Ident).kind == v__ast__IdentKind__constant) { array_push((array*)&names, _MOV((string[]){ v__util__no_dots((*expr._v__ast__Ident).name) })); } } else if (expr._typ == 361 /* v.ast.IndexExpr */) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__IndexExpr).left)), _t14, Array_string); } else if (expr._typ == 359 /* v.ast.IfExpr */) { for (int _t15 = 0; _t15 < (*expr._v__ast__IfExpr).branches.len; ++_t15) { v__ast__IfBranch branch = ((v__ast__IfBranch*)(*expr._v__ast__IfExpr).branches.data)[_t15]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, branch.cond)), _t16, Array_string); for (int _t17 = 0; _t17 < branch.stmts.len; ++_t17) { v__ast__Stmt stmt = ((v__ast__Stmt*)branch.stmts.data)[_t17]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_stmt(t, stmt)), _t18, Array_string); } } } else if (expr._typ == 362 /* v.ast.InfixExpr */) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__InfixExpr).left)), _t19, Array_string); _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__InfixExpr).right)), _t20, Array_string); } else if (expr._typ == 368 /* v.ast.MapInit */) { for (int _t21 = 0; _t21 < (*expr._v__ast__MapInit).keys.len; ++_t21) { v__ast__Expr key = ((v__ast__Expr*)(*expr._v__ast__MapInit).keys.data)[_t21]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, key)), _t22, Array_string); } for (int _t23 = 0; _t23 < (*expr._v__ast__MapInit).vals.len; ++_t23) { v__ast__Expr val = ((v__ast__Expr*)(*expr._v__ast__MapInit).vals.data)[_t23]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, val)), _t24, Array_string); } } else if (expr._typ == 369 /* v.ast.MatchExpr */) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__MatchExpr).cond)), _t25, Array_string); for (int _t26 = 0; _t26 < (*expr._v__ast__MatchExpr).branches.len; ++_t26) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)(*expr._v__ast__MatchExpr).branches.data)[_t26]; for (int _t27 = 0; _t27 < branch.stmts.len; ++_t27) { v__ast__Stmt stmt = ((v__ast__Stmt*)branch.stmts.data)[_t27]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_stmt(t, stmt)), _t28, Array_string); } } } else if (expr._typ == 374 /* v.ast.ParExpr */) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__ParExpr).expr)), _t29, Array_string); } else if (expr._typ == 375 /* v.ast.PostfixExpr */) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__PostfixExpr).expr)), _t30, Array_string); } else if (expr._typ == 376 /* v.ast.PrefixExpr */) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__PrefixExpr).right)), _t31, Array_string); } else if (expr._typ == 383 /* v.ast.StringInterLiteral */) { for (int _t32 = 0; _t32 < (*expr._v__ast__StringInterLiteral).exprs.len; ++_t32) { v__ast__Expr inter_expr = ((v__ast__Expr*)(*expr._v__ast__StringInterLiteral).exprs.data)[_t32]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, inter_expr)), _t33, Array_string); } } else if (expr._typ == 379 /* v.ast.SelectorExpr */) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__SelectorExpr).expr)), _t34, Array_string); } else if (expr._typ == 385 /* v.ast.StructInit */) { if ((*expr._v__ast__StructInit).has_update_expr) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*expr._v__ast__StructInit).update_expr)), _t35, Array_string); } for (int _t36 = 0; _t36 < (*expr._v__ast__StructInit).init_fields.len; ++_t36) { v__ast__StructInitField field = ((v__ast__StructInitField*)(*expr._v__ast__StructInit).init_fields.data)[_t36]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, field.expr)), _t37, Array_string); } } else { } return names; } Array_string v__ast__Table_dependent_names_in_stmt(v__ast__Table* t, v__ast__Stmt stmt) { Array_string names = __new_array_with_default(0, 0, sizeof(string), 0); if (stmt._typ == 392 /* v.ast.AssignStmt */) { for (int _t1 = 0; _t1 < (*stmt._v__ast__AssignStmt).left.len; ++_t1) { v__ast__Expr expr = ((v__ast__Expr*)(*stmt._v__ast__AssignStmt).left.data)[_t1]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, expr)), _t2, Array_string); } for (int _t3 = 0; _t3 < (*stmt._v__ast__AssignStmt).right.len; ++_t3) { v__ast__Expr expr = ((v__ast__Expr*)(*stmt._v__ast__AssignStmt).right.data)[_t3]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, expr)), _t4, Array_string); } } else if (stmt._typ == 401 /* v.ast.ExprStmt */) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*stmt._v__ast__ExprStmt).expr)), _t5, Array_string); } else if (stmt._typ == 403 /* v.ast.ForInStmt */) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*stmt._v__ast__ForInStmt).cond)), _t6, Array_string); for (int _t7 = 0; _t7 < (*stmt._v__ast__ForInStmt).stmts.len; ++_t7) { v__ast__Stmt stmt_ = ((v__ast__Stmt*)(*stmt._v__ast__ForInStmt).stmts.data)[_t7]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_stmt(t, stmt_)), _t8, Array_string); } } else if (stmt._typ == 404 /* v.ast.ForStmt */) { for (int _t9 = 0; _t9 < (*stmt._v__ast__ForStmt).stmts.len; ++_t9) { v__ast__Stmt stmt_ = ((v__ast__Stmt*)(*stmt._v__ast__ForStmt).stmts.data)[_t9]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_stmt(t, stmt_)), _t10, Array_string); } } else if (stmt._typ == 402 /* v.ast.ForCStmt */) { _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_stmt(t, (*stmt._v__ast__ForCStmt).init)), _t11, Array_string); _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, (*stmt._v__ast__ForCStmt).cond)), _t12, Array_string); _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_stmt(t, (*stmt._v__ast__ForCStmt).inc)), _t13, Array_string); for (int _t14 = 0; _t14 < (*stmt._v__ast__ForCStmt).stmts.len; ++_t14) { v__ast__Stmt stmt_ = ((v__ast__Stmt*)(*stmt._v__ast__ForCStmt).stmts.data)[_t14]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_stmt(t, stmt_)), _t15, Array_string); } } else if (stmt._typ == 412 /* v.ast.Return */) { for (int _t16 = 0; _t16 < (*stmt._v__ast__Return).exprs.len; ++_t16) { v__ast__Expr expr = ((v__ast__Expr*)(*stmt._v__ast__Return).exprs.data)[_t16]; _PUSH_MANY(&names, (v__ast__Table_dependent_names_in_expr(t, expr)), _t17, Array_string); } } else { } return names; } multi_return_int_v__ast__Type v__ast__Table_get_array_dims(v__ast__Table* t, v__ast__Array arr) { int dims = 1; v__ast__Type elem_type = arr.elem_type; v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(t, elem_type); for (;;) { if (!((elem_sym->info)._typ == 513 /* v.ast.Array */)) break; dims++; elem_type = (*elem_sym->info._v__ast__Array).elem_type; elem_sym = v__ast__Table_sym(t, elem_type); } return (multi_return_int_v__ast__Type){.arg0=dims, .arg1=elem_type}; } multi_return_string_string v__ast__Table_get_trace_fn_name(v__ast__Table* t, v__ast__FnDecl cur_fn, v__ast__CallExpr node) { Array_string _t1 = {0}; Array_v__ast__Type _t1_orig = node.concrete_types; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t3]; string _t2 = v__ast__Table_type_to_str(t, it); array_push((array*)&_t1, &_t2); } string generic_name = Array_string_join(_t1, _S("_")); string hash_fn = str_intp(5, _MOV((StrIntpData[]){{_S("_v__trace__"), 0xfe10, {.d_s = cur_fn.name}}, {_S("_"), 0xfe10, {.d_s = node.name}}, {_S("_"), 0xfe10, {.d_s = generic_name}}, {_S("_"), 0xfe07, {.d_i32 = node.pos.line_nr}}, {_SLIT0, 0, { .d_c = 0 }}})); string fn_name = (node.concrete_types.len > 0 ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.name}}, {_S("_T_"), 0xfe10, {.d_s = generic_name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (node.name)); return (multi_return_string_string){.arg0=hash_fn, .arg1=fn_name}; } Array_v__ast__Attr v__ast__Table_get_attrs(v__ast__Table* t, v__ast__TypeSymbol sym) { if (sym.info._typ == 548 /* v.ast.Enum */) { return (*(v__ast__EnumDecl*)map_get(ADDR(map, t->enum_decls), &(string[]){sym.name}, &(v__ast__EnumDecl[]){ (v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},} })).attrs; } else if (sym.info._typ == 518 /* v.ast.Struct */) { return (*sym.info._v__ast__Struct).attrs; } else if (sym.info._typ == 553 /* v.ast.FnType */) { return (*sym.info._v__ast__FnType).func.attrs; } else if (sym.info._typ == 542 /* v.ast.Interface */) { return (*(v__ast__InterfaceDecl*)map_get(ADDR(map, t->interfaces), &(int[]){sym.idx}, &(v__ast__InterfaceDecl[]){ (v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,} })).attrs; } else if (sym.info._typ == 544 /* v.ast.SumType */) { return (*(v__ast__SumTypeDecl*)map_get(ADDR(map, t->sumtypes), &(int[]){sym.idx}, &(v__ast__SumTypeDecl[]){ (v__ast__SumTypeDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.variants = __new_array(0, 0, sizeof(v__ast__TypeNode)),.is_markused = 0,} })).attrs; } else { return __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); } return __new_array(0, 0, sizeof(v__ast__Attr)); } int v__ast__Table_get_veb_result_type_idx(v__ast__Table* t) { if (t->veb_res_idx_cache > 0) { return t->veb_res_idx_cache; } t->veb_res_idx_cache = v__ast__Table_find_type(t, _S("veb.Result")); return t->veb_res_idx_cache; } inline v__ast__Type v__ast__idx_to_type(int idx) { return ((((u32)(idx)))); } v__ast__Language v__ast__pref_arch_to_table_language(v__pref__Arch pref_arch) { v__ast__Language _t2 = 0; switch (pref_arch) { case v__pref__Arch__amd64: { _t2 = v__ast__Language__amd64; break; } case v__pref__Arch__arm64: { _t2 = v__ast__Language__arm64; break; } case v__pref__Arch__arm32: { _t2 = v__ast__Language__arm32; break; } case v__pref__Arch__rv64: { _t2 = v__ast__Language__rv64; break; } case v__pref__Arch__rv32: { _t2 = v__ast__Language__rv32; break; } case v__pref__Arch__i386: { _t2 = v__ast__Language__i386; break; } case v__pref__Arch__s390x: { _t2 = v__ast__Language__s390x; break; } case v__pref__Arch__ppc64le: { _t2 = v__ast__Language__ppc64le; break; } case v__pref__Arch__loongarch64: { _t2 = v__ast__Language__loongarch64; break; } case v__pref__Arch__js_node: case v__pref__Arch__js_browser: case v__pref__Arch__js_freestanding: { _t2 = v__ast__Language__js; break; } case v__pref__Arch__wasm32: { _t2 = v__ast__Language__wasm32; break; } case v__pref__Arch___auto: case v__pref__Arch___max: { _t2 = v__ast__Language__v; break; } } return _t2; } string v__ast__ShareType_str(v__ast__ShareType t) { if (t == (v__ast__ShareType__mut_t)) { return _S("mut"); } else if (t == (v__ast__ShareType__shared_t)) { return _S("shared"); } else if (t == (v__ast__ShareType__atomic_t)) { return _S("atomic"); } return (string){.str=(byteptr)"", .is_lit=1}; } string v__ast__Type_atomic_typename(v__ast__Type t) { int idx = v__ast__Type_idx(t); if (idx == (_const_v__ast__u32_type_idx)) { return _S("atomic_uint"); } else if (idx == (_const_v__ast__int_type_idx)) { return _S("_Atomic int"); } else if (idx == (_const_v__ast__i32_type_idx)) { return _S("_Atomic int"); } else if (idx == (_const_v__ast__u64_type_idx)) { return _S("atomic_ullong"); } else if (idx == (_const_v__ast__i64_type_idx)) { return _S("atomic_llong"); } else { return _S("unknown_atomic"); } return (string){.str=(byteptr)"", .is_lit=1}; } v__ast__ShareType v__ast__sharetype_from_flags(bool is_shared, bool is_atomic) { return ((v__ast__ShareType)((((int)(((u32[]){(is_atomic)?1:0}[0] << 1U))) | (int[]){(is_shared)?1:0}[0]))); } v__ast__ShareType v__ast__Type_share(v__ast__Type t) { return v__ast__sharetype_from_flags(v__ast__Type_has_flag(t, v__ast__TypeFlag__shared_f), v__ast__Type_has_flag(t, v__ast__TypeFlag__atomic_f)); } inline int v__ast__Type_idx(v__ast__Type t) { return (((u16)(t)) & 0xffffU); } inline bool v__ast__Type_is_void(v__ast__Type t) { return t == _const_v__ast__void_type; } inline int v__ast__Type_nr_muls(v__ast__Type t) { return (((t >> 16)) & 0xff); } inline bool v__ast__Type_is_ptr(v__ast__Type t) { return (((t >> 16)) & 0xff) != 0; } inline bool v__ast__Type_is_pointer(v__ast__Type typ) { return (Array_int_contains(_const_v__ast__pointer_type_idxs, v__ast__Type_idx(typ))); } inline bool v__ast__Type_is_voidptr(v__ast__Type typ) { return v__ast__Type_idx(typ) == 2; } inline bool v__ast__Type_is_any_kind_of_pointer(v__ast__Type t) { return (((t >> 16)) & 0xff) != 0 || (Array_int_contains(_const_v__ast__pointer_type_idxs, ((((u16)(t)) & 0xffffU)))); } inline v__ast__Type v__ast__Type_set_nr_muls(v__ast__Type t, int nr_muls) { if (nr_muls < 0 || nr_muls > 255) { _v_panic(_S("set_nr_muls: nr_muls must be between 0 & 255")); VUNREACHABLE(); } return ((t & 0xff00ffff) | (((u32)(nr_muls)) << 16U)); } inline v__ast__Type v__ast__Type_ref(v__ast__Type t) { v__ast__Type nr_muls = (((t >> 16)) & 0xff); if (nr_muls == 255) { _v_panic(_S("ref: nr_muls is already at max of 255")); VUNREACHABLE(); } return ((t & 0xff00ffff) | ((nr_muls + 1) << 16)); } inline v__ast__Type v__ast__Type_deref(v__ast__Type t) { v__ast__Type nr_muls = (((t >> 16)) & 0xff); if (nr_muls == 0) { _v_panic(str_intp(2, _MOV((StrIntpData[]){{_S("deref: type `"), 0xfe10, {.d_s = v__ast__Type_str(t)}}, {_S("` is not a pointer"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } return ((t & 0xff00ffff) | ((nr_muls - 1) << 16)); } inline bool v__ast__Type_has_flag(v__ast__Type t, v__ast__TypeFlag flag) { return ((t & ((u32)(flag)))) != 0; } inline v__ast__Type v__ast__Type_set_flag(v__ast__Type t, v__ast__TypeFlag flag) { return (t | ((u32)(flag))); } inline v__ast__Type v__ast__Type_clear_flag(v__ast__Type t, v__ast__TypeFlag flag) { return (t & ~(((u32)(flag)))); } inline v__ast__Type v__ast__Type_clear_flags(v__ast__Type t, Array_v__ast__TypeFlag flags) { if (flags.len == 0) { return (t & 0xffffff); } else { u32 typ = ((u32)(t)); for (int _t2 = 0; _t2 < flags.len; ++_t2) { v__ast__TypeFlag flag = ((v__ast__TypeFlag*)flags.data)[_t2]; typ = (typ & ~(((u32)(flag)))); } return typ; } return 0; } inline v__ast__Type v__ast__Type_clear_option_and_result(v__ast__Type t) { return (t & ~0x03000000); } inline bool v__ast__Type_has_option_or_result(v__ast__Type t) { return (t & 0x03000000) != 0; } inline string v__ast__TypeSymbol_scoped_name(v__ast__TypeSymbol* ts) { return ((ts->info)._typ == 518 /* v.ast.Struct */ && ((*(v__ast__Struct*)__as_cast((ts->info)._v__ast__Struct,(ts->info)._typ, 518)).scoped_name).len != 0 ? ((*ts->info._v__ast__Struct).scoped_name) : (ts->name)); } inline string v__ast__TypeSymbol_scoped_cname(v__ast__TypeSymbol* ts) { return ((ts->info)._typ == 518 /* v.ast.Struct */ && ((*(v__ast__Struct*)__as_cast((ts->info)._v__ast__Struct,(ts->info)._typ, 518)).scoped_name).len != 0 ? (string_replace((*ts->info._v__ast__Struct).scoped_name, _S("."), _S("__"))) : (ts->cname)); } int v__ast__TypeSymbol_nr_dims(v__ast__TypeSymbol* ts) { if (ts->info._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(global_table, (*ts->info._v__ast__Alias).parent_type); if ((parent_sym->info)._typ == 513 /* v.ast.Array */) { return (*parent_sym->info._v__ast__Array).nr_dims; } return 0; } else if (ts->info._typ == 513 /* v.ast.Array */) { v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(global_table, (*ts->info._v__ast__Array).elem_type); if ((elem_sym->info)._typ == 539 /* v.ast.Alias */) { return (int)((*ts->info._v__ast__Array).nr_dims + v__ast__TypeSymbol_nr_dims(elem_sym)); } return (*ts->info._v__ast__Array).nr_dims; } else { return 0; } return 0; } string v__ast__Type_str(v__ast__Type t) { return str_intp(3, _MOV((StrIntpData[]){{_S("ast.Type(0x"), 0xfe10, {.d_s = u32_hex(t)}}, {_S(" = "), 0xfe06, {.d_u32 = ((u32)(t))}}, {_S(")"), 0, { .d_c = 0 }}})); } string v__ast__Table_type_str(v__ast__Table* t, v__ast__Type typ) { return v__ast__Table_sym(t, typ)->name; } Array_string v__ast__Type_debug(v__ast__Type t) { Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("idx: 0x"), 0x10fe10, {.d_s = int_hex(v__ast__Type_idx(t))}}, {_SLIT0, 0, { .d_c = 0 }}})) })); array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("type: 0x"), 0x10fe10, {.d_s = u32_hex(t)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("nr_muls: "), 0xfe07, {.d_i32 = v__ast__Type_nr_muls(t)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); if (v__ast__Type_has_flag(t, v__ast__TypeFlag__option)) { array_push((array*)&res, _MOV((string[]){ _S("option") })); } if (v__ast__Type_has_flag(t, v__ast__TypeFlag__result)) { array_push((array*)&res, _MOV((string[]){ _S("result") })); } if (v__ast__Type_has_flag(t, v__ast__TypeFlag__variadic)) { array_push((array*)&res, _MOV((string[]){ _S("variadic") })); } if (v__ast__Type_has_flag(t, v__ast__TypeFlag__generic)) { array_push((array*)&res, _MOV((string[]){ _S("generic") })); } if (v__ast__Type_has_flag(t, v__ast__TypeFlag__shared_f)) { array_push((array*)&res, _MOV((string[]){ _S("shared_f") })); } if (v__ast__Type_has_flag(t, v__ast__TypeFlag__atomic_f)) { array_push((array*)&res, _MOV((string[]){ _S("atomic_f") })); } return res; } inline v__ast__Type v__ast__Type_derive(v__ast__Type t, v__ast__Type t_from) { return (((0xffff0000 & t_from)) | ((u16)(t))); } inline v__ast__Type v__ast__Type_derive_add_muls(v__ast__Type t, v__ast__Type t_from) { return v__ast__Type_set_nr_muls((((((0xff000000 & t_from)) | ((u16)(t))))), (int)(v__ast__Type_nr_muls(t) + v__ast__Type_nr_muls(t_from))); } inline v__ast__Type v__ast__Type_idx_type(v__ast__Type t) { return v__ast__idx_to_type(v__ast__Type_idx(t)); } inline v__ast__Type v__ast__new_type(int idx) { if (idx < 1 || idx > 65535) { _v_panic(_S("new_type: idx must be between 1 & 65535")); VUNREACHABLE(); } return idx; } inline bool v__ast__Type_is_float(v__ast__Type typ) { return !v__ast__Type_is_ptr(typ) && (Array_int_contains(_const_v__ast__float_type_idxs, v__ast__Type_idx(typ))); } inline bool v__ast__Type_is_int(v__ast__Type typ) { return !v__ast__Type_is_ptr(typ) && (Array_int_contains(_const_v__ast__integer_type_idxs, v__ast__Type_idx(typ))); } inline bool v__ast__Type_is_int_valptr(v__ast__Type typ) { return v__ast__Type_is_ptr(typ) && (Array_int_contains(_const_v__ast__integer_type_idxs, v__ast__Type_idx(typ))); } inline bool v__ast__Type_is_float_valptr(v__ast__Type typ) { return v__ast__Type_is_ptr(typ) && (Array_int_contains(_const_v__ast__float_type_idxs, v__ast__Type_idx(typ))); } inline bool v__ast__Type_is_pure_int(v__ast__Type typ) { return (Array_int_contains(_const_v__ast__integer_type_idxs, ((int)(typ)))); } inline bool v__ast__Type_is_signed(v__ast__Type typ) { return (Array_int_contains(_const_v__ast__signed_integer_type_idxs, v__ast__Type_idx(typ))); } inline bool v__ast__Type_is_unsigned(v__ast__Type typ) { return (Array_int_contains(_const_v__ast__unsigned_integer_type_idxs, v__ast__Type_idx(typ))); } inline bool v__ast__Type_is_int_literal(v__ast__Type typ) { return ((int)(typ)) == 28; } inline bool v__ast__Type_is_number(v__ast__Type typ) { return (Array_int_contains(_const_v__ast__number_type_idxs, v__ast__Type_clear_flags(typ, __new_array(0, 0, sizeof(v__ast__TypeFlag))))); } inline bool v__ast__Type_is_string(v__ast__Type typ) { return v__ast__Type_idx(typ) == 21; } inline bool v__ast__Type_is_bool(v__ast__Type typ) { return v__ast__Type_idx(typ) == 19; } VV_LOC Array_v__ast__Type v__ast__new_charptr_types(void) { return new_array_from_c_array(2, 2, sizeof(v__ast__Type), _MOV((v__ast__Type[2]){_const_v__ast__charptr_type, v__ast__Type_set_nr_muls(v__ast__new_type(_const_v__ast__char_type_idx), 1)})); } VV_LOC Array_v__ast__Type v__ast__new_byteptr_types(void) { return new_array_from_c_array(2, 2, sizeof(v__ast__Type), _MOV((v__ast__Type[2]){_const_v__ast__byteptr_type, v__ast__Type_set_nr_muls(v__ast__new_type(_const_v__ast__u8_type_idx), 1)})); } VV_LOC Array_v__ast__Type v__ast__new_voidptr_types(void) { return new_array_from_c_array(2, 2, sizeof(v__ast__Type), _MOV((v__ast__Type[2]){_const_v__ast__voidptr_type, v__ast__Type_set_nr_muls(v__ast__new_type(_const_v__ast__voidptr_type_idx), 1)})); } Array_v__ast__Type v__ast__merge_types(Array_Array_v__ast__Type params) { Array_v__ast__Type res = __new_array_with_default(0, params.len, sizeof(v__ast__Type), 0); for (int _t1 = 0; _t1 < params.len; ++_t1) { Array_v__ast__Type types = ((Array_v__ast__Type*)params.data)[_t1]; for (int _t2 = 0; _t2 < types.len; ++_t2) { v__ast__Type t = ((v__ast__Type*)types.data)[_t2]; if (!(Array_v__ast__Type_contains(res, t))) { array_push((array*)&res, _MOV((v__ast__Type[]){ t })); } } } return res; } v__ast__Type v__ast__mktyp(v__ast__Type typ) { return ((typ == (_const_v__ast__float_literal_type))? (_const_v__ast__f64_type) : (typ == (_const_v__ast__int_literal_type))? (_const_v__ast__int_type) : (typ)); } v__ast__Kind v__ast__Table_type_kind(v__ast__Table* t, v__ast__Type typ) { if (v__ast__Type_nr_muls(typ) > 0 || v__ast__Type_has_option_or_result(typ)) { return v__ast__Kind__placeholder; } return v__ast__Table_sym(t, typ)->kind; } bool v__ast__Table_type_is_for_pointer_arithmetic(v__ast__Table* t, v__ast__Type typ) { if (v__ast__Table_sym(t, typ)->kind == v__ast__Kind__struct) { return false; } else { return v__ast__Type_is_any_kind_of_pointer(typ) || v__ast__Type_is_int_valptr(typ); } return 0; } string v__ast__TypeSymbol_str(v__ast__TypeSymbol* t) { return t->name; } string v__ast__TypeSymbol_str_with_correct_nr_muls(v__ast__TypeSymbol* t, int n) { string prefix = strings__repeat('&', n); return string__plus(prefix, t->name); } VNORETURN VV_LOC void v__ast__TypeSymbol_no_info_panic(v__ast__TypeSymbol* t, string fname) { _v_panic(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fname}}, {_S(": no info for type: "), 0xfe10, {.d_s = t->name}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); while(1); } inline v__ast__Enum v__ast__TypeSymbol_enum_info(v__ast__TypeSymbol* t) { if ((t->info)._typ == 548 /* v.ast.Enum */) { return (*t->info._v__ast__Enum); } if ((t->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* fsym = v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type); if ((fsym->info)._typ == 548 /* v.ast.Enum */) { return (*fsym->info._v__ast__Enum); } } v__ast__TypeSymbol_no_info_panic(t, _S("TypeSymbol.enum_info")); VUNREACHABLE(); return (v__ast__Enum){.vals = __new_array(0, 0, sizeof(string)),.is_flag = 0,.is_multi_allowed = 0,.uses_exprs = 0,.typ = 0,.attrs = new_map(sizeof(string), sizeof(Array_v__ast__Attr), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}; } inline v__ast__MultiReturn v__ast__TypeSymbol_mr_info(v__ast__TypeSymbol* t) { if ((t->info)._typ == 552 /* v.ast.MultiReturn */) { return (*t->info._v__ast__MultiReturn); } if ((t->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* fsym = v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type); if ((fsym->info)._typ == 552 /* v.ast.MultiReturn */) { return (*fsym->info._v__ast__MultiReturn); } } v__ast__TypeSymbol_no_info_panic(t, _S("TypeSymbol.mr_info")); VUNREACHABLE(); return (v__ast__MultiReturn){.types = __new_array(0, 0, sizeof(v__ast__Type)),}; } inline v__ast__Array v__ast__TypeSymbol_array_info(v__ast__TypeSymbol* t) { if ((t->info)._typ == 513 /* v.ast.Array */) { return (*t->info._v__ast__Array); } if ((t->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* fsym = v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type); if ((fsym->info)._typ == 513 /* v.ast.Array */) { return (*fsym->info._v__ast__Array); } } v__ast__TypeSymbol_no_info_panic(t, _S("TypeSymbol.array_info")); VUNREACHABLE(); return (v__ast__Array){.nr_dims = 0,.elem_type = 0,}; } inline v__ast__ArrayFixed v__ast__TypeSymbol_array_fixed_info(v__ast__TypeSymbol* t) { if ((t->info)._typ == 549 /* v.ast.ArrayFixed */) { return (*t->info._v__ast__ArrayFixed); } if ((t->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* fsym = v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type); if ((fsym->info)._typ == 549 /* v.ast.ArrayFixed */) { return (*fsym->info._v__ast__ArrayFixed); } } v__ast__TypeSymbol_no_info_panic(t, _S("TypeSymbol.array_fixed_info")); VUNREACHABLE(); return (v__ast__ArrayFixed){.size = 0,.size_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.elem_type = 0,.is_fn_ret = 0,}; } inline v__ast__Chan v__ast__TypeSymbol_chan_info(v__ast__TypeSymbol* t) { if ((t->info)._typ == 550 /* v.ast.Chan */) { return (*t->info._v__ast__Chan); } if ((t->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* fsym = v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type); if ((fsym->info)._typ == 550 /* v.ast.Chan */) { return (*fsym->info._v__ast__Chan); } } v__ast__TypeSymbol_no_info_panic(t, _S("TypeSymbol.chan_info")); VUNREACHABLE(); return (v__ast__Chan){.elem_type = 0,.is_mut = 0,}; } inline v__ast__Thread v__ast__TypeSymbol_thread_info(v__ast__TypeSymbol* t) { if ((t->info)._typ == 551 /* v.ast.Thread */) { return (*t->info._v__ast__Thread); } if ((t->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* fsym = v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type); if ((fsym->info)._typ == 551 /* v.ast.Thread */) { return (*fsym->info._v__ast__Thread); } } v__ast__TypeSymbol_no_info_panic(t, _S("TypeSymbol.thread_info")); VUNREACHABLE(); return (v__ast__Thread){.return_type = 0,}; } inline v__ast__Map v__ast__TypeSymbol_map_info(v__ast__TypeSymbol* t) { if ((t->info)._typ == 514 /* v.ast.Map */) { return (*t->info._v__ast__Map); } if ((t->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* fsym = v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type); if ((fsym->info)._typ == 514 /* v.ast.Map */) { return (*fsym->info._v__ast__Map); } } v__ast__TypeSymbol_no_info_panic(t, _S("TypeSymbol.map_info")); VUNREACHABLE(); return (v__ast__Map){.key_type = 0,.value_type = 0,}; } inline v__ast__Struct v__ast__TypeSymbol_struct_info(v__ast__TypeSymbol* t) { if ((t->info)._typ == 518 /* v.ast.Struct */) { return (*t->info._v__ast__Struct); } if ((t->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* fsym = v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type); if ((fsym->info)._typ == 518 /* v.ast.Struct */) { return (*fsym->info._v__ast__Struct); } } v__ast__TypeSymbol_no_info_panic(t, _S("TypeSymbol.struct_info")); VUNREACHABLE(); return (v__ast__Struct){.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.embeds = __new_array(0, 0, sizeof(v__ast__Type)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.is_typedef = 0,.is_union = 0,.is_heap = 0,.is_minify = 0,.is_anon = 0,.is_generic = 0,.is_shared = 0,.is_markused = 0,.has_option = 0,.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.parent_type = 0,}; } inline v__ast__SumType v__ast__TypeSymbol_sumtype_info(v__ast__TypeSymbol* t) { if ((t->info)._typ == 544 /* v.ast.SumType */) { return (*t->info._v__ast__SumType); } if ((t->info)._typ == 544 /* v.ast.SumType */) { v__ast__TypeSymbol* fsym = v__ast__Table_final_sym(global_table, (*t->info._v__ast__SumType).parent_type); if ((fsym->info)._typ == 544 /* v.ast.SumType */) { return (*fsym->info._v__ast__SumType); } } v__ast__TypeSymbol_no_info_panic(t, _S("TypeSymbol.sumtype_info")); VUNREACHABLE(); return (v__ast__SumType){.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.found_fields = 0,.is_anon = 0,.is_generic = 0,.variants = __new_array(0, 0, sizeof(v__ast__Type)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.parent_type = 0,}; } bool v__ast__TypeSymbol_is_heap(v__ast__TypeSymbol* t) { if ((t->info)._typ == 518 /* v.ast.Struct */) { return (*t->info._v__ast__Struct).is_heap; } else { return false; } return 0; } bool v__ast__ArrayFixed_is_compatible(v__ast__ArrayFixed* t, v__ast__ArrayFixed t2) { return t->size == t2.size && t->elem_type == t2.elem_type; } bool v__ast__TypeSymbol_is_empty_struct_array(v__ast__TypeSymbol* t) { if ((t->info)._typ == 549 /* v.ast.ArrayFixed */) { v__ast__TypeSymbol* elem_sym = v__ast__Table_final_sym(global_table, (*t->info._v__ast__ArrayFixed).elem_type); if ((elem_sym->info)._typ == 518 /* v.ast.Struct */) { return v__ast__Struct_is_empty_struct(&(*elem_sym->info._v__ast__Struct)); } } return false; } inline bool v__ast__Struct_is_empty_struct(v__ast__Struct* t) { return t->fields.len == 0 && t->embeds.len == 0; } inline bool v__ast__Struct_is_unresolved_generic(v__ast__Struct* t) { return t->generic_types.len > 0 && t->concrete_types.len == 0; } bool v__ast__TypeSymbol_is_primitive_fixed_array(v__ast__TypeSymbol* t) { if ((t->info)._typ == 549 /* v.ast.ArrayFixed */) { return v__ast__TypeSymbol_is_primitive(v__ast__Table_final_sym(global_table, (*t->info._v__ast__ArrayFixed).elem_type)); } else if ((t->info)._typ == 539 /* v.ast.Alias */) { return v__ast__TypeSymbol_is_primitive_fixed_array(v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type)); } else { return false; } return 0; } bool v__ast__TypeSymbol_is_array_fixed(v__ast__TypeSymbol* t) { if ((t->info)._typ == 549 /* v.ast.ArrayFixed */) { return true; } else if ((t->info)._typ == 539 /* v.ast.Alias */) { return v__ast__TypeSymbol_is_array_fixed(v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type)); } else { return false; } return 0; } bool v__ast__TypeSymbol_is_c_struct(v__ast__TypeSymbol* t) { if ((t->info)._typ == 518 /* v.ast.Struct */) { return t->language == v__ast__Language__c; } else if ((t->info)._typ == 539 /* v.ast.Alias */) { return v__ast__TypeSymbol_is_c_struct(v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type)); } return false; } bool v__ast__TypeSymbol_is_array_fixed_ret(v__ast__TypeSymbol* t) { if ((t->info)._typ == 549 /* v.ast.ArrayFixed */) { return (*t->info._v__ast__ArrayFixed).is_fn_ret; } else if ((t->info)._typ == 539 /* v.ast.Alias */) { return v__ast__TypeSymbol_is_array_fixed_ret(v__ast__Table_final_sym(global_table, (*t->info._v__ast__Alias).parent_type)); } else { return false; } return 0; } void v__ast__Table_register_builtin_type_symbols(v__ast__Table* t) { v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__placeholder,.name = _S("reserved_0"),.cname = (string){.str=(byteptr)"", .is_lit=1},.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__void,.name = _S("void"),.cname = _S("void"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__voidptr,.name = _S("voidptr"),.cname = _S("voidptr"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__byteptr,.name = _S("byteptr"),.cname = _S("byteptr"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__charptr,.name = _S("charptr"),.cname = _S("charptr"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__i8,.name = _S("i8"),.cname = _S("i8"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__i16,.name = _S("i16"),.cname = _S("i16"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__i32,.name = _S("i32"),.cname = _S("i32"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__int,.name = _S("int"),.cname = _const_v__ast__int_type_name,.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__i64,.name = _S("i64"),.cname = _S("i64"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__isize,.name = _S("isize"),.cname = _S("isize"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__u8,.name = _S("u8"),.cname = _S("u8"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__u16,.name = _S("u16"),.cname = _S("u16"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__u32,.name = _S("u32"),.cname = _S("u32"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__u64,.name = _S("u64"),.cname = _S("u64"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__usize,.name = _S("usize"),.cname = _S("usize"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__f32,.name = _S("f32"),.cname = _S("f32"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__f64,.name = _S("f64"),.cname = _S("f64"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__char,.name = _S("char"),.cname = _S("char"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__bool,.name = _S("bool"),.cname = _S("bool"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__none,.name = _S("none"),.cname = _S("none"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){ .parent_idx = 0, .info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557}, .kind = v__ast__Kind__string, .name = _S("string"), .cname = _S("string"), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = _S("builtin"), .is_pub = true, .is_builtin = true, .language = 0, .idx = 0, .size = -1, .align = -1, })); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__rune,.name = _S("rune"),.cname = _S("rune"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){ .parent_idx = 0, .info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557}, .kind = v__ast__Kind__array, .name = _S("array"), .cname = _S("array"), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = _S("builtin"), .is_pub = true, .is_builtin = true, .language = 0, .idx = 0, .size = -1, .align = -1, })); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){ .parent_idx = 0, .info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557}, .kind = v__ast__Kind__map, .name = _S("map"), .cname = _S("map"), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = _S("builtin"), .is_pub = true, .is_builtin = true, .language = 0, .idx = 0, .size = -1, .align = -1, })); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__chan,.name = _S("chan"),.cname = _S("chan"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__any,.name = _S("any"),.cname = _S("any"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__float_literal,.name = _S("float literal"),.cname = _S("float_literal"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__int_literal,.name = _S("int literal"),.cname = _S("int_literal"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){ .parent_idx = 0, .info = v__ast__Thread_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Thread, (((v__ast__Thread){.return_type = _const_v__ast__void_type,})))), .kind = v__ast__Kind__thread, .name = _S("thread"), .cname = _S("__v_thread"), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = _S("builtin"), .is_pub = true, .is_builtin = 0, .language = 0, .idx = 0, .size = -1, .align = -1, })); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){ .parent_idx = 0, .info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557}, .kind = v__ast__Kind__interface, .name = _S("IError"), .cname = _S("IError"), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = _S("builtin"), .is_pub = true, .is_builtin = true, .language = 0, .idx = 0, .size = -1, .align = -1, })); v__ast__Table_register_sym(t, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__voidptr,.name = _S("nil"),.cname = _S("voidptr"),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = _S("builtin"),.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); } inline bool v__ast__TypeSymbol_is_pointer(v__ast__TypeSymbol* t) { return (t->kind == v__ast__Kind__byteptr || t->kind == v__ast__Kind__charptr || t->kind == v__ast__Kind__voidptr); } inline bool v__ast__TypeSymbol_is_int(v__ast__TypeSymbol* t) { bool res = (t->kind == v__ast__Kind__i8 || t->kind == v__ast__Kind__i16 || t->kind == v__ast__Kind__int || t->kind == v__ast__Kind__i64 || t->kind == v__ast__Kind__i32 || t->kind == v__ast__Kind__isize || t->kind == v__ast__Kind__u8 || t->kind == v__ast__Kind__u16 || t->kind == v__ast__Kind__u32 || t->kind == v__ast__Kind__u64 || t->kind == v__ast__Kind__usize || t->kind == v__ast__Kind__int_literal || t->kind == v__ast__Kind__rune); if (!res && t->kind == v__ast__Kind__alias) { return v__ast__Type_is_int((*(v__ast__Alias*)__as_cast((t->info)._v__ast__Alias,(t->info)._typ, 539)).parent_type); } return res; } inline bool v__ast__TypeSymbol_is_float(v__ast__TypeSymbol* t) { return (t->kind == v__ast__Kind__f32 || t->kind == v__ast__Kind__f64 || t->kind == v__ast__Kind__float_literal); } inline bool v__ast__TypeSymbol_is_string(v__ast__TypeSymbol* t) { return t->kind == v__ast__Kind__string; } inline bool v__ast__TypeSymbol_is_number(v__ast__TypeSymbol* t) { return v__ast__TypeSymbol_is_int(t) || v__ast__TypeSymbol_is_float(t); } inline bool v__ast__TypeSymbol_is_bool(v__ast__TypeSymbol* t) { return t->kind == v__ast__Kind__bool; } inline bool v__ast__TypeSymbol_is_primitive(v__ast__TypeSymbol* t) { return v__ast__TypeSymbol_is_number(t) || v__ast__TypeSymbol_is_pointer(t) || v__ast__TypeSymbol_is_string(t) || v__ast__TypeSymbol_is_bool(t); } inline bool v__ast__TypeSymbol_is_builtin(v__ast__TypeSymbol* t) { return fast_string_eq(t->mod, _S("builtin")); } multi_return_int_int v__ast__Table_type_size(v__ast__Table* t, v__ast__Type typ) { if (v__ast__Type_has_option_or_result(typ)) { return v__ast__Table_type_size(t, _const_v__ast__error_type_idx); } if (v__ast__Type_nr_muls(typ) > 0) { return (multi_return_int_int){.arg0=t->pointer_size, .arg1=t->pointer_size}; } v__ast__TypeSymbol* sym = v__ast__Table_sym(t, typ); if (sym->size != -1) { return (multi_return_int_int){.arg0=sym->size, .arg1=sym->align}; } int size = 0; int align = 0; switch (sym->kind) { case v__ast__Kind__placeholder: case v__ast__Kind__void: case v__ast__Kind__none: case v__ast__Kind__generic_inst: { break; } case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__function: case v__ast__Kind__usize: case v__ast__Kind__isize: case v__ast__Kind__any: case v__ast__Kind__thread: case v__ast__Kind__chan: { size = t->pointer_size; align = t->pointer_size; break; } case v__ast__Kind__i8: case v__ast__Kind__u8: case v__ast__Kind__char: case v__ast__Kind__bool: { size = 1; align = 1; break; } case v__ast__Kind__i16: case v__ast__Kind__u16: { size = 2; align = 2; break; } case v__ast__Kind__i32: case v__ast__Kind__u32: case v__ast__Kind__rune: case v__ast__Kind__f32: case v__ast__Kind__enum: { size = 4; align = 4; break; } case v__ast__Kind__int: { #if defined(CUSTOM_DEFINE_new_int) { #if defined(__V_arm64) || defined(__V_amd64) { size = 8; align = 8; } #else { size = 4; align = 4; } #endif } #else { size = 4; align = 4; } #endif break; } case v__ast__Kind__i64: case v__ast__Kind__u64: case v__ast__Kind__int_literal: case v__ast__Kind__f64: case v__ast__Kind__float_literal: { size = 8; align = 8; break; } case v__ast__Kind__alias: { multi_return_int_int mr_30247 = v__ast__Table_type_size(t, (*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type); size = mr_30247.arg0; align = mr_30247.arg1; break; } case v__ast__Kind__struct: case v__ast__Kind__string: case v__ast__Kind__multi_return: { int max_alignment = 0; int total_size = 0; Array_v__ast__Type _t6; /* if prepend */ if ((sym->info)._typ == 518 /* v.ast.Struct */) { Array_v__ast__Type _t7 = {0}; Array_v__ast__StructField _t7_orig = (*sym->info._v__ast__Struct).fields; int _t7_len = _t7_orig.len; _t7 = __new_array(0, _t7_len, sizeof(v__ast__Type)); for (int _t9 = 0; _t9 < _t7_len; ++_t9) { v__ast__StructField it = ((v__ast__StructField*) _t7_orig.data)[_t9]; v__ast__Type _t8 = it.typ; array_push((array*)&_t7, &_t8); } _t6 =_t7; } else { _t6 = (*(v__ast__MultiReturn*)__as_cast((sym->info)._v__ast__MultiReturn,(sym->info)._typ, 552)).types; } Array_v__ast__Type types = _t6; for (int _t10 = 0; _t10 < types.len; ++_t10) { v__ast__Type ftyp = ((v__ast__Type*)types.data)[_t10]; multi_return_int_int mr_30557 = v__ast__Table_type_size(t, ftyp); int field_size = mr_30557.arg0; int alignment = mr_30557.arg1; if (alignment > max_alignment) { max_alignment = alignment; } total_size = (int)(v__ast__round_up(total_size, alignment) + field_size); } size = v__ast__round_up(total_size, max_alignment); align = max_alignment; break; } case v__ast__Kind__sum_type: case v__ast__Kind__interface: case v__ast__Kind__aggregate: { if (sym->info._typ == 544 /* v.ast.SumType */) { size = (int)(((int)((*sym->info._v__ast__SumType).fields.len + 2)) * t->pointer_size); align = t->pointer_size; } else if (sym->info._typ == 537 /* v.ast.Aggregate */) { size = (int)(((int)((*sym->info._v__ast__Aggregate).fields.len + 2)) * t->pointer_size); align = t->pointer_size; } else if (sym->info._typ == 542 /* v.ast.Interface */) { size = (int)(((int)((*sym->info._v__ast__Interface).fields.len + 2)) * t->pointer_size); align = t->pointer_size; for (int _t11 = 0; _t11 < (*sym->info._v__ast__Interface).embeds.len; ++_t11) { v__ast__Type etyp = ((v__ast__Type*)(*sym->info._v__ast__Interface).embeds.data)[_t11]; multi_return_int_int mr_31117 = v__ast__Table_type_size(t, etyp); int esize = mr_31117.arg0; size += (int)(esize - (int)(2 * t->pointer_size)); } } else { } break; } case v__ast__Kind__array_fixed: { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549); multi_return_int_int mr_31314 = v__ast__Table_type_size(t, info.elem_type); int elem_size = mr_31314.arg0; int elem_align = mr_31314.arg1; size = (int)(info.size * elem_size); align = elem_align; break; } case v__ast__Kind__map: { size = (t->pointer_size == 8 ? (120) : (80)); align = t->pointer_size; break; } case v__ast__Kind__array: { size = (t->pointer_size == 8 ? (32) : (24)); align = t->pointer_size; break; } } sym->size = size; sym->align = align; return (multi_return_int_int){.arg0=size, .arg1=align}; } inline VV_LOC int v__ast__round_up(int n, int multiple) { return (((int)((int)(n + multiple) - 1)) & -multiple); } string v__ast__Kind_str(v__ast__Kind k) { string _t2 = (string){.str=(byteptr)"", .is_lit=1}; switch (k) { case v__ast__Kind__placeholder: { _t2 = _S("placeholder"); break; } case v__ast__Kind__void: { _t2 = _S("void"); break; } case v__ast__Kind__voidptr: { _t2 = _S("voidptr"); break; } case v__ast__Kind__charptr: { _t2 = _S("charptr"); break; } case v__ast__Kind__byteptr: { _t2 = _S("byteptr"); break; } case v__ast__Kind__struct: { _t2 = _S("struct"); break; } case v__ast__Kind__int: { _t2 = _S("int"); break; } case v__ast__Kind__i8: { _t2 = _S("i8"); break; } case v__ast__Kind__i16: { _t2 = _S("i16"); break; } case v__ast__Kind__i32: { _t2 = _S("i32"); break; } case v__ast__Kind__i64: { _t2 = _S("i64"); break; } case v__ast__Kind__isize: { _t2 = _S("isize"); break; } case v__ast__Kind__u8: { _t2 = _S("u8"); break; } case v__ast__Kind__u16: { _t2 = _S("u16"); break; } case v__ast__Kind__u32: { _t2 = _S("u32"); break; } case v__ast__Kind__u64: { _t2 = _S("u64"); break; } case v__ast__Kind__usize: { _t2 = _S("usize"); break; } case v__ast__Kind__int_literal: { _t2 = _S("int_literal"); break; } case v__ast__Kind__f32: { _t2 = _S("f32"); break; } case v__ast__Kind__f64: { _t2 = _S("f64"); break; } case v__ast__Kind__float_literal: { _t2 = _S("float_literal"); break; } case v__ast__Kind__string: { _t2 = _S("string"); break; } case v__ast__Kind__char: { _t2 = _S("char"); break; } case v__ast__Kind__bool: { _t2 = _S("bool"); break; } case v__ast__Kind__none: { _t2 = _S("none"); break; } case v__ast__Kind__array: { _t2 = _S("array"); break; } case v__ast__Kind__array_fixed: { _t2 = _S("array_fixed"); break; } case v__ast__Kind__map: { _t2 = _S("map"); break; } case v__ast__Kind__chan: { _t2 = _S("chan"); break; } case v__ast__Kind__multi_return: { _t2 = _S("multi_return"); break; } case v__ast__Kind__sum_type: { _t2 = _S("sum_type"); break; } case v__ast__Kind__alias: { _t2 = _S("alias"); break; } case v__ast__Kind__enum: { _t2 = _S("enum"); break; } case v__ast__Kind__any: { _t2 = _S("any"); break; } case v__ast__Kind__function: { _t2 = _S("function"); break; } case v__ast__Kind__interface: { _t2 = _S("interface"); break; } case v__ast__Kind__generic_inst: { _t2 = _S("generic_inst"); break; } case v__ast__Kind__rune: { _t2 = _S("rune"); break; } case v__ast__Kind__aggregate: { _t2 = _S("aggregate"); break; } case v__ast__Kind__thread: { _t2 = _S("thread"); break; } } return _t2; } string Array_v__ast__Kind_str(Array_v__ast__Kind kinds) { string kinds_str = _S(""); for (int i = 0; i < kinds.len; ++i) { v__ast__Kind k = ((v__ast__Kind*)kinds.data)[i]; kinds_str = string__plus(kinds_str, v__ast__Kind_str(k)); if (i < (int)(kinds.len - 1)) { kinds_str = string__plus(kinds_str, _S("_")); } } return kinds_str; } string v__ast__Table_type_to_str(v__ast__Table* t, v__ast__Type typ) { return v__ast__Table_type_to_str_using_aliases(t, typ, new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ); } string v__ast__Table_type_to_code(v__ast__Table* t, v__ast__Type typ) { if (typ == (_const_v__ast__int_literal_type) || typ == (_const_v__ast__float_literal_type)) { return v__ast__Kind_str(v__ast__Table_sym(t, typ)->kind); } else { return v__ast__Table_type_to_str_using_aliases(t, typ, new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ); } return (string){.str=(byteptr)"", .is_lit=1}; } string v__ast__Table_clean_generics_type_str(v__ast__Table* t, v__ast__Type typ) { string result = v__ast__Table_type_to_str(t, typ); return string_all_before(result, _S("[")); } VV_LOC string v__ast__strip_extra_struct_types(string name) { int start = 0; bool is_start = false; int nested_count = 0; Array_string strips = __new_array_with_default(0, 0, sizeof(string), 0); for (int i = 0; i < name.len; ++i) { u8 ch = name.str[i]; if (ch == '<') { if (is_start) { nested_count++; } else { is_start = true; start = i; } } else if (ch == '>') { if (nested_count > 0) { nested_count--; } else { array_push((array*)&strips, _MOV((string[]){ string_substr(name, start, (int)(i + 1)) })); array_push((array*)&strips, _MOV((string[]){ _S("") })); is_start = false; } } } if (strips.len > 0) { return string_replace_each(name, strips); } else { return name; } return (string){.str=(byteptr)"", .is_lit=1}; } string v__ast__Table_type_to_str_using_aliases(v__ast__Table* t, v__ast__Type typ, Map_string_string import_aliases) { bool v__ast__Table_type_to_str_using_aliases_defer_0 = false; v__ast__Table* mt; u64 cache_key; string res; cache_key = (((((u64)(import_aliases.len)) << 32U)) | ((u64)(typ))); string* _t2 = (string*)(map_get_check(ADDR(map, t->cached_type_to_str->val), &(u64[]){cache_key})); _option_string _t1 = {0}; if (_t2) { *((string*)&_t1.data) = *((string*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { string cached_res = (*(string*)_t1.data); return cached_res; } v__ast__TypeSymbol* sym = v__ast__Table_sym(t, typ); res = sym->name; mt = ((v__ast__Table*)(t)); v__ast__Table_type_to_str_using_aliases_defer_0 = true; switch (sym->kind) { case v__ast__Kind__int_literal: case v__ast__Kind__float_literal: { break; } case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__i32: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__isize: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__usize: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__string: case v__ast__Kind__bool: case v__ast__Kind__none: case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: { res = v__ast__Kind_str(sym->kind); break; } case v__ast__Kind__array: { if (typ == _const_v__ast__array_type) { res = _S("array"); string _t4 = res; // Defer begin if (v__ast__Table_type_to_str_using_aliases_defer_0) { sync__RwMutex_lock(&mt->cached_type_to_str->mtx); /*lock*/ { map_set(&mt->cached_type_to_str->val, &(u64[]){cache_key}, &(string[]) { res }); } sync__RwMutex_unlock(&mt->cached_type_to_str->mtx);; } // Defer end return _t4; } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__variadic)) { res = v__ast__Table_type_to_str_using_aliases(t, v__ast__Table_value_type(t, typ), import_aliases); } else { if ((sym->info)._typ == 513 /* v.ast.Array */) { string elem_str = v__ast__Table_type_to_str_using_aliases(t, (*sym->info._v__ast__Array).elem_type, import_aliases); res = str_intp(2, _MOV((StrIntpData[]){{_S("[]"), 0xfe10, {.d_s = elem_str}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { res = _S("array"); } } break; } case v__ast__Kind__array_fixed: { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549); string elem_str = v__ast__Table_type_to_str_using_aliases(t, info.elem_type, import_aliases); if ((info.size_expr)._typ == 354 /* v.ast.EmptyExpr */) { res = str_intp(3, _MOV((StrIntpData[]){{_S("["), 0xfe07, {.d_i32 = info.size}}, {_S("]"), 0xfe10, {.d_s = elem_str}}, {_SLIT0, 0, { .d_c = 0 }}})); } else if ((info.size_expr)._typ == 358 /* v.ast.Ident */) { string size_str = v__ast__Table_shorten_user_defined_typenames(t, (*info.size_expr._v__ast__Ident).name, import_aliases); res = str_intp(3, _MOV((StrIntpData[]){{_S("["), 0xfe10, {.d_s = size_str}}, {_S("]"), 0xfe10, {.d_s = elem_str}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { res = str_intp(3, _MOV((StrIntpData[]){{_S("["), 0xfe10, {.d_s = v__ast__Expr_str(&info.size_expr)}}, {_S("]"), 0xfe10, {.d_s = elem_str}}, {_SLIT0, 0, { .d_c = 0 }}})); } break; } case v__ast__Kind__chan: { if (!fast_string_eq(sym->mod, _S("builtin")) && !fast_string_eq(sym->name, _S("chan"))) { v__ast__Chan info = *(v__ast__Chan*)__as_cast((sym->info)._v__ast__Chan,(sym->info)._typ, 550); v__ast__Type elem_type = info.elem_type; string mut_str = _S(""); if (info.is_mut) { mut_str = _S("mut "); elem_type = v__ast__Type_set_nr_muls(elem_type, (int)(v__ast__Type_nr_muls(elem_type) - 1)); } string elem_str = v__ast__Table_type_to_str_using_aliases(t, elem_type, import_aliases); res = str_intp(3, _MOV((StrIntpData[]){{_S("chan "), 0xfe10, {.d_s = mut_str}}, {_SLIT0, 0xfe10, {.d_s = elem_str}}, {_SLIT0, 0, { .d_c = 0 }}})); } break; } case v__ast__Kind__function: { v__ast__FnType info = *(v__ast__FnType*)__as_cast((sym->info)._v__ast__FnType,(sym->info)._typ, 553); if (!t->is_fmt) { res = v__ast__Table_fn_signature(t, (voidptr)&info.func, ((v__ast__FnSignatureOpts){.skip_receiver = 0,.type_only = true,})); } else { if (string_starts_with(res, _S("fn ("))) { bool _t5 = false; Array_v__ast__Param _t5_orig = info.func.params; int _t5_len = _t5_orig.len; for (int _t6 = 0; _t6 < _t5_len; ++_t6) { v__ast__Param it = ((v__ast__Param*) _t5_orig.data)[_t6]; if ((it.name).len != 0) { _t5 = true; break; } } bool has_names =_t5; res = v__ast__Table_fn_signature_using_aliases(t, (voidptr)&info.func, import_aliases, ((v__ast__FnSignatureOpts){.skip_receiver = 0,.type_only = !has_names,})); } else { res = v__ast__Table_shorten_user_defined_typenames(t, res, import_aliases); } } break; } case v__ast__Kind__map: { if (((int)(typ)) == 24) { res = _S("map"); string _t7 = res; // Defer begin if (v__ast__Table_type_to_str_using_aliases_defer_0) { sync__RwMutex_lock(&mt->cached_type_to_str->mtx); /*lock*/ { map_set(&mt->cached_type_to_str->val, &(u64[]){cache_key}, &(string[]) { res }); } sync__RwMutex_unlock(&mt->cached_type_to_str->mtx);; } // Defer end return _t7; } v__ast__Map info = *(v__ast__Map*)__as_cast((sym->info)._v__ast__Map,(sym->info)._typ, 514); string key_str = v__ast__Table_type_to_str_using_aliases(t, info.key_type, import_aliases); string val_str = v__ast__Table_type_to_str_using_aliases(t, info.value_type, import_aliases); res = str_intp(3, _MOV((StrIntpData[]){{_S("map["), 0xfe10, {.d_s = key_str}}, {_S("]"), 0xfe10, {.d_s = val_str}}, {_SLIT0, 0, { .d_c = 0 }}})); break; } case v__ast__Kind__multi_return: { res = _S("("); v__ast__MultiReturn info = *(v__ast__MultiReturn*)__as_cast((sym->info)._v__ast__MultiReturn,(sym->info)._typ, 552); for (int i = 0; i < info.types.len; ++i) { v__ast__Type typ2 = ((v__ast__Type*)info.types.data)[i]; if (i > 0) { res = string__plus(res, _S(", ")); } res = string__plus(res, v__ast__Table_type_to_str_using_aliases(t, typ2, import_aliases)); } res = string__plus(res, _S(")")); break; } case v__ast__Kind__struct: case v__ast__Kind__interface: case v__ast__Kind__sum_type: { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { if (sym->info._typ == 518 /* v.ast.Struct */) { res = string__plus(res, _S("[")); for (int i = 0; i < (*sym->info._v__ast__Struct).generic_types.len; ++i) { v__ast__Type gtyp = ((v__ast__Type*)(*sym->info._v__ast__Struct).generic_types.data)[i]; res = string__plus(res, v__ast__Table_sym(t, gtyp)->name); if (i != (int)((*sym->info._v__ast__Struct).generic_types.len - 1)) { res = string__plus(res, _S(", ")); } } res = string__plus(res, _S("]")); } else if (sym->info._typ == 542 /* v.ast.Interface */) { res = string__plus(res, _S("[")); for (int i = 0; i < (*sym->info._v__ast__Interface).generic_types.len; ++i) { v__ast__Type gtyp = ((v__ast__Type*)(*sym->info._v__ast__Interface).generic_types.data)[i]; res = string__plus(res, v__ast__Table_sym(t, gtyp)->name); if (i != (int)((*sym->info._v__ast__Interface).generic_types.len - 1)) { res = string__plus(res, _S(", ")); } } res = string__plus(res, _S("]")); } else if (sym->info._typ == 544 /* v.ast.SumType */) { res = string__plus(res, _S("[")); for (int i = 0; i < (*sym->info._v__ast__SumType).generic_types.len; ++i) { v__ast__Type gtyp = ((v__ast__Type*)(*sym->info._v__ast__SumType).generic_types.data)[i]; res = string__plus(res, v__ast__Table_sym(t, gtyp)->name); if (i != (int)((*sym->info._v__ast__SumType).generic_types.len - 1)) { res = string__plus(res, _S(", ")); } } res = string__plus(res, _S("]")); } else { } } else if ((sym->info)._typ == 544 /* v.ast.SumType */ && (*(v__ast__SumType*)__as_cast((sym->info)._v__ast__SumType,(sym->info)._typ, 544)).is_anon) { Array_string _t8 = {0}; Array_v__ast__Type _t8_orig = (*sym->info._v__ast__SumType).variants; int _t8_len = _t8_orig.len; _t8 = __new_array(0, _t8_len, sizeof(string)); for (int _t10 = 0; _t10 < _t8_len; ++_t10) { v__ast__Type it = ((v__ast__Type*) _t8_orig.data)[_t10]; string _t9 = v__ast__Table_shorten_user_defined_typenames(t, v__ast__Table_sym(t, it)->name, import_aliases); array_push((array*)&_t8, &_t9); } Array_string variant_names =_t8; res = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = Array_string_join(variant_names, _S("|"))}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { res = v__ast__strip_extra_struct_types(res); res = v__ast__Table_shorten_user_defined_typenames(t, res, import_aliases); } break; } case v__ast__Kind__generic_inst: { v__ast__GenericInst info = *(v__ast__GenericInst*)__as_cast((sym->info)._v__ast__GenericInst,(sym->info)._typ, 555); res = v__ast__Table_shorten_user_defined_typenames(t, string_all_before(sym->name, _S("[")), import_aliases); res = string__plus(res, _S("[")); for (int i = 0; i < info.concrete_types.len; ++i) { v__ast__Type ctyp = ((v__ast__Type*)info.concrete_types.data)[i]; res = string__plus(res, v__ast__Table_type_to_str_using_aliases(t, ctyp, import_aliases)); if (i != (int)(info.concrete_types.len - 1)) { res = string__plus(res, _S(", ")); } } res = string__plus(res, _S("]")); break; } case v__ast__Kind__void: { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { res = _S("?"); string _t11 = res; // Defer begin if (v__ast__Table_type_to_str_using_aliases_defer_0) { sync__RwMutex_lock(&mt->cached_type_to_str->mtx); /*lock*/ { map_set(&mt->cached_type_to_str->val, &(u64[]){cache_key}, &(string[]) { res }); } sync__RwMutex_unlock(&mt->cached_type_to_str->mtx);; } // Defer end return _t11; } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__result)) { res = _S("!"); string _t12 = res; // Defer begin if (v__ast__Table_type_to_str_using_aliases_defer_0) { sync__RwMutex_lock(&mt->cached_type_to_str->mtx); /*lock*/ { map_set(&mt->cached_type_to_str->val, &(u64[]){cache_key}, &(string[]) { res }); } sync__RwMutex_unlock(&mt->cached_type_to_str->mtx);; } // Defer end return _t12; } res = _S("void"); string _t13 = res; // Defer begin if (v__ast__Table_type_to_str_using_aliases_defer_0) { sync__RwMutex_lock(&mt->cached_type_to_str->mtx); /*lock*/ { map_set(&mt->cached_type_to_str->val, &(u64[]){cache_key}, &(string[]) { res }); } sync__RwMutex_unlock(&mt->cached_type_to_str->mtx);; } // Defer end return _t13; } case v__ast__Kind__thread: { v__ast__Type rtype = v__ast__TypeSymbol_thread_info(sym).return_type; if (rtype != 1) { res = string__plus(_S("thread "), v__ast__Table_type_to_str_using_aliases(t, rtype, import_aliases)); } break; } case v__ast__Kind__alias: case v__ast__Kind__any: case v__ast__Kind__placeholder: case v__ast__Kind__enum: { res = v__ast__Table_shorten_user_defined_typenames(t, res, import_aliases); break; } case v__ast__Kind__aggregate: { break; } } int nr_muls = v__ast__Type_nr_muls(typ); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f)) { nr_muls--; res = string__plus(_S("shared "), res); } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__atomic_f)) { nr_muls--; res = string__plus(_S("atomic "), res); } if (nr_muls > 0 && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__variadic)) { res = string__plus(strings__repeat('&', nr_muls), res); } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { res = str_intp(2, _MOV((StrIntpData[]){{_S("?"), 0xfe10, {.d_s = res}}, {_SLIT0, 0, { .d_c = 0 }}})); } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__result)) { res = str_intp(2, _MOV((StrIntpData[]){{_S("!"), 0xfe10, {.d_s = res}}, {_SLIT0, 0, { .d_c = 0 }}})); } string _t14 = res; // Defer begin if (v__ast__Table_type_to_str_using_aliases_defer_0) { sync__RwMutex_lock(&mt->cached_type_to_str->mtx); /*lock*/ { map_set(&mt->cached_type_to_str->val, &(u64[]){cache_key}, &(string[]) { res }); } sync__RwMutex_unlock(&mt->cached_type_to_str->mtx);; } // Defer end return _t14; } VV_LOC string v__ast__Table_shorten_user_defined_typenames(v__ast__Table* t, string original_name, Map_string_string import_aliases) { string* _t2 = (string*)(map_get_check(ADDR(map, import_aliases), &(string[]){original_name})); _option_string _t1 = {0}; if (_t2) { *((string*)&_t1.data) = *((string*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { string alias = (*(string*)_t1.data); return alias; } _option_multi_return_string_string _t4 = string_rsplit_once(original_name, _S(".")); if (_t4.state != 0) { IError err = _t4.err; return original_name; } multi_return_string_string mr_40155 = (*(multi_return_string_string*)_t4.data); string mod = mr_40155.arg0; string typ = mr_40155.arg1; if (!string_contains(mod, _S("["))) { if (!t->is_fmt) { mod = string_all_after_last(mod, _S(".")); } string* _t7 = (string*)(map_get_check(ADDR(map, import_aliases), &(string[]){mod})); _option_string _t6 = {0}; if (_t7) { *((string*)&_t6.data) = *((string*)_t7); } else { _t6.state = 2; _t6.err = _v_error(_S("map key does not exist")); } if (_t6.state == 0) { string alias = (*(string*)_t6.data); mod = alias; } else if ((t->cmod_prefix).len != 0) { string* _t9 = (string*)(map_get_check(ADDR(map, import_aliases), &(string[]){string__plus(t->cmod_prefix, mod)})); _option_string _t8 = {0}; if (_t9) { *((string*)&_t8.data) = *((string*)_t9); } else { _t8.state = 2; _t8.err = _v_error(_S("map key does not exist")); } if (_t8.state == 0) { string alias = (*(string*)_t8.data); mod = alias; } else { IError err = _t8.err; return string_all_after(original_name, t->cmod_prefix); } } } if (string_contains(original_name, _S("[]"))) { _option_multi_return_string_string _t11; if (_t11 = string_split_once(original_name, _S("[")), _t11.state == 0) { string lhs = (*(multi_return_string_string*)_t11.data).arg0; string typ_after_lsbr = (*(multi_return_string_string*)_t11.data).arg1; _option_multi_return_string_string _t12; if (_t12 = string_rsplit_once(lhs, _S(".")), _t12.state == 0) { string mod_ = (*(multi_return_string_string*)_t12.data).arg0; string typ_before_lsbr = (*(multi_return_string_string*)_t12.data).arg1; mod = mod_; typ = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = typ_before_lsbr}}, {_S("["), 0xfe10, {.d_s = typ_after_lsbr}}, {_SLIT0, 0, { .d_c = 0 }}})); } } } return str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mod}}, {_S("."), 0xfe10, {.d_s = typ}}, {_SLIT0, 0, { .d_c = 0 }}})); } string v__ast__Table_fn_signature(v__ast__Table* t, v__ast__Fn* func, v__ast__FnSignatureOpts opts) { return v__ast__Table_fn_signature_using_aliases(t, func, new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) , opts); } string v__ast__Table_fn_signature_using_aliases(v__ast__Table* t, v__ast__Fn* func, Map_string_string import_aliases, v__ast__FnSignatureOpts opts) { strings__Builder sb = strings__new_builder(20); if (!opts.skip_receiver) { strings__Builder_write_string(&sb, _S("fn ")); } if (!opts.type_only) { strings__Builder_write_string(&sb, func->name); } strings__Builder_write_string(&sb, _S("(")); int start = (int[]){(func->is_method && opts.skip_receiver)?1:0}[0]; for (int i = start; i < func->params.len; ++i) { if (i != start) { strings__Builder_write_string(&sb, _S(", ")); } v__ast__Param param = (*(v__ast__Param*)array_get(func->params, i)); v__ast__Type typ = param.typ; if (param.is_mut) { if (v__ast__Type_is_ptr(param.typ)) { typ = v__ast__Type_deref(typ); } strings__Builder_write_string(&sb, _S("mut ")); } if (!opts.type_only) { strings__Builder_write_string(&sb, param.name); strings__Builder_write_string(&sb, _S(" ")); } string styp = v__ast__Table_type_to_str_using_aliases(t, typ, import_aliases); if (i == (int)(func->params.len - 1) && func->is_variadic) { strings__Builder_write_string(&sb, _S("...")); strings__Builder_write_string(&sb, styp); } else { strings__Builder_write_string(&sb, styp); } } strings__Builder_write_string(&sb, _S(")")); if (func->return_type != _const_v__ast__void_type) { strings__Builder_write_string(&sb, _S(" ")); strings__Builder_write_string(&sb, v__ast__Table_type_to_str_using_aliases(t, func->return_type, import_aliases)); } return strings__Builder_str(&sb); } string v__ast__TypeSymbol_symbol_name_except_generic(v__ast__TypeSymbol* t) { string prefix = _S(""); string name = t->name; for (int i = 0; i < t->name.len; ++i) { u8 ch = t->name.str[i]; if (ch == '&' || ch == '[' || ch == ']') { continue; } if (i > 0) { prefix = string_substr(t->name, 0, i); name = string_substr(t->name, i, 2147483647); } break; } if (string_contains(name, _S("["))) { name = string_all_before(name, _S("[")); } return string__plus(prefix, name); } string v__ast__TypeSymbol_embed_name(v__ast__TypeSymbol* t) { if (string_contains(t->name, _S("<"))) { return (*(string*)array_last(string_split((*(string*)array_get(string_split(t->name, _S("<")), 0)), _S(".")))); } else if (string_contains(t->name, _S("["))) { return (*(string*)array_last(string_split((*(string*)array_get(string_split(t->name, _S("[")), 0)), _S(".")))); } else { return (*(string*)array_last(string_split(t->name, _S(".")))); } return (string){.str=(byteptr)"", .is_lit=1}; } bool v__ast__TypeSymbol_has_method(v__ast__TypeSymbol* t, string name) { Array_v__ast__Fn _t1 = t->methods; for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__ast__Fn* method = ((v__ast__Fn*)_t1.data) + _t2; if (method->name.len == name.len && string__eq(method->name, name)) { return true; } } return false; } bool v__ast__TypeSymbol_has_method_with_generic_parent(v__ast__TypeSymbol* t, string name) { _option_v__ast__Fn _t1 = v__ast__TypeSymbol_find_method_with_generic_parent(t, name); if (_t1.state != 0) { IError err = _t1.err; return false; } v__ast__Fn m = (*(v__ast__Fn*)_t1.data); return t->kind != v__ast__Kind__interface || !m.no_body; } _option_v__ast__Fn v__ast__TypeSymbol_find_method(v__ast__TypeSymbol* t, string name) { Array_v__ast__Fn _t1 = t->methods; for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__ast__Fn* method = ((v__ast__Fn*)_t1.data) + _t2; if (method->name.len == name.len && string__eq(method->name, name)) { _option_v__ast__Fn _t3; _option_ok(&(v__ast__Fn[]) { *method }, (_option*)(&_t3), sizeof(v__ast__Fn)); return _t3; } } return (_option_v__ast__Fn){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__Fn v__ast__TypeSymbol_find_method_with_generic_parent(v__ast__TypeSymbol* t, string name) { _option_v__ast__Fn _t1; if (_t1 = v__ast__TypeSymbol_find_method(t, name), _t1.state == 0) { v__ast__Fn m = *(v__ast__Fn*)_t1.data; _option_v__ast__Fn _t2; _option_ok(&(v__ast__Fn[]) { m }, (_option*)(&_t2), sizeof(v__ast__Fn)); return _t2; } v__ast__Table* table = global_table; if (t->info._typ == 518 /* v.ast.Struct */) { if (v__ast__Type_has_flag((*t->info._v__ast__Struct).parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(table, (*t->info._v__ast__Struct).parent_type); _option_v__ast__Fn _t3; if (_t3 = v__ast__TypeSymbol_find_method(parent_sym, name), _t3.state == 0) { v__ast__Fn x = *(v__ast__Fn*)_t3.data; if (parent_sym->info._typ == 518 /* v.ast.Struct */) { v__ast__Fn method = x; Array_string _t4 = {0}; Array_v__ast__Type _t4_orig = (*parent_sym->info._v__ast__Struct).generic_types; int _t4_len = _t4_orig.len; _t4 = __new_array(0, _t4_len, sizeof(string)); for (int _t6 = 0; _t6 < _t4_len; ++_t6) { v__ast__Type it = ((v__ast__Type*) _t4_orig.data)[_t6]; string _t5 = v__ast__Table_sym(table, it)->name; array_push((array*)&_t4, &_t5); } Array_string generic_names =_t4; v__ast__TypeSymbol* return_sym = v__ast__Table_sym(table, method.return_type); if (return_sym->kind == v__ast__Kind__struct || return_sym->kind == v__ast__Kind__interface || return_sym->kind == v__ast__Kind__sum_type) { method.return_type = v__ast__Table_unwrap_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Struct).concrete_types); } else { _option_v__ast__Type _t7; if (_t7 = v__ast__Table_convert_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Struct).concrete_types), _t7.state == 0) { v__ast__Type rt = *(v__ast__Type*)_t7.data; method.return_type = rt; } } method.params = array_clone_to_depth(&method.params, 0); for (int _t8 = 0; _t8 < method.params.len; ++_t8) { v__ast__Param* param = ((v__ast__Param*)method.params.data) + _t8; _option_v__ast__Type _t9; if (_t9 = v__ast__Table_convert_generic_type(table, param->typ, generic_names, (*t->info._v__ast__Struct).concrete_types), _t9.state == 0) { v__ast__Type pt = *(v__ast__Type*)_t9.data; param->typ = pt; } } _option_v__ast__Fn _t10; _option_ok(&(v__ast__Fn[]) { method }, (_option*)(&_t10), sizeof(v__ast__Fn)); return _t10; } else if (parent_sym->info._typ == 542 /* v.ast.Interface */) { v__ast__Fn method = x; Array_string _t11 = {0}; Array_v__ast__Type _t11_orig = (*parent_sym->info._v__ast__Interface).generic_types; int _t11_len = _t11_orig.len; _t11 = __new_array(0, _t11_len, sizeof(string)); for (int _t13 = 0; _t13 < _t11_len; ++_t13) { v__ast__Type it = ((v__ast__Type*) _t11_orig.data)[_t13]; string _t12 = v__ast__Table_sym(table, it)->name; array_push((array*)&_t11, &_t12); } Array_string generic_names =_t11; v__ast__TypeSymbol* return_sym = v__ast__Table_sym(table, method.return_type); if (return_sym->kind == v__ast__Kind__struct || return_sym->kind == v__ast__Kind__interface || return_sym->kind == v__ast__Kind__sum_type) { method.return_type = v__ast__Table_unwrap_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Interface).concrete_types); } else { _option_v__ast__Type _t14; if (_t14 = v__ast__Table_convert_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Interface).concrete_types), _t14.state == 0) { v__ast__Type rt = *(v__ast__Type*)_t14.data; method.return_type = rt; } } method.params = array_clone_to_depth(&method.params, 0); for (int _t15 = 0; _t15 < method.params.len; ++_t15) { v__ast__Param* param = ((v__ast__Param*)method.params.data) + _t15; _option_v__ast__Type _t16; if (_t16 = v__ast__Table_convert_generic_type(table, param->typ, generic_names, (*t->info._v__ast__Interface).concrete_types), _t16.state == 0) { v__ast__Type pt = *(v__ast__Type*)_t16.data; param->typ = pt; } } _option_v__ast__Fn _t17; _option_ok(&(v__ast__Fn[]) { method }, (_option*)(&_t17), sizeof(v__ast__Fn)); return _t17; } else if (parent_sym->info._typ == 544 /* v.ast.SumType */) { v__ast__Fn method = x; Array_string _t18 = {0}; Array_v__ast__Type _t18_orig = (*parent_sym->info._v__ast__SumType).generic_types; int _t18_len = _t18_orig.len; _t18 = __new_array(0, _t18_len, sizeof(string)); for (int _t20 = 0; _t20 < _t18_len; ++_t20) { v__ast__Type it = ((v__ast__Type*) _t18_orig.data)[_t20]; string _t19 = v__ast__Table_sym(table, it)->name; array_push((array*)&_t18, &_t19); } Array_string generic_names =_t18; v__ast__TypeSymbol* return_sym = v__ast__Table_sym(table, method.return_type); if (return_sym->kind == v__ast__Kind__struct || return_sym->kind == v__ast__Kind__interface || return_sym->kind == v__ast__Kind__sum_type) { method.return_type = v__ast__Table_unwrap_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__SumType).concrete_types); } else { _option_v__ast__Type _t21; if (_t21 = v__ast__Table_convert_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__SumType).concrete_types), _t21.state == 0) { v__ast__Type rt = *(v__ast__Type*)_t21.data; method.return_type = rt; } } method.params = array_clone_to_depth(&method.params, 0); for (int _t22 = 0; _t22 < method.params.len; ++_t22) { v__ast__Param* param = ((v__ast__Param*)method.params.data) + _t22; _option_v__ast__Type _t23; if (_t23 = v__ast__Table_convert_generic_type(table, param->typ, generic_names, (*t->info._v__ast__SumType).concrete_types), _t23.state == 0) { v__ast__Type pt = *(v__ast__Type*)_t23.data; param->typ = pt; } } _option_v__ast__Fn _t24; _option_ok(&(v__ast__Fn[]) { method }, (_option*)(&_t24), sizeof(v__ast__Fn)); return _t24; } else { } } } } else if (t->info._typ == 542 /* v.ast.Interface */) { if (v__ast__Type_has_flag((*t->info._v__ast__Interface).parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(table, (*t->info._v__ast__Interface).parent_type); _option_v__ast__Fn _t25; if (_t25 = v__ast__TypeSymbol_find_method(parent_sym, name), _t25.state == 0) { v__ast__Fn x = *(v__ast__Fn*)_t25.data; if (parent_sym->info._typ == 518 /* v.ast.Struct */) { v__ast__Fn method = x; Array_string _t26 = {0}; Array_v__ast__Type _t26_orig = (*parent_sym->info._v__ast__Struct).generic_types; int _t26_len = _t26_orig.len; _t26 = __new_array(0, _t26_len, sizeof(string)); for (int _t28 = 0; _t28 < _t26_len; ++_t28) { v__ast__Type it = ((v__ast__Type*) _t26_orig.data)[_t28]; string _t27 = v__ast__Table_sym(table, it)->name; array_push((array*)&_t26, &_t27); } Array_string generic_names =_t26; v__ast__TypeSymbol* return_sym = v__ast__Table_sym(table, method.return_type); if (return_sym->kind == v__ast__Kind__struct || return_sym->kind == v__ast__Kind__interface || return_sym->kind == v__ast__Kind__sum_type) { method.return_type = v__ast__Table_unwrap_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Struct).concrete_types); } else { _option_v__ast__Type _t29; if (_t29 = v__ast__Table_convert_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Struct).concrete_types), _t29.state == 0) { v__ast__Type rt = *(v__ast__Type*)_t29.data; method.return_type = rt; } } method.params = array_clone_to_depth(&method.params, 0); for (int _t30 = 0; _t30 < method.params.len; ++_t30) { v__ast__Param* param = ((v__ast__Param*)method.params.data) + _t30; _option_v__ast__Type _t31; if (_t31 = v__ast__Table_convert_generic_type(table, param->typ, generic_names, (*t->info._v__ast__Struct).concrete_types), _t31.state == 0) { v__ast__Type pt = *(v__ast__Type*)_t31.data; param->typ = pt; } } _option_v__ast__Fn _t32; _option_ok(&(v__ast__Fn[]) { method }, (_option*)(&_t32), sizeof(v__ast__Fn)); return _t32; } else if (parent_sym->info._typ == 542 /* v.ast.Interface */) { v__ast__Fn method = x; Array_string _t33 = {0}; Array_v__ast__Type _t33_orig = (*parent_sym->info._v__ast__Interface).generic_types; int _t33_len = _t33_orig.len; _t33 = __new_array(0, _t33_len, sizeof(string)); for (int _t35 = 0; _t35 < _t33_len; ++_t35) { v__ast__Type it = ((v__ast__Type*) _t33_orig.data)[_t35]; string _t34 = v__ast__Table_sym(table, it)->name; array_push((array*)&_t33, &_t34); } Array_string generic_names =_t33; v__ast__TypeSymbol* return_sym = v__ast__Table_sym(table, method.return_type); if (return_sym->kind == v__ast__Kind__struct || return_sym->kind == v__ast__Kind__interface || return_sym->kind == v__ast__Kind__sum_type) { method.return_type = v__ast__Table_unwrap_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Interface).concrete_types); } else { _option_v__ast__Type _t36; if (_t36 = v__ast__Table_convert_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Interface).concrete_types), _t36.state == 0) { v__ast__Type rt = *(v__ast__Type*)_t36.data; method.return_type = rt; } } method.params = array_clone_to_depth(&method.params, 0); for (int _t37 = 0; _t37 < method.params.len; ++_t37) { v__ast__Param* param = ((v__ast__Param*)method.params.data) + _t37; _option_v__ast__Type _t38; if (_t38 = v__ast__Table_convert_generic_type(table, param->typ, generic_names, (*t->info._v__ast__Interface).concrete_types), _t38.state == 0) { v__ast__Type pt = *(v__ast__Type*)_t38.data; param->typ = pt; } } _option_v__ast__Fn _t39; _option_ok(&(v__ast__Fn[]) { method }, (_option*)(&_t39), sizeof(v__ast__Fn)); return _t39; } else if (parent_sym->info._typ == 544 /* v.ast.SumType */) { v__ast__Fn method = x; Array_string _t40 = {0}; Array_v__ast__Type _t40_orig = (*parent_sym->info._v__ast__SumType).generic_types; int _t40_len = _t40_orig.len; _t40 = __new_array(0, _t40_len, sizeof(string)); for (int _t42 = 0; _t42 < _t40_len; ++_t42) { v__ast__Type it = ((v__ast__Type*) _t40_orig.data)[_t42]; string _t41 = v__ast__Table_sym(table, it)->name; array_push((array*)&_t40, &_t41); } Array_string generic_names =_t40; v__ast__TypeSymbol* return_sym = v__ast__Table_sym(table, method.return_type); if (return_sym->kind == v__ast__Kind__struct || return_sym->kind == v__ast__Kind__interface || return_sym->kind == v__ast__Kind__sum_type) { method.return_type = v__ast__Table_unwrap_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__SumType).concrete_types); } else { _option_v__ast__Type _t43; if (_t43 = v__ast__Table_convert_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__SumType).concrete_types), _t43.state == 0) { v__ast__Type rt = *(v__ast__Type*)_t43.data; method.return_type = rt; } } method.params = array_clone_to_depth(&method.params, 0); for (int _t44 = 0; _t44 < method.params.len; ++_t44) { v__ast__Param* param = ((v__ast__Param*)method.params.data) + _t44; _option_v__ast__Type _t45; if (_t45 = v__ast__Table_convert_generic_type(table, param->typ, generic_names, (*t->info._v__ast__SumType).concrete_types), _t45.state == 0) { v__ast__Type pt = *(v__ast__Type*)_t45.data; param->typ = pt; } } _option_v__ast__Fn _t46; _option_ok(&(v__ast__Fn[]) { method }, (_option*)(&_t46), sizeof(v__ast__Fn)); return _t46; } else { } } } } else if (t->info._typ == 544 /* v.ast.SumType */) { if (v__ast__Type_has_flag((*t->info._v__ast__SumType).parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(table, (*t->info._v__ast__SumType).parent_type); _option_v__ast__Fn _t47; if (_t47 = v__ast__TypeSymbol_find_method(parent_sym, name), _t47.state == 0) { v__ast__Fn x = *(v__ast__Fn*)_t47.data; if (parent_sym->info._typ == 518 /* v.ast.Struct */) { v__ast__Fn method = x; Array_string _t48 = {0}; Array_v__ast__Type _t48_orig = (*parent_sym->info._v__ast__Struct).generic_types; int _t48_len = _t48_orig.len; _t48 = __new_array(0, _t48_len, sizeof(string)); for (int _t50 = 0; _t50 < _t48_len; ++_t50) { v__ast__Type it = ((v__ast__Type*) _t48_orig.data)[_t50]; string _t49 = v__ast__Table_sym(table, it)->name; array_push((array*)&_t48, &_t49); } Array_string generic_names =_t48; v__ast__TypeSymbol* return_sym = v__ast__Table_sym(table, method.return_type); if (return_sym->kind == v__ast__Kind__struct || return_sym->kind == v__ast__Kind__interface || return_sym->kind == v__ast__Kind__sum_type) { method.return_type = v__ast__Table_unwrap_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Struct).concrete_types); } else { _option_v__ast__Type _t51; if (_t51 = v__ast__Table_convert_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Struct).concrete_types), _t51.state == 0) { v__ast__Type rt = *(v__ast__Type*)_t51.data; method.return_type = rt; } } method.params = array_clone_to_depth(&method.params, 0); for (int _t52 = 0; _t52 < method.params.len; ++_t52) { v__ast__Param* param = ((v__ast__Param*)method.params.data) + _t52; _option_v__ast__Type _t53; if (_t53 = v__ast__Table_convert_generic_type(table, param->typ, generic_names, (*t->info._v__ast__Struct).concrete_types), _t53.state == 0) { v__ast__Type pt = *(v__ast__Type*)_t53.data; param->typ = pt; } } _option_v__ast__Fn _t54; _option_ok(&(v__ast__Fn[]) { method }, (_option*)(&_t54), sizeof(v__ast__Fn)); return _t54; } else if (parent_sym->info._typ == 542 /* v.ast.Interface */) { v__ast__Fn method = x; Array_string _t55 = {0}; Array_v__ast__Type _t55_orig = (*parent_sym->info._v__ast__Interface).generic_types; int _t55_len = _t55_orig.len; _t55 = __new_array(0, _t55_len, sizeof(string)); for (int _t57 = 0; _t57 < _t55_len; ++_t57) { v__ast__Type it = ((v__ast__Type*) _t55_orig.data)[_t57]; string _t56 = v__ast__Table_sym(table, it)->name; array_push((array*)&_t55, &_t56); } Array_string generic_names =_t55; v__ast__TypeSymbol* return_sym = v__ast__Table_sym(table, method.return_type); if (return_sym->kind == v__ast__Kind__struct || return_sym->kind == v__ast__Kind__interface || return_sym->kind == v__ast__Kind__sum_type) { method.return_type = v__ast__Table_unwrap_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Interface).concrete_types); } else { _option_v__ast__Type _t58; if (_t58 = v__ast__Table_convert_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__Interface).concrete_types), _t58.state == 0) { v__ast__Type rt = *(v__ast__Type*)_t58.data; method.return_type = rt; } } method.params = array_clone_to_depth(&method.params, 0); for (int _t59 = 0; _t59 < method.params.len; ++_t59) { v__ast__Param* param = ((v__ast__Param*)method.params.data) + _t59; _option_v__ast__Type _t60; if (_t60 = v__ast__Table_convert_generic_type(table, param->typ, generic_names, (*t->info._v__ast__Interface).concrete_types), _t60.state == 0) { v__ast__Type pt = *(v__ast__Type*)_t60.data; param->typ = pt; } } _option_v__ast__Fn _t61; _option_ok(&(v__ast__Fn[]) { method }, (_option*)(&_t61), sizeof(v__ast__Fn)); return _t61; } else if (parent_sym->info._typ == 544 /* v.ast.SumType */) { v__ast__Fn method = x; Array_string _t62 = {0}; Array_v__ast__Type _t62_orig = (*parent_sym->info._v__ast__SumType).generic_types; int _t62_len = _t62_orig.len; _t62 = __new_array(0, _t62_len, sizeof(string)); for (int _t64 = 0; _t64 < _t62_len; ++_t64) { v__ast__Type it = ((v__ast__Type*) _t62_orig.data)[_t64]; string _t63 = v__ast__Table_sym(table, it)->name; array_push((array*)&_t62, &_t63); } Array_string generic_names =_t62; v__ast__TypeSymbol* return_sym = v__ast__Table_sym(table, method.return_type); if (return_sym->kind == v__ast__Kind__struct || return_sym->kind == v__ast__Kind__interface || return_sym->kind == v__ast__Kind__sum_type) { method.return_type = v__ast__Table_unwrap_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__SumType).concrete_types); } else { _option_v__ast__Type _t65; if (_t65 = v__ast__Table_convert_generic_type(table, method.return_type, generic_names, (*t->info._v__ast__SumType).concrete_types), _t65.state == 0) { v__ast__Type rt = *(v__ast__Type*)_t65.data; method.return_type = rt; } } method.params = array_clone_to_depth(&method.params, 0); for (int _t66 = 0; _t66 < method.params.len; ++_t66) { v__ast__Param* param = ((v__ast__Param*)method.params.data) + _t66; _option_v__ast__Type _t67; if (_t67 = v__ast__Table_convert_generic_type(table, param->typ, generic_names, (*t->info._v__ast__SumType).concrete_types), _t67.state == 0) { v__ast__Type pt = *(v__ast__Type*)_t67.data; param->typ = pt; } } _option_v__ast__Fn _t68; _option_ok(&(v__ast__Fn[]) { method }, (_option*)(&_t68), sizeof(v__ast__Fn)); return _t68; } else { } } } } else { } return (_option_v__ast__Fn){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } bool v__ast__TypeSymbol_is_js_compatible(v__ast__TypeSymbol* t) { v__ast__Table* table = global_table; if (t->kind == v__ast__Kind__void) { return true; } if (t->kind == v__ast__Kind__function) { return true; } if (t->language == v__ast__Language__js || string_starts_with(t->name, _S("JS."))) { return true; } if (t->info._typ == 544 /* v.ast.SumType */) { for (int _t4 = 0; _t4 < (*t->info._v__ast__SumType).variants.len; ++_t4) { v__ast__Type variant = ((v__ast__Type*)(*t->info._v__ast__SumType).variants.data)[_t4]; v__ast__TypeSymbol* sym = v__ast__Table_final_sym(table, variant); if (!v__ast__TypeSymbol_is_js_compatible(sym)) { return false; } } return true; } else { return true; } return 0; } multi_return_bool_bool_int v__ast__TypeSymbol_str_method_info(v__ast__TypeSymbol* t) { bool has_str_method = false; bool expects_ptr = false; int nr_args = 0; _option_v__ast__Fn _t1; if (_t1 = v__ast__TypeSymbol_find_method_with_generic_parent(t, _S("str")), _t1.state == 0) { v__ast__Fn sym_str_method = *(v__ast__Fn*)_t1.data; has_str_method = t->kind != v__ast__Kind__interface || !sym_str_method.no_body; nr_args = sym_str_method.params.len; if (nr_args > 0) { expects_ptr = v__ast__Type_is_ptr((*(v__ast__Param*)array_get(sym_str_method.params, 0)).typ); } } else { IError err = _t1.err; expects_ptr = v__ast__TypeSymbol_is_c_struct(t); } return (multi_return_bool_bool_int){.arg0=has_str_method, .arg1=expects_ptr, .arg2=nr_args}; } _option_v__ast__StructField v__ast__TypeSymbol_find_field(v__ast__TypeSymbol* t, string name) { if (t->info._typ == 518 /* v.ast.Struct */) { return v__ast__Struct_find_field((*t->info._v__ast__Struct), name); } else if (t->info._typ == 542 /* v.ast.Interface */) { return v__ast__Interface_find_field(&(*t->info._v__ast__Interface), name); } else if (t->info._typ == 544 /* v.ast.SumType */) { return v__ast__SumType_find_sum_type_field(&(*t->info._v__ast__SumType), name); } else if (t->info._typ == 537 /* v.ast.Aggregate */) { return v__ast__Aggregate_find_field(&(*t->info._v__ast__Aggregate), name); } else { return (_option_v__ast__StructField){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } return (_option_v__ast__StructField){.state=2, .err=_const_none__, .data={E_STRUCT}}; } bool v__ast__TypeSymbol_has_field(v__ast__TypeSymbol* t, string name) { _option_v__ast__StructField _t1 = v__ast__TypeSymbol_find_field(t, name); if (_t1.state != 0) { IError err = _t1.err; return false; } ; return true; } VV_LOC _option_v__ast__StructField v__ast__Aggregate_find_field(v__ast__Aggregate* a, string name) { Array_v__ast__StructField _t1 = a->fields; for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__ast__StructField* field = ((v__ast__StructField*)_t1.data) + _t2; if (field->name.len == name.len && string__eq(field->name, name)) { _option_v__ast__StructField _t3; _option_ok(&(v__ast__StructField[]) { *field }, (_option*)(&_t3), sizeof(v__ast__StructField)); return _t3; } } return (_option_v__ast__StructField){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__StructField v__ast__Interface_find_field(v__ast__Interface* i, string name) { Array_v__ast__StructField _t1 = i->fields; for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__ast__StructField* field = ((v__ast__StructField*)_t1.data) + _t2; if (field->name.len == name.len && string__eq(field->name, name)) { _option_v__ast__StructField _t3; _option_ok(&(v__ast__StructField[]) { *field }, (_option*)(&_t3), sizeof(v__ast__StructField)); return _t3; } } return (_option_v__ast__StructField){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } bool v__ast__Interface_has_method(v__ast__Interface* i, string name) { Array_v__ast__Fn _t1 = i->methods; for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__ast__Fn* method = ((v__ast__Fn*)_t1.data) + _t2; if (method->name.len == name.len && string__eq(method->name, name)) { return true; } } return false; } _option_v__ast__StructField v__ast__Struct_find_field(v__ast__Struct s, string name) { Array_v__ast__StructField _t1 = s.fields; for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__ast__StructField* field = ((v__ast__StructField*)_t1.data) + _t2; if (name.len == field->name.len && string__eq(field->name, name)) { _option_v__ast__StructField _t3; _option_ok(&(v__ast__StructField[]) { *field }, (_option*)(&_t3), sizeof(v__ast__StructField)); return _t3; } } return (_option_v__ast__StructField){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__StructField v__ast__SumType_find_sum_type_field(v__ast__SumType* s, string name) { Array_v__ast__StructField _t1 = s->fields; for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__ast__StructField* field = ((v__ast__StructField*)_t1.data) + _t2; if (string__eq(field->name, name)) { _option_v__ast__StructField _t3; _option_ok(&(v__ast__StructField[]) { *field }, (_option*)(&_t3), sizeof(v__ast__StructField)); return _t3; } } return (_option_v__ast__StructField){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } string v__ast__Table_find_missing_variants(v__ast__Table* t, v__ast__SumType* s, string field_name) { Array_string res = __new_array_with_default(0, 5, sizeof(string), 0); for (int _t1 = 0; _t1 < s->variants.len; ++_t1) { v__ast__Type variant = ((v__ast__Type*)s->variants.data)[_t1]; v__ast__TypeSymbol* ts = v__ast__Table_sym(t, variant); if (ts->kind != v__ast__Kind__struct) { continue; } bool found = false; v__ast__Struct struct_info = *(v__ast__Struct*)__as_cast((ts->info)._v__ast__Struct,(ts->info)._typ, 518); for (int _t2 = 0; _t2 < struct_info.fields.len; ++_t2) { v__ast__StructField field = ((v__ast__StructField*)struct_info.fields.data)[_t2]; if (string__eq(field.name, field_name)) { found = true; break; } } if (!found) { array_push((array*)&res, _MOV((string[]){ string_clone(ts->name) })); } } string str = Array_string_join(res, _S(", ")); return string_replace(str, _S("'"), _S("`")); } bool v__ast__Interface_defines_method(v__ast__Interface i, string name) { bool _t1 = false; Array_v__ast__Fn _t1_orig = i.methods; int _t1_len = _t1_orig.len; for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__Fn it = ((v__ast__Fn*) _t1_orig.data)[_t2]; if (string__eq(it.name, name)) { _t1 = true; break; } } if (_t1) { return true; } if (v__ast__Type_has_flag(i.parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(global_table, i.parent_type); v__ast__Interface parent_info = *(v__ast__Interface*)__as_cast((parent_sym->info)._v__ast__Interface,(parent_sym->info)._typ, 542); bool _t4 = false; Array_v__ast__Fn _t4_orig = parent_info.methods; int _t4_len = _t4_orig.len; for (int _t5 = 0; _t5 < _t4_len; ++_t5) { v__ast__Fn it = ((v__ast__Fn*) _t4_orig.data)[_t5]; if (string__eq(it.name, name)) { _t4 = true; break; } } if (_t4) { return true; } } return false; } Array_string v__ast__Interface_get_methods(v__ast__Interface i) { if (i.methods.len > 0) { Array_string _t2 = {0}; Array_v__ast__Fn _t2_orig = i.methods; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Fn it = ((v__ast__Fn*) _t2_orig.data)[_t4]; string _t3 = it.name; array_push((array*)&_t2, &_t3); } return _t2; } if (v__ast__Type_has_flag(i.parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(global_table, i.parent_type); v__ast__Interface parent_info = *(v__ast__Interface*)__as_cast((parent_sym->info)._v__ast__Interface,(parent_sym->info)._typ, 542); Array_string _t6 = {0}; Array_v__ast__Fn _t6_orig = parent_info.methods; int _t6_len = _t6_orig.len; _t6 = __new_array(0, _t6_len, sizeof(string)); for (int _t8 = 0; _t8 < _t6_len; ++_t8) { v__ast__Fn it = ((v__ast__Fn*) _t6_orig.data)[_t8]; string _t7 = it.name; array_push((array*)&_t6, &_t7); } return _t6; } return __new_array_with_default(0, 0, sizeof(string), 0); } Array_v__ast__Fn v__ast__TypeSymbol_get_methods(v__ast__TypeSymbol* t) { Array_v__ast__Fn _t1 = {0}; Array_v__ast__Fn _t1_orig = t->methods; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Fn)); for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__Fn it = ((v__ast__Fn*) _t1_orig.data)[_t2]; if (it.attrs.len == 0) { array_push((array*)&_t1, &it); } } Array_v__ast__Fn methods =_t1; Array_v__ast__Fn _t3 = {0}; Array_v__ast__Fn _t3_orig = t->methods; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__Fn)); for (int _t4 = 0; _t4 < _t3_len; ++_t4) { v__ast__Fn it = ((v__ast__Fn*) _t3_orig.data)[_t4]; if (it.attrs.len > 0) { array_push((array*)&_t3, &it); } } Array_v__ast__Fn methods_with_attrs =_t3; if (t->info._typ == 518 /* v.ast.Struct */) { if (v__ast__Type_has_flag((*t->info._v__ast__Struct).parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(global_table, (*t->info._v__ast__Struct).parent_type); if (parent_sym->info._typ == 518 /* v.ast.Struct */) { Array_v__ast__Fn parent_methods = parent_sym->methods; if (parent_methods.len > 0) { Array_v__ast__Fn _t6 = {0}; Array_v__ast__Fn _t6_orig = parent_methods; int _t6_len = _t6_orig.len; _t6 = __new_array(0, _t6_len, sizeof(v__ast__Fn)); for (int _t7 = 0; _t7 < _t6_len; ++_t7) { v__ast__Fn it = ((v__ast__Fn*) _t6_orig.data)[_t7]; if (it.attrs.len == 0) { array_push((array*)&_t6, &it); } } _PUSH_MANY(&methods, (_t6), _t5, Array_v__ast__Fn); Array_v__ast__Fn _t9 = {0}; Array_v__ast__Fn _t9_orig = parent_methods; int _t9_len = _t9_orig.len; _t9 = __new_array(0, _t9_len, sizeof(v__ast__Fn)); for (int _t10 = 0; _t10 < _t9_len; ++_t10) { v__ast__Fn it = ((v__ast__Fn*) _t9_orig.data)[_t10]; if (it.attrs.len > 0) { array_push((array*)&_t9, &it); } } _PUSH_MANY(&methods_with_attrs, (_t9), _t8, Array_v__ast__Fn); } } else if (parent_sym->info._typ == 542 /* v.ast.Interface */) { Array_v__ast__Fn parent_methods = parent_sym->methods; if (parent_methods.len > 0) { Array_v__ast__Fn _t12 = {0}; Array_v__ast__Fn _t12_orig = parent_methods; int _t12_len = _t12_orig.len; _t12 = __new_array(0, _t12_len, sizeof(v__ast__Fn)); for (int _t13 = 0; _t13 < _t12_len; ++_t13) { v__ast__Fn it = ((v__ast__Fn*) _t12_orig.data)[_t13]; if (it.attrs.len == 0) { array_push((array*)&_t12, &it); } } _PUSH_MANY(&methods, (_t12), _t11, Array_v__ast__Fn); Array_v__ast__Fn _t15 = {0}; Array_v__ast__Fn _t15_orig = parent_methods; int _t15_len = _t15_orig.len; _t15 = __new_array(0, _t15_len, sizeof(v__ast__Fn)); for (int _t16 = 0; _t16 < _t15_len; ++_t16) { v__ast__Fn it = ((v__ast__Fn*) _t15_orig.data)[_t16]; if (it.attrs.len > 0) { array_push((array*)&_t15, &it); } } _PUSH_MANY(&methods_with_attrs, (_t15), _t14, Array_v__ast__Fn); } } else if (parent_sym->info._typ == 544 /* v.ast.SumType */) { Array_v__ast__Fn parent_methods = parent_sym->methods; if (parent_methods.len > 0) { Array_v__ast__Fn _t18 = {0}; Array_v__ast__Fn _t18_orig = parent_methods; int _t18_len = _t18_orig.len; _t18 = __new_array(0, _t18_len, sizeof(v__ast__Fn)); for (int _t19 = 0; _t19 < _t18_len; ++_t19) { v__ast__Fn it = ((v__ast__Fn*) _t18_orig.data)[_t19]; if (it.attrs.len == 0) { array_push((array*)&_t18, &it); } } _PUSH_MANY(&methods, (_t18), _t17, Array_v__ast__Fn); Array_v__ast__Fn _t21 = {0}; Array_v__ast__Fn _t21_orig = parent_methods; int _t21_len = _t21_orig.len; _t21 = __new_array(0, _t21_len, sizeof(v__ast__Fn)); for (int _t22 = 0; _t22 < _t21_len; ++_t22) { v__ast__Fn it = ((v__ast__Fn*) _t21_orig.data)[_t22]; if (it.attrs.len > 0) { array_push((array*)&_t21, &it); } } _PUSH_MANY(&methods_with_attrs, (_t21), _t20, Array_v__ast__Fn); } } else { } } } else if (t->info._typ == 542 /* v.ast.Interface */) { if (v__ast__Type_has_flag((*t->info._v__ast__Interface).parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(global_table, (*t->info._v__ast__Interface).parent_type); if (parent_sym->info._typ == 518 /* v.ast.Struct */) { Array_v__ast__Fn parent_methods = parent_sym->methods; if (parent_methods.len > 0) { Array_v__ast__Fn _t24 = {0}; Array_v__ast__Fn _t24_orig = parent_methods; int _t24_len = _t24_orig.len; _t24 = __new_array(0, _t24_len, sizeof(v__ast__Fn)); for (int _t25 = 0; _t25 < _t24_len; ++_t25) { v__ast__Fn it = ((v__ast__Fn*) _t24_orig.data)[_t25]; if (it.attrs.len == 0) { array_push((array*)&_t24, &it); } } _PUSH_MANY(&methods, (_t24), _t23, Array_v__ast__Fn); Array_v__ast__Fn _t27 = {0}; Array_v__ast__Fn _t27_orig = parent_methods; int _t27_len = _t27_orig.len; _t27 = __new_array(0, _t27_len, sizeof(v__ast__Fn)); for (int _t28 = 0; _t28 < _t27_len; ++_t28) { v__ast__Fn it = ((v__ast__Fn*) _t27_orig.data)[_t28]; if (it.attrs.len > 0) { array_push((array*)&_t27, &it); } } _PUSH_MANY(&methods_with_attrs, (_t27), _t26, Array_v__ast__Fn); } } else if (parent_sym->info._typ == 542 /* v.ast.Interface */) { Array_v__ast__Fn parent_methods = parent_sym->methods; if (parent_methods.len > 0) { Array_v__ast__Fn _t30 = {0}; Array_v__ast__Fn _t30_orig = parent_methods; int _t30_len = _t30_orig.len; _t30 = __new_array(0, _t30_len, sizeof(v__ast__Fn)); for (int _t31 = 0; _t31 < _t30_len; ++_t31) { v__ast__Fn it = ((v__ast__Fn*) _t30_orig.data)[_t31]; if (it.attrs.len == 0) { array_push((array*)&_t30, &it); } } _PUSH_MANY(&methods, (_t30), _t29, Array_v__ast__Fn); Array_v__ast__Fn _t33 = {0}; Array_v__ast__Fn _t33_orig = parent_methods; int _t33_len = _t33_orig.len; _t33 = __new_array(0, _t33_len, sizeof(v__ast__Fn)); for (int _t34 = 0; _t34 < _t33_len; ++_t34) { v__ast__Fn it = ((v__ast__Fn*) _t33_orig.data)[_t34]; if (it.attrs.len > 0) { array_push((array*)&_t33, &it); } } _PUSH_MANY(&methods_with_attrs, (_t33), _t32, Array_v__ast__Fn); } } else if (parent_sym->info._typ == 544 /* v.ast.SumType */) { Array_v__ast__Fn parent_methods = parent_sym->methods; if (parent_methods.len > 0) { Array_v__ast__Fn _t36 = {0}; Array_v__ast__Fn _t36_orig = parent_methods; int _t36_len = _t36_orig.len; _t36 = __new_array(0, _t36_len, sizeof(v__ast__Fn)); for (int _t37 = 0; _t37 < _t36_len; ++_t37) { v__ast__Fn it = ((v__ast__Fn*) _t36_orig.data)[_t37]; if (it.attrs.len == 0) { array_push((array*)&_t36, &it); } } _PUSH_MANY(&methods, (_t36), _t35, Array_v__ast__Fn); Array_v__ast__Fn _t39 = {0}; Array_v__ast__Fn _t39_orig = parent_methods; int _t39_len = _t39_orig.len; _t39 = __new_array(0, _t39_len, sizeof(v__ast__Fn)); for (int _t40 = 0; _t40 < _t39_len; ++_t40) { v__ast__Fn it = ((v__ast__Fn*) _t39_orig.data)[_t40]; if (it.attrs.len > 0) { array_push((array*)&_t39, &it); } } _PUSH_MANY(&methods_with_attrs, (_t39), _t38, Array_v__ast__Fn); } } else { } } } else if (t->info._typ == 544 /* v.ast.SumType */) { if (v__ast__Type_has_flag((*t->info._v__ast__SumType).parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(global_table, (*t->info._v__ast__SumType).parent_type); if (parent_sym->info._typ == 518 /* v.ast.Struct */) { Array_v__ast__Fn parent_methods = parent_sym->methods; if (parent_methods.len > 0) { Array_v__ast__Fn _t42 = {0}; Array_v__ast__Fn _t42_orig = parent_methods; int _t42_len = _t42_orig.len; _t42 = __new_array(0, _t42_len, sizeof(v__ast__Fn)); for (int _t43 = 0; _t43 < _t42_len; ++_t43) { v__ast__Fn it = ((v__ast__Fn*) _t42_orig.data)[_t43]; if (it.attrs.len == 0) { array_push((array*)&_t42, &it); } } _PUSH_MANY(&methods, (_t42), _t41, Array_v__ast__Fn); Array_v__ast__Fn _t45 = {0}; Array_v__ast__Fn _t45_orig = parent_methods; int _t45_len = _t45_orig.len; _t45 = __new_array(0, _t45_len, sizeof(v__ast__Fn)); for (int _t46 = 0; _t46 < _t45_len; ++_t46) { v__ast__Fn it = ((v__ast__Fn*) _t45_orig.data)[_t46]; if (it.attrs.len > 0) { array_push((array*)&_t45, &it); } } _PUSH_MANY(&methods_with_attrs, (_t45), _t44, Array_v__ast__Fn); } } else if (parent_sym->info._typ == 542 /* v.ast.Interface */) { Array_v__ast__Fn parent_methods = parent_sym->methods; if (parent_methods.len > 0) { Array_v__ast__Fn _t48 = {0}; Array_v__ast__Fn _t48_orig = parent_methods; int _t48_len = _t48_orig.len; _t48 = __new_array(0, _t48_len, sizeof(v__ast__Fn)); for (int _t49 = 0; _t49 < _t48_len; ++_t49) { v__ast__Fn it = ((v__ast__Fn*) _t48_orig.data)[_t49]; if (it.attrs.len == 0) { array_push((array*)&_t48, &it); } } _PUSH_MANY(&methods, (_t48), _t47, Array_v__ast__Fn); Array_v__ast__Fn _t51 = {0}; Array_v__ast__Fn _t51_orig = parent_methods; int _t51_len = _t51_orig.len; _t51 = __new_array(0, _t51_len, sizeof(v__ast__Fn)); for (int _t52 = 0; _t52 < _t51_len; ++_t52) { v__ast__Fn it = ((v__ast__Fn*) _t51_orig.data)[_t52]; if (it.attrs.len > 0) { array_push((array*)&_t51, &it); } } _PUSH_MANY(&methods_with_attrs, (_t51), _t50, Array_v__ast__Fn); } } else if (parent_sym->info._typ == 544 /* v.ast.SumType */) { Array_v__ast__Fn parent_methods = parent_sym->methods; if (parent_methods.len > 0) { Array_v__ast__Fn _t54 = {0}; Array_v__ast__Fn _t54_orig = parent_methods; int _t54_len = _t54_orig.len; _t54 = __new_array(0, _t54_len, sizeof(v__ast__Fn)); for (int _t55 = 0; _t55 < _t54_len; ++_t55) { v__ast__Fn it = ((v__ast__Fn*) _t54_orig.data)[_t55]; if (it.attrs.len == 0) { array_push((array*)&_t54, &it); } } _PUSH_MANY(&methods, (_t54), _t53, Array_v__ast__Fn); Array_v__ast__Fn _t57 = {0}; Array_v__ast__Fn _t57_orig = parent_methods; int _t57_len = _t57_orig.len; _t57 = __new_array(0, _t57_len, sizeof(v__ast__Fn)); for (int _t58 = 0; _t58 < _t57_len; ++_t58) { v__ast__Fn it = ((v__ast__Fn*) _t57_orig.data)[_t58]; if (it.attrs.len > 0) { array_push((array*)&_t57, &it); } } _PUSH_MANY(&methods_with_attrs, (_t57), _t56, Array_v__ast__Fn); } } else { } } } else { } _PUSH_MANY(&methods, (methods_with_attrs), _t59, Array_v__ast__Fn); return methods; } VV_LOC bool v__transformer__IndexState_safe_access(v__transformer__IndexState* i, string key, int __v_new) { #if defined(CUSTOM_DEFINE_no_bounds_checking) { return false; } #endif if (i->disabled) { return false; } int* _t5 = (int*)(map_get_check(ADDR(map, i->max_index), &(string[]){key})); _option_int _t4 = {0}; if (_t5) { *((int*)&_t4.data) = *((int*)_t5); } else { _t4.state = 2; _t4.err = _v_error(_S("map key does not exist")); } ; if (_t4.state != 0) { IError err = _t4.err; ; map_set(&i->max_index, &(string[]){key}, &(int[]) { __v_new }); return false; } int old = (*(int*)_t4.data); if (__v_new > old) { if (old < -1) { ; return false; } ; map_set(&i->max_index, &(string[]){key}, &(int[]) { __v_new }); return false; } ; return true; } VV_LOC int v__transformer__IndexState_safe_offset(v__transformer__IndexState* i, string key) { #if defined(CUSTOM_DEFINE_no_bounds_checking) { return -2; } #endif if (i->disabled) { return -2; } int* _t6 = (int*)(map_get_check(ADDR(map, i->max_index), &(string[]){key})); _option_int _t5 = {0}; if (_t6) { *((int*)&_t5.data) = *((int*)_t6); } else { _t5.state = 2; _t5.err = _v_error(_S("map key does not exist")); } ; if (_t5.state != 0) { IError err = _t5.err; *(int*) _t5.data = -1; } return (*(int*)_t5.data); } VV_LOC void v__transformer__IndexState_indent(v__transformer__IndexState* i, bool is_function) { Array_v__transformer__KeyVal kvs = __new_array_with_default(0, i->max_index.len, sizeof(v__transformer__KeyVal), 0); Map_string_int _t1 = i->max_index; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string k = *(string*)DenseArray_key(&_t1.key_values, _t2); k = string_clone(k); int v = (*(int*)DenseArray_value(&_t1.key_values, _t2)); array_push((array*)&kvs, _MOV((v__transformer__KeyVal[]){ ((v__transformer__KeyVal){.key = k,.value = v,}) })); } array_push((array*)&i->saved_disabled, _MOV((bool[]){ i->disabled })); array_push((array*)&i->saved_key_vals, &kvs); if (is_function) { i->disabled = false; } i->level += 1; } VV_LOC void v__transformer__IndexState_unindent(v__transformer__IndexState* i) { i->level -= 1; Array_string keys = __new_array_with_default(0, i->max_index.len, sizeof(string), 0); Map_string_int _t1 = i->max_index; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string k = *(string*)DenseArray_key(&_t1.key_values, _t2); k = string_clone(k); array_push((array*)&keys, _MOV((string[]){ string_clone(k) })); } for (int _t6 = 0; _t6 < keys.len; ++_t6) { string k = ((string*)keys.data)[_t6]; map_delete(&i->max_index, &(string[]){k}); } Array_v__transformer__KeyVal _t7 = (*(Array_v__transformer__KeyVal*)array_pop(&i->saved_key_vals)); for (int _t8 = 0; _t8 < _t7.len; ++_t8) { v__transformer__KeyVal saved = ((v__transformer__KeyVal*)_t7.data)[_t8]; map_set(&i->max_index, &(string[]){saved.key}, &(int[]) { saved.value }); } i->disabled = (*(bool*)array_pop(&i->saved_disabled)); } v__transformer__Transformer* v__transformer__new_transformer(v__pref__Preferences* pref_) { return ((v__transformer__Transformer*)memdup(&(v__transformer__Transformer){.pref = pref_,.index = ((v__transformer__IndexState*)memdup(&(v__transformer__IndexState){.max_index = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.saved_disabled = __new_array_with_default(0, 1000, sizeof(bool), 0),.saved_key_vals = __new_array_with_default(0, 1000, sizeof(Array_v__transformer__KeyVal), 0),.disabled = 0,.level = 0,}, sizeof(v__transformer__IndexState))),.table = ((void*)0),.file = ((void*)0),.is_assert = 0,.inside_dump = 0,.strings_builder_type = _const_v__ast__no_type,}, sizeof(v__transformer__Transformer))); } v__transformer__Transformer* v__transformer__new_transformer_with_table(v__ast__Table* table, v__pref__Preferences* pref_) { v__transformer__Transformer* transformer = v__transformer__new_transformer(pref_); transformer->table = table; return transformer; } void v__transformer__Transformer_transform_files(v__transformer__Transformer* t, Array_v__ast__File_ptr ast_files) { t->strings_builder_type = v__ast__Table_find_type(t->table, _S("strings.Builder")); for (int i = 0; i < ast_files.len; ++i) { v__ast__File* file = (*(v__ast__File**)array_get(ast_files, i)); v__transformer__Transformer_transform(t, file); } } void v__transformer__Transformer_transform(v__transformer__Transformer* t, v__ast__File* ast_file) { t->file = ast_file; for (int _t1 = 0; _t1 < ast_file->stmts.len; ++_t1) { v__ast__Stmt* stmt = ((v__ast__Stmt*)ast_file->stmts.data) + _t1; *stmt = v__transformer__Transformer_stmt(t, stmt); } } void v__transformer__Transformer_find_new_array_len(v__transformer__Transformer* t, v__ast__AssignStmt node) { if (!t->pref->is_prod) { return; } v__ast__Expr right = (*(v__ast__Expr*)array_get(node.right, 0)); if ((right)._typ == 338 /* v.ast.ArrayInit */) { v__ast__Expr left = (*(v__ast__Expr*)array_get(node.left, 0)); if ((left)._typ == 358 /* v.ast.Ident */) { if ((*left._v__ast__Ident).is_mut) { v__transformer__IndexState_safe_access(t->index, (*left._v__ast__Ident).name, -2); return; } if (!(*right._v__ast__ArrayInit).has_len) { v__transformer__IndexState_safe_access(t->index, (*left._v__ast__Ident).name, -1); return; } int len = ((int)(0)); v__ast__Expr value = (*right._v__ast__ArrayInit).len_expr; if ((value)._typ == 363 /* v.ast.IntegerLiteral */) { len = (int)(string_int((*value._v__ast__IntegerLiteral).val) + 1); } v__transformer__IndexState_safe_access(t->index, (*left._v__ast__Ident).name, len); } } } void v__transformer__Transformer_find_new_range(v__transformer__Transformer* t, v__ast__AssignStmt node) { if (!t->pref->is_prod) { return; } v__ast__Expr right = (*(v__ast__Expr*)array_get(node.right, 0)); if ((right)._typ == 361 /* v.ast.IndexExpr */) { v__ast__Expr left = (*(v__ast__Expr*)array_get(node.left, 0)); if ((left)._typ == 358 /* v.ast.Ident */) { if ((*left._v__ast__Ident).is_mut) { v__transformer__IndexState_safe_access(t->index, (*left._v__ast__Ident).name, -2); return; } v__ast__Expr index = (*right._v__ast__IndexExpr).index; if ((index)._typ == 377 /* v.ast.RangeExpr */) { v__ast__Expr range_low = (*index._v__ast__RangeExpr).low; if ((range_low)._typ == 363 /* v.ast.IntegerLiteral */) { v__ast__Expr sub_left = (*right._v__ast__IndexExpr).left; if ((sub_left)._typ == 358 /* v.ast.Ident */) { int safe = v__transformer__IndexState_safe_offset(t->index, (*sub_left._v__ast__Ident).name); int low = string_int((*range_low._v__ast__IntegerLiteral).val); if (safe >= low) { v__transformer__IndexState_safe_access(t->index, (*left._v__ast__Ident).name, (int)(safe - low)); } } } } } } } void v__transformer__Transformer_find_mut_self_assign(v__transformer__Transformer* t, v__ast__AssignStmt node) { if (!t->pref->is_prod) { return; } } void v__transformer__Transformer_check_safe_array(v__transformer__Transformer* t, v__ast__IndexExpr* node) { if (!t->pref->is_prod) { return; } if (!node->is_array) { return; } v__ast__Expr index = node->index; v__ast__Expr name = node->left; if (index._typ == 363 /* v.ast.IntegerLiteral */) { bool is_direct = v__transformer__IndexState_safe_access(t->index, v__ast__Expr_str(&name), string_int((*index._v__ast__IntegerLiteral).val)); node->is_direct = is_direct; } else if (index._typ == 377 /* v.ast.RangeExpr */) { if ((*index._v__ast__RangeExpr).has_high) { v__ast__Expr high = (*index._v__ast__RangeExpr).high; if ((high)._typ == 363 /* v.ast.IntegerLiteral */) { v__transformer__IndexState_safe_access(t->index, v__ast__Expr_str(&name), string_int((*high._v__ast__IntegerLiteral).val)); return; } } if ((*index._v__ast__RangeExpr).has_low) { v__ast__Expr low = (*index._v__ast__RangeExpr).low; if ((low)._typ == 363 /* v.ast.IntegerLiteral */) { v__transformer__IndexState_safe_access(t->index, v__ast__Expr_str(&name), string_int((*low._v__ast__IntegerLiteral).val)); return; } } } else if (index._typ == 345 /* v.ast.CastExpr */) { if (!fast_string_eq((*index._v__ast__CastExpr).typname, _S("int"))) { return; } v__ast__Expr index_expr = (*index._v__ast__CastExpr).expr; if ((index_expr)._typ == 363 /* v.ast.IntegerLiteral */) { string val = (*index_expr._v__ast__IntegerLiteral).val; node->is_direct = v__transformer__IndexState_safe_access(t->index, v__ast__Expr_str(&name), string_int(val)); } } else if (index._typ == 355 /* v.ast.EnumVal */) { ; } else if (index._typ == 358 /* v.ast.Ident */) { } else { } } v__ast__Stmt v__transformer__Transformer_stmt(v__transformer__Transformer* t, v__ast__Stmt* node) { #if defined(CUSTOM_DEFINE_trace_transformer) { string ntype = string_replace(charptr_vstring_literal(v_typeof_sumtype_v__ast__Stmt( (*node)._typ )), _S("v.ast."), _S("")); eprintln(str_intp(5, _MOV((StrIntpData[]){{_S("transformer: "), 0x64fe10, {.d_s = t->file->path}}, {_S(" | pos: "), 0x4efe10, {.d_s = v__token__Pos_line_str((*(node->pos)))}}, {_S(" | node: "), 0x18fe30, {.d_s = ntype}}, {_S(" | "), 0xfe10, {.d_s = v__ast__Stmt_str(*node)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__ast__Stmt* onode = node; if (node->_typ == 399 /* v.ast.EmptyStmt */) { } else if (node->_typ == 335 /* v.ast.NodeError */) { } else if (node->_typ == 390 /* v.ast.AsmStmt */) { } else if (node->_typ == 397 /* v.ast.DebuggerStmt */) { } else if (node->_typ == 391 /* v.ast.AssertStmt */) { return v__transformer__Transformer_assert_stmt(t, &/*mut*/(*node->_v__ast__AssertStmt)); } else if (node->_typ == 392 /* v.ast.AssignStmt */) { v__transformer__Transformer_find_new_array_len(t, (*node->_v__ast__AssignStmt)); v__transformer__Transformer_find_new_range(t, (*node->_v__ast__AssignStmt)); v__transformer__Transformer_find_mut_self_assign(t, (*node->_v__ast__AssignStmt)); for (int _t3 = 0; _t3 < (*node->_v__ast__AssignStmt).right.len; ++_t3) { v__ast__Expr* right = ((v__ast__Expr*)(*node->_v__ast__AssignStmt).right.data) + _t3; *right = v__transformer__Transformer_expr(t, right); } for (int _t4 = 0; _t4 < (*node->_v__ast__AssignStmt).left.len; ++_t4) { v__ast__Expr* left = ((v__ast__Expr*)(*node->_v__ast__AssignStmt).left.data) + _t4; *left = v__transformer__Transformer_expr(t, left); } } else if (node->_typ == 393 /* v.ast.Block */) { v__transformer__IndexState_indent(t->index, false); for (int _t5 = 0; _t5 < (*node->_v__ast__Block).stmts.len; ++_t5) { v__ast__Stmt* stmt = ((v__ast__Stmt*)(*node->_v__ast__Block).stmts.data) + _t5; *stmt = v__transformer__Transformer_stmt(t, stmt); } v__transformer__IndexState_unindent(t->index); } else if (node->_typ == 394 /* v.ast.BranchStmt */) { t->index->disabled = true; } else if (node->_typ == 395 /* v.ast.ComptimeFor */) { for (int _t6 = 0; _t6 < (*node->_v__ast__ComptimeFor).stmts.len; ++_t6) { v__ast__Stmt* stmt = ((v__ast__Stmt*)(*node->_v__ast__ComptimeFor).stmts.data) + _t6; *stmt = v__transformer__Transformer_stmt(t, stmt); } } else if (node->_typ == 396 /* v.ast.ConstDecl */) { for (int _t7 = 0; _t7 < (*node->_v__ast__ConstDecl).fields.len; ++_t7) { v__ast__ConstField* field = ((v__ast__ConstField*)(*node->_v__ast__ConstDecl).fields.data) + _t7; field->expr = v__transformer__Transformer_expr(t, &field->expr); } } else if (node->_typ == 398 /* v.ast.DeferStmt */) { for (int _t8 = 0; _t8 < (*node->_v__ast__DeferStmt).stmts.len; ++_t8) { v__ast__Stmt* stmt = ((v__ast__Stmt*)(*node->_v__ast__DeferStmt).stmts.data) + _t8; *stmt = v__transformer__Transformer_stmt(t, stmt); } } else if (node->_typ == 400 /* v.ast.EnumDecl */) { for (int _t9 = 0; _t9 < (*node->_v__ast__EnumDecl).fields.len; ++_t9) { v__ast__EnumField* field = ((v__ast__EnumField*)(*node->_v__ast__EnumDecl).fields.data) + _t9; if (field->has_expr) { field->expr = v__transformer__Transformer_expr(t, &field->expr); } } } else if (node->_typ == 401 /* v.ast.ExprStmt */) { v__ast__Expr _t10 = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}; if ((*node->_v__ast__ExprStmt).expr._typ == 359 /* v.ast.IfExpr */) { _t10 = v__transformer__Transformer_expr_stmt_if_expr(t, (voidptr)&(*(*node->_v__ast__ExprStmt).expr._v__ast__IfExpr)); } else if ((*node->_v__ast__ExprStmt).expr._typ == 369 /* v.ast.MatchExpr */) { _t10 = v__transformer__Transformer_expr_stmt_match_expr(t, (voidptr)&(*(*node->_v__ast__ExprStmt).expr._v__ast__MatchExpr)); } else { _t10 = v__transformer__Transformer_expr(t, &(*node->_v__ast__ExprStmt).expr); } (*node->_v__ast__ExprStmt).expr = _t10; if (((*node->_v__ast__ExprStmt).expr)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast(((*node->_v__ast__ExprStmt).expr)._v__ast__CallExpr,((*node->_v__ast__ExprStmt).expr)._typ, 344)).is_expand_simple_interpolation) { v__transformer__Transformer_simplify_nested_interpolation_in_sb(t, onode, (voidptr)&(*(*node->_v__ast__ExprStmt).expr._v__ast__CallExpr), (*node->_v__ast__ExprStmt).typ); } } else if (node->_typ == 237 /* v.ast.FnDecl */) { if (t->pref->trace_calls) { v__transformer__Transformer_fn_decl_trace_calls(t, &/*mut*/(*node->_v__ast__FnDecl)); } v__transformer__IndexState_indent(t->index, true); for (int _t11 = 0; _t11 < (*node->_v__ast__FnDecl).stmts.len; ++_t11) { v__ast__Stmt* stmt = ((v__ast__Stmt*)(*node->_v__ast__FnDecl).stmts.data) + _t11; *stmt = v__transformer__Transformer_stmt(t, stmt); } v__transformer__IndexState_unindent(t->index); } else if (node->_typ == 402 /* v.ast.ForCStmt */) { return v__transformer__Transformer_for_c_stmt(t, &/*mut*/(*node->_v__ast__ForCStmt)); } else if (node->_typ == 403 /* v.ast.ForInStmt */) { v__transformer__IndexState_indent(t->index, false); for (int _t13 = 0; _t13 < (*node->_v__ast__ForInStmt).stmts.len; ++_t13) { v__ast__Stmt* stmt = ((v__ast__Stmt*)(*node->_v__ast__ForInStmt).stmts.data) + _t13; *stmt = v__transformer__Transformer_stmt(t, stmt); } v__transformer__IndexState_unindent(t->index); } else if (node->_typ == 404 /* v.ast.ForStmt */) { return v__transformer__Transformer_for_stmt(t, &/*mut*/(*node->_v__ast__ForStmt)); } else if (node->_typ == 405 /* v.ast.GlobalDecl */) { for (int _t15 = 0; _t15 < (*node->_v__ast__GlobalDecl).fields.len; ++_t15) { v__ast__GlobalField* field = ((v__ast__GlobalField*)(*node->_v__ast__GlobalDecl).fields.data) + _t15; field->expr = v__transformer__Transformer_expr(t, &field->expr); } } else if (node->_typ == 406 /* v.ast.GotoLabel */) { } else if (node->_typ == 407 /* v.ast.GotoStmt */) { t->index->disabled = true; } else if (node->_typ == 408 /* v.ast.HashStmt */) { for (int _t16 = 0; _t16 < (*node->_v__ast__HashStmt).ct_conds.len; ++_t16) { v__ast__Expr* cond = ((v__ast__Expr*)(*node->_v__ast__HashStmt).ct_conds.data) + _t16; *cond = v__transformer__Transformer_expr(t, cond); } } else if (node->_typ == 409 /* v.ast.Import */) { } else if (node->_typ == 410 /* v.ast.InterfaceDecl */) { return v__transformer__Transformer_interface_decl(t, &/*mut*/(*node->_v__ast__InterfaceDecl)); } else if (node->_typ == 411 /* v.ast.Module */) { } else if (node->_typ == 412 /* v.ast.Return */) { for (int _t18 = 0; _t18 < (*node->_v__ast__Return).exprs.len; ++_t18) { v__ast__Expr* expr = ((v__ast__Expr*)(*node->_v__ast__Return).exprs.data) + _t18; *expr = v__transformer__Transformer_expr(t, expr); } } else if (node->_typ == 413 /* v.ast.SemicolonStmt */) { } else if (node->_typ == 414 /* v.ast.SqlStmt */) { } else if (node->_typ == 415 /* v.ast.StructDecl */) { for (int _t19 = 0; _t19 < (*node->_v__ast__StructDecl).fields.len; ++_t19) { v__ast__StructField* field = ((v__ast__StructField*)(*node->_v__ast__StructDecl).fields.data) + _t19; field->default_expr = v__transformer__Transformer_expr(t, &field->default_expr); } } else if (node->_typ == 334 /* v.ast.TypeDecl */) { } return *node; } v__ast__Stmt v__transformer__Transformer_assert_stmt(v__transformer__Transformer* t, v__ast__AssertStmt* node) { t->is_assert = true; node->expr = v__transformer__Transformer_expr(t, &node->expr); if (!t->pref->is_prod) { return v__ast__AssertStmt_to_sumtype_v__ast__Stmt(node); } if ((node->expr)._typ == 362 /* v.ast.InfixExpr */) { v__ast__Expr right = (*node->expr._v__ast__InfixExpr).right; if (right._typ == 363 /* v.ast.IntegerLiteral */) { v__ast__Expr left = (*node->expr._v__ast__InfixExpr).left; if ((left)._typ == 379 /* v.ast.SelectorExpr */) { int len = string_int((*right._v__ast__IntegerLiteral).val); if (fast_string_eq((*left._v__ast__SelectorExpr).field_name, _S("len"))) { if ((*node->expr._v__ast__InfixExpr).op == (v__token__Kind__eq)) { v__transformer__IndexState_safe_access(t->index, v__ast__Expr_str(&(*left._v__ast__SelectorExpr).expr), (int)(len - 1)); } else if ((*node->expr._v__ast__InfixExpr).op == (v__token__Kind__ge)) { v__transformer__IndexState_safe_access(t->index, v__ast__Expr_str(&(*left._v__ast__SelectorExpr).expr), (int)(len - 1)); } else if ((*node->expr._v__ast__InfixExpr).op == (v__token__Kind__gt)) { v__transformer__IndexState_safe_access(t->index, v__ast__Expr_str(&(*left._v__ast__SelectorExpr).expr), len); } else { } } } } else if (right._typ == 379 /* v.ast.SelectorExpr */) { v__ast__Expr left = (*node->expr._v__ast__InfixExpr).left; if ((left)._typ == 363 /* v.ast.IntegerLiteral */) { int len = string_int((*left._v__ast__IntegerLiteral).val); if (fast_string_eq((*right._v__ast__SelectorExpr).field_name, _S("len"))) { if ((*node->expr._v__ast__InfixExpr).op == (v__token__Kind__eq)) { v__transformer__IndexState_safe_access(t->index, v__ast__Expr_str(&(*right._v__ast__SelectorExpr).expr), (int)(len - 1)); } else if ((*node->expr._v__ast__InfixExpr).op == (v__token__Kind__le)) { v__transformer__IndexState_safe_access(t->index, v__ast__Expr_str(&(*right._v__ast__SelectorExpr).expr), (int)(len - 1)); } else if ((*node->expr._v__ast__InfixExpr).op == (v__token__Kind__lt)) { v__transformer__IndexState_safe_access(t->index, v__ast__Expr_str(&(*right._v__ast__SelectorExpr).expr), len); } else { } } } } else { } } t->is_assert = false; return v__ast__AssertStmt_to_sumtype_v__ast__Stmt(node); } v__ast__Expr v__transformer__Transformer_expr_stmt_if_expr(v__transformer__Transformer* t, v__ast__IfExpr* node) { int stop_index = -1; Array_int unreachable_branches = __new_array_with_default(0, node->branches.len, sizeof(int), 0); if (node->is_comptime) { return v__ast__IfExpr_to_sumtype_v__ast__Expr(node); } for (int i = 0; i < node->branches.len; ++i) { v__ast__IfBranch* branch = ((v__ast__IfBranch*)node->branches.data) + i; v__ast__Expr cond = v__transformer__Transformer_expr(t, &branch->cond); *branch = ((v__ast__IfBranch){.pos = ((*branch)).pos,.body_pos = ((*branch)).body_pos,.comments = ((*branch)).comments,.cond = cond,.pkg_exist = ((*branch)).pkg_exist,.stmts = ((*branch)).stmts,.scope = ((*branch)).scope,}); if ((cond)._typ == 342 /* v.ast.BoolLiteral */) { if ((*cond._v__ast__BoolLiteral).val) { stop_index = i; break; } else { array_push((array*)&unreachable_branches, _MOV((int[]){ i })); } } v__transformer__IndexState_indent(t->index, false); for (int _t3 = 0; _t3 < branch->stmts.len; ++_t3) { v__ast__Stmt* stmt = ((v__ast__Stmt*)branch->stmts.data) + _t3; *stmt = v__transformer__Transformer_stmt(t, stmt); } v__transformer__IndexState_unindent(t->index); } if (stop_index != -1) { Array_int _t4 = {0}; Array_int _t4_orig = unreachable_branches; int _t4_len = _t4_orig.len; _t4 = __new_array(0, _t4_len, sizeof(int)); for (int _t5 = 0; _t5 < _t4_len; ++_t5) { int it = ((int*) _t4_orig.data)[_t5]; if (it < stop_index) { array_push((array*)&_t4, &it); } } unreachable_branches =_t4; node->branches = array_slice(node->branches, 0, (int)(stop_index + 1)); } for (;;) { if (!(unreachable_branches.len != 0)) break; array_delete(&node->branches, (*(int*)array_pop(&unreachable_branches))); } if (node->branches.len == 1 && string__eq(charptr_vstring_literal(v_typeof_sumtype_v__ast__Expr( ((*(v__ast__IfBranch*)array_get(node->branches, 0)).cond)._typ )), _S("unknown v.ast.Expr"))) { (*(v__ast__IfBranch*)array_get(node->branches, 0)).cond = v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = true,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } return v__ast__IfExpr_to_sumtype_v__ast__Expr(node); } v__ast__Expr v__transformer__Transformer_expr_stmt_match_expr(v__transformer__Transformer* t, v__ast__MatchExpr* node) { bool terminate = false; v__ast__Expr cond = v__transformer__Transformer_expr(t, &node->cond); node->cond = cond; for (int _t1 = 0; _t1 < node->branches.len; ++_t1) { v__ast__MatchBranch* branch = ((v__ast__MatchBranch*)node->branches.data) + _t1; if (branch->is_else) { v__transformer__IndexState_indent(t->index, false); for (int _t2 = 0; _t2 < branch->stmts.len; ++_t2) { v__ast__Stmt* stmt = ((v__ast__Stmt*)branch->stmts.data) + _t2; *stmt = v__transformer__Transformer_stmt(t, stmt); } v__transformer__IndexState_unindent(t->index); continue; } for (int _t3 = 0; _t3 < branch->exprs.len; ++_t3) { v__ast__Expr* expr = ((v__ast__Expr*)branch->exprs.data) + _t3; *expr = v__transformer__Transformer_expr(t, expr); if (cond._typ == 342 /* v.ast.BoolLiteral */) { if ((expr)->_typ == 342 /* v.ast.BoolLiteral */) { if ((*cond._v__ast__BoolLiteral).val == (*expr->_v__ast__BoolLiteral).val) { branch->exprs = new_array_from_c_array(1, 1, sizeof(v__ast__Expr), _MOV((v__ast__Expr[1]){v__ast__BoolLiteral_to_sumtype_v__ast__Expr(&(*expr->_v__ast__BoolLiteral))})); node->branches = new_array_from_c_array(1, 1, sizeof(v__ast__MatchBranch), _MOV((v__ast__MatchBranch[1]){*branch})); terminate = true; } } } else if (cond._typ == 363 /* v.ast.IntegerLiteral */) { if ((expr)->_typ == 363 /* v.ast.IntegerLiteral */) { if (string_int((*cond._v__ast__IntegerLiteral).val) == string_int((*expr->_v__ast__IntegerLiteral).val)) { branch->exprs = new_array_from_c_array(1, 1, sizeof(v__ast__Expr), _MOV((v__ast__Expr[1]){v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(&(*expr->_v__ast__IntegerLiteral))})); node->branches = new_array_from_c_array(1, 1, sizeof(v__ast__MatchBranch), _MOV((v__ast__MatchBranch[1]){*branch})); terminate = true; } } } else if (cond._typ == 356 /* v.ast.FloatLiteral */) { if ((expr)->_typ == 356 /* v.ast.FloatLiteral */) { if (string_f32((*cond._v__ast__FloatLiteral).val) == string_f32((*expr->_v__ast__FloatLiteral).val)) { branch->exprs = new_array_from_c_array(1, 1, sizeof(v__ast__Expr), _MOV((v__ast__Expr[1]){v__ast__FloatLiteral_to_sumtype_v__ast__Expr(&(*expr->_v__ast__FloatLiteral))})); node->branches = new_array_from_c_array(1, 1, sizeof(v__ast__MatchBranch), _MOV((v__ast__MatchBranch[1]){*branch})); terminate = true; } } } else if (cond._typ == 384 /* v.ast.StringLiteral */) { if ((expr)->_typ == 384 /* v.ast.StringLiteral */) { if (string__eq((*cond._v__ast__StringLiteral).val, (*expr->_v__ast__StringLiteral).val)) { branch->exprs = new_array_from_c_array(1, 1, sizeof(v__ast__Expr), _MOV((v__ast__Expr[1]){v__ast__StringLiteral_to_sumtype_v__ast__Expr(&(*expr->_v__ast__StringLiteral))})); node->branches = new_array_from_c_array(1, 1, sizeof(v__ast__MatchBranch), _MOV((v__ast__MatchBranch[1]){*branch})); terminate = true; } } } else { } } v__transformer__IndexState_indent(t->index, false); for (int _t4 = 0; _t4 < branch->stmts.len; ++_t4) { v__ast__Stmt* stmt = ((v__ast__Stmt*)branch->stmts.data) + _t4; *stmt = v__transformer__Transformer_stmt(t, stmt); } v__transformer__IndexState_unindent(t->index); if (terminate) { break; } } return v__ast__MatchExpr_to_sumtype_v__ast__Expr(node); } v__ast__Stmt v__transformer__Transformer_for_c_stmt(v__transformer__Transformer* t, v__ast__ForCStmt* node) { if (node->has_init && !node->is_multi) { node->init = v__transformer__Transformer_stmt(t, &node->init); } if (node->has_cond) { node->cond = v__transformer__Transformer_expr(t, &node->cond); } v__transformer__IndexState_indent(t->index, false); for (int _t1 = 0; _t1 < node->stmts.len; ++_t1) { v__ast__Stmt* stmt = ((v__ast__Stmt*)node->stmts.data) + _t1; *stmt = v__transformer__Transformer_stmt(t, stmt); } v__transformer__IndexState_unindent(t->index); if (node->has_inc && !node->is_multi) { node->inc = v__transformer__Transformer_stmt(t, &node->inc); } return v__ast__ForCStmt_to_sumtype_v__ast__Stmt(node); } v__ast__Stmt v__transformer__Transformer_for_stmt(v__transformer__Transformer* t, v__ast__ForStmt* node) { node->cond = v__transformer__Transformer_expr(t, &node->cond); if (node->cond._typ == 342 /* v.ast.BoolLiteral */) { if (!(*(v__ast__BoolLiteral*)__as_cast((node->cond)._v__ast__BoolLiteral,(node->cond)._typ, 342)).val) { return _const_v__ast__empty_stmt; } } else { if (!node->is_inf) { v__transformer__IndexState_indent(t->index, false); for (int _t2 = 0; _t2 < node->stmts.len; ++_t2) { v__ast__Stmt* stmt = ((v__ast__Stmt*)node->stmts.data) + _t2; *stmt = v__transformer__Transformer_stmt(t, stmt); } v__transformer__IndexState_unindent(t->index); } } for (int _t3 = 0; _t3 < node->stmts.len; ++_t3) { v__ast__Stmt* stmt = ((v__ast__Stmt*)node->stmts.data) + _t3; *stmt = v__transformer__Transformer_stmt(t, stmt); } return v__ast__ForStmt_to_sumtype_v__ast__Stmt(node); } v__ast__Stmt v__transformer__Transformer_interface_decl(v__transformer__Transformer* t, v__ast__InterfaceDecl* node) { for (int _t1 = 0; _t1 < node->fields.len; ++_t1) { v__ast__StructField* field = ((v__ast__StructField*)node->fields.data) + _t1; field->default_expr = v__transformer__Transformer_expr(t, &field->default_expr); } return v__ast__InterfaceDecl_to_sumtype_v__ast__Stmt(node); } v__ast__Expr v__transformer__Transformer_expr(v__transformer__Transformer* t, v__ast__Expr* node) { if (t->inside_dump) { return *node; } if (node->_typ == 336 /* v.ast.AnonFn */) { (*node->_v__ast__AnonFn).decl = ({ v__ast__Stmt _t2 = v__transformer__Transformer_stmt(t, HEAP(v__ast__Stmt, v__ast__FnDecl_to_sumtype_v__ast__Stmt(&(*node->_v__ast__AnonFn).decl))); *(v__ast__FnDecl*)__as_cast(_t2._v__ast__FnDecl,_t2._typ, 237); }); } else if (node->_typ == 337 /* v.ast.ArrayDecompose */) { (*node->_v__ast__ArrayDecompose).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__ArrayDecompose).expr); } else if (node->_typ == 338 /* v.ast.ArrayInit */) { for (int _t3 = 0; _t3 < (*node->_v__ast__ArrayInit).exprs.len; ++_t3) { v__ast__Expr* expr = ((v__ast__Expr*)(*node->_v__ast__ArrayInit).exprs.data) + _t3; *expr = v__transformer__Transformer_expr(t, expr); } (*node->_v__ast__ArrayInit).len_expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__ArrayInit).len_expr); (*node->_v__ast__ArrayInit).cap_expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__ArrayInit).cap_expr); (*node->_v__ast__ArrayInit).init_expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__ArrayInit).init_expr); } else if (node->_typ == 339 /* v.ast.AsCast */) { (*node->_v__ast__AsCast).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__AsCast).expr); } else if (node->_typ == 343 /* v.ast.CTempVar */) { (*node->_v__ast__CTempVar).orig = v__transformer__Transformer_expr(t, &(*node->_v__ast__CTempVar).orig); } else if (node->_typ == 344 /* v.ast.CallExpr */) { (*node->_v__ast__CallExpr).left = v__transformer__Transformer_expr(t, &(*node->_v__ast__CallExpr).left); for (int _t4 = 0; _t4 < (*node->_v__ast__CallExpr).args.len; ++_t4) { v__ast__CallArg* arg = ((v__ast__CallArg*)(*node->_v__ast__CallExpr).args.data) + _t4; arg->expr = v__transformer__Transformer_expr(t, &arg->expr); } (*node->_v__ast__CallExpr).or_block = ({ v__ast__Expr _t5 = v__transformer__Transformer_expr(t, HEAP(v__ast__Expr, v__ast__OrExpr_to_sumtype_v__ast__Expr(&(*node->_v__ast__CallExpr).or_block))); *(v__ast__OrExpr*)__as_cast(_t5._v__ast__OrExpr,_t5._typ, 373); }); } else if (node->_typ == 345 /* v.ast.CastExpr */) { (*node->_v__ast__CastExpr).arg = v__transformer__Transformer_expr(t, &(*node->_v__ast__CastExpr).arg); (*node->_v__ast__CastExpr).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__CastExpr).expr); } else if (node->_typ == 346 /* v.ast.ChanInit */) { (*node->_v__ast__ChanInit).cap_expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__ChanInit).cap_expr); } else if (node->_typ == 349 /* v.ast.ComptimeCall */) { for (int _t6 = 0; _t6 < (*node->_v__ast__ComptimeCall).args.len; ++_t6) { v__ast__CallArg* arg = ((v__ast__CallArg*)(*node->_v__ast__ComptimeCall).args.data) + _t6; arg->expr = v__transformer__Transformer_expr(t, &arg->expr); } } else if (node->_typ == 350 /* v.ast.ComptimeSelector */) { (*node->_v__ast__ComptimeSelector).left = v__transformer__Transformer_expr(t, &(*node->_v__ast__ComptimeSelector).left); (*node->_v__ast__ComptimeSelector).field_expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__ComptimeSelector).field_expr); } else if (node->_typ == 352 /* v.ast.ConcatExpr */) { for (int _t7 = 0; _t7 < (*node->_v__ast__ConcatExpr).vals.len; ++_t7) { v__ast__Expr* val = ((v__ast__Expr*)(*node->_v__ast__ConcatExpr).vals.data) + _t7; *val = v__transformer__Transformer_expr(t, val); } } else if (node->_typ == 353 /* v.ast.DumpExpr */) { bool old_inside_dump = t->inside_dump; t->inside_dump = true; (*node->_v__ast__DumpExpr).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__DumpExpr).expr); t->inside_dump = old_inside_dump; } else if (node->_typ == 357 /* v.ast.GoExpr */) { (*node->_v__ast__GoExpr).call_expr = ({ v__ast__Expr _t8 = v__transformer__Transformer_expr(t, HEAP(v__ast__Expr, v__ast__CallExpr_to_sumtype_v__ast__Expr(&(*node->_v__ast__GoExpr).call_expr))); *(v__ast__CallExpr*)__as_cast(_t8._v__ast__CallExpr,_t8._typ, 344); }); } else if (node->_typ == 359 /* v.ast.IfExpr */) { return v__transformer__Transformer_if_expr(t, &/*mut*/(*node->_v__ast__IfExpr)); } else if (node->_typ == 360 /* v.ast.IfGuardExpr */) { (*node->_v__ast__IfGuardExpr).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__IfGuardExpr).expr); } else if (node->_typ == 361 /* v.ast.IndexExpr */) { v__transformer__Transformer_check_safe_array(t, &/*mut*/(*node->_v__ast__IndexExpr)); (*node->_v__ast__IndexExpr).left = v__transformer__Transformer_expr(t, &(*node->_v__ast__IndexExpr).left); (*node->_v__ast__IndexExpr).index = v__transformer__Transformer_expr(t, &(*node->_v__ast__IndexExpr).index); (*node->_v__ast__IndexExpr).or_expr = ({ v__ast__Expr _t10 = v__transformer__Transformer_expr(t, HEAP(v__ast__Expr, v__ast__OrExpr_to_sumtype_v__ast__Expr(&(*node->_v__ast__IndexExpr).or_expr))); *(v__ast__OrExpr*)__as_cast(_t10._v__ast__OrExpr,_t10._typ, 373); }); } else if (node->_typ == 362 /* v.ast.InfixExpr */) { return v__transformer__Transformer_infix_expr(t, &/*mut*/(*node->_v__ast__InfixExpr)); } else if (node->_typ == 364 /* v.ast.IsRefType */) { (*node->_v__ast__IsRefType).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__IsRefType).expr); } else if (node->_typ == 366 /* v.ast.Likely */) { (*node->_v__ast__Likely).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__Likely).expr); } else if (node->_typ == 367 /* v.ast.LockExpr */) { for (int _t12 = 0; _t12 < (*node->_v__ast__LockExpr).stmts.len; ++_t12) { v__ast__Stmt* stmt = ((v__ast__Stmt*)(*node->_v__ast__LockExpr).stmts.data) + _t12; *stmt = v__transformer__Transformer_stmt(t, stmt); } for (int _t13 = 0; _t13 < (*node->_v__ast__LockExpr).lockeds.len; ++_t13) { v__ast__Expr* locked = ((v__ast__Expr*)(*node->_v__ast__LockExpr).lockeds.data) + _t13; *locked = v__transformer__Transformer_expr(t, locked); } } else if (node->_typ == 368 /* v.ast.MapInit */) { for (int _t14 = 0; _t14 < (*node->_v__ast__MapInit).keys.len; ++_t14) { v__ast__Expr* key = ((v__ast__Expr*)(*node->_v__ast__MapInit).keys.data) + _t14; *key = v__transformer__Transformer_expr(t, key); } for (int _t15 = 0; _t15 < (*node->_v__ast__MapInit).vals.len; ++_t15) { v__ast__Expr* val = ((v__ast__Expr*)(*node->_v__ast__MapInit).vals.data) + _t15; *val = v__transformer__Transformer_expr(t, val); } } else if (node->_typ == 369 /* v.ast.MatchExpr */) { return v__transformer__Transformer_match_expr(t, &/*mut*/(*node->_v__ast__MatchExpr)); } else if (node->_typ == 373 /* v.ast.OrExpr */) { for (int _t17 = 0; _t17 < (*node->_v__ast__OrExpr).stmts.len; ++_t17) { v__ast__Stmt* stmt = ((v__ast__Stmt*)(*node->_v__ast__OrExpr).stmts.data) + _t17; *stmt = v__transformer__Transformer_stmt(t, stmt); } } else if (node->_typ == 374 /* v.ast.ParExpr */) { (*node->_v__ast__ParExpr).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__ParExpr).expr); } else if (node->_typ == 375 /* v.ast.PostfixExpr */) { (*node->_v__ast__PostfixExpr).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__PostfixExpr).expr); } else if (node->_typ == 376 /* v.ast.PrefixExpr */) { (*node->_v__ast__PrefixExpr).right = v__transformer__Transformer_expr(t, &(*node->_v__ast__PrefixExpr).right); (*node->_v__ast__PrefixExpr).or_block = ({ v__ast__Expr _t18 = v__transformer__Transformer_expr(t, HEAP(v__ast__Expr, v__ast__OrExpr_to_sumtype_v__ast__Expr(&(*node->_v__ast__PrefixExpr).or_block))); *(v__ast__OrExpr*)__as_cast(_t18._v__ast__OrExpr,_t18._typ, 373); }); } else if (node->_typ == 377 /* v.ast.RangeExpr */) { (*node->_v__ast__RangeExpr).low = v__transformer__Transformer_expr(t, &(*node->_v__ast__RangeExpr).low); (*node->_v__ast__RangeExpr).high = v__transformer__Transformer_expr(t, &(*node->_v__ast__RangeExpr).high); } else if (node->_typ == 378 /* v.ast.SelectExpr */) { for (int _t19 = 0; _t19 < (*node->_v__ast__SelectExpr).branches.len; ++_t19) { v__ast__SelectBranch* branch = ((v__ast__SelectBranch*)(*node->_v__ast__SelectExpr).branches.data) + _t19; branch->stmt = v__transformer__Transformer_stmt(t, &branch->stmt); for (int _t20 = 0; _t20 < branch->stmts.len; ++_t20) { v__ast__Stmt* stmt = ((v__ast__Stmt*)branch->stmts.data) + _t20; *stmt = v__transformer__Transformer_stmt(t, stmt); } } } else if (node->_typ == 379 /* v.ast.SelectorExpr */) { (*node->_v__ast__SelectorExpr).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__SelectorExpr).expr); if (((*node->_v__ast__SelectorExpr).expr)._typ == 384 /* v.ast.StringLiteral */ && fast_string_eq((*node->_v__ast__SelectorExpr).field_name, _S("len"))) { if (!string_contains((*(*node->_v__ast__SelectorExpr).expr._v__ast__StringLiteral).val, _S("\\")) || (*(*node->_v__ast__SelectorExpr).expr._v__ast__StringLiteral).is_raw) { return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = int_str((*(*node->_v__ast__SelectorExpr).expr._v__ast__StringLiteral).val.len),.pos = (*node->_v__ast__SelectorExpr).pos,})))); } } } else if (node->_typ == 380 /* v.ast.SizeOf */) { (*node->_v__ast__SizeOf).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__SizeOf).expr); } else if (node->_typ == 382 /* v.ast.SqlExpr */) { return v__transformer__Transformer_sql_expr(t, &/*mut*/(*node->_v__ast__SqlExpr)); } else if (node->_typ == 383 /* v.ast.StringInterLiteral */) { for (int _t23 = 0; _t23 < (*node->_v__ast__StringInterLiteral).exprs.len; ++_t23) { v__ast__Expr* expr = ((v__ast__Expr*)(*node->_v__ast__StringInterLiteral).exprs.data) + _t23; *expr = v__transformer__Transformer_expr(t, expr); } } else if (node->_typ == 385 /* v.ast.StructInit */) { (*node->_v__ast__StructInit).update_expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__StructInit).update_expr); for (int _t24 = 0; _t24 < (*node->_v__ast__StructInit).init_fields.len; ++_t24) { v__ast__StructInitField* init_field = ((v__ast__StructInitField*)(*node->_v__ast__StructInit).init_fields.data) + _t24; init_field->expr = v__transformer__Transformer_expr(t, &init_field->expr); } } else if (node->_typ == 388 /* v.ast.UnsafeExpr */) { (*node->_v__ast__UnsafeExpr).expr = v__transformer__Transformer_expr(t, &(*node->_v__ast__UnsafeExpr).expr); } else { } return *node; } VV_LOC void v__transformer__Transformer_trans_const_value_to_literal(v__transformer__Transformer* t, v__ast__Expr* expr) { v__ast__Expr expr_ = *expr; if ((expr_)._typ == 358 /* v.ast.Ident */) { _option_v__ast__Var_ptr _t1; if (_t1 = v__ast__Scope_find_var((*expr_._v__ast__Ident).scope, (*expr_._v__ast__Ident).name), _t1.state == 0) { return; } _option_v__ast__ConstField_ptr _t2; if (_t2 = v__ast__Scope_find_const(t->table->global_scope, v__ast__Ident_full_name(&(*expr_._v__ast__Ident))), _t2.state == 0) { v__ast__ConstField* obj = *(v__ast__ConstField**)_t2.data; if ((obj->expr)._typ == 342 /* v.ast.BoolLiteral */) { *expr = obj->expr; } else if ((obj->expr)._typ == 363 /* v.ast.IntegerLiteral */) { *expr = obj->expr; } else if ((obj->expr)._typ == 356 /* v.ast.FloatLiteral */) { *expr = obj->expr; } else if ((obj->expr)._typ == 384 /* v.ast.StringLiteral */) { *expr = obj->expr; } else if ((obj->expr)._typ == 362 /* v.ast.InfixExpr */) { v__ast__Expr folded_expr = v__transformer__Transformer_infix_expr(t, (voidptr)&(*obj->expr._v__ast__InfixExpr)); if ((folded_expr)._typ == 342 /* v.ast.BoolLiteral */) { *expr = folded_expr; } else if ((folded_expr)._typ == 363 /* v.ast.IntegerLiteral */) { *expr = folded_expr; } else if ((folded_expr)._typ == 356 /* v.ast.FloatLiteral */) { *expr = folded_expr; } else if ((folded_expr)._typ == 384 /* v.ast.StringLiteral */) { *expr = folded_expr; } } } } } v__ast__Expr v__transformer__Transformer_infix_expr(v__transformer__Transformer* t, v__ast__InfixExpr* node) { node->left = v__transformer__Transformer_expr(t, &node->left); node->right = v__transformer__Transformer_expr(t, &node->right); if (!t->pref->translated) { v__transformer__Transformer_trans_const_value_to_literal(t, &node->left); v__transformer__Transformer_trans_const_value_to_literal(t, &node->right); } v__token__Pos pos = v__ast__Expr_pos(node->left); v__token__Pos_extend(pos, node->pos); v__token__Pos_extend(pos, v__ast__Expr_pos(node->right)); if (t->pref->is_debug || t->is_assert) { return v__ast__InfixExpr_to_sumtype_v__ast__Expr(node); } else { if (node->left._typ == 342 /* v.ast.BoolLiteral */) { if (node->right._typ == 342 /* v.ast.BoolLiteral */) { if (node->op == (v__token__Kind__eq)) { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = (*node->left._v__ast__BoolLiteral).val == (*node->right._v__ast__BoolLiteral).val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } else if (node->op == (v__token__Kind__ne)) { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = (*node->left._v__ast__BoolLiteral).val != (*node->right._v__ast__BoolLiteral).val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } else if (node->op == (v__token__Kind__and)) { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = (*node->left._v__ast__BoolLiteral).val && (*node->right._v__ast__BoolLiteral).val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } else if (node->op == (v__token__Kind__logical_or)) { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = (*node->left._v__ast__BoolLiteral).val || (*node->right._v__ast__BoolLiteral).val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } else { } } else { } } else if (node->left._typ == 384 /* v.ast.StringLiteral */) { if (node->right._typ == 384 /* v.ast.StringLiteral */) { if (node->op == (v__token__Kind__eq)) { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = string__eq((*node->left._v__ast__StringLiteral).val, (*node->right._v__ast__StringLiteral).val),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } else if (node->op == (v__token__Kind__ne)) { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = !string__eq((*node->left._v__ast__StringLiteral).val, (*node->right._v__ast__StringLiteral).val),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } else if (node->op == (v__token__Kind__plus)) { return (t->pref->backend == v__pref__Backend__c ? (v__ast__StringLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__StringLiteral, (((v__ast__StringLiteral){.val = string__plus(v__util__smart_quote((*node->left._v__ast__StringLiteral).val, (*node->left._v__ast__StringLiteral).is_raw), v__util__smart_quote((*node->right._v__ast__StringLiteral).val, (*node->right._v__ast__StringLiteral).is_raw)),.is_raw = 0,.language = 0,.pos = pos,}))))) : (v__ast__InfixExpr_to_sumtype_v__ast__Expr(node))); } else { } } else { } } else if (node->left._typ == 363 /* v.ast.IntegerLiteral */) { if (node->right._typ == 363 /* v.ast.IntegerLiteral */) { i64 left_val = string_i64((*node->left._v__ast__IntegerLiteral).val); i64 right_val = string_i64((*node->right._v__ast__IntegerLiteral).val); switch (node->op) { case v__token__Kind__eq: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val == right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__ne: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val != right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__gt: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val > right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__ge: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val >= right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__lt: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val < right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__le: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val <= right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__plus: { return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = i64_str(((i64)(left_val + right_val))),.pos = pos,})))); } case v__token__Kind__mul: { return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = i64_str(((i64)(left_val * right_val))),.pos = pos,})))); } case v__token__Kind__minus: { if (left_val == -9223372036854775807 && right_val == 1) { return v__ast__InfixExpr_to_sumtype_v__ast__Expr(node); } return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = i64_str(((i64)(left_val - right_val))),.pos = pos,})))); } case v__token__Kind__div: { return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = i64_str(((i64)(left_val / right_val))),.pos = pos,})))); } case v__token__Kind__mod: { return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = i64_str(((i64)(left_val % right_val))),.pos = pos,})))); } case v__token__Kind__xor: { return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = i64_str(((left_val ^ right_val))),.pos = pos,})))); } case v__token__Kind__pipe: { return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = i64_str(((left_val | right_val))),.pos = pos,})))); } case v__token__Kind__amp: { return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = i64_str(((left_val & right_val))),.pos = pos,})))); } case v__token__Kind__left_shift: { return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = i64_str(((left_val << right_val))),.pos = pos,})))); } case v__token__Kind__right_shift: { return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = i64_str(((left_val >> right_val))),.pos = pos,})))); } case v__token__Kind__unsigned_right_shift: { return v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = u64_str(((((u64)(((u64)(left_val)))) >> right_val))),.pos = pos,})))); } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__and: case v__token__Kind__logical_or: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__not_in: case v__token__Kind__not_is: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_in: case v__token__Kind__key_interface: case v__token__Kind__key_is: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { break; } } } } else { } } else if (node->left._typ == 356 /* v.ast.FloatLiteral */) { if (node->right._typ == 356 /* v.ast.FloatLiteral */) { f64 left_val = string_f64((*node->left._v__ast__FloatLiteral).val); f64 right_val = string_f64((*node->right._v__ast__FloatLiteral).val); switch (node->op) { case v__token__Kind__eq: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val == right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__ne: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val != right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__gt: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val > right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__ge: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val >= right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__lt: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val < right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__le: { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = left_val <= right_val,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } case v__token__Kind__plus: { return v__ast__FloatLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__FloatLiteral, (((v__ast__FloatLiteral){.val = f64_str(((f64)(left_val + right_val))),.pos = pos,})))); } case v__token__Kind__mul: { return v__ast__FloatLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__FloatLiteral, (((v__ast__FloatLiteral){.val = f64_str(((f64)(left_val * right_val))),.pos = pos,})))); } case v__token__Kind__minus: { return v__ast__FloatLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__FloatLiteral, (((v__ast__FloatLiteral){.val = f64_str(((f64)(left_val - right_val))),.pos = pos,})))); } case v__token__Kind__div: { return v__ast__FloatLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__FloatLiteral, (((v__ast__FloatLiteral){.val = f64_str(((f64)(left_val / right_val))),.pos = pos,})))); } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__mod: case v__token__Kind__xor: case v__token__Kind__pipe: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__and: case v__token__Kind__logical_or: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__amp: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__left_shift: case v__token__Kind__right_shift: case v__token__Kind__unsigned_right_shift: case v__token__Kind__not_in: case v__token__Kind__not_is: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_in: case v__token__Kind__key_interface: case v__token__Kind__key_is: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { break; } } } } else { } } else { } return v__ast__InfixExpr_to_sumtype_v__ast__Expr(node); } return (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}; } v__ast__Expr v__transformer__Transformer_if_expr(v__transformer__Transformer* t, v__ast__IfExpr* node) { for (int _t1 = 0; _t1 < node->branches.len; ++_t1) { v__ast__IfBranch* branch = ((v__ast__IfBranch*)node->branches.data) + _t1; branch->cond = v__transformer__Transformer_expr(t, &branch->cond); v__transformer__IndexState_indent(t->index, false); for (int i = 0; i < branch->stmts.len; ++i) { v__ast__Stmt* stmt = ((v__ast__Stmt*)branch->stmts.data) + i; *stmt = v__transformer__Transformer_stmt(t, stmt); if (i == (int)(branch->stmts.len - 1)) { if ((stmt)->_typ == 401 /* v.ast.ExprStmt */) { v__ast__Expr expr = (*stmt->_v__ast__ExprStmt).expr; if (expr._typ == 359 /* v.ast.IfExpr */) { if ((*expr._v__ast__IfExpr).branches.len == 1) { array_delete(&branch->stmts, (int)(branch->stmts.len - 1)); _PUSH_MANY(&branch->stmts, ((*(v__ast__IfBranch*)array_get((*expr._v__ast__IfExpr).branches, 0)).stmts), _t2, Array_v__ast__Stmt); break; } } else if (expr._typ == 369 /* v.ast.MatchExpr */) { if ((*expr._v__ast__MatchExpr).branches.len == 1) { array_delete(&branch->stmts, (int)(branch->stmts.len - 1)); _PUSH_MANY(&branch->stmts, ((*(v__ast__MatchBranch*)array_get((*expr._v__ast__MatchExpr).branches, 0)).stmts), _t3, Array_v__ast__Stmt); break; } } else { } } } } v__transformer__IndexState_unindent(t->index); } node->left = v__transformer__Transformer_expr(t, &node->left); return v__ast__IfExpr_to_sumtype_v__ast__Expr(node); } v__ast__Expr v__transformer__Transformer_match_expr(v__transformer__Transformer* t, v__ast__MatchExpr* node) { node->cond = v__transformer__Transformer_expr(t, &node->cond); for (int _t1 = 0; _t1 < node->branches.len; ++_t1) { v__ast__MatchBranch* branch = ((v__ast__MatchBranch*)node->branches.data) + _t1; for (int _t2 = 0; _t2 < branch->exprs.len; ++_t2) { v__ast__Expr* expr = ((v__ast__Expr*)branch->exprs.data) + _t2; *expr = v__transformer__Transformer_expr(t, expr); } v__transformer__IndexState_indent(t->index, false); for (int i = 0; i < branch->stmts.len; ++i) { v__ast__Stmt* stmt = ((v__ast__Stmt*)branch->stmts.data) + i; *stmt = v__transformer__Transformer_stmt(t, stmt); if (i == (int)(branch->stmts.len - 1)) { if ((stmt)->_typ == 401 /* v.ast.ExprStmt */) { v__ast__Expr expr = (*stmt->_v__ast__ExprStmt).expr; if (expr._typ == 359 /* v.ast.IfExpr */) { if ((*expr._v__ast__IfExpr).branches.len == 1) { array_delete(&branch->stmts, (int)(branch->stmts.len - 1)); _PUSH_MANY(&branch->stmts, ((*(v__ast__IfBranch*)array_get((*expr._v__ast__IfExpr).branches, 0)).stmts), _t3, Array_v__ast__Stmt); break; } } else if (expr._typ == 369 /* v.ast.MatchExpr */) { if ((*expr._v__ast__MatchExpr).branches.len == 1) { array_delete(&branch->stmts, (int)(branch->stmts.len - 1)); _PUSH_MANY(&branch->stmts, ((*(v__ast__MatchBranch*)array_get((*expr._v__ast__MatchExpr).branches, 0)).stmts), _t4, Array_v__ast__Stmt); break; } } else { } } } } v__transformer__IndexState_unindent(t->index); } return v__ast__MatchExpr_to_sumtype_v__ast__Expr(node); } v__ast__Expr v__transformer__Transformer_sql_expr(v__transformer__Transformer* t, v__ast__SqlExpr* node) { node->db_expr = v__transformer__Transformer_expr(t, &node->db_expr); if (node->has_where) { node->where_expr = v__transformer__Transformer_expr(t, &node->where_expr); } if (node->has_order) { node->order_expr = v__transformer__Transformer_expr(t, &node->order_expr); } if (node->has_limit) { node->limit_expr = v__transformer__Transformer_expr(t, &node->limit_expr); } if (node->has_offset) { node->offset_expr = v__transformer__Transformer_expr(t, &node->offset_expr); } for (int _t1 = 0; _t1 < node->fields.len; ++_t1) { v__ast__StructField* field = ((v__ast__StructField*)node->fields.data) + _t1; field->default_expr = v__transformer__Transformer_expr(t, &field->default_expr); } Map_int_v__ast__SqlExpr _t2 = node->sub_structs; int _t4 = _t2.key_values.len; for (int _t3 = 0; _t3 < _t4; ++_t3 ) { int _t5 = _t2.key_values.len - _t4; _t4 = _t2.key_values.len; if (_t5 < 0) { _t3 = -1; continue; } if (!DenseArray_has_index(&_t2.key_values, _t3)) {continue;} v__ast__SqlExpr* sub_struct = &(*(v__ast__SqlExpr*)DenseArray_value(&_t2.key_values, _t3)); *sub_struct = ({ v__ast__Expr _t6 = v__transformer__Transformer_expr(t, HEAP(v__ast__Expr, v__ast__SqlExpr_to_sumtype_v__ast__Expr(sub_struct))); *(v__ast__SqlExpr*)__as_cast(_t6._v__ast__SqlExpr,_t6._typ, 382); }); } return v__ast__SqlExpr_to_sumtype_v__ast__Expr(node); } void v__transformer__Transformer_fn_decl_trace_calls(v__transformer__Transformer* t, v__ast__FnDecl* node) { if (node->no_body) { return; } if (string_starts_with(node->name, _S("v.trace_calls."))) { return; } string _t1; /* if prepend */ if (node->is_method) { string receiver_name = v__ast__Table_type_to_str(global_table, node->receiver.typ); _t1 = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->mod}}, {_S(" "), 0xfe10, {.d_s = receiver_name}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_S("/"), 0xfe07, {.d_i32 = node->params.len}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { _t1 = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->mod}}, {_S(" "), 0xfe10, {.d_s = node->name}}, {_S("/"), 0xfe07, {.d_i32 = node->params.len}}, {_SLIT0, 0, { .d_c = 0 }}})); } string fname = _t1; bool _t2 = false; Array_string _t2_orig = t->pref->trace_fns; int _t2_len = _t2_orig.len; for (int _t3 = 0; _t3 < _t2_len; ++_t3) { string it = ((string*) _t2_orig.data)[_t3]; if (string_match_glob(fname, it)) { _t2 = true; break; } } if (!_t2) { return; } v__ast__ExprStmt expr_stmt = ((v__ast__ExprStmt){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (((v__ast__CallExpr){ .pos = node->pos, .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .mod = node->mod, .name = _S("v.trace_calls.on_call"), .is_method = 0, .is_field = 0, .is_fn_var = 0, .is_fn_a_const = 0, .is_keep_alive = 0, .is_noreturn = 0, .is_ctor_new = 0, .is_file_translated = 0, .is_static_method = 0, .args = new_array_from_c_array(1, 1, sizeof(v__ast__CallArg), _MOV((v__ast__CallArg[1]){((v__ast__CallArg){.is_mut = 0,.share = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__StringLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__StringLiteral, (((v__ast__StringLiteral){.val = fname,.is_raw = 0,.language = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))),.typ = _const_v__ast__string_type_idx,.is_tmp_autofree = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.should_be_ptr = 0,.ct_expr = 0,})})), .expected_arg_types = __new_array(0, 0, sizeof(v__ast__Type)), .comptime_ret_val = 0, .language = v__ast__Language__v, .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .left_type = 0, .receiver_type = 0, .receiver_concrete_type = 0, .return_type = 0, .return_type_generic = 0, .nr_ret_values = -1, .fn_var_type = 0, .const_name = (string){.str=(byteptr)"", .is_lit=1}, .should_be_skipped = 0, .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .concrete_list_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .raw_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .free_receiver = 0, .scope = node->scope, .from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)), .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .is_return_used = 0, .is_expand_simple_interpolation = 0, .is_unwrapped_fn_selector = 0, })))),.is_expr = 0,.typ = 0,}); array_prepend(&node->stmts, &(v__ast__Stmt[]){v__ast__ExprStmt_to_sumtype_v__ast__Stmt(&expr_stmt)}); } bool v__transformer__Transformer_simplify_nested_interpolation_in_sb(v__transformer__Transformer* t, v__ast__Stmt* onode, v__ast__CallExpr* nexpr, v__ast__Type ntype) { if (t->pref->autofree) { return false; } if (((*(v__ast__CallArg*)array_get(nexpr->args, 0)).expr)._typ != 383 /* v.ast.StringInterLiteral */) { return false; } v__ast__StringInterLiteral original = *(v__ast__StringInterLiteral*)__as_cast(((*(v__ast__CallArg*)array_get(nexpr->args, 0)).expr)._v__ast__StringInterLiteral,((*(v__ast__CallArg*)array_get(nexpr->args, 0)).expr)._typ, 383); for (int idx = 0; idx < original.fwidths.len; ++idx) { int w = ((int*)original.fwidths.data)[idx]; if (w != 0) { return false; } if ((*(int*)array_get(original.precisions, idx)) != 987698) { return false; } if ((*(bool*)array_get(original.need_fmts, idx))) { return false; } if ((*(v__ast__Type*)array_get(original.expr_types, idx)) == _const_v__ast__string_type) { continue; } if (!v__ast__Type_is_int((*(v__ast__Type*)array_get(original.expr_types, idx)))) { return false; } } Array_v__ast__Stmt calls = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); for (int _t7 = 0; _t7 < original.vals.len; ++_t7) { string val = ((string*)original.vals.data)[_t7]; if ((val).len == 0) { array_push((array*)&calls, _MOV((v__ast__Stmt[]){ v__ast__EmptyStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__EmptyStmt, (((v__ast__EmptyStmt){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))) })); continue; } v__ast__ExprStmt ncall = ((v__ast__ExprStmt){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (((v__ast__CallExpr){.pos = (nexpr)->pos,.name_pos = (nexpr)->name_pos,.mod = (nexpr)->mod,.name = (nexpr)->name,.is_method = (nexpr)->is_method,.is_field = (nexpr)->is_field,.is_fn_var = (nexpr)->is_fn_var,.is_fn_a_const = (nexpr)->is_fn_a_const,.is_keep_alive = (nexpr)->is_keep_alive,.is_noreturn = (nexpr)->is_noreturn,.is_ctor_new = (nexpr)->is_ctor_new,.is_file_translated = (nexpr)->is_file_translated,.is_static_method = (nexpr)->is_static_method,.args = new_array_from_c_array(1, 1, sizeof(v__ast__CallArg), _MOV((v__ast__CallArg[1]){((v__ast__CallArg){.is_mut = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).is_mut,.share = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).share,.comments = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).comments,.expr = v__ast__StringLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__StringLiteral, (((v__ast__StringLiteral){.val = val,.is_raw = 0,.language = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))),.typ = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).typ,.is_tmp_autofree = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).is_tmp_autofree,.pos = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).pos,.should_be_ptr = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).should_be_ptr,.ct_expr = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).ct_expr,})})),.expected_arg_types = (nexpr)->expected_arg_types,.comptime_ret_val = (nexpr)->comptime_ret_val,.language = (nexpr)->language,.or_block = (nexpr)->or_block,.left = (nexpr)->left,.left_type = (nexpr)->left_type,.receiver_type = (nexpr)->receiver_type,.receiver_concrete_type = (nexpr)->receiver_concrete_type,.return_type = (nexpr)->return_type,.return_type_generic = (nexpr)->return_type_generic,.nr_ret_values = (nexpr)->nr_ret_values,.fn_var_type = (nexpr)->fn_var_type,.const_name = (nexpr)->const_name,.should_be_skipped = (nexpr)->should_be_skipped,.concrete_types = (nexpr)->concrete_types,.concrete_list_pos = (nexpr)->concrete_list_pos,.raw_concrete_types = (nexpr)->raw_concrete_types,.free_receiver = (nexpr)->free_receiver,.scope = (nexpr)->scope,.from_embed_types = (nexpr)->from_embed_types,.comments = (nexpr)->comments,.is_return_used = (nexpr)->is_return_used,.is_expand_simple_interpolation = (nexpr)->is_expand_simple_interpolation,.is_unwrapped_fn_selector = (nexpr)->is_unwrapped_fn_selector,})))),.is_expr = 0,.typ = ntype,}); array_push((array*)&calls, _MOV((v__ast__Stmt[]){ v__ast__ExprStmt_to_sumtype_v__ast__Stmt(&ncall) })); } for (int idx = 0; idx < original.exprs.len; ++idx) { v__ast__Expr expr = ((v__ast__Expr*)original.exprs.data)[idx]; v__ast__ExprStmt ncall = ((v__ast__ExprStmt){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (((v__ast__CallExpr){.pos = (nexpr)->pos,.name_pos = (nexpr)->name_pos,.mod = (nexpr)->mod,.name = (nexpr)->name,.is_method = (nexpr)->is_method,.is_field = (nexpr)->is_field,.is_fn_var = (nexpr)->is_fn_var,.is_fn_a_const = (nexpr)->is_fn_a_const,.is_keep_alive = (nexpr)->is_keep_alive,.is_noreturn = (nexpr)->is_noreturn,.is_ctor_new = (nexpr)->is_ctor_new,.is_file_translated = (nexpr)->is_file_translated,.is_static_method = (nexpr)->is_static_method,.args = new_array_from_c_array(1, 1, sizeof(v__ast__CallArg), _MOV((v__ast__CallArg[1]){((v__ast__CallArg){.is_mut = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).is_mut,.share = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).share,.comments = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).comments,.expr = expr,.typ = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).typ,.is_tmp_autofree = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).is_tmp_autofree,.pos = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).pos,.should_be_ptr = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).should_be_ptr,.ct_expr = ((*(v__ast__CallArg*)array_get(nexpr->args, 0))).ct_expr,})})),.expected_arg_types = (nexpr)->expected_arg_types,.comptime_ret_val = (nexpr)->comptime_ret_val,.language = (nexpr)->language,.or_block = (nexpr)->or_block,.left = (nexpr)->left,.left_type = (nexpr)->left_type,.receiver_type = (nexpr)->receiver_type,.receiver_concrete_type = (nexpr)->receiver_concrete_type,.return_type = (nexpr)->return_type,.return_type_generic = (nexpr)->return_type_generic,.nr_ret_values = (nexpr)->nr_ret_values,.fn_var_type = (nexpr)->fn_var_type,.const_name = (nexpr)->const_name,.should_be_skipped = (nexpr)->should_be_skipped,.concrete_types = (nexpr)->concrete_types,.concrete_list_pos = (nexpr)->concrete_list_pos,.raw_concrete_types = (nexpr)->raw_concrete_types,.free_receiver = (nexpr)->free_receiver,.scope = (nexpr)->scope,.from_embed_types = (nexpr)->from_embed_types,.comments = (nexpr)->comments,.is_return_used = (nexpr)->is_return_used,.is_expand_simple_interpolation = (nexpr)->is_expand_simple_interpolation,.is_unwrapped_fn_selector = (nexpr)->is_unwrapped_fn_selector,})))),.is_expr = 0,.typ = ntype,}); v__ast__Type etype = (*(v__ast__Type*)array_get(original.expr_types, idx)); if (v__ast__Type_is_int(etype)) { if ((ncall.expr)._typ == 344 /* v.ast.CallExpr */) { (*ncall.expr._v__ast__CallExpr).name = _S("write_decimal"); } } array_insert(&calls, (int)(1 + (int)(2 * idx)), &(v__ast__Stmt[]){v__ast__ExprStmt_to_sumtype_v__ast__Stmt(&ncall)}); } { // Unsafe block *onode = v__ast__Block_to_sumtype_v__ast__Stmt(ADDR(v__ast__Block, (((v__ast__Block){.is_unsafe = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = calls,})))); } return true; } void v__markused__mark_used(v__ast__Table* table, v__pref__Preferences* pref_, Array_v__ast__File_ptr ast_files) { bool v__markused__mark_used_defer_0 = false; multi_return_Map_string_v__ast__FnDecl_Map_string_v__ast__ConstField_Map_string_v__ast__GlobalField_Map_string_v__ast__TypeDecl_Map_string_v__ast__StructDecl mr_467 = v__markused__all_global_decl(ast_files); Map_string_v__ast__FnDecl all_fns = mr_467.arg0; Map_string_v__ast__ConstField all_consts = mr_467.arg1; Map_string_v__ast__GlobalField all_globals = mr_467.arg2; Map_string_v__ast__TypeDecl all_decltypes = mr_467.arg3; Map_string_v__ast__StructDecl all_structs = mr_467.arg4; v__util__timing_start(_S("MARKUSED")); v__markused__mark_used_defer_0 = true; bool trace_skip_unused = string__eq((*(string*)map_get(ADDR(map, pref_->compile_values), &(string[]){_S("trace_skip_unused")}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })), _S("true")); bool trace_skip_unused_all_fns = string__eq((*(string*)map_get(ADDR(map, pref_->compile_values), &(string[]){_S("trace_skip_unused_all_fns")}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })), _S("true")); bool trace_skip_unused_fn_names = string__eq((*(string*)map_get(ADDR(map, pref_->compile_values), &(string[]){_S("trace_skip_unused_fn_names")}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })), _S("true")); bool trace_skip_unused_just_unused_fns = string__eq((*(string*)map_get(ADDR(map, pref_->compile_values), &(string[]){_S("trace_skip_unused_just_unused_fns")}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })), _S("true")); string used_fns = (*(string*)map_get(ADDR(map, pref_->compile_values), &(string[]){_S("used_fns")}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })); string charptr_idx_str = int_literal_str(_const_v__ast__charptr_type_idx); string string_idx_str = int_literal_str(_const_v__ast__string_type_idx); string array_idx_str = int_literal_str(_const_v__ast__array_type_idx); string map_idx_str = int_literal_str(_const_v__ast__map_type_idx); string ref_map_idx_str = int_str(((int)(v__ast__Type_ref(_const_v__ast__map_type)))); string ref_densearray_idx_str = int_str(((int)(v__ast__Type_ref(v__ast__Table_find_type(table, _S("DenseArray")))))); string ref_array_idx_str = int_str(((int)(v__ast__Type_ref(_const_v__ast__array_type)))); Array_string all_fn_root_names = __new_array_with_default(0, 0, sizeof(string), 0); bool include_panic_deps = false; if ((used_fns).len != 0) { Array_string aused_fns = string_split(used_fns, _S(",")); Array_string all_fns_keys = map_keys(&all_fns); Array_string matching = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < aused_fns.len; ++_t1) { string ufn = ((string*)aused_fns.data)[_t1]; if (string_contains(ufn, _S("*"))) { Array_string _t2 = {0}; Array_string _t2_orig = all_fns_keys; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t3 = 0; _t3 < _t2_len; ++_t3) { string it = ((string*) _t2_orig.data)[_t3]; if (string_match_glob(it, ufn)) { array_push((array*)&_t2, &it); } } Array_string matching_fns =_t2; if (matching_fns.len > 0) { _PUSH_MANY(&matching, (matching_fns), _t4, Array_string); } } else { array_push((array*)&matching, _MOV((string[]){ string_clone(ufn) })); } } _PUSH_MANY(&all_fn_root_names, (matching), _t6, Array_string); for (int _t7 = 0; _t7 < matching.len; ++_t7) { string m = ((string*)matching.data)[_t7]; println(str_intp(2, _MOV((StrIntpData[]){{_S("> used_fn, found matching symbol: "), 0xfe10, {.d_s = m}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } if (pref_->backend == v__pref__Backend__native) { array_push((array*)&all_fn_root_names, _MOV((string[]){ _S("main.main") })); } else { Array_string core_fns = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("main.main")})); if (pref_->is_bare) { array_push((array*)&core_fns, _MOV((string[]){ _S("init_global_allocator") })); } if ((*(v__ast__File**)array_get(ast_files, (int)(ast_files.len - 1)))->imports.len > 0) { array_push((array*)&core_fns, _MOV((string[]){ _S("builtin_init") })); } if ((Array_string_contains(pref_->compile_defines, _S("use_libbacktrace")))) { array_push((array*)&core_fns, _MOV((string[]){ _S("print_libbacktrace") })); } if ((Array_string_contains(pref_->compile_defines, _S("callstack")))) { array_push((array*)&core_fns, _MOV((string[]){ string__plus(ref_array_idx_str, _S(".push")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(ref_array_idx_str, _S(".pop")) })); } if (pref_->autofree) { array_push((array*)&core_fns, _MOV((string[]){ string__plus(string_idx_str, _S(".clone_static")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(string_idx_str, _S(".option_clone_static")) })); } if (table->used_features->auto_str || pref_->is_shared) { include_panic_deps = true; array_push((array*)&core_fns, _MOV((string[]){ _S("isnil") })); array_push((array*)&core_fns, _MOV((string[]){ _S("__new_array") })); array_push((array*)&core_fns, _MOV((string[]){ _S("__new_array_noscan") })); array_push((array*)&core_fns, _MOV((string[]){ _S("__new_array_with_multi_default") })); array_push((array*)&core_fns, _MOV((string[]){ _S("__new_array_with_multi_default_noscan") })); array_push((array*)&core_fns, _MOV((string[]){ _S("__new_array_with_array_default") })); array_push((array*)&core_fns, _MOV((string[]){ _S("__new_array_with_array_default_noscan") })); array_push((array*)&core_fns, _MOV((string[]){ _S("new_array_from_c_array") })); } if (table->used_features->index || pref_->is_shared) { include_panic_deps = true; array_push((array*)&core_fns, _MOV((string[]){ string__plus(string_idx_str, _S(".at_with_check")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(string_idx_str, _S(".clone")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(string_idx_str, _S(".clone_static")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(string_idx_str, _S(".at")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(array_idx_str, _S(".set")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(array_idx_str, _S(".get_with_check")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(ref_array_idx_str, _S(".set")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(map_idx_str, _S(".get")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(map_idx_str, _S(".set")) })); array_push((array*)&core_fns, _MOV((string[]){ _S("__new_array_noscan") })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(ref_array_idx_str, _S(".push_noscan")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(ref_array_idx_str, _S(".push_many_noscan")) })); } if (table->used_features->range_index || pref_->is_shared) { array_push((array*)&core_fns, _MOV((string[]){ string__plus(string_idx_str, _S(".substr_with_check")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(string_idx_str, _S(".substr_ni")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(string_idx_str, _S(".substr")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(array_idx_str, _S(".slice_ni")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(array_idx_str, _S(".get_with_check")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(array_idx_str, _S(".clone_static_to_depth")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(array_idx_str, _S(".clone_to_depth")) })); } if (table->used_features->auto_str || table->used_features->dump) { array_push((array*)&core_fns, _MOV((string[]){ string__plus(string_idx_str, _S(".repeat")) })); array_push((array*)&core_fns, _MOV((string[]){ _S("tos3") })); } if (table->used_features->arr_prepend) { array_push((array*)&core_fns, _MOV((string[]){ string__plus(ref_array_idx_str, _S(".prepend_many")) })); } if (table->used_features->arr_reverse) { array_push((array*)&core_fns, _MOV((string[]){ string__plus(array_idx_str, _S(".reverse")) })); } if (table->used_features->arr_pop) { array_push((array*)&core_fns, _MOV((string[]){ string__plus(ref_array_idx_str, _S(".pop")) })); } if (table->used_features->arr_first) { array_push((array*)&core_fns, _MOV((string[]){ string__plus(array_idx_str, _S(".first")) })); } if (table->used_features->arr_last) { array_push((array*)&core_fns, _MOV((string[]){ string__plus(array_idx_str, _S(".last")) })); } if (table->used_features->arr_insert) { array_push((array*)&core_fns, _MOV((string[]){ string__plus(ref_array_idx_str, _S(".insert_many")) })); } if (table->used_features->dump) { include_panic_deps = true; string builderptr_idx = int_str(((int)(v__ast__Type_ref(v__ast__Table_find_type(table, _S("strings.Builder")))))); _PUSH_MANY(&core_fns, (new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){string__plus(builderptr_idx, _S(".str")), string__plus(builderptr_idx, _S(".free")), string__plus(builderptr_idx, _S(".write_rune"))}))), _t51, Array_string); } if (table->used_features->print_options) { include_panic_deps = true; array_push((array*)&core_fns, _MOV((string[]){ _S("_option_ok") })); array_push((array*)&core_fns, _MOV((string[]){ _S("_result_ok") })); } if (table->used_features->anon_fn) { array_push((array*)&core_fns, _MOV((string[]){ _S("memdup_uncollectable") })); array_push((array*)&core_fns, _MOV((string[]){ _S("builtin.closure.closure_alloc") })); array_push((array*)&core_fns, _MOV((string[]){ _S("builtin.closure.closure_init") })); array_push((array*)&core_fns, _MOV((string[]){ _S("builtin.closure.closure_create") })); } if (table->used_features->arr_map) { include_panic_deps = true; array_push((array*)&core_fns, _MOV((string[]){ _S("__new_array_with_map_default") })); array_push((array*)&core_fns, _MOV((string[]){ _S("new_map_noscan_key") })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(ref_map_idx_str, _S(".clone")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(ref_densearray_idx_str, _S(".clone")) })); array_push((array*)&core_fns, _MOV((string[]){ string__plus(map_idx_str, _S(".clone")) })); } if (table->used_features->type_name) { array_push((array*)&core_fns, _MOV((string[]){ string__plus(charptr_idx_str, _S(".vstring_literal")) })); } if (pref_->trace_calls || pref_->trace_fns.len > 0) { include_panic_deps = true; array_push((array*)&core_fns, _MOV((string[]){ _S("vgettid") })); array_push((array*)&core_fns, _MOV((string[]){ _S("C.gettid") })); array_push((array*)&core_fns, _MOV((string[]){ _S("v.trace_calls.on_c_main") })); array_push((array*)&core_fns, _MOV((string[]){ _S("v.trace_calls.current_time") })); array_push((array*)&core_fns, _MOV((string[]){ _S("v.trace_calls.on_call") })); } if (_IN_MAP(ADDR(string, _S("C.cJSON_Parse")), ADDR(map, all_fns))) { array_push((array*)&core_fns, _MOV((string[]){ _S("_result_ok") })); array_push((array*)&core_fns, _MOV((string[]){ _S("tos5") })); array_push((array*)&core_fns, _MOV((string[]){ _S("time.unix") })); array_push((array*)&core_fns, _MOV((string[]){ _S("error") })); include_panic_deps = true; } if (v__pref__Preferences_should_use_segfault_handler(pref_)) { array_push((array*)&core_fns, _MOV((string[]){ _S("v_segmentation_fault_handler") })); } _PUSH_MANY(&all_fn_root_names, (core_fns), _t74, Array_string); } if (pref_->is_bare) { _PUSH_MANY(&all_fn_root_names, (new_array_from_c_array(6, 6, sizeof(string), _MOV((string[6]){_S("strlen"), _S("memcmp"), _S("memcpy"), _S("realloc"), _S("vsnprintf"), _S("vsprintf")}))), _t75, Array_string); } bool is_noscan_whitelisted = (pref_->gc_mode == v__pref__GarbageCollectionMode__boehm_full_opt || pref_->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt); bool _t76 = false; Array_string _t76_orig = all_fn_root_names; int _t76_len = _t76_orig.len; for (int _t77 = 0; _t77 < _t76_len; ++_t77) { string it = ((string*) _t76_orig.data)[_t77]; if (string_contains(it, _S("noscan")) && !(_SLIT_EQ(it.str, it.len, "vcalloc_noscan") || _SLIT_EQ(it.str, it.len, "malloc_noscan"))) { _t76 = true; break; } } bool has_noscan =_t76; int _t79 = all_fns.key_values.len; for (int _t78 = 0; _t78 < _t79; ++_t78 ) { int _t80 = all_fns.key_values.len - _t79; _t79 = all_fns.key_values.len; if (_t80 < 0) { _t78 = -1; continue; } if (!DenseArray_has_index(&all_fns.key_values, _t78)) {continue;} string k = *(string*)DenseArray_key(&all_fns.key_values, _t78); k = string_clone(k); v__ast__FnDecl* mfn = &(*(v__ast__FnDecl*)DenseArray_value(&all_fns.key_values, _t78)); if (trace_skip_unused_all_fns) { println(str_intp(3, _MOV((StrIntpData[]){{_S("k: "), 0xfe10, {.d_s = k}}, {_S(" | mfn: "), 0xfe10, {.d_s = mfn->name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (mfn->is_pub && pref_->is_shared) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); continue; } bool _t82 = (pref_->translated); bool _t83 = false; if (_t82) { Array_v__ast__Attr _t83_orig = mfn->attrs; int _t83_len = _t83_orig.len; for (int _t84 = 0; _t84 < _t83_len; ++_t84) { v__ast__Attr it = ((v__ast__Attr*) _t83_orig.data)[_t84]; if (fast_string_eq(it.name, _S("c"))) { _t83 = true; break; } } } if ( _t82 &&_t83) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); continue; } if (has_noscan && is_noscan_whitelisted && string_ends_with(mfn->name, _S("_noscan"))) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); continue; } if (mfn->is_method) { string method_receiver_typename = v__ast__Table_type_to_str(table, mfn->receiver.typ); if (_SLIT_EQ(method_receiver_typename.str, method_receiver_typename.len, "&sync.Channel")) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); continue; } } bool has_dot = string_contains(k, _S(".")); if (has_dot) { if (string_ends_with(k, _S(".init")) || string_ends_with(k, _S(".cleanup"))) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); continue; } if (pref_->is_prof && (string_starts_with(k, _S("time.vpc_now")) || string_starts_with(k, _S("v.profile.")))) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); continue; } if (string_ends_with(k, _S(".lock")) || string_ends_with(k, _S(".unlock")) || string_ends_with(k, _S(".rlock")) || string_ends_with(k, _S(".runlock"))) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); continue; } } if (string_ends_with(k, _S("before_request"))) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); continue; } if (pref_->is_test) { if (string_starts_with(k, _S("test_")) || (has_dot && (string_contains(k, _S(".test_")) || string_contains(k, _S(".vtest_"))))) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); continue; } if (string_starts_with(k, _S("testsuite_")) || (has_dot && string_contains(k, _S(".testsuite_")))) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); continue; } } if (pref_->prealloc && string_starts_with(k, _S("prealloc_"))) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); continue; } } if (pref_->is_debug) { array_push((array*)&all_fn_root_names, _MOV((string[]){ _S("panic_debug") })); array_push((array*)&all_fn_root_names, _MOV((string[]){ _S("tos3") })); } if (pref_->is_test) { array_push((array*)&all_fn_root_names, _MOV((string[]){ _S("main.cb_assertion_ok") })); array_push((array*)&all_fn_root_names, _MOV((string[]){ _S("main.cb_assertion_failed") })); _option_v__ast__TypeSymbol_ptr _t99; if (_t99 = v__ast__Table_find_sym(table, _S("main.BenchedTests")), _t99.state == 0) { v__ast__TypeSymbol* benched_tests_sym = *(v__ast__TypeSymbol**)_t99.data; string bts_type = v__ast__Type_str((*(v__ast__Param*)array_get((*(v__ast__Fn*)array_get(benched_tests_sym->methods, 0)).params, 0)).typ); array_push((array*)&all_fn_root_names, _MOV((string[]){ string__plus(bts_type, _S(".testing_step_start")) })); array_push((array*)&all_fn_root_names, _MOV((string[]){ string__plus(bts_type, _S(".testing_step_end")) })); array_push((array*)&all_fn_root_names, _MOV((string[]){ string__plus(bts_type, _S(".end_testing")) })); array_push((array*)&all_fn_root_names, _MOV((string[]){ _S("main.start_testing") })); } } v__markused__handle_vweb(table, &all_fn_root_names, _S("veb.Result"), _S("veb.filter"), _S("veb.Context")); v__markused__handle_vweb(table, &all_fn_root_names, _S("vweb.Result"), _S("vweb.filter"), _S("vweb.Context")); v__markused__handle_vweb(table, &all_fn_root_names, _S("x.vweb.Result"), _S("x.vweb.filter"), _S("x.vweb.Context")); Array_v__ast__Type* _t105 = (Array_v__ast__Type*)(map_get_check(ADDR(map, table->iface_types), &(string[]){_S("orm.Connection")})); _option_Array_v__ast__Type _t104 = {0}; if (_t105) { *((Array_v__ast__Type*)&_t104.data) = *((Array_v__ast__Type*)_t105); } else { _t104.state = 2; _t104.err = _v_error(_S("map key does not exist")); } ; if (_t104.state != 0) { IError err = _t104.err; *(Array_v__ast__Type*) _t104.data = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); } Array_v__ast__Type orm_connection_implementations = (*(Array_v__ast__Type*)_t104.data); if (orm_connection_implementations.len > 0) { int _t107 = all_fns.key_values.len; for (int _t106 = 0; _t106 < _t107; ++_t106 ) { int _t108 = all_fns.key_values.len - _t107; _t107 = all_fns.key_values.len; if (_t108 < 0) { _t106 = -1; continue; } if (!DenseArray_has_index(&all_fns.key_values, _t106)) {continue;} string k = *(string*)DenseArray_key(&all_fns.key_values, _t106); k = string_clone(k); if (string_starts_with(k, _S("orm."))) { array_push((array*)&all_fn_root_names, _MOV((string[]){ string_clone(k) })); } } for (int _t110 = 0; _t110 < orm_connection_implementations.len; ++_t110) { v__ast__Type orm_type = ((v__ast__Type*)orm_connection_implementations.data)[_t110]; string typ = int_str(((int)(orm_type))); array_push((array*)&all_fn_root_names, _MOV((string[]){ string__plus(typ, _S(".select")) })); array_push((array*)&all_fn_root_names, _MOV((string[]){ string__plus(typ, _S(".insert")) })); array_push((array*)&all_fn_root_names, _MOV((string[]){ string__plus(typ, _S(".update")) })); array_push((array*)&all_fn_root_names, _MOV((string[]){ string__plus(typ, _S(".delete")) })); array_push((array*)&all_fn_root_names, _MOV((string[]){ string__plus(typ, _S(".create")) })); array_push((array*)&all_fn_root_names, _MOV((string[]){ string__plus(typ, _S(".drop")) })); array_push((array*)&all_fn_root_names, _MOV((string[]){ string__plus(typ, _S(".last_id")) })); } } if ((Array_string_contains(pref_->compile_defines, _S("debug_used_features")))) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> debug_used_features: "), 0xfe10, {.d_s = str_intp(1, _MOV((StrIntpData[]){{_S("&"), 0xfe10 ,{.d_s = isnil(table->used_features) ? _S("nil") : v__ast__UsedFeatures_str(*table->used_features)}}}))}}, {_SLIT0, 0, { .d_c = 0 }}}))); } v__markused__Walker* walker = v__markused__Walker__static__new(((v__markused__Walker){ .table = table, .features = ((void*)0), .used_fns = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .trace_enabled = (Array_string_contains(pref_->compile_defines, _S("trace_skip_unused_walker"))), .used_consts = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .used_globals = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .used_fields = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .used_syms = new_map(sizeof(int), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .used_none = 0, .used_option = 0, .used_result = 0, .used_panic = 0, .pref = pref_, .all_fns = all_fns, .all_consts = all_consts, .all_globals = all_globals, .all_fields = new_map(sizeof(string), sizeof(v__ast__StructField), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .all_decltypes = all_decltypes, .all_structs = all_structs, .level = 0, .is_builtin_mod = 0, .uses_atomic = 0, .uses_array = 0, .uses_channel = 0, .uses_lock = 0, .uses_ct_fields = 0, .uses_ct_methods = 0, .uses_ct_params = 0, .uses_ct_values = 0, .uses_ct_variants = 0, .uses_ct_attribute = 0, .uses_external_type = 0, .uses_err = 0, .uses_asserts = 0, .uses_map_update = 0, .uses_debugger = 0, .uses_mem_align = 0, .uses_eq = 0, .uses_interp = 0, .uses_guard = 0, .uses_orm = 0, .uses_str = new_map(sizeof(v__ast__Type), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .uses_free = new_map(sizeof(v__ast__Type), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .uses_spawn = 0, .uses_dump = 0, .uses_memdup = 0, .uses_arr_void = 0, })); v__markused__Walker_mark_markused_consts(walker); v__markused__Walker_mark_markused_globals(walker); v__markused__Walker_mark_markused_syms(walker); v__markused__Walker_mark_markused_fns(walker); v__markused__Walker_mark_markused_decltypes(walker); v__markused__Walker_mark_generic_types(walker); if (pref_->use_cache) { v__markused__Walker_mark_by_sym_name(walker, _S("IError")); } v__markused__Walker_mark_root_fns(walker, all_fn_root_names); v__markused__Walker_mark_by_sym_name(walker, _S("vweb.RedirectParams")); v__markused__Walker_mark_by_sym_name(walker, _S("vweb.RequestParams")); int _t119 = all_consts.key_values.len; for (int _t118 = 0; _t118 < _t119; ++_t118 ) { int _t120 = all_consts.key_values.len - _t119; _t119 = all_consts.key_values.len; if (_t120 < 0) { _t118 = -1; continue; } if (!DenseArray_has_index(&all_consts.key_values, _t118)) {continue;} string kcon = *(string*)DenseArray_key(&all_consts.key_values, _t118); kcon = string_clone(kcon); v__ast__ConstField con = (*(v__ast__ConstField*)DenseArray_value(&all_consts.key_values, _t118)); if (pref_->is_shared && con.is_pub) { v__markused__Walker_mark_const_as_used(walker, kcon); continue; } bool _t121 = (pref_->translated); bool _t122 = false; if (_t121) { Array_v__ast__Attr _t122_orig = con.attrs; int _t122_len = _t122_orig.len; for (int _t123 = 0; _t123 < _t122_len; ++_t123) { v__ast__Attr it = ((v__ast__Attr*) _t122_orig.data)[_t123]; if (fast_string_eq(it.name, _S("export"))) { _t122 = true; break; } } } if ( _t121 &&_t122) { v__markused__Walker_mark_const_as_used(walker, kcon); continue; } } if (trace_skip_unused_fn_names) { Map_string_bool _t124 = walker->used_fns; int _t126 = _t124.key_values.len; for (int _t125 = 0; _t125 < _t126; ++_t125 ) { int _t127 = _t124.key_values.len - _t126; _t126 = _t124.key_values.len; if (_t127 < 0) { _t125 = -1; continue; } if (!DenseArray_has_index(&_t124.key_values, _t125)) {continue;} string key = *(string*)DenseArray_key(&_t124.key_values, _t125); key = string_clone(key); println(str_intp(2, _MOV((StrIntpData[]){{_S("> used fn key: "), 0xfe10, {.d_s = key}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } v__markused__Walker_finalize(walker, include_panic_deps); table->used_features->used_none = walker->used_none; if (walker->used_none == 0) { map_delete(&walker->used_fns, &(string[]){str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(_const_v__ast__none_type))}}, {_S(".str"), 0, { .d_c = 0 }}}))}); } table->used_features->used_fns = map_move(&walker->used_fns); table->used_features->used_consts = map_move(&walker->used_consts); table->used_features->used_globals = map_move(&walker->used_globals); table->used_features->used_syms = map_move(&walker->used_syms); if (trace_skip_unused) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">> t.used_fns: "), 0xfe10, {.d_s = Array_string_str(map_keys(&table->used_features->used_fns))}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">> t.used_consts: "), 0xfe10, {.d_s = Array_string_str(map_keys(&table->used_features->used_consts))}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">> t.used_globals: "), 0xfe10, {.d_s = Array_string_str(map_keys(&table->used_features->used_globals))}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">> t.used_syms: "), 0xfe10, {.d_s = Array_int_str(map_keys(&table->used_features->used_syms))}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">> walker.table.used_features.used_maps: "), 0xfe07, {.d_i32 = walker->table->used_features->used_maps}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (trace_skip_unused_just_unused_fns) { Array_string all_fns_keys = map_keys(&all_fns); Array_string used_fns_keys = map_keys(&table->used_features->used_fns); for (int _t128 = 0; _t128 < all_fns_keys.len; ++_t128) { string k = ((string*)all_fns_keys.data)[_t128]; if ((Array_string_contains(used_fns_keys, k))) { continue; } println(str_intp(2, _MOV((StrIntpData[]){{_S("> k: "), 0xfe10, {.d_s = k}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } // Defer begin if (v__markused__mark_used_defer_0) { v__util__timing_measure(_S("MARKUSED")); } // Defer end } VV_LOC multi_return_Map_string_v__ast__FnDecl_Map_string_v__ast__ConstField_Map_string_v__ast__GlobalField_Map_string_v__ast__TypeDecl_Map_string_v__ast__StructDecl v__markused__all_global_decl(Array_v__ast__File_ptr ast_files) { bool v__markused__all_global_decl_defer_0 = false; v__util__timing_start(_S("all_global_decl")); v__markused__all_global_decl_defer_0 = true; Map_string_v__ast__FnDecl all_fns = new_map(sizeof(string), sizeof(v__ast__FnDecl), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_v__ast__ConstField all_consts = new_map(sizeof(string), sizeof(v__ast__ConstField), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_v__ast__GlobalField all_globals = new_map(sizeof(string), sizeof(v__ast__GlobalField), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_v__ast__TypeDecl all_decltypes = new_map(sizeof(string), sizeof(v__ast__TypeDecl), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_v__ast__StructDecl all_structs = new_map(sizeof(string), sizeof(v__ast__StructDecl), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int i = 0; i < ast_files.len; ++i) { for (int _t1 = 0; _t1 < (*(v__ast__File**)array_get(ast_files, i))->stmts.len; ++_t1) { v__ast__Stmt node = ((v__ast__Stmt*)(*(v__ast__File**)array_get(ast_files, i))->stmts.data)[_t1]; if (node._typ == 237 /* v.ast.FnDecl */) { string fkey = v__ast__FnDecl_fkey(&(*node._v__ast__FnDecl)); if (!_IN_MAP(ADDR(string, fkey), ADDR(map, all_fns)) || !(*node._v__ast__FnDecl).no_body) { (*(v__ast__FnDecl*)map_get_and_set((map*)&all_fns, &(string[]){fkey}, &(v__ast__FnDecl[]){ (v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = (v__ast__StructField){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.option_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = (v__ast__StructDecl){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,},},.receiver_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_method = 0,.is_static_type_method = 0,.static_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.method_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.body_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.end_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_expand_simple_interpolation = 0,} })) = (*node._v__ast__FnDecl); } } else if (node._typ == 396 /* v.ast.ConstDecl */) { for (int _t2 = 0; _t2 < (*node._v__ast__ConstDecl).fields.len; ++_t2) { v__ast__ConstField cfield = ((v__ast__ConstField*)(*node._v__ast__ConstDecl).fields.data)[_t2]; string ckey = cfield.name; (*(v__ast__ConstField*)map_get_and_set((map*)&all_consts, &(string[]){ckey}, &(v__ast__ConstField[]){ (v__ast__ConstField){.mod = (string){.str=(byteptr)"", .is_lit=1},.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_markused = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_virtual_c = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comptime_expr_value = _const_v__ast__empty_comptime_const_value,} })) = cfield; } } else if (node._typ == 405 /* v.ast.GlobalDecl */) { for (int _t3 = 0; _t3 < (*node._v__ast__GlobalDecl).fields.len; ++_t3) { v__ast__GlobalField gfield = ((v__ast__GlobalField*)(*node._v__ast__GlobalDecl).fields.data)[_t3]; string gkey = gfield.name; (*(v__ast__GlobalField*)map_get_and_set((map*)&all_globals, &(string[]){gkey}, &(v__ast__GlobalField[]){ (v__ast__GlobalField){.name = (string){.str=(byteptr)"", .is_lit=1},.has_expr = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_markused = 0,.is_volatile = 0,.is_exported = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),} })) = gfield; } } else if (node._typ == 415 /* v.ast.StructDecl */) { (*(v__ast__StructDecl*)map_get_and_set((map*)&all_structs, &(string[]){(*node._v__ast__StructDecl).name}, &(v__ast__StructDecl[]){ (v__ast__StructDecl){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,} })) = (*node._v__ast__StructDecl); } else if (node._typ == 334 /* v.ast.TypeDecl */) { if ((*((*node._v__ast__TypeDecl).is_markused))) { map_set(&all_decltypes, &(string[]){(*((*node._v__ast__TypeDecl).name))}, &(v__ast__TypeDecl[]) { (*node._v__ast__TypeDecl) }); } } else { } } } multi_return_Map_string_v__ast__FnDecl_Map_string_v__ast__ConstField_Map_string_v__ast__GlobalField_Map_string_v__ast__TypeDecl_Map_string_v__ast__StructDecl _t4 = (multi_return_Map_string_v__ast__FnDecl_Map_string_v__ast__ConstField_Map_string_v__ast__GlobalField_Map_string_v__ast__TypeDecl_Map_string_v__ast__StructDecl){.arg0=all_fns, .arg1=all_consts, .arg2=all_globals, .arg3=all_decltypes, .arg4=all_structs}; // Defer begin if (v__markused__all_global_decl_defer_0) { v__util__timing_measure(_S("all_global_decl")); } // Defer end return _t4; } VV_LOC void v__markused__mark_all_methods_used(v__ast__Table* table, Array_string* all_fn_root_names, v__ast__Type typ) { v__ast__TypeSymbol* sym = v__ast__Table_sym(table, typ); string styp = int_str(((int)(typ))); for (int _t1 = 0; _t1 < sym->methods.len; ++_t1) { v__ast__Fn method = ((v__ast__Fn*)sym->methods.data)[_t1]; array_push((array*)all_fn_root_names, _MOV((string[]){ string__plus(string__plus(styp, _S(".")), method.name) })); } } VV_LOC void v__markused__handle_vweb(v__ast__Table* table, Array_string* all_fn_root_names, string result_name, string filter_name, string context_name) { v__ast__Type result_type_idx = v__ast__Table_find_type(table, result_name); if (result_type_idx == 0) { return; } array_push((array*)all_fn_root_names, _MOV((string[]){ string_clone(filter_name) })); v__ast__Type typ_vweb_context = v__ast__Type_set_nr_muls(v__ast__Table_find_type(table, context_name), 1); v__markused__mark_all_methods_used(table, all_fn_root_names, typ_vweb_context); for (int _t2 = 0; _t2 < table->used_features->used_veb_types.len; ++_t2) { v__ast__Type vgt = ((v__ast__Type*)table->used_features->used_veb_types.data)[_t2]; v__ast__TypeSymbol* sym_app = v__ast__Table_sym(table, vgt); string pvgt = int_str(((int)(v__ast__Type_set_nr_muls(vgt, 1)))); for (int _t3 = 0; _t3 < sym_app->methods.len; ++_t3) { v__ast__Fn m = ((v__ast__Fn*)sym_app->methods.data)[_t3]; bool skip = true; if (fast_string_eq(m.name, _S("before_request"))) { skip = false; } if (m.return_type == result_type_idx) { skip = false; } if (skip) { continue; } array_push((array*)all_fn_root_names, _MOV((string[]){ string__plus(string__plus(pvgt, _S(".")), m.name) })); } } } v__markused__Walker* v__markused__Walker__static__new(v__markused__Walker params) { v__markused__Walker* new_walker = ((v__markused__Walker*)memdup(&(v__markused__Walker){.table = (params).table,.features = (params).features,.used_fns = (params).used_fns,.trace_enabled = (params).trace_enabled,.used_consts = (params).used_consts,.used_globals = (params).used_globals,.used_fields = (params).used_fields,.used_syms = (params).used_syms,.used_none = (params).used_none,.used_option = (params).used_option,.used_result = (params).used_result,.used_panic = (params).used_panic,.pref = (params).pref,.all_fns = (params).all_fns,.all_consts = (params).all_consts,.all_globals = (params).all_globals,.all_fields = (params).all_fields,.all_decltypes = (params).all_decltypes,.all_structs = (params).all_structs,.level = (params).level,.is_builtin_mod = (params).is_builtin_mod,.uses_atomic = (params).uses_atomic,.uses_array = (params).uses_array,.uses_channel = (params).uses_channel,.uses_lock = (params).uses_lock,.uses_ct_fields = (params).uses_ct_fields,.uses_ct_methods = (params).uses_ct_methods,.uses_ct_params = (params).uses_ct_params,.uses_ct_values = (params).uses_ct_values,.uses_ct_variants = (params).uses_ct_variants,.uses_ct_attribute = (params).uses_ct_attribute,.uses_external_type = (params).uses_external_type,.uses_err = (params).uses_err,.uses_asserts = (params).uses_asserts,.uses_map_update = (params).uses_map_update,.uses_debugger = (params).uses_debugger,.uses_mem_align = (params).uses_mem_align,.uses_eq = (params).uses_eq,.uses_interp = (params).uses_interp,.uses_guard = (params).uses_guard,.uses_orm = (params).uses_orm,.uses_str = (params).uses_str,.uses_free = (params).uses_free,.uses_spawn = (params).uses_spawn,.uses_dump = (params).uses_dump,.uses_memdup = (params).uses_memdup,.uses_arr_void = (params).uses_arr_void,}, sizeof(v__markused__Walker))); new_walker->features = params.table->used_features; return new_walker; } inline void v__markused__Walker_mark_fn_as_used(v__markused__Walker* w, string fkey) { #if defined(CUSTOM_DEFINE_trace_skip_unused_marked) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(" fn > |"), 0xfe10, {.d_s = fkey}}, {_S("|"), 0, { .d_c = 0 }}}))); } #endif map_set(&w->used_fns, &(string[]){fkey}, &(bool[]) { true }); } inline void v__markused__Walker_mark_builtin_array_method_as_used(v__markused__Walker* w, string method_name) { v__markused__Walker_mark_builtin_type_method_as_used(w, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = _const_v__ast__array_type_idx}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_SLIT0, 0, { .d_c = 0 }}})), str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(v__ast__Type_ref(_const_v__ast__array_type)))}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } inline void v__markused__Walker_mark_builtin_map_method_as_used(v__markused__Walker* w, string method_name) { v__markused__Walker_mark_builtin_type_method_as_used(w, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = _const_v__ast__map_type_idx}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_SLIT0, 0, { .d_c = 0 }}})), str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(v__ast__Type_ref(_const_v__ast__map_type)))}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } void v__markused__Walker_mark_builtin_type_method_as_used(v__markused__Walker* w, string k, string rk) { v__ast__FnDecl* _t4 = (v__ast__FnDecl*)(map_get_check(ADDR(map, w->all_fns), &(string[]){rk})); _option_v__ast__FnDecl _t3 = {0}; if (_t4) { *((v__ast__FnDecl*)&_t3.data) = *((v__ast__FnDecl*)_t4); } else { _t3.state = 2; _t3.err = _v_error(_S("map key does not exist")); } v__ast__FnDecl* _t2 = (v__ast__FnDecl*)(map_get_check(ADDR(map, w->all_fns), &(string[]){k})); _option_v__ast__FnDecl _t1 = {0}; if (_t2) { *((v__ast__FnDecl*)&_t1.data) = *((v__ast__FnDecl*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { v__ast__FnDecl cfn = (*(v__ast__FnDecl*)_t1.data); v__markused__Walker_fn_decl(w, (voidptr)&cfn); v__markused__Walker_mark_fn_as_used(w, k); } else if (_t3.state == 0) { v__ast__FnDecl cfn = (*(v__ast__FnDecl*)_t3.data); v__markused__Walker_fn_decl(w, (voidptr)&cfn); v__markused__Walker_mark_fn_as_used(w, rk); } } void v__markused__Walker_mark_const_as_used(v__markused__Walker* w, string ckey) { #if defined(CUSTOM_DEFINE_trace_skip_unused_marked) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(" const > |"), 0xfe10, {.d_s = ckey}}, {_S("|"), 0, { .d_c = 0 }}}))); } #endif if ((*(bool*)map_get(ADDR(map, w->used_consts), &(string[]){ckey}, &(bool[]){ 0 }))) { return; } map_set(&w->used_consts, &(string[]){ckey}, &(bool[]) { true }); v__ast__ConstField* _t3 = (v__ast__ConstField*)(map_get_check(ADDR(map, w->all_consts), &(string[]){ckey})); _option_v__ast__ConstField _t2 = {0}; if (_t3) { *((v__ast__ConstField*)&_t2.data) = *((v__ast__ConstField*)_t3); } else { _t2.state = 2; _t2.err = _v_error(_S("map key does not exist")); } ; if (_t2.state != 0) { IError err = _t2.err; return; } v__ast__ConstField cfield = (*(v__ast__ConstField*)_t2.data); v__markused__Walker_expr(w, cfield.expr); v__markused__Walker_mark_by_type(w, cfield.typ); } void v__markused__Walker_mark_global_as_used(v__markused__Walker* w, string ckey) { #if defined(CUSTOM_DEFINE_trace_skip_unused_marked) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(" global > |"), 0xfe10, {.d_s = ckey}}, {_S("|"), 0, { .d_c = 0 }}}))); } #endif if ((*(bool*)map_get(ADDR(map, w->used_globals), &(string[]){ckey}, &(bool[]){ 0 }))) { return; } map_set(&w->used_globals, &(string[]){ckey}, &(bool[]) { true }); v__ast__GlobalField* _t3 = (v__ast__GlobalField*)(map_get_check(ADDR(map, w->all_globals), &(string[]){ckey})); _option_v__ast__GlobalField _t2 = {0}; if (_t3) { *((v__ast__GlobalField*)&_t2.data) = *((v__ast__GlobalField*)_t3); } else { _t2.state = 2; _t2.err = _v_error(_S("map key does not exist")); } ; if (_t2.state != 0) { IError err = _t2.err; return; } v__ast__GlobalField gfield = (*(v__ast__GlobalField*)_t2.data); v__markused__Walker_expr(w, gfield.expr); if (!gfield.has_expr) { v__markused__Walker_mark_by_type(w, gfield.typ); } } void v__markused__Walker_mark_markused_fns(v__markused__Walker* w) { Map_string_v__ast__FnDecl _t1 = w->all_fns; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} v__ast__FnDecl* func = &(*(v__ast__FnDecl*)DenseArray_value(&_t1.key_values, _t2)); if (func->is_exported || func->is_markused) { #if defined(CUSTOM_DEFINE_trace_skip_unused_exported_fns) { if (func->is_exported) { println(str_intp(2, _MOV((StrIntpData[]){{_S(">>>> walking exported func: "), 0xfe10, {.d_s = func->name}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } if (func->is_markused) { println(str_intp(2, _MOV((StrIntpData[]){{_S(">>>> walking markused func: "), 0xfe10, {.d_s = func->name}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } } #endif v__markused__Walker_fn_decl(w, func); continue; } if (_us32_eq(func->return_type,w->table->veb_res_idx_cache)) { #if defined(CUSTOM_DEFINE_trace_skip_veb_actions) { println(str_intp(2, _MOV((StrIntpData[]){{_S(">>>> walking veb action func: "), 0xfe10, {.d_s = func->name}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } #endif v__markused__Walker_fn_decl(w, func); } } } void v__markused__Walker_mark_root_fns(v__markused__Walker* w, Array_string all_fn_root_names) { if (w->trace_enabled) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">>>>>>> ROOT "), 0xfe10, {.d_s = Array_string_str(all_fn_root_names)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } for (int _t1 = 0; _t1 < all_fn_root_names.len; ++_t1) { string fn_name = ((string*)all_fn_root_names.data)[_t1]; if (!_IN_MAP(ADDR(string, fn_name), ADDR(map, w->used_fns))) { #if defined(CUSTOM_DEFINE_trace_skip_unused_roots) { println(str_intp(2, _MOV((StrIntpData[]){{_S(">>>> walking root func: "), 0xfe10, {.d_s = fn_name}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } #endif v__markused__Walker_fn_decl(w, (voidptr)&(*(v__ast__FnDecl*)map_get(ADDR(map, w->all_fns), &(string[]){fn_name}, &(v__ast__FnDecl[]){ (v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = (v__ast__StructField){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.option_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = (v__ast__StructDecl){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,},},.receiver_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_method = 0,.is_static_type_method = 0,.static_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.method_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.body_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.end_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_expand_simple_interpolation = 0,} }))); } } } void v__markused__Walker_mark_markused_consts(v__markused__Walker* w) { Map_string_v__ast__ConstField _t1 = w->all_consts; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string ckey = *(string*)DenseArray_key(&_t1.key_values, _t2); ckey = string_clone(ckey); v__ast__ConstField* constfield = &(*(v__ast__ConstField*)DenseArray_value(&_t1.key_values, _t2)); if (constfield->is_markused) { #if defined(CUSTOM_DEFINE_trace_skip_unused_markused_consts) { println(str_intp(2, _MOV((StrIntpData[]){{_S(">>>> walking markused const: "), 0xfe10, {.d_s = ckey}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__markused__Walker_mark_const_as_used(w, ckey); } } } void v__markused__Walker_mark_markused_globals(v__markused__Walker* w) { Map_string_v__ast__GlobalField _t1 = w->all_globals; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string gkey = *(string*)DenseArray_key(&_t1.key_values, _t2); gkey = string_clone(gkey); v__ast__GlobalField* globalfield = &(*(v__ast__GlobalField*)DenseArray_value(&_t1.key_values, _t2)); if (globalfield->is_markused || globalfield->is_exported) { #if defined(CUSTOM_DEFINE_trace_skip_unused_markused_globals) { println(str_intp(2, _MOV((StrIntpData[]){{_S(">>>> walking markused global: "), 0xfe10, {.d_s = gkey}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__markused__Walker_mark_global_as_used(w, gkey); } } } void v__markused__Walker_mark_markused_syms(v__markused__Walker* w) { for (int _t1 = 0; _t1 < w->table->type_symbols.len; ++_t1) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)w->table->type_symbols.data)[_t1]; if ((sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518)).is_markused) { v__markused__Walker_mark_by_sym(w, *sym); } else if ((sym->info)._typ == 542 /* v.ast.Interface */ && (*(v__ast__Interface*)__as_cast((sym->info)._v__ast__Interface,(sym->info)._typ, 542)).is_markused) { v__markused__Walker_mark_by_sym(w, *sym); } } } void v__markused__Walker_mark_markused_decltypes(v__markused__Walker* w) { Map_string_v__ast__TypeDecl _t1 = w->all_decltypes; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} v__ast__TypeDecl decl = (*(v__ast__TypeDecl*)DenseArray_value(&_t1.key_values, _t2)); if ((*(decl.is_markused))) { v__markused__Walker_mark_by_type(w, (*(decl.typ))); } } } void v__markused__Walker_stmt(v__markused__Walker* w, v__ast__Stmt node_) { v__ast__Stmt node = node_; if (node._typ == 399 /* v.ast.EmptyStmt */) { } else if (node._typ == 397 /* v.ast.DebuggerStmt */) { w->uses_debugger = true; } else if (node._typ == 390 /* v.ast.AsmStmt */) { v__markused__Walker_asm_io(w, (*node._v__ast__AsmStmt).output); v__markused__Walker_asm_io(w, (*node._v__ast__AsmStmt).input); } else if (node._typ == 391 /* v.ast.AssertStmt */) { if ((*node._v__ast__AssertStmt).is_used) { w->uses_asserts = true; v__markused__Walker_expr(w, (*node._v__ast__AssertStmt).expr); if (((*node._v__ast__AssertStmt).extra)._typ != 354 /* v.ast.EmptyExpr */) { v__markused__Walker_expr(w, (*node._v__ast__AssertStmt).extra); } } } else if (node._typ == 392 /* v.ast.AssignStmt */) { v__markused__Walker_exprs(w, (*node._v__ast__AssignStmt).left); v__markused__Walker_exprs(w, (*node._v__ast__AssignStmt).right); } else if (node._typ == 393 /* v.ast.Block */) { v__markused__Walker_stmts(w, (*node._v__ast__Block).stmts); } else if (node._typ == 395 /* v.ast.ComptimeFor */) { v__markused__Walker_mark_by_type(w, (*node._v__ast__ComptimeFor).typ); v__markused__Walker_stmts(w, (*node._v__ast__ComptimeFor).stmts); switch ((*node._v__ast__ComptimeFor).kind) { case v__ast__ComptimeForKind__attributes: { w->uses_ct_attribute = true; break; } case v__ast__ComptimeForKind__variants: { w->uses_ct_variants = true; break; } case v__ast__ComptimeForKind__params: { w->uses_ct_params = true; break; } case v__ast__ComptimeForKind__values: { w->uses_ct_values = true; break; } case v__ast__ComptimeForKind__fields: { w->uses_ct_fields = true; break; } case v__ast__ComptimeForKind__methods: { w->uses_ct_methods = true; break; } } } else if (node._typ == 396 /* v.ast.ConstDecl */) { v__markused__Walker_const_fields(w, (*node._v__ast__ConstDecl).fields); } else if (node._typ == 401 /* v.ast.ExprStmt */) { v__markused__Walker_expr(w, (*node._v__ast__ExprStmt).expr); } else if (node._typ == 237 /* v.ast.FnDecl */) { v__markused__Walker_fn_decl(w, &/*mut*/(*node._v__ast__FnDecl)); } else if (node._typ == 402 /* v.ast.ForCStmt */) { if ((*node._v__ast__ForCStmt).has_init) { v__markused__Walker_stmt(w, (*node._v__ast__ForCStmt).init); } if ((*node._v__ast__ForCStmt).has_cond) { v__markused__Walker_expr(w, (*node._v__ast__ForCStmt).cond); } if ((*node._v__ast__ForCStmt).has_inc) { v__markused__Walker_stmt(w, (*node._v__ast__ForCStmt).inc); } v__markused__Walker_stmts(w, (*node._v__ast__ForCStmt).stmts); } else if (node._typ == 403 /* v.ast.ForInStmt */) { v__markused__Walker_expr(w, (*node._v__ast__ForInStmt).cond); v__markused__Walker_expr(w, (*node._v__ast__ForInStmt).high); v__markused__Walker_stmts(w, (*node._v__ast__ForInStmt).stmts); v__markused__Walker_mark_by_type(w, (*node._v__ast__ForInStmt).cond_type); if ((*node._v__ast__ForInStmt).kind == v__ast__Kind__map) { w->features->used_maps++; } else if ((*node._v__ast__ForInStmt).kind == v__ast__Kind__struct) { if ((*node._v__ast__ForInStmt).cond_type == 0) { return; } v__ast__TypeSymbol* cond_type_sym = v__ast__Table_sym(w->table, (*node._v__ast__ForInStmt).cond_type); _option_v__ast__Fn _t1; if (_t1 = v__ast__TypeSymbol_find_method(cond_type_sym, _S("next")), _t1.state == 0) { v__ast__Fn next_fn = *(v__ast__Fn*)_t1.data; v__markused__Walker_fn_decl(w, ((v__ast__FnDecl*)(next_fn.source_fn))); } } } else if (node._typ == 404 /* v.ast.ForStmt */) { if (!(*node._v__ast__ForStmt).is_inf) { v__markused__Walker_expr(w, (*node._v__ast__ForStmt).cond); } v__markused__Walker_stmts(w, (*node._v__ast__ForStmt).stmts); } else if (node._typ == 412 /* v.ast.Return */) { v__markused__Walker_exprs(w, (*node._v__ast__Return).exprs); } else if (node._typ == 414 /* v.ast.SqlStmt */) { v__markused__Walker_expr(w, (*node._v__ast__SqlStmt).db_expr); v__markused__Walker_expr(w, v__ast__OrExpr_to_sumtype_v__ast__Expr(&(*node._v__ast__SqlStmt).or_expr)); for (int _t2 = 0; _t2 < (*node._v__ast__SqlStmt).lines.len; ++_t2) { v__ast__SqlStmtLine line = ((v__ast__SqlStmtLine*)(*node._v__ast__SqlStmt).lines.data)[_t2]; if (line.table_expr.typ != 0) { v__markused__Walker_mark_by_sym(w, *v__ast__Table_sym(w->table, line.table_expr.typ)); } v__markused__Walker_expr(w, line.where_expr); v__markused__Walker_exprs(w, line.update_exprs); } w->uses_orm = true; } else if (node._typ == 415 /* v.ast.StructDecl */) { for (int _t3 = 0; _t3 < (*node._v__ast__StructDecl).implements_types.len; ++_t3) { v__ast__TypeNode typ = ((v__ast__TypeNode*)(*node._v__ast__StructDecl).implements_types.data)[_t3]; v__markused__Walker_mark_by_type(w, typ.typ); } v__markused__Walker_struct_fields(w, (*node._v__ast__StructDecl).fields); if (!w->uses_mem_align) { w->uses_mem_align = Array_v__ast__Attr_contains((*node._v__ast__StructDecl).attrs, _S("aligned")); } } else if (node._typ == 398 /* v.ast.DeferStmt */) { v__markused__Walker_stmts(w, (*node._v__ast__DeferStmt).stmts); } else if (node._typ == 405 /* v.ast.GlobalDecl */) { for (int _t4 = 0; _t4 < (*node._v__ast__GlobalDecl).fields.len; ++_t4) { v__ast__GlobalField gf = ((v__ast__GlobalField*)(*node._v__ast__GlobalDecl).fields.data)[_t4]; if (gf.has_expr) { v__markused__Walker_expr(w, gf.expr); } } } else if (node._typ == 394 /* v.ast.BranchStmt */) { } else if (node._typ == 400 /* v.ast.EnumDecl */) { } else if (node._typ == 406 /* v.ast.GotoLabel */) { } else if (node._typ == 407 /* v.ast.GotoStmt */) { } else if (node._typ == 408 /* v.ast.HashStmt */) { } else if (node._typ == 409 /* v.ast.Import */) { } else if (node._typ == 410 /* v.ast.InterfaceDecl */) { } else if (node._typ == 413 /* v.ast.SemicolonStmt */) { } else if (node._typ == 411 /* v.ast.Module */) { } else if (node._typ == 334 /* v.ast.TypeDecl */) { } else if (node._typ == 335 /* v.ast.NodeError */) { } } VV_LOC void v__markused__Walker_asm_io(v__markused__Walker* w, Array_v__ast__AsmIO ios) { for (int _t1 = 0; _t1 < ios.len; ++_t1) { v__ast__AsmIO io = ((v__ast__AsmIO*)ios.data)[_t1]; v__markused__Walker_expr(w, io.expr); } } VV_LOC void v__markused__Walker_defer_stmts(v__markused__Walker* w, Array_v__ast__DeferStmt stmts) { for (int _t1 = 0; _t1 < stmts.len; ++_t1) { v__ast__DeferStmt stmt = ((v__ast__DeferStmt*)stmts.data)[_t1]; v__markused__Walker_stmts(w, stmt.stmts); } } VV_LOC void v__markused__Walker_stmts(v__markused__Walker* w, Array_v__ast__Stmt stmts) { for (int _t1 = 0; _t1 < stmts.len; ++_t1) { v__ast__Stmt stmt = ((v__ast__Stmt*)stmts.data)[_t1]; v__markused__Walker_stmt(w, stmt); } } VV_LOC void v__markused__Walker_exprs(v__markused__Walker* w, Array_v__ast__Expr exprs) { for (int _t1 = 0; _t1 < exprs.len; ++_t1) { v__ast__Expr expr = ((v__ast__Expr*)exprs.data)[_t1]; v__markused__Walker_expr(w, expr); } } VV_LOC void v__markused__Walker_expr(v__markused__Walker* w, v__ast__Expr node_) { v__ast__Expr node = node_; if (node._typ == 354 /* v.ast.EmptyExpr */) { } else if (node._typ == 351 /* v.ast.ComptimeType */) { } else if (node._typ == 336 /* v.ast.AnonFn */) { v__markused__Walker_fn_decl(w, (voidptr)&(*node._v__ast__AnonFn).decl); } else if (node._typ == 338 /* v.ast.ArrayInit */) { v__ast__TypeSymbol* sym = v__ast__Table_sym(w->table, (*node._v__ast__ArrayInit).elem_type); v__markused__Walker_mark_by_sym(w, *sym); if ((sym->info)._typ == 551 /* v.ast.Thread */) { v__markused__Walker_mark_by_type(w, v__ast__Table_find_or_register_array(w->table, (*sym->info._v__ast__Thread).return_type)); } v__markused__Walker_mark_by_type(w, (*node._v__ast__ArrayInit).typ); v__markused__Walker_expr(w, (*node._v__ast__ArrayInit).len_expr); v__markused__Walker_expr(w, (*node._v__ast__ArrayInit).cap_expr); v__markused__Walker_expr(w, (*node._v__ast__ArrayInit).init_expr); v__markused__Walker_exprs(w, (*node._v__ast__ArrayInit).exprs); w->uses_array = true; } else if (node._typ == 340 /* v.ast.Assoc */) { v__markused__Walker_exprs(w, (*node._v__ast__Assoc).exprs); } else if (node._typ == 337 /* v.ast.ArrayDecompose */) { v__markused__Walker_expr(w, (*node._v__ast__ArrayDecompose).expr); } else if (node._typ == 344 /* v.ast.CallExpr */) { v__markused__Walker_call_expr(w, &/*mut*/(*node._v__ast__CallExpr)); if (fast_string_eq((*node._v__ast__CallExpr).name, _S("json.decode"))) { v__markused__Walker_mark_by_type(w, (*(v__ast__TypeNode*)__as_cast(((*(v__ast__CallArg*)array_get((*node._v__ast__CallExpr).args, 0)).expr)._v__ast__TypeNode,((*(v__ast__CallArg*)array_get((*node._v__ast__CallExpr).args, 0)).expr)._typ, 386)).typ); } else if (fast_string_eq((*node._v__ast__CallExpr).name, _S("json.encode")) && (*(v__ast__CallArg*)array_get((*node._v__ast__CallExpr).args, 0)).typ != 0) { v__ast__TypeSymbol* sym = v__ast__Table_final_sym(w->table, (*(v__ast__CallArg*)array_get((*node._v__ast__CallExpr).args, 0)).typ); if ((sym->info)._typ == 514 /* v.ast.Map */) { v__markused__Walker_mark_by_type(w, v__ast__Table_find_or_register_array(w->table, (*sym->info._v__ast__Map).key_type)); } } else if (!(*node._v__ast__CallExpr).is_method && (*node._v__ast__CallExpr).args.len == 1 && (*(v__ast__CallArg*)array_get((*node._v__ast__CallExpr).args, 0)).typ != _const_v__ast__string_type && (fast_string_eq((*node._v__ast__CallExpr).name, _S("println")) || fast_string_eq((*node._v__ast__CallExpr).name, _S("print")) || fast_string_eq((*node._v__ast__CallExpr).name, _S("eprint")) || fast_string_eq((*node._v__ast__CallExpr).name, _S("eprintln")))) { map_set(&w->uses_str, &(v__ast__Type[]){(*(v__ast__CallArg*)array_get((*node._v__ast__CallExpr).args, 0)).typ}, &(bool[]) { true }); } else if ((*node._v__ast__CallExpr).is_method && fast_string_eq((*node._v__ast__CallExpr).name, _S("str"))) { map_set(&w->uses_str, &(v__ast__Type[]){(*node._v__ast__CallExpr).left_type}, &(bool[]) { true }); } else if ((*node._v__ast__CallExpr).is_method && fast_string_eq((*node._v__ast__CallExpr).name, _S("free"))) { map_set(&w->uses_free, &(v__ast__Type[]){(*node._v__ast__CallExpr).left_type}, &(bool[]) { true }); } if (!w->is_builtin_mod && !w->uses_external_type) { if ((*node._v__ast__CallExpr).is_method) { w->uses_external_type = fast_string_eq((*node._v__ast__CallExpr).mod, _S("builtin")); } else if (string_contains((*node._v__ast__CallExpr).name, _S(".")) && string_all_before_last((*node._v__ast__CallExpr).name, _S(".")).len > 1) { w->uses_external_type = true; } } if ((*node._v__ast__CallExpr).is_method && (*node._v__ast__CallExpr).left_type != 0 && (v__ast__Table_final_sym(w->table, (*node._v__ast__CallExpr).left_type)->kind == v__ast__Kind__array_fixed || v__ast__Table_final_sym(w->table, (*node._v__ast__CallExpr).left_type)->kind == v__ast__Kind__array)) { v__markused__Walker_mark_by_type(w, (*node._v__ast__CallExpr).return_type); } } else if (node._typ == 345 /* v.ast.CastExpr */) { v__markused__Walker_expr(w, (*node._v__ast__CastExpr).expr); v__markused__Walker_expr(w, (*node._v__ast__CastExpr).arg); if (!w->uses_memdup) { v__ast__TypeSymbol* fsym = v__ast__Table_final_sym(w->table, (*node._v__ast__CastExpr).typ); w->uses_memdup = fsym->kind == v__ast__Kind__sum_type; } v__markused__Walker_mark_by_type(w, (*node._v__ast__CastExpr).typ); if (v__ast__Type_has_flag((*node._v__ast__CastExpr).typ, v__ast__TypeFlag__option)) { w->used_option++; } else if (v__ast__Type_has_flag((*node._v__ast__CastExpr).typ, v__ast__TypeFlag__result)) { w->used_result++; } } else if (node._typ == 346 /* v.ast.ChanInit */) { v__markused__Walker_expr(w, (*node._v__ast__ChanInit).cap_expr); v__markused__Walker_mark_by_type(w, (*node._v__ast__ChanInit).typ); w->uses_channel = true; } else if (node._typ == 352 /* v.ast.ConcatExpr */) { v__markused__Walker_exprs(w, (*node._v__ast__ConcatExpr).vals); v__markused__Walker_mark_by_sym(w, *v__ast__Table_sym(w->table, (*node._v__ast__ConcatExpr).return_type)); } else if (node._typ == 350 /* v.ast.ComptimeSelector */) { v__markused__Walker_expr(w, (*node._v__ast__ComptimeSelector).left); v__markused__Walker_expr(w, (*node._v__ast__ComptimeSelector).field_expr); } else if (node._typ == 349 /* v.ast.ComptimeCall */) { v__markused__Walker_expr(w, (*node._v__ast__ComptimeCall).left); if ((*node._v__ast__ComptimeCall).is_vweb) { v__markused__Walker_stmts(w, (*node._v__ast__ComptimeCall).veb_tmpl.stmts); } if ((*node._v__ast__ComptimeCall).kind == v__ast__ComptimeCallKind__embed_file) { w->features->used_maps++; } } else if (node._typ == 353 /* v.ast.DumpExpr */) { v__markused__Walker_expr(w, (*node._v__ast__DumpExpr).expr); w->uses_dump = true; v__markused__Walker_mark_by_type(w, (*node._v__ast__DumpExpr).expr_type); } else if (node._typ == 381 /* v.ast.SpawnExpr */) { if ((*node._v__ast__SpawnExpr).is_expr) { v__markused__Walker_fn_by_name(w, _S("free")); } v__markused__Walker_expr(w, v__ast__CallExpr_to_sumtype_v__ast__Expr(&(*node._v__ast__SpawnExpr).call_expr)); w->uses_spawn = true; if (w->pref->os == v__pref__OS__windows) { v__markused__Walker_fn_by_name(w, _S("panic_lasterr")); v__markused__Walker_fn_by_name(w, _S("winapi_lasterr_str")); } else { v__markused__Walker_fn_by_name(w, _S("c_error_number_str")); v__markused__Walker_fn_by_name(w, _S("panic_error_number")); } } else if (node._typ == 357 /* v.ast.GoExpr */) { if ((*node._v__ast__GoExpr).is_expr) { v__markused__Walker_fn_by_name(w, _S("free")); } v__markused__Walker_mark_by_type(w, (*node._v__ast__GoExpr).call_expr.return_type); v__markused__Walker_expr(w, v__ast__CallExpr_to_sumtype_v__ast__Expr(&(*node._v__ast__GoExpr).call_expr)); } else if (node._typ == 361 /* v.ast.IndexExpr */) { v__markused__Walker_expr(w, (*node._v__ast__IndexExpr).left); v__markused__Walker_expr(w, (*node._v__ast__IndexExpr).index); if ((*node._v__ast__IndexExpr).or_expr.kind == v__ast__OrKind__block) { w->uses_guard = true; } v__markused__Walker_mark_by_type(w, (*node._v__ast__IndexExpr).typ); v__markused__Walker_or_block(w, (*node._v__ast__IndexExpr).or_expr); if ((*node._v__ast__IndexExpr).left_type == 0) { return; } v__ast__TypeSymbol* sym = v__ast__Table_final_sym(w->table, (*node._v__ast__IndexExpr).left_type); if ((sym->info)._typ == 514 /* v.ast.Map */) { if ((*node._v__ast__IndexExpr).is_setter) { v__markused__Walker_mark_builtin_map_method_as_used(w, _S("set")); } else { v__markused__Walker_mark_builtin_map_method_as_used(w, _S("get")); } v__markused__Walker_mark_by_sym(w, *v__ast__Table_sym(w->table, (*sym->info._v__ast__Map).key_type)); v__markused__Walker_mark_by_sym(w, *v__ast__Table_sym(w->table, (*sym->info._v__ast__Map).value_type)); w->features->used_maps++; } else if ((sym->info)._typ == 513 /* v.ast.Array */) { if ((*node._v__ast__IndexExpr).is_setter) { v__markused__Walker_mark_builtin_array_method_as_used(w, _S("set")); } else { v__markused__Walker_mark_builtin_array_method_as_used(w, _S("get")); } v__markused__Walker_mark_by_sym(w, *v__ast__Table_sym(w->table, (*sym->info._v__ast__Array).elem_type)); } else if (sym->kind == v__ast__Kind__string) { if (((*node._v__ast__IndexExpr).index)._typ == 377 /* v.ast.RangeExpr */) { v__markused__Walker_mark_builtin_array_method_as_used(w, _S("slice")); w->features->range_index = true; } } else if ((sym->info)._typ == 518 /* v.ast.Struct */) { v__markused__Walker_mark_by_sym(w, *sym); } else if ((sym->info)._typ == 544 /* v.ast.SumType */) { v__markused__Walker_mark_by_sym(w, *sym); } } else if (node._typ == 362 /* v.ast.InfixExpr */) { v__markused__Walker_expr(w, (*node._v__ast__InfixExpr).left); v__markused__Walker_expr(w, (*node._v__ast__InfixExpr).right); v__markused__Walker_or_block(w, (*node._v__ast__InfixExpr).or_block); if ((*node._v__ast__InfixExpr).left_type != 0) { v__ast__TypeSymbol* sym = v__ast__Table_sym(w->table, (*node._v__ast__InfixExpr).left_type); v__markused__Walker_mark_by_sym(w, *sym); if (sym->kind == v__ast__Kind__struct) { _option_v__ast__Fn _t1; if (_t1 = v__ast__TypeSymbol_find_method(sym, v__token__Kind_str((*node._v__ast__InfixExpr).op)), _t1.state == 0) { v__ast__Fn opmethod = *(v__ast__Fn*)_t1.data; v__markused__Walker_fn_decl(w, ((v__ast__FnDecl*)(opmethod.source_fn))); } } } v__ast__Type right_type = ((*node._v__ast__InfixExpr).right_type == 0 && ((*node._v__ast__InfixExpr).right)._typ == 386 /* v.ast.TypeNode */ ? ((*(*node._v__ast__InfixExpr).right._v__ast__TypeNode).typ) : ((*node._v__ast__InfixExpr).right_type)); if (right_type != 0) { v__markused__Walker_mark_by_type(w, right_type); v__ast__TypeSymbol* right_sym = v__ast__Table_sym(w->table, right_type); if ((*node._v__ast__InfixExpr).op == v__token__Kind__not_in || (*node._v__ast__InfixExpr).op == v__token__Kind__key_in) { if (right_sym->kind == v__ast__Kind__map) { w->features->used_maps++; } if (!w->uses_arr_void && (right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__array_fixed)) { w->uses_arr_void = true; } } else if ((*node._v__ast__InfixExpr).op == v__token__Kind__key_is || (*node._v__ast__InfixExpr).op == v__token__Kind__not_is) { v__markused__Walker_mark_by_sym(w, *right_sym); } } if (!w->uses_eq && ((*node._v__ast__InfixExpr).op == v__token__Kind__eq || (*node._v__ast__InfixExpr).op == v__token__Kind__ne)) { w->uses_eq = true; } } else if (node._typ == 360 /* v.ast.IfGuardExpr */) { v__markused__Walker_expr(w, (*node._v__ast__IfGuardExpr).expr); v__markused__Walker_mark_by_type(w, (*node._v__ast__IfGuardExpr).expr_type); w->uses_guard = true; } else if (node._typ == 359 /* v.ast.IfExpr */) { v__markused__Walker_expr(w, (*node._v__ast__IfExpr).left); for (int _t2 = 0; _t2 < (*node._v__ast__IfExpr).branches.len; ++_t2) { v__ast__IfBranch b = ((v__ast__IfBranch*)(*node._v__ast__IfExpr).branches.data)[_t2]; v__markused__Walker_expr(w, b.cond); v__markused__Walker_stmts(w, b.stmts); } } else if (node._typ == 358 /* v.ast.Ident */) { if ((*node._v__ast__Ident).kind == (v__ast__IdentKind__constant)) { v__markused__Walker_mark_const_as_used(w, (*node._v__ast__Ident).name); } else if ((*node._v__ast__Ident).kind == (v__ast__IdentKind__function)) { v__markused__Walker_fn_by_name(w, (*node._v__ast__Ident).name); if (((*node._v__ast__Ident).info)._typ == 476 /* v.ast.IdentFn */) { v__markused__Walker_mark_by_type(w, (*((*node._v__ast__Ident).info.typ))); } } else if ((*node._v__ast__Ident).kind == (v__ast__IdentKind__global)) { v__markused__Walker_mark_global_as_used(w, (*node._v__ast__Ident).name); } else if ((*node._v__ast__Ident).kind == (v__ast__IdentKind__blank_ident)) { } else { if (_IN_MAP(ADDR(string, (*node._v__ast__Ident).name), ADDR(map, w->all_consts))) { v__markused__Walker_mark_const_as_used(w, (*node._v__ast__Ident).name); } else if (_IN_MAP(ADDR(string, (*node._v__ast__Ident).name), ADDR(map, w->all_globals))) { v__markused__Walker_mark_global_as_used(w, (*node._v__ast__Ident).name); } else { if (!w->uses_err && !w->is_builtin_mod && fast_string_eq((*node._v__ast__Ident).name, _S("err"))) { v__markused__Walker_fn_by_name(w, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(_const_v__ast__error_type))}}, {_S(".str"), 0, { .d_c = 0 }}}))); w->uses_err = true; } v__markused__Walker_fn_by_name(w, (*node._v__ast__Ident).name); } if (!w->uses_atomic && ((*node._v__ast__Ident).info)._typ == 477 /* v.ast.IdentVar */) { w->uses_atomic = v__ast__Type_has_flag((*((*node._v__ast__Ident).info.typ)), v__ast__TypeFlag__atomic_f); } } v__markused__Walker_or_block(w, (*node._v__ast__Ident).or_expr); } else if (node._typ == 365 /* v.ast.LambdaExpr */) { v__markused__Walker_expr(w, v__ast__AnonFn_to_sumtype_v__ast__Expr((*node._v__ast__LambdaExpr).func)); } else if (node._typ == 366 /* v.ast.Likely */) { v__markused__Walker_expr(w, (*node._v__ast__Likely).expr); } else if (node._typ == 368 /* v.ast.MapInit */) { v__markused__Walker_exprs(w, (*node._v__ast__MapInit).keys); v__markused__Walker_exprs(w, (*node._v__ast__MapInit).vals); if ((*node._v__ast__MapInit).has_update_expr) { v__markused__Walker_expr(w, (*node._v__ast__MapInit).update_expr); } if ((*node._v__ast__MapInit).vals.len > 0 && (*node._v__ast__MapInit).has_update_expr) { w->uses_map_update = true; } v__ast__Map mapinfo = v__ast__TypeSymbol_map_info(v__ast__Table_final_sym(w->table, (*node._v__ast__MapInit).typ)); v__ast__TypeSymbol* ksym = v__ast__Table_sym(w->table, mapinfo.key_type); v__ast__TypeSymbol* vsym = v__ast__Table_sym(w->table, mapinfo.value_type); if (v__ast__Type_has_flag((*node._v__ast__MapInit).typ, v__ast__TypeFlag__shared_f)) { w->uses_lock = true; } v__markused__Walker_mark_by_sym(w, *ksym); v__markused__Walker_mark_by_sym(w, *vsym); w->features->used_maps++; v__markused__Walker_mark_by_type(w, (*node._v__ast__MapInit).typ); } else if (node._typ == 369 /* v.ast.MatchExpr */) { v__markused__Walker_expr(w, (*node._v__ast__MatchExpr).cond); for (int _t3 = 0; _t3 < (*node._v__ast__MatchExpr).branches.len; ++_t3) { v__ast__MatchBranch b = ((v__ast__MatchBranch*)(*node._v__ast__MatchExpr).branches.data)[_t3]; v__markused__Walker_exprs(w, b.exprs); for (int _t4 = 0; _t4 < b.exprs.len; ++_t4) { v__ast__Expr expr = ((v__ast__Expr*)b.exprs.data)[_t4]; if ((expr)._typ == 386 /* v.ast.TypeNode */) { v__markused__Walker_mark_by_sym(w, *v__ast__Table_sym(w->table, (*expr._v__ast__TypeNode).typ)); } } v__markused__Walker_stmts(w, b.stmts); } } else if (node._typ == 371 /* v.ast.None */) { w->used_none++; } else if (node._typ == 370 /* v.ast.Nil */) { } else if (node._typ == 374 /* v.ast.ParExpr */) { v__markused__Walker_expr(w, (*node._v__ast__ParExpr).expr); } else if (node._typ == 376 /* v.ast.PrefixExpr */) { if (!w->uses_memdup && (*node._v__ast__PrefixExpr).op == v__token__Kind__amp) { w->uses_memdup = true; } v__markused__Walker_expr(w, (*node._v__ast__PrefixExpr).right); } else if (node._typ == 375 /* v.ast.PostfixExpr */) { v__markused__Walker_expr(w, (*node._v__ast__PostfixExpr).expr); } else if (node._typ == 377 /* v.ast.RangeExpr */) { if ((*node._v__ast__RangeExpr).has_low) { v__markused__Walker_expr(w, (*node._v__ast__RangeExpr).low); } if ((*node._v__ast__RangeExpr).has_high) { v__markused__Walker_expr(w, (*node._v__ast__RangeExpr).high); } } else if (node._typ == 380 /* v.ast.SizeOf */) { v__markused__Walker_expr(w, (*node._v__ast__SizeOf).expr); v__markused__Walker_mark_by_type(w, (*node._v__ast__SizeOf).typ); } else if (node._typ == 364 /* v.ast.IsRefType */) { v__markused__Walker_expr(w, (*node._v__ast__IsRefType).expr); v__markused__Walker_mark_by_type(w, (*node._v__ast__IsRefType).typ); } else if (node._typ == 383 /* v.ast.StringInterLiteral */) { w->uses_interp = true; v__markused__Walker_exprs(w, (*node._v__ast__StringInterLiteral).exprs); } else if (node._typ == 379 /* v.ast.SelectorExpr */) { v__markused__Walker_expr(w, (*node._v__ast__SelectorExpr).expr); if ((*node._v__ast__SelectorExpr).expr_type != 0) { v__markused__Walker_mark_by_type(w, (*node._v__ast__SelectorExpr).expr_type); _result_v__ast__Fn _t5; if (_t5 = v__ast__Table_find_method(w->table, v__ast__Table_sym(w->table, (*node._v__ast__SelectorExpr).expr_type), (*node._v__ast__SelectorExpr).field_name), !_t5.is_error) { v__ast__Fn method = *(v__ast__Fn*)_t5.data; v__markused__Walker_fn_by_name(w, v__ast__Fn_fkey(&method)); } } v__markused__Walker_mark_by_type(w, (*node._v__ast__SelectorExpr).typ); v__markused__Walker_or_block(w, (*node._v__ast__SelectorExpr).or_block); } else if (node._typ == 382 /* v.ast.SqlExpr */) { v__markused__Walker_expr(w, (*node._v__ast__SqlExpr).db_expr); v__markused__Walker_expr(w, v__ast__OrExpr_to_sumtype_v__ast__Expr(&(*node._v__ast__SqlExpr).or_expr)); v__markused__Walker_expr(w, (*node._v__ast__SqlExpr).offset_expr); v__markused__Walker_expr(w, (*node._v__ast__SqlExpr).order_expr); v__markused__Walker_expr(w, (*node._v__ast__SqlExpr).limit_expr); v__markused__Walker_expr(w, (*node._v__ast__SqlExpr).where_expr); v__markused__Walker_mark_by_type(w, (*node._v__ast__SqlExpr).typ); w->uses_orm = true; } else if (node._typ == 385 /* v.ast.StructInit */) { if ((*node._v__ast__StructInit).typ == 0) { return; } v__ast__TypeSymbol* sym = v__ast__Table_sym(w->table, (*node._v__ast__StructInit).typ); v__markused__Walker_mark_by_sym(w, *sym); if ((*node._v__ast__StructInit).has_update_expr) { v__markused__Walker_expr(w, (*node._v__ast__StructInit).update_expr); } for (int _t6 = 0; _t6 < (*node._v__ast__StructInit).init_fields.len; ++_t6) { v__ast__StructInitField sif = ((v__ast__StructInitField*)(*node._v__ast__StructInit).init_fields.data)[_t6]; v__markused__Walker_expr(w, sif.expr); } } else if (node._typ == 387 /* v.ast.TypeOf */) { v__markused__Walker_expr(w, (*node._v__ast__TypeOf).expr); v__markused__Walker_mark_by_type(w, (*node._v__ast__TypeOf).typ); } else if (node._typ == 339 /* v.ast.AsCast */) { v__markused__Walker_expr(w, (*node._v__ast__AsCast).expr); v__markused__Walker_fn_by_name(w, _S("__as_cast")); v__markused__Walker_fn_by_name(w, _S("new_array_from_c_array")); v__markused__Walker_mark_by_sym_name(w, _S("VCastTypeIndexName")); } else if (node._typ == 341 /* v.ast.AtExpr */) { } else if (node._typ == 342 /* v.ast.BoolLiteral */) { } else if (node._typ == 356 /* v.ast.FloatLiteral */) { } else if (node._typ == 347 /* v.ast.CharLiteral */) { } else if (node._typ == 363 /* v.ast.IntegerLiteral */) { } else if (node._typ == 384 /* v.ast.StringLiteral */) { } else if (node._typ == 343 /* v.ast.CTempVar */) { v__markused__Walker_expr(w, (*node._v__ast__CTempVar).orig); } else if (node._typ == 348 /* v.ast.Comment */) { } else if (node._typ == 355 /* v.ast.EnumVal */) { v__ast__EnumDecl* _t8 = (v__ast__EnumDecl*)(map_get_check(ADDR(map, w->table->enum_decls), &(string[]){(*node._v__ast__EnumVal).enum_name})); _option_v__ast__EnumDecl _t7 = {0}; if (_t8) { *((v__ast__EnumDecl*)&_t7.data) = *((v__ast__EnumDecl*)_t8); } else { _t7.state = 2; _t7.err = _v_error(_S("map key does not exist")); } if (_t7.state == 0) { v__ast__EnumDecl e = (*(v__ast__EnumDecl*)_t7.data); Array_v__ast__EnumField _t9 = {0}; Array_v__ast__EnumField _t9_orig = e.fields; int _t9_len = _t9_orig.len; _t9 = __new_array(0, _t9_len, sizeof(v__ast__EnumField)); for (int _t10 = 0; _t10 < _t9_len; ++_t10) { v__ast__EnumField it = ((v__ast__EnumField*) _t9_orig.data)[_t10]; if (string__eq(it.name, (*node._v__ast__EnumVal).val)) { array_push((array*)&_t9, &it); } } Array_v__ast__EnumField filtered =_t9; if (filtered.len != 0 && ((*(v__ast__EnumField*)array_get(filtered, 0)).expr)._typ != 354 /* v.ast.EmptyExpr */) { v__markused__Walker_expr(w, (*(v__ast__EnumField*)array_get(filtered, 0)).expr); } } v__markused__Walker_mark_by_sym_name(w, (*node._v__ast__EnumVal).enum_name); } else if (node._typ == 367 /* v.ast.LockExpr */) { w->uses_lock = true; v__markused__Walker_stmts(w, (*node._v__ast__LockExpr).stmts); } else if (node._typ == 372 /* v.ast.OffsetOf */) { } else if (node._typ == 373 /* v.ast.OrExpr */) { v__markused__Walker_or_block(w, (*node._v__ast__OrExpr)); } else if (node._typ == 378 /* v.ast.SelectExpr */) { for (int _t11 = 0; _t11 < (*node._v__ast__SelectExpr).branches.len; ++_t11) { v__ast__SelectBranch branch = ((v__ast__SelectBranch*)(*node._v__ast__SelectExpr).branches.data)[_t11]; v__markused__Walker_stmt(w, branch.stmt); v__markused__Walker_stmts(w, branch.stmts); } w->uses_channel = true; } else if (node._typ == 386 /* v.ast.TypeNode */) { v__markused__Walker_mark_by_type(w, (*node._v__ast__TypeNode).typ); } else if (node._typ == 388 /* v.ast.UnsafeExpr */) { v__markused__Walker_expr(w, (*node._v__ast__UnsafeExpr).expr); } else if (node._typ == 335 /* v.ast.NodeError */) { } } void v__markused__Walker_fn_decl(v__markused__Walker* w, v__ast__FnDecl* node) { bool v__markused__Walker_fn_decl_defer_0 = false; bool last_is_builtin_mod; bool v__markused__Walker_fn_decl_defer_1 = false; if (node == ((void*)0)) { return; } if (w->level == 0) { last_is_builtin_mod = w->is_builtin_mod; w->is_builtin_mod = (fast_string_eq(node->mod, _S("builtin")) || fast_string_eq(node->mod, _S("os")) || fast_string_eq(node->mod, _S("strconv")) || fast_string_eq(node->mod, _S("builtin.closure"))); v__markused__Walker_fn_decl_defer_0 = true; } if (node->language == v__ast__Language__c) { v__markused__Walker_mark_fn_as_used(w, v__ast__FnDecl_fkey(node)); v__markused__Walker_mark_fn_ret_and_params(w, node->return_type, node->params); // Defer begin if (v__markused__Walker_fn_decl_defer_0) { w->is_builtin_mod = last_is_builtin_mod; } // Defer end return; } string fkey = v__ast__FnDecl_fkey(node); if ((*(bool*)map_get(ADDR(map, w->used_fns), &(string[]){fkey}, &(bool[]){ 0 }))) { // Defer begin if (v__markused__Walker_fn_decl_defer_0) { w->is_builtin_mod = last_is_builtin_mod; } // Defer end return; } if (node->no_body) { // Defer begin if (v__markused__Walker_fn_decl_defer_0) { w->is_builtin_mod = last_is_builtin_mod; } // Defer end return; } if (w->trace_enabled) { w->level++; v__markused__Walker_fn_decl_defer_1 = true; string receiver_name = (node->is_method && node->receiver.typ != 0 ? (string__plus(v__ast__Table_type_to_str(w->table, node->receiver.typ), _S("."))) : (_S(""))); eprintln(str_intp(4, _MOV((StrIntpData[]){{_S(">>>"), 0xfe10, {.d_s = string_repeat(_S(" "), w->level)}}, {_SLIT0, 0xfe10, {.d_s = receiver_name}}, {_SLIT0, 0xfe10, {.d_s = node->name}}, {_S(" [decl]"), 0, { .d_c = 0 }}}))); } if (node->is_method) { v__markused__Walker_mark_by_type(w, node->receiver.typ); } v__markused__Walker_mark_fn_ret_and_params(w, node->return_type, node->params); v__markused__Walker_mark_fn_as_used(w, fkey); v__markused__Walker_stmts(w, node->stmts); v__markused__Walker_defer_stmts(w, node->defer_stmts); // Defer begin if (v__markused__Walker_fn_decl_defer_1) { w->level--; } // Defer end // Defer begin if (v__markused__Walker_fn_decl_defer_0) { w->is_builtin_mod = last_is_builtin_mod; } // Defer end } void v__markused__Walker_call_expr(v__markused__Walker* w, v__ast__CallExpr* node) { bool v__markused__Walker_call_expr_defer_0 = false; if (node == ((void*)0)) { return; } for (int _t1 = 0; _t1 < node->args.len; ++_t1) { v__ast__CallArg arg = ((v__ast__CallArg*)node->args.data)[_t1]; v__markused__Walker_expr(w, arg.expr); } for (int _t2 = 0; _t2 < node->concrete_types.len; ++_t2) { v__ast__Type concrete_type = ((v__ast__Type*)node->concrete_types.data)[_t2]; v__markused__Walker_mark_by_type(w, concrete_type); } if (node->language == v__ast__Language__c) { if (fast_string_eq(node->name, _S("C.wyhash")) || fast_string_eq(node->name, _S("C.wyhash64"))) { w->features->used_maps++; } v__markused__Walker_mark_by_type(w, node->return_type); return; } if (node->is_method && node->left_type != 0) { v__markused__Walker_mark_by_type(w, node->left_type); v__ast__TypeSymbol* left_sym = v__ast__Table_sym(w->table, node->left_type); if ((left_sym->info)._typ == 537 /* v.ast.Aggregate */) { for (int _t3 = 0; _t3 < (*left_sym->info._v__ast__Aggregate).types.len; ++_t3) { v__ast__Type receiver_type = ((v__ast__Type*)(*left_sym->info._v__ast__Aggregate).types.data)[_t3]; v__ast__TypeSymbol* receiver_sym = v__ast__Table_sym(w->table, receiver_type); _option_v__ast__Fn _t4; if (_t4 = v__ast__TypeSymbol_find_method(receiver_sym, node->name), _t4.state == 0) { v__ast__Fn m = *(v__ast__Fn*)_t4.data; string fn_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(m.receiver_type))}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})); if (!(*(bool*)map_get(ADDR(map, w->used_fns), &(string[]){fn_name}, &(bool[]){ 0 }))) { v__markused__Walker_fn_by_name(w, fn_name); } } } } else if ((left_sym->info)._typ == 542 /* v.ast.Interface */) { for (int _t5 = 0; _t5 < (*left_sym->info._v__ast__Interface).types.len; ++_t5) { v__ast__Type typ = ((v__ast__Type*)(*left_sym->info._v__ast__Interface).types.data)[_t5]; v__ast__TypeSymbol* sym = v__ast__Table_sym(w->table, typ); _result_multi_return_v__ast__Fn_Array_v__ast__Type _t6 = v__ast__Table_find_method_from_embeds(w->table, sym, node->name); if (_t6.is_error) { IError err = _t6.err; *(multi_return_v__ast__Fn_Array_v__ast__Type*) _t6.data = (multi_return_v__ast__Fn_Array_v__ast__Type){.arg0=((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } multi_return_v__ast__Fn_Array_v__ast__Type mr_20659 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t6.data); Array_v__ast__Type embed_types = mr_20659.arg1; if (embed_types.len != 0) { string fn_embed = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)((*(v__ast__Type*)array_last(embed_types))))}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})); v__markused__Walker_fn_by_name(w, fn_embed); } } } else if (node->from_embed_types.len != 0 && !v__ast__Type_has_flag(node->left_type, v__ast__TypeFlag__generic)) { _result_multi_return_v__ast__Fn_Array_v__ast__Type _t7 = v__ast__Table_find_method_from_embeds(w->table, v__ast__Table_final_sym(w->table, node->left_type), node->name); if (_t7.is_error) { IError err = _t7.err; *(multi_return_v__ast__Fn_Array_v__ast__Type*) _t7.data = (multi_return_v__ast__Fn_Array_v__ast__Type){.arg0=((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } multi_return_v__ast__Fn_Array_v__ast__Type mr_20978 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t7.data); Array_v__ast__Type embed_types = mr_20978.arg1; if (embed_types.len != 0) { string fn_embed = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)((*(v__ast__Type*)array_last(embed_types))))}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})); v__markused__Walker_fn_by_name(w, fn_embed); } } else { if (left_sym->info._typ == 513 /* v.ast.Array */) { if (!w->uses_arr_void && (fast_string_eq(node->name, _S("contains")) || fast_string_eq(node->name, _S("index")))) { if (v__ast__Table_final_sym(w->table, (*left_sym->info._v__ast__Array).elem_type)->kind == v__ast__Kind__function) { w->uses_arr_void = true; } } } else if (left_sym->info._typ == 549 /* v.ast.ArrayFixed */) { if (!w->uses_arr_void && (fast_string_eq(node->name, _S("contains")) || fast_string_eq(node->name, _S("index")))) { if (v__ast__Table_final_sym(w->table, (*left_sym->info._v__ast__ArrayFixed).elem_type)->kind == v__ast__Kind__function) { w->uses_arr_void = true; } } } else { } } } v__markused__Walker_expr(w, node->left); v__markused__Walker_or_block(w, node->or_block); string fn_name = v__ast__CallExpr_fkey(node); v__ast__Type receiver_typ = node->receiver_type; if ((*(bool*)map_get(ADDR(map, w->used_fns), &(string[]){fn_name}, &(bool[]){ 0 }))) { return; } if (node->is_method) { if (node->left_type != 0) { v__ast__TypeSymbol* lsym = v__ast__Table_sym(w->table, node->left_type); if (lsym->kind == (v__ast__Kind__array)) { v__markused__Walker_mark_builtin_array_method_as_used(w, node->name); } else if (lsym->kind == (v__ast__Kind__map)) { v__markused__Walker_mark_builtin_map_method_as_used(w, node->name); } else { } } } else if (node->is_fn_a_const) { string const_fn_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->mod}}, {_S("."), 0xfe10, {.d_s = fn_name}}, {_SLIT0, 0, { .d_c = 0 }}})); if (_IN_MAP(ADDR(string, const_fn_name), ADDR(map, w->all_consts))) { v__markused__Walker_mark_const_as_used(w, const_fn_name); } } else if (node->is_fn_var) { v__markused__Walker_mark_global_as_used(w, node->name); } v__markused__Walker_mark_fn_as_used(w, fn_name); if (node->is_method && v__ast__Type_has_flag(node->receiver_type, v__ast__TypeFlag__generic) && node->receiver_concrete_type != 0 && !v__ast__Type_has_flag(node->receiver_concrete_type, v__ast__TypeFlag__generic)) { fn_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(node->receiver_concrete_type))}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})); receiver_typ = node->receiver_concrete_type; v__markused__Walker_mark_fn_as_used(w, fn_name); } v__markused__Walker_mark_by_type(w, node->return_type); v__ast__FnDecl* _t9 = (v__ast__FnDecl*)(map_get_check(ADDR(map, w->all_fns), &(string[]){fn_name})); _option_v__ast__FnDecl _t8 = {0}; if (_t9) { *((v__ast__FnDecl*)&_t8.data) = *((v__ast__FnDecl*)_t9); } else { _t8.state = 2; _t8.err = _v_error(_S("map key does not exist")); } ; if (_t8.state != 0) { IError err = _t8.err; return; } v__ast__FnDecl stmt = (*(v__ast__FnDecl*)_t8.data); if (!stmt.should_be_skipped && string__eq(stmt.name, node->name)) { if (!node->is_method || receiver_typ == stmt.receiver.typ) { if (w->trace_enabled) { w->level++; v__markused__Walker_call_expr_defer_0 = true; string receiver_name = (node->receiver_type != 0 ? (string__plus(v__ast__Table_type_to_str(w->table, node->receiver_type), _S("."))) : (_S(""))); eprintln(str_intp(4, _MOV((StrIntpData[]){{_S(">>>"), 0xfe10, {.d_s = string_repeat(_S(" "), w->level)}}, {_SLIT0, 0xfe10, {.d_s = receiver_name}}, {_SLIT0, 0xfe10, {.d_s = node->name}}, {_S(" [call]"), 0, { .d_c = 0 }}}))); } v__markused__Walker_mark_fn_ret_and_params(w, stmt.return_type, stmt.params); v__markused__Walker_stmts(w, stmt.stmts); } if (v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__option)) { w->used_option++; } else if (v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__result)) { w->used_result++; } } // Defer begin if (v__markused__Walker_call_expr_defer_0) { w->level--; } // Defer end } void v__markused__Walker_fn_by_name(v__markused__Walker* w, string fn_name) { bool v__markused__Walker_fn_by_name_defer_0 = false; if ((*(bool*)map_get(ADDR(map, w->used_fns), &(string[]){fn_name}, &(bool[]){ 0 }))) { return; } v__ast__FnDecl* _t2 = (v__ast__FnDecl*)(map_get_check(ADDR(map, w->all_fns), &(string[]){fn_name})); _option_v__ast__FnDecl _t1 = {0}; if (_t2) { *((v__ast__FnDecl*)&_t1.data) = *((v__ast__FnDecl*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } ; if (_t1.state != 0) { IError err = _t1.err; return; } v__ast__FnDecl stmt = (*(v__ast__FnDecl*)_t1.data); if (w->trace_enabled) { w->level++; v__markused__Walker_fn_by_name_defer_0 = true; string receiver_name = (string_contains(fn_name, _S(".")) && string_int(string_all_before_last(fn_name, _S("."))) > 0 ? (string__plus(v__ast__Table_type_to_str(w->table, string_int(string_all_before_last(fn_name, _S(".")))), _S("."))) : (_S(""))); eprintln(str_intp(4, _MOV((StrIntpData[]){{_S(">>>"), 0xfe10, {.d_s = string_repeat(_S(" "), w->level)}}, {_SLIT0, 0xfe10, {.d_s = receiver_name}}, {_SLIT0, 0xfe10, {.d_s = string_all_after_last(fn_name, _S("."))}}, {_S(" [by_name]"), 0, { .d_c = 0 }}}))); } v__markused__Walker_mark_fn_as_used(w, fn_name); v__markused__Walker_mark_fn_ret_and_params(w, stmt.return_type, stmt.params); v__markused__Walker_stmts(w, stmt.stmts); // Defer begin if (v__markused__Walker_fn_by_name_defer_0) { w->level--; } // Defer end } void v__markused__Walker_struct_fields(v__markused__Walker* w, Array_v__ast__StructField sfields) { for (int _t1 = 0; _t1 < sfields.len; ++_t1) { v__ast__StructField sf = ((v__ast__StructField*)sfields.data)[_t1]; if (sf.has_default_expr) { v__markused__Walker_expr(w, sf.default_expr); } if (!w->uses_atomic && v__ast__Type_has_flag(sf.typ, v__ast__TypeFlag__atomic_f)) { w->uses_atomic = true; } } } void v__markused__Walker_const_fields(v__markused__Walker* w, Array_v__ast__ConstField cfields) { for (int _t1 = 0; _t1 < cfields.len; ++_t1) { v__ast__ConstField cf = ((v__ast__ConstField*)cfields.data)[_t1]; v__markused__Walker_expr(w, cf.expr); } } inline void v__markused__Walker_or_block(v__markused__Walker* w, v__ast__OrExpr node) { if (node.kind == v__ast__OrKind__block) { v__markused__Walker_stmts(w, node.stmts); } else if (node.kind == v__ast__OrKind__propagate_option) { w->used_option++; w->used_panic++; } else if (node.kind == v__ast__OrKind__propagate_result) { w->used_result++; w->used_panic++; } } void v__markused__Walker_mark_fn_ret_and_params(v__markused__Walker* w, v__ast__Type return_type, Array_v__ast__Param params) { if (return_type != 0) { if (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__option)) { w->used_option++; } else if (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__result)) { w->used_result++; } v__markused__Walker_mark_by_type(w, v__ast__Type_clear_option_and_result(return_type)); } for (int _t1 = 0; _t1 < params.len; ++_t1) { v__ast__Param param = ((v__ast__Param*)params.data)[_t1]; v__markused__Walker_mark_by_type(w, param.typ); } } inline void v__markused__Walker_mark_by_sym_name(v__markused__Walker* w, string name) { _option_v__ast__TypeSymbol_ptr _t1; if (_t1 = v__ast__Table_find_sym(w->table, name), _t1.state == 0) { v__ast__TypeSymbol* sym = *(v__ast__TypeSymbol**)_t1.data; v__markused__Walker_mark_by_sym(w, *sym); } } inline void v__markused__Walker_mark_by_type(v__markused__Walker* w, v__ast__Type typ) { if (typ == 0 || v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { return; } v__markused__Walker_mark_by_sym(w, *v__ast__Table_sym(w->table, typ)); } void v__markused__Walker_mark_by_sym(v__markused__Walker* w, v__ast__TypeSymbol isym) { if (_IN_MAP(ADDR(int, isym.idx), ADDR(map, w->used_syms))) { return; } map_set(&w->used_syms, &(int[]){isym.idx}, &(bool[]) { true }); if (isym.info._typ == 518 /* v.ast.Struct */) { for (int _t1 = 0; _t1 < (*isym.info._v__ast__Struct).fields.len; ++_t1) { v__ast__StructField ifield = ((v__ast__StructField*)(*isym.info._v__ast__Struct).fields.data)[_t1]; if (ifield.has_default_expr) { v__markused__Walker_expr(w, ifield.default_expr); } if (ifield.typ != 0) { v__ast__TypeSymbol* fsym = v__ast__Table_sym(w->table, v__ast__Type_idx(ifield.typ)); if (v__ast__Type_has_flag(ifield.typ, v__ast__TypeFlag__option)) { w->used_option++; if (!ifield.has_default_expr) { w->used_none++; } } if (fsym->info._typ == 514 /* v.ast.Map */) { w->features->used_maps++; v__markused__Walker_mark_by_sym(w, *fsym); } else { v__markused__Walker_mark_by_sym(w, *fsym); } } if (!w->features->auto_str_ptr && v__ast__Type_is_ptr(ifield.typ) && _IN_MAP(ADDR(int, isym.idx), ADDR(map, w->features->print_types))) { w->features->auto_str_ptr = true; } } for (int _t2 = 0; _t2 < (*isym.info._v__ast__Struct).embeds.len; ++_t2) { v__ast__Type embed = ((v__ast__Type*)(*isym.info._v__ast__Struct).embeds.data)[_t2]; v__markused__Walker_mark_by_type(w, embed); } v__ast__StructDecl* _t4 = (v__ast__StructDecl*)(map_get_check(ADDR(map, w->all_structs), &(string[]){isym.name})); _option_v__ast__StructDecl _t3 = {0}; if (_t4) { *((v__ast__StructDecl*)&_t3.data) = *((v__ast__StructDecl*)_t4); } else { _t3.state = 2; _t3.err = _v_error(_S("map key does not exist")); } if (_t3.state == 0) { v__ast__StructDecl decl = (*(v__ast__StructDecl*)_t3.data); v__markused__Walker_struct_fields(w, decl.fields); if (!w->uses_mem_align) { w->uses_mem_align = Array_v__ast__Attr_contains(decl.attrs, _S("aligned")); } for (int _t5 = 0; _t5 < decl.implements_types.len; ++_t5) { v__ast__TypeNode iface_typ = ((v__ast__TypeNode*)decl.implements_types.data)[_t5]; v__markused__Walker_mark_by_type(w, iface_typ.typ); } } } else if (isym.info._typ == 549 /* v.ast.ArrayFixed */) { w->uses_array = true; v__markused__Walker_mark_by_type(w, (*isym.info._v__ast__ArrayFixed).elem_type); } else if (isym.info._typ == 513 /* v.ast.Array */) { w->uses_array = true; v__markused__Walker_mark_by_type(w, (*isym.info._v__ast__Array).elem_type); } else if (isym.info._typ == 544 /* v.ast.SumType */) { for (int _t6 = 0; _t6 < (*isym.info._v__ast__SumType).variants.len; ++_t6) { v__ast__Type typ = ((v__ast__Type*)(*isym.info._v__ast__SumType).variants.data)[_t6]; if (typ == _const_v__ast__map_type) { w->features->used_maps++; continue; } v__markused__Walker_mark_by_type(w, typ); } } else if (isym.info._typ == 514 /* v.ast.Map */) { v__markused__Walker_mark_by_type(w, (*isym.info._v__ast__Map).key_type); v__markused__Walker_mark_by_type(w, (*isym.info._v__ast__Map).value_type); w->features->used_maps++; } else if (isym.info._typ == 539 /* v.ast.Alias */) { v__markused__Walker_mark_by_type(w, (*isym.info._v__ast__Alias).parent_type); } else if (isym.info._typ == 553 /* v.ast.FnType */) { for (int _t7 = 0; _t7 < (*isym.info._v__ast__FnType).func.params.len; ++_t7) { v__ast__Param param = ((v__ast__Param*)(*isym.info._v__ast__FnType).func.params.data)[_t7]; v__markused__Walker_mark_by_type(w, param.typ); } if ((*isym.info._v__ast__FnType).func.return_type != 0) { v__markused__Walker_mark_by_type(w, v__ast__Type_clear_option_and_result((*isym.info._v__ast__FnType).func.return_type)); } } else if (isym.info._typ == 552 /* v.ast.MultiReturn */) { for (int _t8 = 0; _t8 < (*isym.info._v__ast__MultiReturn).types.len; ++_t8) { v__ast__Type typ = ((v__ast__Type*)(*isym.info._v__ast__MultiReturn).types.data)[_t8]; v__markused__Walker_mark_by_type(w, typ); } } else if (isym.info._typ == 550 /* v.ast.Chan */) { w->uses_channel = true; v__markused__Walker_mark_by_type(w, (*isym.info._v__ast__Chan).elem_type); } else if (isym.info._typ == 537 /* v.ast.Aggregate */) { for (int _t9 = 0; _t9 < (*isym.info._v__ast__Aggregate).types.len; ++_t9) { v__ast__Type typ = ((v__ast__Type*)(*isym.info._v__ast__Aggregate).types.data)[_t9]; v__markused__Walker_mark_by_type(w, typ); } } else if (isym.info._typ == 548 /* v.ast.Enum */) { v__markused__Walker_mark_by_type(w, (*isym.info._v__ast__Enum).typ); v__ast__EnumDecl* _t11 = (v__ast__EnumDecl*)(map_get_check(ADDR(map, w->table->enum_decls), &(string[]){isym.name})); _option_v__ast__EnumDecl _t10 = {0}; if (_t11) { *((v__ast__EnumDecl*)&_t10.data) = *((v__ast__EnumDecl*)_t11); } else { _t10.state = 2; _t10.err = _v_error(_S("map key does not exist")); } if (_t10.state == 0) { v__ast__EnumDecl enum_ = (*(v__ast__EnumDecl*)_t10.data); for (int _t12 = 0; _t12 < enum_.fields.len; ++_t12) { v__ast__EnumField field = ((v__ast__EnumField*)enum_.fields.data)[_t12]; if (field.has_expr) { v__markused__Walker_expr(w, field.expr); } } } } else if (isym.info._typ == 542 /* v.ast.Interface */) { for (int _t13 = 0; _t13 < (*isym.info._v__ast__Interface).types.len; ++_t13) { v__ast__Type typ = ((v__ast__Type*)(*isym.info._v__ast__Interface).types.data)[_t13]; if (typ == _const_v__ast__map_type) { w->features->used_maps++; } v__markused__Walker_mark_by_type(w, typ); for (int _t14 = 0; _t14 < (*isym.info._v__ast__Interface).methods.len; ++_t14) { v__ast__Fn method = ((v__ast__Fn*)(*isym.info._v__ast__Interface).methods.data)[_t14]; Array_v__ast__Type _t15 = new_array_from_c_array(2, 2, sizeof(v__ast__Type), _MOV((v__ast__Type[2]){v__ast__Type_set_nr_muls(typ, 1), v__ast__Type_set_nr_muls(typ, 0)})); for (int _t16 = 0; _t16 < _t15.len; ++_t16) { v__ast__Type ityp = ((v__ast__Type*)_t15.data)[_t16]; string mname = string__plus(string__plus(int_str(((int)(v__ast__Type_clear_flags(ityp, __new_array(0, 0, sizeof(v__ast__TypeFlag)))))), _S(".")), method.name); v__markused__Walker_fn_by_name(w, mname); } } Array_v__ast__Fn _t17 = v__ast__Table_get_embed_methods(w->table, v__ast__Table_sym(w->table, typ)); for (int _t18 = 0; _t18 < _t17.len; ++_t18) { v__ast__Fn embed_method = ((v__ast__Fn*)_t17.data)[_t18]; string mname = string__plus(string__plus(int_str(((int)(v__ast__Type_clear_flags((*(v__ast__Param*)array_get(embed_method.params, 0)).typ, __new_array(0, 0, sizeof(v__ast__TypeFlag)))))), _S(".")), embed_method.name); v__markused__Walker_fn_by_name(w, mname); } } for (int _t19 = 0; _t19 < (*isym.info._v__ast__Interface).embeds.len; ++_t19) { v__ast__Type embed = ((v__ast__Type*)(*isym.info._v__ast__Interface).embeds.data)[_t19]; v__markused__Walker_mark_by_type(w, embed); } for (int _t20 = 0; _t20 < (*isym.info._v__ast__Interface).generic_types.len; ++_t20) { v__ast__Type generic_type = ((v__ast__Type*)(*isym.info._v__ast__Interface).generic_types.data)[_t20]; v__markused__Walker_mark_by_type(w, generic_type); } v__markused__Walker_mark_by_type(w, (*isym.info._v__ast__Interface).parent_type); for (int _t21 = 0; _t21 < (*isym.info._v__ast__Interface).fields.len; ++_t21) { v__ast__StructField field = ((v__ast__StructField*)(*isym.info._v__ast__Interface).fields.data)[_t21]; v__markused__Walker_mark_by_type(w, field.typ); } for (int _t22 = 0; _t22 < isym.methods.len; ++_t22) { v__ast__Fn method = ((v__ast__Fn*)isym.methods.data)[_t22]; v__markused__Walker_mark_by_type(w, method.receiver_type); v__markused__Walker_mark_fn_ret_and_params(w, method.return_type, method.params); } } else if (isym.info._typ == 551 /* v.ast.Thread */) { v__markused__Walker_mark_by_type(w, (*isym.info._v__ast__Thread).return_type); } else { } } VV_LOC void v__markused__Walker_remove_unused_fn_generic_types(v__markused__Walker* w) { Map_string_v__ast__FnDecl _t1 = w->all_fns; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} v__ast__FnDecl node = (*(v__ast__FnDecl*)DenseArray_value(&_t1.key_values, _t2)); int count = 0; string nkey = v__ast__FnDecl_fkey(&node); Array_Array_v__ast__Type* _t6 = (Array_Array_v__ast__Type*)(map_get_check(ADDR(map, w->table->fn_generic_types), &(string[]){nkey})); _option_Array_Array_v__ast__Type _t5 = {0}; if (_t6) { *((Array_Array_v__ast__Type*)&_t5.data) = *((Array_Array_v__ast__Type*)_t6); } else { _t5.state = 2; _t5.err = _v_error(_S("map key does not exist")); } if (_t5.state == 0) { Array_Array_v__ast__Type all_concrete_types = (*(Array_Array_v__ast__Type*)_t5.data); if (all_concrete_types.len == 0) { continue; } for (int k = 0; k < all_concrete_types.len; ++k) { Array_v__ast__Type concrete_types = ((Array_v__ast__Type*)all_concrete_types.data)[k]; if (concrete_types.len != 1) { continue; } if (!_IN_MAP(ADDR(int, v__ast__Type_idx((*(v__ast__Type*)array_get(concrete_types, 0)))), ADDR(map, w->used_syms))) { array_delete(&(*(Array_Array_v__ast__Type*)map_get(ADDR(map, w->table->fn_generic_types), &(string[]){nkey}, &(Array_Array_v__ast__Type[]){ __new_array(0, 0, sizeof(Array_v__ast__Type)) })), (int)(k - count)); count++; } } } } } VV_LOC void v__markused__Walker_remove_unused_dump_type(v__markused__Walker* w) { Map_int_string _t1 = w->table->dumps; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} int typ = *(int*)DenseArray_key(&_t1.key_values, _t2); if (!_IN_MAP(ADDR(int, v__ast__Type_idx(((((u32)(typ)))))), ADDR(map, w->used_syms))) { map_delete(&w->table->dumps, &(int[]){typ}); } } } VV_LOC void v__markused__Walker_mark_resource_dependencies(v__markused__Walker* w) { if (w->trace_enabled) { eprintln(_S(">>>>>>>>>> DEPS USAGE")); } if (w->uses_eq) { v__markused__Walker_fn_by_name(w, _S("fast_string_eq")); } if (w->features->auto_str_ptr) { v__markused__Walker_fn_by_name(w, _S("isnil")); v__markused__Walker_fn_by_name(w, _S("tos4")); v__markused__Walker_fn_by_name(w, _S("str_intp")); } if (w->uses_channel) { v__markused__Walker_fn_by_name(w, _S("sync.new_channel_st")); v__markused__Walker_fn_by_name(w, _S("sync.channel_select")); } if (w->uses_lock) { v__markused__Walker_mark_by_sym_name(w, _S("sync.RwMutex")); } if (w->uses_array) { if (w->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full_opt || w->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt) { v__markused__Walker_fn_by_name(w, _S("__new_array_noscan")); v__markused__Walker_fn_by_name(w, _S("new_array_from_c_array_noscan")); v__markused__Walker_fn_by_name(w, _S("__new_array_with_multi_default_noscan")); v__markused__Walker_fn_by_name(w, _S("__new_array_with_array_default_noscan")); v__markused__Walker_fn_by_name(w, _S("__new_array_with_default_noscan")); } v__markused__Walker_fn_by_name(w, _S("__new_array")); v__markused__Walker_fn_by_name(w, _S("new_array_from_c_array")); v__markused__Walker_fn_by_name(w, _S("__new_array_with_multi_default")); v__markused__Walker_fn_by_name(w, _S("__new_array_with_array_default")); v__markused__Walker_fn_by_name(w, _S("__new_array_with_default")); v__markused__Walker_fn_by_name(w, string__plus(int_str(((int)(v__ast__Type_ref(_const_v__ast__array_type)))), _S(".set"))); } if (w->uses_orm) { v__markused__Walker_fn_by_name(w, _S("__new_array_with_default_noscan")); v__markused__Walker_fn_by_name(w, _S("new_array_from_c_array")); v__markused__Walker_fn_by_name(w, _S("__new_array")); v__markused__Walker_fn_by_name(w, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = _const_v__ast__array_type_idx}}, {_S(".get"), 0, { .d_c = 0 }}}))); v__markused__Walker_fn_by_name(w, string__plus(int_str(((int)(v__ast__Type_ref(_const_v__ast__array_type)))), _S(".push"))); } if (w->uses_ct_fields) { v__markused__Walker_mark_by_sym_name(w, _S("FieldData")); } if (w->uses_ct_methods) { v__markused__Walker_mark_by_sym_name(w, _S("FunctionData")); } if (w->uses_ct_params) { v__markused__Walker_mark_by_sym_name(w, _S("MethodParam")); } if (w->uses_ct_values) { v__markused__Walker_mark_by_sym_name(w, _S("EnumData")); } if (w->uses_ct_variants) { v__markused__Walker_mark_by_sym_name(w, _S("VariantData")); } if (w->uses_ct_attribute) { v__markused__Walker_mark_by_sym_name(w, _S("VAttribute")); } if (w->uses_map_update) { v__markused__Walker_fn_by_name(w, _S("new_map_update_init")); } if (w->uses_mem_align) { v__markused__Walker_fn_by_name(w, _S("memdup_align")); } if (w->uses_guard) { v__markused__Walker_fn_by_name(w, _S("error")); } if (w->uses_dump) { v__markused__Walker_fn_by_name(w, _S("eprint")); v__markused__Walker_fn_by_name(w, _S("eprintln")); } if (w->uses_spawn) { v__markused__Walker_fn_by_name(w, _S("malloc")); v__markused__Walker_fn_by_name(w, _S("tos3")); } if (w->uses_memdup) { v__markused__Walker_fn_by_name(w, _S("memdup")); } if (w->uses_debugger) { v__markused__Walker_mark_by_type(w, v__ast__Table_find_or_register_map(w->table, _const_v__ast__string_type, _const_v__ast__string_type)); } if (w->uses_arr_void) { v__markused__Walker_mark_by_type(w, v__ast__Table_find_or_register_array(w->table, _const_v__ast__voidptr_type)); } Map_int_bool _t1 = w->table->used_features->print_types; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} int typ = *(int*)DenseArray_key(&_t1.key_values, _t2); v__markused__Walker_mark_by_type(w, typ); } if (w->trace_enabled) { Array_string _t5 = {0}; Array_int _t5_orig = map_keys(&w->table->used_features->print_types); int _t5_len = _t5_orig.len; _t5 = __new_array(0, _t5_len, sizeof(string)); for (int _t7 = 0; _t7 < _t5_len; ++_t7) { int it = ((int*) _t5_orig.data)[_t7]; string _t6 = v__ast__Table_type_to_str(w->table, it); array_push((array*)&_t5, &_t6); } Array_string types =_t5; eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">>>>>>>>>> PRINT TYPES "), 0xfe10, {.d_s = Array_string_str(types)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (w->trace_enabled) { Array_string _t8 = {0}; Array_v__ast__Type _t8_orig = map_keys(&w->uses_str); int _t8_len = _t8_orig.len; _t8 = __new_array(0, _t8_len, sizeof(string)); for (int _t10 = 0; _t10 < _t8_len; ++_t10) { v__ast__Type it = ((v__ast__Type*) _t8_orig.data)[_t10]; string _t9 = v__ast__Table_type_to_str(w->table, it); array_push((array*)&_t8, &_t9); } Array_string types =_t8; eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">>>>>>>>>> USES .str() CALLS ON TYPES "), 0xfe10, {.d_s = Array_string_str(types)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (w->trace_enabled) { Array_string _t11 = {0}; Array_v__ast__Type _t11_orig = map_keys(&w->uses_free); int _t11_len = _t11_orig.len; _t11 = __new_array(0, _t11_len, sizeof(string)); for (int _t13 = 0; _t13 < _t11_len; ++_t13) { v__ast__Type it = ((v__ast__Type*) _t11_orig.data)[_t13]; string _t12 = v__ast__Table_type_to_str(w->table, it); array_push((array*)&_t11, &_t12); } Array_string types =_t11; eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">>>>>>>>>> USES .free() CALLS ON TYPES "), 0xfe10, {.d_s = Array_string_str(types)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (w->trace_enabled) { eprintln(_S(">>>>>>>>>> ALL_FNS LOOP")); } bool has_ptr_print = false; Map_string_v__ast__FnDecl map_fns = new_map(sizeof(string), sizeof(v__ast__FnDecl), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; bool has_str_call = w->uses_interp || w->uses_asserts || w->uses_str.len > 0 || w->features->print_types.len > 0; Map_string_v__ast__FnDecl _t14 = w->all_fns; int _t16 = _t14.key_values.len; for (int _t15 = 0; _t15 < _t16; ++_t15 ) { int _t17 = _t14.key_values.len - _t16; _t16 = _t14.key_values.len; if (_t17 < 0) { _t15 = -1; continue; } if (!DenseArray_has_index(&_t14.key_values, _t15)) {continue;} string k = *(string*)DenseArray_key(&_t14.key_values, _t15); k = string_clone(k); v__ast__FnDecl* func = &(*(v__ast__FnDecl*)DenseArray_value(&_t14.key_values, _t15)); if (has_str_call && string_ends_with(k, _S(".str"))) { if (_IN_MAP(ADDR(int, v__ast__Type_idx(func->receiver.typ)), ADDR(map, w->used_syms))) { v__markused__Walker_fn_by_name(w, k); if (!has_ptr_print && v__ast__Type_is_ptr(func->receiver.typ)) { v__markused__Walker_fn_by_name(w, _S("ptr_str")); has_ptr_print = true; } } continue; } if (w->pref->autofree || (w->uses_free.len > 0 && string_ends_with(k, _S(".free")) && _IN_MAP(ADDR(int, v__ast__Type_idx(func->receiver.typ)), ADDR(map, w->used_syms)))) { v__markused__Walker_fn_by_name(w, k); continue; } if (w->uses_atomic && string_starts_with(k, _S("_Atomic"))) { v__markused__Walker_fn_by_name(w, k); continue; } if (fast_string_eq(func->name, _S("+")) || fast_string_eq(func->name, _S("-")) || fast_string_eq(func->name, _S("*")) || fast_string_eq(func->name, _S("%")) || fast_string_eq(func->name, _S("/")) || fast_string_eq(func->name, _S("<")) || fast_string_eq(func->name, _S("=="))) { if (_IN_MAP(ADDR(int, v__ast__Type_idx(func->receiver.typ)), ADDR(map, w->used_syms))) { v__markused__Walker_fn_by_name(w, k); } continue; } if (!func->is_static_type_method && func->receiver.typ != _const_v__ast__void_type && func->generic_names.len > 0) { if (_IN_MAP(ADDR(v__ast__Type, v__ast__Type_set_nr_muls(func->receiver.typ, 0)), ADDR(map, w->table->used_features->comptime_syms)) || _IN_MAP(ADDR(v__ast__Type, func->receiver.typ), ADDR(map, w->table->used_features->comptime_syms))) { v__markused__Walker_fn_by_name(w, k); continue; } } if (func->is_method && !v__ast__Type_has_flag(func->receiver.typ, v__ast__TypeFlag__generic) && v__ast__Type_is_ptr(func->receiver.typ)) { string method_receiver_typename = v__ast__Table_type_to_str(w->table, func->receiver.typ); if (_SLIT_EQ(method_receiver_typename.str, method_receiver_typename.len, "&map") || _SLIT_EQ(method_receiver_typename.str, method_receiver_typename.len, "&mapnode") || _SLIT_EQ(method_receiver_typename.str, method_receiver_typename.len, "&SortedMap") || _SLIT_EQ(method_receiver_typename.str, method_receiver_typename.len, "&DenseArray")) { (*(v__ast__FnDecl*)map_get_and_set((map*)&map_fns, &(string[]){k}, &(v__ast__FnDecl[]){ (v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = (v__ast__StructField){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.option_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = (v__ast__StructDecl){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,},},.receiver_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_method = 0,.is_static_type_method = 0,.static_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.method_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.body_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.end_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_expand_simple_interpolation = 0,} })) = *func; } } else if (string_starts_with(k, _S("map_"))) { (*(v__ast__FnDecl*)map_get_and_set((map*)&map_fns, &(string[]){k}, &(v__ast__FnDecl[]){ (v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = (v__ast__StructField){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.option_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = (v__ast__StructDecl){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,},},.receiver_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_method = 0,.is_static_type_method = 0,.static_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.method_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.body_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.end_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_expand_simple_interpolation = 0,} })) = *func; } } if (w->features->used_maps > 0) { v__markused__Walker_fn_by_name(w, _S("new_map")); v__markused__Walker_fn_by_name(w, _S("new_map_init")); v__markused__Walker_fn_by_name(w, _S("map_hash_string")); if (w->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full_opt || w->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt) { v__markused__Walker_fn_by_name(w, _S("new_map_noscan_key")); v__markused__Walker_fn_by_name(w, _S("new_map_noscan_value")); v__markused__Walker_fn_by_name(w, _S("new_map_noscan_key_value")); v__markused__Walker_fn_by_name(w, _S("new_map_init_noscan_key")); v__markused__Walker_fn_by_name(w, _S("new_map_init_noscan_value")); v__markused__Walker_fn_by_name(w, _S("new_map_init_noscan_key_value")); } int _t19 = map_fns.key_values.len; for (int _t18 = 0; _t18 < _t19; ++_t18 ) { int _t20 = map_fns.key_values.len - _t19; _t19 = map_fns.key_values.len; if (_t20 < 0) { _t18 = -1; continue; } if (!DenseArray_has_index(&map_fns.key_values, _t18)) {continue;} v__ast__FnDecl* func = &(*(v__ast__FnDecl*)DenseArray_value(&map_fns.key_values, _t18)); if (!func->is_method) { v__markused__Walker_fn_decl(w, func); } else { string method_receiver_typename = v__ast__Table_type_to_str(w->table, func->receiver.typ); if (_SLIT_EQ(method_receiver_typename.str, method_receiver_typename.len, "&map") || _SLIT_EQ(method_receiver_typename.str, method_receiver_typename.len, "&DenseArray")) { v__markused__Walker_fn_decl(w, func); } } } } else { int _t22 = map_fns.key_values.len; for (int _t21 = 0; _t21 < _t22; ++_t21 ) { int _t23 = map_fns.key_values.len - _t22; _t22 = map_fns.key_values.len; if (_t23 < 0) { _t21 = -1; continue; } if (!DenseArray_has_index(&map_fns.key_values, _t21)) {continue;} string k = *(string*)DenseArray_key(&map_fns.key_values, _t21); k = string_clone(k); v__ast__FnDecl func = (*(v__ast__FnDecl*)DenseArray_value(&map_fns.key_values, _t21)); if (!func.is_method) { continue; } map_delete(&w->used_fns, &(string[]){k}); } map_delete(&w->used_fns, &(string[]){_S("new_map")}); map_delete(&w->used_fns, &(string[]){_S("new_map_init")}); map_delete(&w->used_fns, &(string[]){_S("map_hash_string")}); map_delete(&w->used_fns, &(string[]){_S("new_dense_array")}); map_delete(&w->used_fns, &(string[]){_S("new_dense_array_noscan")}); } } void v__markused__Walker_finalize(v__markused__Walker* w, bool include_panic_deps) { v__markused__Walker_mark_resource_dependencies(w); if (w->trace_enabled) { eprintln(_S(">>>>>>>>>> FINALIZE")); } if (w->uses_asserts) { v__markused__Walker_fn_by_name(w, _S("__print_assert_failure")); v__markused__Walker_fn_by_name(w, _S("isnil")); v__markused__Walker_mark_by_sym_name(w, _S("VAssertMetaInfo")); } if (w->used_panic > 0) { v__markused__Walker_mark_fn_as_used(w, _S("panic_option_not_set")); v__markused__Walker_mark_fn_as_used(w, _S("panic_result_not_set")); } if (w->used_none > 0 || w->table->used_features->auto_str) { v__markused__Walker_mark_fn_as_used(w, _S("_option_none")); v__markused__Walker_mark_by_sym_name(w, _S("_option")); } if (w->used_option > 0) { v__markused__Walker_mark_fn_as_used(w, _S("_option_clone")); v__markused__Walker_mark_fn_as_used(w, _S("_option_ok")); v__markused__Walker_mark_by_sym_name(w, _S("_option")); } if (w->used_result > 0) { v__markused__Walker_mark_fn_as_used(w, _S("_result_ok")); v__markused__Walker_mark_by_sym_name(w, _S("_result")); } if (((int)((int)(w->used_option + w->used_result) + w->used_none)) > 0) { v__markused__Walker_mark_const_as_used(w, _S("none__")); } if (include_panic_deps || w->uses_external_type || w->uses_asserts || w->uses_debugger || w->uses_interp) { if (w->trace_enabled) { eprintln(str_intp(5, _MOV((StrIntpData[]){{_S(">>>>> PANIC DEPS "), 0xfe10, {.d_s = include_panic_deps ? _S("true") : _S("false")}}, {_S(" | external_type="), 0xfe10, {.d_s = w->uses_external_type ? _S("true") : _S("false")}}, {_S(" | asserts="), 0xfe10, {.d_s = w->uses_asserts ? _S("true") : _S("false")}}, {_S(" | dbg="), 0xfe10, {.d_s = w->uses_debugger ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); } string ref_array_idx_str = int_str(((int)(v__ast__Type_ref(_const_v__ast__array_type)))); string string_idx_str = int_literal_str(_const_v__ast__string_type_idx); if (w->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full_opt || w->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt) { v__markused__Walker_fn_by_name(w, _S("__new_array_with_default_noscan")); v__markused__Walker_fn_by_name(w, string__plus(ref_array_idx_str, _S(".push_noscan"))); } v__markused__Walker_fn_by_name(w, _S("str_intp")); v__markused__Walker_fn_by_name(w, _S("__new_array_with_default")); v__markused__Walker_fn_by_name(w, string__plus(ref_array_idx_str, _S(".push"))); v__markused__Walker_fn_by_name(w, string__plus(string_idx_str, _S(".substr"))); v__markused__Walker_fn_by_name(w, _S("v_fixed_index")); v__markused__Walker_mark_by_sym_name(w, _S("StrIntpData")); v__markused__Walker_mark_by_sym_name(w, _S("StrIntpMem")); } v__markused__Walker_remove_unused_fn_generic_types(w); v__markused__Walker_remove_unused_dump_type(w); if (w->trace_enabled) { Array_string _t1 = {0}; Array_int _t1_orig = map_keys(&w->used_syms); int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { int it = ((int*) _t1_orig.data)[_t3]; string _t2 = v__ast__Table_type_to_str(w->table, it); array_push((array*)&_t1, &_t2); } Array_string syms =_t1; eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">>>>>>>>>> USED SYMS "), 0xfe10, {.d_s = Array_string_str(syms)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } void v__markused__Walker_mark_generic_types(v__markused__Walker* w) { if (w->trace_enabled) { eprintln(_S(">>>>>>>>>> COMPTIME SYMS+CALLS")); } Map_string_bool _t1 = w->table->used_features->comptime_calls; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string k = *(string*)DenseArray_key(&_t1.key_values, _t2); k = string_clone(k); v__markused__Walker_fn_by_name(w, k); } Map_v__ast__Type_bool _t5 = w->table->used_features->comptime_syms; int _t7 = _t5.key_values.len; for (int _t6 = 0; _t6 < _t7; ++_t6 ) { int _t8 = _t5.key_values.len - _t7; _t7 = _t5.key_values.len; if (_t8 < 0) { _t6 = -1; continue; } if (!DenseArray_has_index(&_t5.key_values, _t6)) {continue;} v__ast__Type k = *(v__ast__Type*)DenseArray_key(&_t5.key_values, _t6); v__ast__TypeSymbol* sym = v__ast__Table_sym(w->table, k); v__markused__Walker_mark_by_sym(w, *sym); Array_v__ast__Fn _t9 = v__ast__TypeSymbol_get_methods(sym); for (int _t10 = 0; _t10 < _t9.len; ++_t10) { v__ast__Fn method = ((v__ast__Fn*)_t9.data)[_t10]; v__markused__Walker_fn_by_name(w, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Type_str(k)}}, {_S("."), 0xfe10, {.d_s = method.name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } } multi_return_v__ast__StructField_string v__type_resolver__TypeResolver_get_comptime_selector_var_type(v__type_resolver__TypeResolver* t, v__ast__ComptimeSelector node) { string field_name = t->info.comptime_for_field_value.name; v__ast__TypeSymbol* left_sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, node.left_type)); _result_v__ast__StructField _t1 = v__ast__Table_find_field_with_embeds(t->table, left_sym, field_name); if (_t1.is_error) { IError err = _t1.err; v__type_resolver__TypeResolver_error(t, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__ast__Expr_str(&node.left)}}, {_S("` has no field named `"), 0xfe10, {.d_s = field_name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node.left)); VUNREACHABLE(); ; } v__ast__StructField field = (*(v__ast__StructField*)_t1.data); return (multi_return_v__ast__StructField_string){.arg0=field, .arg1=field_name}; } inline bool v__type_resolver__ResolverInfo_has_comptime_expr(v__type_resolver__ResolverInfo* t, v__ast__Expr node) { bool _t2 = (((node)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node)._v__ast__Ident,(node)._typ, 358)).ct_expr) || ((node)._typ == 361 /* v.ast.IndexExpr */ && v__type_resolver__ResolverInfo_has_comptime_expr(t, (*(v__ast__IndexExpr*)__as_cast((node)._v__ast__IndexExpr,(node)._typ, 361)).left)) || (node)._typ == 350 /* v.ast.ComptimeSelector */); bool _t3 = ((!_t2) && (node)._typ == 385 /* v.ast.StructInit */); bool _t4 = false; if (_t3) { Array_v__ast__StructInitField _t4_orig = (*(v__ast__StructInit*)__as_cast((node)._v__ast__StructInit,(node)._typ, 385)).init_fields; int _t4_len = _t4_orig.len; for (int _t5 = 0; _t5 < _t4_len; ++_t5) { v__ast__StructInitField it = ((v__ast__StructInitField*) _t4_orig.data)[_t5]; if ((it.expr)._typ == 336 /* v.ast.AnonFn */ && (*(v__ast__AnonFn*)__as_cast((it.expr)._v__ast__AnonFn,(it.expr)._typ, 336)).decl.generic_names.len > 0) { _t4 = true; break; } } } return _t2 || ( _t3 && _t4) || ((node)._typ == 375 /* v.ast.PostfixExpr */ && v__type_resolver__ResolverInfo_has_comptime_expr(t, (*(v__ast__PostfixExpr*)__as_cast((node)._v__ast__PostfixExpr,(node)._typ, 375)).expr)) || ((node)._typ == 379 /* v.ast.SelectorExpr */ && v__type_resolver__ResolverInfo_has_comptime_expr(t, (*(v__ast__SelectorExpr*)__as_cast((node)._v__ast__SelectorExpr,(node)._typ, 379)).expr)) || ((node)._typ == 338 /* v.ast.ArrayInit */ && v__ast__Type_has_flag((*(v__ast__ArrayInit*)__as_cast((node)._v__ast__ArrayInit,(node)._typ, 338)).elem_type, v__ast__TypeFlag__generic)) || ((node)._typ == 368 /* v.ast.MapInit */ && v__ast__Type_has_flag((*(v__ast__MapInit*)__as_cast((node)._v__ast__MapInit,(node)._typ, 368)).typ, v__ast__TypeFlag__generic)) || ((node)._typ == 362 /* v.ast.InfixExpr */ && (v__type_resolver__ResolverInfo_has_comptime_expr(t, (*(v__ast__InfixExpr*)__as_cast((node)._v__ast__InfixExpr,(node)._typ, 362)).left) || v__type_resolver__ResolverInfo_has_comptime_expr(t, (*(v__ast__InfixExpr*)__as_cast((node)._v__ast__InfixExpr,(node)._typ, 362)).right))); } inline bool v__type_resolver__ResolverInfo_is_comptime(v__type_resolver__ResolverInfo* t, v__ast__Expr node) { bool _t2 = 0; if (node._typ == 358 /* v.ast.Ident */) { _t2 = (*node._v__ast__Ident).ct_expr; } else if (node._typ == 361 /* v.ast.IndexExpr */) { _t2 = (((*node._v__ast__IndexExpr).left)._typ == 358 /* v.ast.Ident */ ? ((*(*node._v__ast__IndexExpr).left._v__ast__Ident).ct_expr) : (false)); } else if (node._typ == 379 /* v.ast.SelectorExpr */) { return ((*node._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*node._v__ast__SelectorExpr).expr)._v__ast__Ident,((*node._v__ast__SelectorExpr).expr)._typ, 358)).ct_expr; } else if (node._typ == 362 /* v.ast.InfixExpr */) { return (*node._v__ast__InfixExpr).left_ct_expr || (*node._v__ast__InfixExpr).right_ct_expr; } else if (node._typ == 374 /* v.ast.ParExpr */) { return v__type_resolver__ResolverInfo_is_comptime(t, (*node._v__ast__ParExpr).expr); } else if (node._typ == 350 /* v.ast.ComptimeSelector */) { return true; } else if (node._typ == 375 /* v.ast.PostfixExpr */) { return v__type_resolver__ResolverInfo_is_comptime(t, (*node._v__ast__PostfixExpr).expr); } else { _t2 = false; } return _t2; } inline bool v__type_resolver__ResolverInfo_is_comptime_variant_var(v__type_resolver__ResolverInfo* t, v__ast__Ident node) { return string__eq(node.name, t->comptime_for_variant_var); } v__ast__Type v__type_resolver__TypeResolver_typeof_type(v__type_resolver__TypeResolver* t, v__ast__Expr node, v__ast__Type default_type) { if (v__type_resolver__ResolverInfo_is_comptime(&t->info, node)) { return v__type_resolver__TypeResolver_get_type(t, node); } else if ((node)._typ == 379 /* v.ast.SelectorExpr */ && (*(v__ast__SelectorExpr*)__as_cast((node)._v__ast__SelectorExpr,(node)._typ, 379)).expr_type != 0) { if (((*node._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */ && (*node._v__ast__SelectorExpr).is_field_typ) { return v__type_resolver__TypeResolver_get_type_from_comptime_var(t, (*(*node._v__ast__SelectorExpr).expr._v__ast__Ident)); } v__ast__ScopeStructField* field = v__ast__Scope_find_struct_field((*node._v__ast__SelectorExpr).scope, v__ast__Expr_str(&(*node._v__ast__SelectorExpr).expr), (*node._v__ast__SelectorExpr).expr_type, (*node._v__ast__SelectorExpr).field_name); if (field != ((void*)0)) { if (field->smartcasts.len > 0) { return (*(v__ast__Type*)array_last(field->smartcasts)); } } v__ast__TypeSymbol* sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*node._v__ast__SelectorExpr).expr_type)); _result_v__ast__StructField _t4; if (_t4 = v__ast__Table_find_field_with_embeds(t->table, sym, (*node._v__ast__SelectorExpr).field_name), !_t4.is_error) { v__ast__StructField f = *(v__ast__StructField*)_t4.data; return f.typ; } } else if ((node)._typ == 379 /* v.ast.SelectorExpr */ && (*(v__ast__SelectorExpr*)__as_cast((node)._v__ast__SelectorExpr,(node)._typ, 379)).name_type != 0) { if (fast_string_eq((*node._v__ast__SelectorExpr).field_name, _S("value_type")) || fast_string_eq((*node._v__ast__SelectorExpr).field_name, _S("element_type"))) { return v__ast__Table_value_type(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*node._v__ast__SelectorExpr).name_type)); } else if (fast_string_eq((*node._v__ast__SelectorExpr).field_name, _S("key_type"))) { v__ast__TypeSymbol* sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*node._v__ast__SelectorExpr).name_type)); if ((sym->info)._typ == 514 /* v.ast.Map */) { return v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*sym->info._v__ast__Map).key_type); } } } return default_type; } v__ast__Type v__type_resolver__TypeResolver_typeof_field_type(v__type_resolver__TypeResolver* t, v__ast__Type typ, string field_name) { if (_SLIT_EQ(field_name.str, field_name.len, "name")) { return _const_v__ast__string_type; } else if (_SLIT_EQ(field_name.str, field_name.len, "idx")) { return v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, typ); } else if (_SLIT_EQ(field_name.str, field_name.len, "unaliased_typ")) { return v__ast__Table_unaliased_type(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, typ)); } else if (_SLIT_EQ(field_name.str, field_name.len, "indirections")) { return _const_v__ast__int_type; } else if (_SLIT_EQ(field_name.str, field_name.len, "key_type")) { v__ast__TypeSymbol* sym = v__ast__Table_final_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, typ)); if ((sym->info)._typ == 514 /* v.ast.Map */) { return v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*sym->info._v__ast__Map).key_type); } return _const_v__ast__no_type; } else if (_SLIT_EQ(field_name.str, field_name.len, "value_type") || _SLIT_EQ(field_name.str, field_name.len, "element_type")) { return v__ast__Table_value_type(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, typ)); } else { return typ; } return 0; } inline v__ast__ComptimeVarKind v__type_resolver__ResolverInfo_get_ct_type_var(v__type_resolver__ResolverInfo* t, v__ast__Expr node) { if ((node)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((node)._v__ast__Ident,(node)._typ, 358)).obj)._typ == 422 /* v.ast.Var */) { return (*(*node._v__ast__Ident).obj._v__ast__Var).ct_type_var; } else if ((node)._typ == 361 /* v.ast.IndexExpr */) { return v__type_resolver__ResolverInfo_get_ct_type_var(t, (*node._v__ast__IndexExpr).left); } else if ((node)._typ == 362 /* v.ast.InfixExpr */) { return v__type_resolver__ResolverInfo_get_ct_type_var(t, (*node._v__ast__InfixExpr).left); } else if ((node)._typ == 374 /* v.ast.ParExpr */) { return v__type_resolver__ResolverInfo_get_ct_type_var(t, (*node._v__ast__ParExpr).expr); } else if ((node)._typ == 379 /* v.ast.SelectorExpr */) { return v__type_resolver__ResolverInfo_get_ct_type_var(t, (*node._v__ast__SelectorExpr).expr); } return v__ast__ComptimeVarKind__no_comptime; } inline v__ast__Type v__type_resolver__TypeResolver_get_type_from_comptime_var(v__type_resolver__TypeResolver* t, v__ast__Ident var) { if (fast_string_eq(var.name, t->info.comptime_for_variant_var)) { return v__type_resolver__TypeResolver_get_ct_type_or_default(t, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = t->info.comptime_for_variant_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), _const_v__ast__void_type); } else if (fast_string_eq(var.name, t->info.comptime_for_method_param_var)) { return v__type_resolver__TypeResolver_get_ct_type_or_default(t, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = t->info.comptime_for_method_param_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), _const_v__ast__void_type); } else { return t->info.comptime_for_field_type; } return 0; } inline v__ast__Type v__type_resolver__TypeResolver_get_comptime_selector_type(v__type_resolver__TypeResolver* t, v__ast__ComptimeSelector node, v__ast__Type default_type) { if (node.is_name && (node.field_expr)._typ == 379 /* v.ast.SelectorExpr */ && v__type_resolver__ResolverInfo_check_comptime_is_field_selector(&t->info, *(v__ast__SelectorExpr*)__as_cast((node.field_expr)._v__ast__SelectorExpr,(node.field_expr)._typ, 379))) { return v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, t->info.comptime_for_field_type); } return default_type; } inline bool v__type_resolver__ResolverInfo_is_comptime_selector_field_name(v__type_resolver__ResolverInfo* t, v__ast__SelectorExpr node, string field_name) { return (((t->comptime_for_field_var).len != 0 && (node.expr)._typ == 358 /* v.ast.Ident */ && string__eq((*(v__ast__Ident*)__as_cast((node.expr)._v__ast__Ident,(node.expr)._typ, 358)).name, t->comptime_for_field_var)) || node.name_type != 0) && string__eq(node.field_name, field_name); } inline bool v__type_resolver__ResolverInfo_is_comptime_selector_type(v__type_resolver__ResolverInfo* t, v__ast__SelectorExpr node) { if (t->inside_comptime_for && (node.expr)._typ == 358 /* v.ast.Ident */) { return (string__eq((*node.expr._v__ast__Ident).name, t->comptime_for_enum_var) || string__eq((*node.expr._v__ast__Ident).name, t->comptime_for_variant_var) || string__eq((*node.expr._v__ast__Ident).name, t->comptime_for_field_var) || string__eq((*node.expr._v__ast__Ident).name, t->comptime_for_method_param_var)) && fast_string_eq(node.field_name, _S("typ")); } return false; } inline bool v__type_resolver__ResolverInfo_check_comptime_is_field_selector(v__type_resolver__ResolverInfo* t, v__ast__SelectorExpr node) { if ((t->comptime_for_field_var).len != 0 && (node.expr)._typ == 358 /* v.ast.Ident */) { return string__eq((*node.expr._v__ast__Ident).name, t->comptime_for_field_var); } return false; } inline bool v__type_resolver__ResolverInfo_check_comptime_is_field_selector_bool(v__type_resolver__ResolverInfo* t, v__ast__SelectorExpr node) { if (v__type_resolver__ResolverInfo_check_comptime_is_field_selector(t, node)) { return (fast_string_eq(node.field_name, _S("is_mut")) || fast_string_eq(node.field_name, _S("is_pub")) || fast_string_eq(node.field_name, _S("is_shared")) || fast_string_eq(node.field_name, _S("is_atomic")) || fast_string_eq(node.field_name, _S("is_option")) || fast_string_eq(node.field_name, _S("is_array")) || fast_string_eq(node.field_name, _S("is_map")) || fast_string_eq(node.field_name, _S("is_chan")) || fast_string_eq(node.field_name, _S("is_struct")) || fast_string_eq(node.field_name, _S("is_alias")) || fast_string_eq(node.field_name, _S("is_enum"))); } return false; } bool v__type_resolver__TypeResolver_get_comptime_selector_bool_field(v__type_resolver__TypeResolver* t, string field_name) { v__ast__StructField field = t->info.comptime_for_field_value; v__ast__Type field_typ = t->info.comptime_for_field_type; v__ast__TypeSymbol* field_sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, t->info.comptime_for_field_type)); if (_SLIT_EQ(field_name.str, field_name.len, "is_pub")) { return field.is_pub; } else if (_SLIT_EQ(field_name.str, field_name.len, "is_mut")) { return field.is_mut; } else if (_SLIT_EQ(field_name.str, field_name.len, "is_shared")) { return v__ast__Type_has_flag(field_typ, v__ast__TypeFlag__shared_f); } else if (_SLIT_EQ(field_name.str, field_name.len, "is_atomic")) { return v__ast__Type_has_flag(field_typ, v__ast__TypeFlag__atomic_f); } else if (_SLIT_EQ(field_name.str, field_name.len, "is_option")) { return v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option); } else if (_SLIT_EQ(field_name.str, field_name.len, "is_array")) { return (field_sym->kind == v__ast__Kind__array || field_sym->kind == v__ast__Kind__array_fixed); } else if (_SLIT_EQ(field_name.str, field_name.len, "is_map")) { return field_sym->kind == v__ast__Kind__map; } else if (_SLIT_EQ(field_name.str, field_name.len, "is_chan")) { return field_sym->kind == v__ast__Kind__chan; } else if (_SLIT_EQ(field_name.str, field_name.len, "is_struct")) { return field_sym->kind == v__ast__Kind__struct; } else if (_SLIT_EQ(field_name.str, field_name.len, "is_alias")) { return field_sym->kind == v__ast__Kind__alias; } else if (_SLIT_EQ(field_name.str, field_name.len, "is_enum")) { return field_sym->kind == v__ast__Kind__enum; } else { return false; } return 0; } bool v__type_resolver__TypeResolver_is_comptime_type(v__type_resolver__TypeResolver* t, v__ast__Type x, v__ast__ComptimeType y) { v__ast__Kind x_kind = v__ast__Table_type_kind(t->table, x); switch (y.kind) { case v__ast__ComptimeTypeKind__unknown: { return false; } case v__ast__ComptimeTypeKind__map: { return x_kind == v__ast__Kind__map; } case v__ast__ComptimeTypeKind__string: { return x_kind == v__ast__Kind__string; } case v__ast__ComptimeTypeKind__voidptr: { return v__ast__Type_is_voidptr(x); } case v__ast__ComptimeTypeKind__pointer: { return v__ast__Type_is_any_kind_of_pointer(x); } case v__ast__ComptimeTypeKind__int: { return (x_kind == v__ast__Kind__i8 || x_kind == v__ast__Kind__i16 || x_kind == v__ast__Kind__i32 || x_kind == v__ast__Kind__int || x_kind == v__ast__Kind__i64 || x_kind == v__ast__Kind__u8 || x_kind == v__ast__Kind__u16 || x_kind == v__ast__Kind__u32 || x_kind == v__ast__Kind__u64 || x_kind == v__ast__Kind__usize || x_kind == v__ast__Kind__isize || x_kind == v__ast__Kind__int_literal); } case v__ast__ComptimeTypeKind__float: { return (x_kind == v__ast__Kind__f32 || x_kind == v__ast__Kind__f64 || x_kind == v__ast__Kind__float_literal); } case v__ast__ComptimeTypeKind__struct: { return x_kind == v__ast__Kind__struct; } case v__ast__ComptimeTypeKind__iface: { return x_kind == v__ast__Kind__interface; } case v__ast__ComptimeTypeKind__array: { return (x_kind == v__ast__Kind__array || x_kind == v__ast__Kind__array_fixed); } case v__ast__ComptimeTypeKind__array_dynamic: { return x_kind == v__ast__Kind__array; } case v__ast__ComptimeTypeKind__array_fixed: { return x_kind == v__ast__Kind__array_fixed; } case v__ast__ComptimeTypeKind__sum_type: { return x_kind == v__ast__Kind__sum_type; } case v__ast__ComptimeTypeKind__enum: { return x_kind == v__ast__Kind__enum; } case v__ast__ComptimeTypeKind__alias: { return x_kind == v__ast__Kind__alias; } case v__ast__ComptimeTypeKind__function: { return x_kind == v__ast__Kind__function; } case v__ast__ComptimeTypeKind__option: { return v__ast__Type_has_flag(x, v__ast__TypeFlag__option); } } return 0; } v__ast__Type v__type_resolver__TypeResolver_unwrap_generic_expr(v__type_resolver__TypeResolver* ct, v__ast__Expr expr, v__ast__Type default_typ) { if (expr._typ == 384 /* v.ast.StringLiteral */) { return _const_v__ast__string_type; } else if (expr._typ == 383 /* v.ast.StringInterLiteral */) { return _const_v__ast__string_type; } else if (expr._typ == 374 /* v.ast.ParExpr */) { return v__type_resolver__TypeResolver_unwrap_generic_expr(ct, (*expr._v__ast__ParExpr).expr, default_typ); } else if (expr._typ == 345 /* v.ast.CastExpr */) { return (*expr._v__ast__CastExpr).typ; } else if (expr._typ == 362 /* v.ast.InfixExpr */) { if ((*expr._v__ast__InfixExpr).left_ct_expr) { return v__type_resolver__IResolverType_name_table[ct->resolver._typ]._method_unwrap_generic(ct->resolver._object, v__type_resolver__TypeResolver_get_type(ct, (*expr._v__ast__InfixExpr).left)); } if ((*expr._v__ast__InfixExpr).right_ct_expr) { return v__type_resolver__IResolverType_name_table[ct->resolver._typ]._method_unwrap_generic(ct->resolver._object, v__type_resolver__TypeResolver_get_type(ct, (*expr._v__ast__InfixExpr).right)); } return default_typ; } else if (expr._typ == 358 /* v.ast.Ident */) { return ((*expr._v__ast__Ident).ct_expr ? (v__type_resolver__IResolverType_name_table[ct->resolver._typ]._method_unwrap_generic(ct->resolver._object, v__type_resolver__TypeResolver_get_type(ct, v__ast__Ident_to_sumtype_v__ast__Expr(&(*expr._v__ast__Ident))))) : (default_typ)); } else if (expr._typ == 339 /* v.ast.AsCast */) { return v__type_resolver__IResolverType_name_table[ct->resolver._typ]._method_unwrap_generic(ct->resolver._object, (*expr._v__ast__AsCast).typ); } else { return default_typ; } return 0; } inline bool v__type_resolver__TypeResolver_is_generic_param_var(v__type_resolver__TypeResolver* t, v__ast__Expr node) { return (node)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((node)._v__ast__Ident,(node)._typ, 358)).info)._typ == 477 /* v.ast.IdentVar */ && ((*(v__ast__Ident*)__as_cast((node)._v__ast__Ident,(node)._typ, 358)).obj)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast(((*(v__ast__Ident*)__as_cast((node)._v__ast__Ident,(node)._typ, 358)).obj)._v__ast__Var,((*(v__ast__Ident*)__as_cast((node)._v__ast__Ident,(node)._typ, 358)).obj)._typ, 422)).ct_type_var == v__ast__ComptimeVarKind__generic_param; } bool v__type_resolver__TypeResolver_is_generic_expr(v__type_resolver__TypeResolver* t, v__ast__Expr node) { bool _t2 = 0; if (node._typ == 358 /* v.ast.Ident */) { _t2 = v__type_resolver__TypeResolver_is_generic_param_var(t, v__ast__Ident_to_sumtype_v__ast__Expr(&(*node._v__ast__Ident))); } else if (node._typ == 361 /* v.ast.IndexExpr */) { _t2 = v__type_resolver__TypeResolver_is_generic_param_var(t, (*node._v__ast__IndexExpr).left); } else if (node._typ == 344 /* v.ast.CallExpr */) { bool _t3 = false; Array_v__ast__CallArg _t3_orig = (*node._v__ast__CallExpr).args; int _t3_len = _t3_orig.len; for (int _t4 = 0; _t4 < _t3_len; ++_t4) { v__ast__CallArg it = ((v__ast__CallArg*) _t3_orig.data)[_t4]; if (v__type_resolver__TypeResolver_is_generic_param_var(t, it.expr)) { _t3 = true; break; } } if ( _t3) { return true; } if ((*node._v__ast__CallExpr).is_static_method && v__ast__Type_has_flag((*node._v__ast__CallExpr).left_type, v__ast__TypeFlag__generic)) { return true; } if ((*node._v__ast__CallExpr).return_type_generic != 0 && v__ast__Type_has_flag((*node._v__ast__CallExpr).return_type_generic, v__ast__TypeFlag__generic)) { return true; } bool _t8 = false; Array_v__ast__Type _t8_orig = (*node._v__ast__CallExpr).concrete_types; int _t8_len = _t8_orig.len; for (int _t9 = 0; _t9 < _t8_len; ++_t9) { v__ast__Type it = ((v__ast__Type*) _t8_orig.data)[_t9]; if (v__ast__Type_has_flag(it, v__ast__TypeFlag__generic)) { _t8 = true; break; } } _t2 = _t8; } else if (node._typ == 379 /* v.ast.SelectorExpr */) { _t2 = v__type_resolver__TypeResolver_is_generic_param_var(t, (*node._v__ast__SelectorExpr).expr); } else if (node._typ == 339 /* v.ast.AsCast */) { _t2 = v__ast__Type_has_flag((*node._v__ast__AsCast).typ, v__ast__TypeFlag__generic); } else { _t2 = false; } return _t2; } v__ast__Type v__type_resolver__TypeResolver_get_generic_array_fixed_element_type(v__type_resolver__TypeResolver* t, v__ast__ArrayFixed __v_array) { v__ast__ArrayFixed cparam_elem_info = __v_array; v__ast__TypeSymbol* cparam_elem_sym = v__ast__Table_sym(t->table, __v_array.elem_type); for (;;) { if ((cparam_elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { cparam_elem_info = (*cparam_elem_sym->info._v__ast__ArrayFixed); cparam_elem_sym = v__ast__Table_sym(t->table, cparam_elem_info.elem_type); } else { return v__ast__Type_set_nr_muls(cparam_elem_info.elem_type, 0); } } return _const_v__ast__void_type; } v__ast__Type v__type_resolver__TypeResolver_get_generic_array_element_type(v__type_resolver__TypeResolver* t, v__ast__Array __v_array) { v__ast__Array cparam_elem_info = __v_array; v__ast__TypeSymbol* cparam_elem_sym = v__ast__Table_sym(t->table, __v_array.elem_type); for (;;) { if ((cparam_elem_sym->info)._typ == 513 /* v.ast.Array */) { cparam_elem_info = (*cparam_elem_sym->info._v__ast__Array); cparam_elem_sym = v__ast__Table_sym(t->table, cparam_elem_info.elem_type); } else { return v__ast__Type_set_nr_muls(cparam_elem_info.elem_type, 0); } } return _const_v__ast__void_type; } Map_int_v__ast__Type v__type_resolver__TypeResolver_resolve_args(v__type_resolver__TypeResolver* t, v__ast__FnDecl* cur_fn, v__ast__Fn* func, v__ast__CallExpr* node_, Array_v__ast__Type concrete_types) { Map_int_v__ast__Type comptime_args = new_map(sizeof(int), sizeof(v__ast__Type), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop) ; bool has_dynamic_vars = (cur_fn != ((void*)0) && cur_fn->generic_names.len > 0) || (t->info.comptime_for_field_var).len != 0 || func->generic_names.len != node_->raw_concrete_types.len; if (!has_dynamic_vars) { return comptime_args; } int offset = (func->is_method ? (1) : (0)); int k = -1; for (int i = 0; i < node_->args.len; ++i) { v__ast__CallArg* call_arg = ((v__ast__CallArg*)node_->args.data) + i; v__ast__Param _t2; /* if prepend */ if (func->is_variadic && i >= (int)(func->params.len - ((int)(offset + 1)))) { _t2 = (*(v__ast__Param*)array_last(func->params)); } else { _t2 = (*(v__ast__Param*)array_get(func->params, (int)(offset + i))); } v__ast__Param param = _t2; if (!v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { continue; } k++; v__ast__Type param_typ = param.typ; if ((call_arg->expr)._typ == 358 /* v.ast.Ident */) { if (((*call_arg->expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { (*(v__ast__CallArg*)array_get(node_->args, i)).typ = (*(*call_arg->expr._v__ast__Ident).obj._v__ast__Var).typ; if (!((*(*call_arg->expr._v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__generic_var || (*(*call_arg->expr._v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__generic_param || (*(*call_arg->expr._v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__no_comptime)) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(t, call_arg->expr); if (ctyp != _const_v__ast__void_type) { v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(t->table, ctyp); v__ast__TypeSymbol* param_sym = v__ast__Table_final_sym(t->table, param_typ); if ((arg_sym->info)._typ == 513 /* v.ast.Array */ && param_sym->kind == v__ast__Kind__array) { ctyp = (*arg_sym->info._v__ast__Array).elem_type; } else if ((arg_sym->info)._typ == 514 /* v.ast.Map */ && (param_sym->info)._typ == 514 /* v.ast.Map */) { if ((*(*call_arg->expr._v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__value_var) { ctyp = (*arg_sym->info._v__ast__Map).value_type; if (v__ast__Type_nr_muls((*param_sym->info._v__ast__Map).value_type) > 0 && v__ast__Type_nr_muls(ctyp) > 0) { ctyp = v__ast__Type_set_nr_muls(ctyp, 0); } } else if ((*(*call_arg->expr._v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__key_var) { ctyp = (*arg_sym->info._v__ast__Map).key_type; if (v__ast__Type_nr_muls((*param_sym->info._v__ast__Map).key_type) > 0 && v__ast__Type_nr_muls(ctyp) > 0) { ctyp = v__ast__Type_set_nr_muls(ctyp, 0); } } else { bool key_is_generic = v__ast__Type_has_flag((*param_sym->info._v__ast__Map).key_type, v__ast__TypeFlag__generic); if (key_is_generic) { ctyp = v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*arg_sym->info._v__ast__Map).key_type); } if (v__ast__Type_has_flag((*param_sym->info._v__ast__Map).value_type, v__ast__TypeFlag__generic)) { if (key_is_generic) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { ctyp }); k++; } ctyp = v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*arg_sym->info._v__ast__Map).value_type); } } } else if (arg_sym->kind == v__ast__Kind__any) { v__ast__TypeSymbol* cparam_type_sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, ctyp)); if ((param_sym->info)._typ == 514 /* v.ast.Map */ && (cparam_type_sym->info)._typ == 514 /* v.ast.Map */) { if (v__ast__Type_has_flag((*param_sym->info._v__ast__Map).key_type, v__ast__TypeFlag__generic)) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*cparam_type_sym->info._v__ast__Map).key_type }); if (v__ast__Type_has_flag((*param_sym->info._v__ast__Map).value_type, v__ast__TypeFlag__generic)) { k++; ctyp = (*cparam_type_sym->info._v__ast__Map).value_type; } } else if (v__ast__Type_has_flag((*param_sym->info._v__ast__Map).value_type, v__ast__TypeFlag__generic)) { ctyp = (*cparam_type_sym->info._v__ast__Map).value_type; } } } map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { ctyp }); } } else if ((*(*call_arg->expr._v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__generic_param) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(t, call_arg->expr); if (ctyp != _const_v__ast__void_type) { v__ast__TypeSymbol* arg_sym = v__ast__Table_final_sym(t->table, call_arg->typ); v__ast__TypeSymbol* param_typ_sym = v__ast__Table_sym(t->table, param_typ); if (v__ast__Type_has_flag(param_typ, v__ast__TypeFlag__variadic)) { ctyp = v__ast__mktyp(ctyp); map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { ctyp }); } else if ((arg_sym->info)._typ == 513 /* v.ast.Array */ && param_typ_sym->kind == v__ast__Kind__array) { ctyp = v__type_resolver__TypeResolver_get_generic_array_element_type(t, (*arg_sym->info._v__ast__Array)); map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { ctyp }); } else if (arg_sym->kind == v__ast__Kind__struct || arg_sym->kind == v__ast__Kind__interface || arg_sym->kind == v__ast__Kind__sum_type) { Array_v__ast__Type generic_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); if (arg_sym->info._typ == 518 /* v.ast.Struct */) { if (param_typ_sym->generic_types.len > 0) { generic_types = array_clone_to_depth(¶m_typ_sym->generic_types, 0); } else { generic_types = array_clone_to_depth(&(*arg_sym->info._v__ast__Struct).generic_types, 0); } } else if (arg_sym->info._typ == 542 /* v.ast.Interface */) { if (param_typ_sym->generic_types.len > 0) { generic_types = array_clone_to_depth(¶m_typ_sym->generic_types, 0); } else { generic_types = array_clone_to_depth(&(*arg_sym->info._v__ast__Interface).generic_types, 0); } } else if (arg_sym->info._typ == 544 /* v.ast.SumType */) { if (param_typ_sym->generic_types.len > 0) { generic_types = array_clone_to_depth(¶m_typ_sym->generic_types, 0); } else { generic_types = array_clone_to_depth(&(*arg_sym->info._v__ast__SumType).generic_types, 0); } } else { } Array_string _t3 = {0}; Array_v__ast__Type _t3_orig = generic_types; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(string)); for (int _t5 = 0; _t5 < _t3_len; ++_t5) { v__ast__Type it = ((v__ast__Type*) _t3_orig.data)[_t5]; string _t4 = v__ast__Table_sym(t->table, it)->name; array_push((array*)&_t3, &_t4); } Array_string generic_names =_t3; for (int _t6 = 0; _t6 < cur_fn->generic_names.len; ++_t6) { string gt_name = ((string*)cur_fn->generic_names.data)[_t6]; if ((Array_string_contains(generic_names, gt_name)) && generic_types.len == concrete_types.len) { int idx = Array_string_index(generic_names, gt_name); map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*(v__ast__Type*)array_get(concrete_types, idx)) }); break; } } } else if (arg_sym->kind == v__ast__Kind__any) { v__ast__TypeSymbol* cparam_type_sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, ctyp)); if (param_typ_sym->kind == v__ast__Kind__array && (cparam_type_sym->info)._typ == 513 /* v.ast.Array */) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*cparam_type_sym->info._v__ast__Array).elem_type }); } else if ((param_typ_sym->info)._typ == 514 /* v.ast.Map */ && (cparam_type_sym->info)._typ == 514 /* v.ast.Map */) { if (v__ast__Type_has_flag((*param_typ_sym->info._v__ast__Map).key_type, v__ast__TypeFlag__generic)) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*cparam_type_sym->info._v__ast__Map).key_type }); if (v__ast__Type_has_flag((*param_typ_sym->info._v__ast__Map).value_type, v__ast__TypeFlag__generic)) { k++; map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*cparam_type_sym->info._v__ast__Map).value_type }); } } else if (v__ast__Type_has_flag((*param_typ_sym->info._v__ast__Map).value_type, v__ast__TypeFlag__generic)) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*cparam_type_sym->info._v__ast__Map).value_type }); } } else { if (v__ast__Expr_is_auto_deref_var((*(v__ast__CallArg*)array_get(node_->args, i)).expr)) { ctyp = v__ast__Type_deref(ctyp); } if (v__ast__Type_nr_muls(ctyp) > 0 && v__ast__Type_nr_muls(param_typ) > 0) { ctyp = v__ast__Type_set_nr_muls(ctyp, 0); } map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { ctyp }); } } else { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { ctyp }); } } } else if ((*(*call_arg->expr._v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__generic_var) { v__ast__Type ctyp = v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, v__type_resolver__TypeResolver_get_type(t, call_arg->expr)); v__ast__TypeSymbol* cparam_type_sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, ctyp)); v__ast__TypeSymbol* param_typ_sym = v__ast__Table_sym(t->table, param_typ); if (param_typ_sym->kind == v__ast__Kind__array && (cparam_type_sym->info)._typ == 513 /* v.ast.Array */) { ctyp = (*cparam_type_sym->info._v__ast__Array).elem_type; } if (v__ast__Expr_is_auto_deref_var((*(v__ast__CallArg*)array_get(node_->args, i)).expr)) { ctyp = v__ast__Type_deref(ctyp); } if (v__ast__Type_nr_muls(ctyp) > 0 && v__ast__Type_nr_muls(param_typ) > 0) { ctyp = v__ast__Type_set_nr_muls(ctyp, 0); } map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { ctyp }); } } } else if ((call_arg->expr)._typ == 376 /* v.ast.PrefixExpr */) { if (((*call_arg->expr._v__ast__PrefixExpr).right)._typ == 350 /* v.ast.ComptimeSelector */) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { t->info.comptime_for_field_type }); map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { v__ast__Type_deref((*(v__ast__Type*)map_get(ADDR(map, comptime_args), &(int[]){k}, &(v__ast__Type[]){ 0 }))) }); if (v__ast__Type_nr_muls(param_typ) > 0 && v__ast__Type_nr_muls((*(v__ast__Type*)map_get(ADDR(map, comptime_args), &(int[]){k}, &(v__ast__Type[]){ 0 }))) > 0) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { v__ast__Type_set_nr_muls((*(v__ast__Type*)map_get(ADDR(map, comptime_args), &(int[]){k}, &(v__ast__Type[]){ 0 })), 0) }); } } else if (((*call_arg->expr._v__ast__PrefixExpr).right)._typ == 358 /* v.ast.Ident */) { if (v__type_resolver__ResolverInfo_get_ct_type_var(&t->info, (*call_arg->expr._v__ast__PrefixExpr).right) != v__ast__ComptimeVarKind__generic_var) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(t, (*call_arg->expr._v__ast__PrefixExpr).right); if (ctyp != _const_v__ast__void_type) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { ctyp }); if (v__ast__Type_nr_muls(param_typ) > 0 && v__ast__Type_nr_muls((*(v__ast__Type*)map_get(ADDR(map, comptime_args), &(int[]){k}, &(v__ast__Type[]){ 0 }))) > 0) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { v__ast__Type_set_nr_muls((*(v__ast__Type*)map_get(ADDR(map, comptime_args), &(int[]){k}, &(v__ast__Type[]){ 0 })), 0) }); } } } } } else if ((call_arg->expr)._typ == 350 /* v.ast.ComptimeSelector */) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { t->info.comptime_for_field_type }); v__ast__TypeSymbol* arg_sym = v__ast__Table_final_sym(t->table, call_arg->typ); v__ast__TypeSymbol* param_sym = v__ast__Table_sym(t->table, param_typ); if (arg_sym->kind == v__ast__Kind__array && param_sym->kind == v__ast__Kind__array) { v__ast__TypeSymbol* comptime_sym = v__ast__Table_sym(t->table, (*(v__ast__Type*)map_get(ADDR(map, comptime_args), &(int[]){k}, &(v__ast__Type[]){ 0 }))); map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { v__type_resolver__TypeResolver_get_generic_array_element_type(t, *(v__ast__Array*)__as_cast((comptime_sym->info)._v__ast__Array,(comptime_sym->info)._typ, 513)) }); } else if ((arg_sym->info)._typ == 514 /* v.ast.Map */ && (param_sym->info)._typ == 514 /* v.ast.Map */) { v__ast__TypeSymbol* comptime_sym = v__ast__Table_sym(t->table, (*(v__ast__Type*)map_get(ADDR(map, comptime_args), &(int[]){k}, &(v__ast__Type[]){ 0 }))); if ((comptime_sym->info)._typ == 514 /* v.ast.Map */) { if (v__ast__Type_has_flag((*param_sym->info._v__ast__Map).key_type, v__ast__TypeFlag__generic)) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*comptime_sym->info._v__ast__Map).key_type }); if (v__ast__Type_has_flag((*param_sym->info._v__ast__Map).value_type, v__ast__TypeFlag__generic)) { k++; map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*comptime_sym->info._v__ast__Map).value_type }); } } else if (v__ast__Type_has_flag((*param_sym->info._v__ast__Map).value_type, v__ast__TypeFlag__generic)) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*comptime_sym->info._v__ast__Map).value_type }); } } } if (v__ast__Type_nr_muls(param_typ) > 0 && v__ast__Type_nr_muls((*(v__ast__Type*)map_get(ADDR(map, comptime_args), &(int[]){k}, &(v__ast__Type[]){ 0 }))) > 0) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { v__ast__Type_set_nr_muls((*(v__ast__Type*)map_get(ADDR(map, comptime_args), &(int[]){k}, &(v__ast__Type[]){ 0 })), 0) }); } } else if ((call_arg->expr)._typ == 349 /* v.ast.ComptimeCall */) { if (fast_string_eq((*call_arg->expr._v__ast__ComptimeCall).method_name, _S("method"))) { v__ast__TypeSymbol* sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*call_arg->expr._v__ast__ComptimeCall).left_type)); _option_v__ast__Fn _t7; if (_t7 = v__ast__TypeSymbol_find_method(sym, t->info.comptime_for_method->name), _t7.state == 0) { v__ast__Fn m = *(v__ast__Fn*)_t7.data; map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { m.return_type }); } } } else if ((call_arg->expr)._typ == 345 /* v.ast.CastExpr */ && v__ast__Type_has_flag((*(v__ast__CastExpr*)__as_cast((call_arg->expr)._v__ast__CastExpr,(call_arg->expr)._typ, 345)).typ, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* cparam_type_sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*call_arg->expr._v__ast__CastExpr).typ)); v__ast__TypeSymbol* param_typ_sym = v__ast__Table_sym(t->table, param_typ); if (param_typ_sym->kind == v__ast__Kind__map && (cparam_type_sym->info)._typ == 514 /* v.ast.Map */) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*cparam_type_sym->info._v__ast__Map).key_type }); map_set(&comptime_args, &(int[]){(int)(k + 1)}, &(v__ast__Type[]) { (*cparam_type_sym->info._v__ast__Map).value_type }); } } else if ((call_arg->expr)._typ == 361 /* v.ast.IndexExpr */ && v__type_resolver__ResolverInfo_is_comptime(&t->info, v__ast__IndexExpr_to_sumtype_v__ast__Expr((v__ast__IndexExpr*)__as_cast((call_arg->expr)._v__ast__IndexExpr,(call_arg->expr)._typ, 361)))) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(t, call_arg->expr); v__ast__TypeSymbol* param_typ_sym = v__ast__Table_sym(t->table, param_typ); v__ast__TypeSymbol* cparam_type_sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, ctyp)); if (param_typ_sym->kind == v__ast__Kind__array && (cparam_type_sym->info)._typ == 513 /* v.ast.Array */) { ctyp = (*cparam_type_sym->info._v__ast__Array).elem_type; } map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { ctyp }); } else if ((call_arg->expr)._typ == 385 /* v.ast.StructInit */ && v__ast__Type_has_flag((*(v__ast__StructInit*)__as_cast((call_arg->expr)._v__ast__StructInit,(call_arg->expr)._typ, 385)).typ, v__ast__TypeFlag__generic)) { v__ast__Type ctyp = v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*call_arg->expr._v__ast__StructInit).typ); v__ast__TypeSymbol* param_typ_sym = v__ast__Table_sym(t->table, param_typ); v__ast__TypeSymbol* cparam_type_sym = v__ast__Table_sym(t->table, ctyp); if (param_typ_sym->kind == v__ast__Kind__array && (cparam_type_sym->info)._typ == 513 /* v.ast.Array */) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*cparam_type_sym->info._v__ast__Array).elem_type }); } else if (param_typ_sym->kind == v__ast__Kind__map && (cparam_type_sym->info)._typ == 514 /* v.ast.Map */) { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { (*cparam_type_sym->info._v__ast__Map).key_type }); map_set(&comptime_args, &(int[]){(int)(k + 1)}, &(v__ast__Type[]) { (*cparam_type_sym->info._v__ast__Map).value_type }); } else { map_set(&comptime_args, &(int[]){k}, &(v__ast__Type[]) { ctyp }); } } } return comptime_args; } multi_return_bool_Array_v__ast__Type v__type_resolver__TypeResolver_resolve_fn_generic_args(v__type_resolver__TypeResolver* t, v__ast__FnDecl* cur_fn, v__ast__Fn* func, v__ast__CallExpr* node) { Array_v__ast__Type _t1 = {0}; Array_v__ast__Type _t1_orig = node->concrete_types; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t3]; v__ast__Type _t2 = v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, it); array_push((array*)&_t1, &_t2); } Array_v__ast__Type concrete_types =_t1; bool need_recheck = false; if (concrete_types.len > 0) { int rec_len = 0; if (func->is_method && v__ast__Type_has_flag(node->left_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* rec_sym = v__ast__Table_final_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, node->left_type)); if (rec_sym->info._typ == 518 /* v.ast.Struct */) { rec_len += (*rec_sym->info._v__ast__Struct).generic_types.len; } else if (rec_sym->info._typ == 542 /* v.ast.Interface */) { rec_len += (*rec_sym->info._v__ast__Interface).generic_types.len; } else if (rec_sym->info._typ == 544 /* v.ast.SumType */) { rec_len += (*rec_sym->info._v__ast__SumType).generic_types.len; } else { } } Map_int_v__ast__Type comptime_args = v__type_resolver__TypeResolver_resolve_args(t, cur_fn, func, node, concrete_types); if (comptime_args.len > 0) { int _t5 = comptime_args.key_values.len; for (int _t4 = 0; _t4 < _t5; ++_t4 ) { int _t6 = comptime_args.key_values.len - _t5; _t5 = comptime_args.key_values.len; if (_t6 < 0) { _t4 = -1; continue; } if (!DenseArray_has_index(&comptime_args.key_values, _t4)) {continue;} int k = *(int*)DenseArray_key(&comptime_args.key_values, _t4); v__ast__Type v = (*(v__ast__Type*)DenseArray_value(&comptime_args.key_values, _t4)); if (((int)(rec_len + k)) < concrete_types.len) { array_set(&concrete_types, (int)(rec_len + k), &(v__ast__Type[]) { v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, v) }); } } if (v__ast__Table_register_fn_concrete_types(t->table, v__ast__Fn_fkey(func), concrete_types)) { need_recheck = true; } } } return (multi_return_bool_Array_v__ast__Type){.arg0=need_recheck, .arg1=concrete_types}; } VV_LOC v__ast__Type v__type_resolver__DummyResolver_unwrap_generic(v__type_resolver__DummyResolver d, v__ast__Type t) { return t; } inline v__type_resolver__TypeResolver* v__type_resolver__TypeResolver__static__new(v__ast__Table* table, v__type_resolver__IResolverType* resolver) { return ((v__type_resolver__TypeResolver*)memdup(&(v__type_resolver__TypeResolver){.resolver = *resolver,.table = table,.info = ((v__type_resolver__ResolverInfo){.saved_type_map = new_map(sizeof(string), sizeof(v__ast__Type), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.comptime_loop_id = 0,.inside_comptime_for = 0,.inside_comptime_if = 0,.has_different_types = 0,.comptime_for_variant_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_field_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_field_type = 0,.comptime_for_field_value = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.comptime_for_enum_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_attr_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_method_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_method = ((void*)0),.comptime_for_method_ret_type = 0,.comptime_for_method_param_var = (string){.str=(byteptr)"", .is_lit=1},}),.info_stack = __new_array(0, 0, sizeof(v__type_resolver__ResolverInfo)),.type_map = new_map(sizeof(string), sizeof(v__ast__Type), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}, sizeof(v__type_resolver__TypeResolver))); } inline void v__type_resolver__TypeResolver_update_ct_type(v__type_resolver__TypeResolver* t, string key, v__ast__Type var_type) { map_set(&t->type_map, &(string[]){key}, &(v__ast__Type[]) { var_type }); } inline v__ast__Type v__type_resolver__TypeResolver_get_ct_type_or_default(v__type_resolver__TypeResolver* t, string key, v__ast__Type default_type) { v__ast__Type* _t3 = (v__ast__Type*)(map_get_check(ADDR(map, t->type_map), &(string[]){key})); _option_v__ast__Type _t2 = {0}; if (_t3) { *((v__ast__Type*)&_t2.data) = *((v__ast__Type*)_t3); } else { _t2.state = 2; _t2.err = _v_error(_S("map key does not exist")); } ; if (_t2.state != 0) { IError err = _t2.err; *(v__ast__Type*) _t2.data = default_type; } return (*(v__ast__Type*)_t2.data); } VNORETURN VV_LOC void v__type_resolver__TypeResolver_error(v__type_resolver__TypeResolver* t, string s, v__token__Pos pos) { v__util__show_compiler_message(_S("cgen error:"), ((v__errors__CompilerMessage){.message = s,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = (*(t->resolver.file))->path,.pos = pos,.reporter = 0,})); _v_exit(1); VUNREACHABLE(); while(1); } v__ast__Type v__type_resolver__TypeResolver_promote_type(v__type_resolver__TypeResolver* t, v__ast__Type left_type, v__ast__Type right_type) { if (left_type == _const_v__ast__f32_type && right_type == _const_v__ast__f64_type) { return right_type; } return left_type; } inline v__ast__Type v__type_resolver__TypeResolver_get_type_or_default(v__type_resolver__TypeResolver* t, v__ast__Expr node, v__ast__Type default_typ) { if (node._typ == 358 /* v.ast.Ident */) { if ((*node._v__ast__Ident).ct_expr) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(t, node); return (ctyp != _const_v__ast__void_type ? (((*node._v__ast__Ident).or_expr.kind == v__ast__OrKind__absent ? (ctyp) : (v__ast__Type_clear_flag(ctyp, v__ast__TypeFlag__option)))) : (default_typ)); } } else if (node._typ == 379 /* v.ast.SelectorExpr */) { if (((*node._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*node._v__ast__SelectorExpr).expr)._v__ast__Ident,((*node._v__ast__SelectorExpr).expr)._typ, 358)).ct_expr) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(t, node); return (ctyp != _const_v__ast__void_type ? (ctyp) : (default_typ)); } return default_typ; } else if (node._typ == 374 /* v.ast.ParExpr */) { return v__type_resolver__TypeResolver_get_type_or_default(t, (*node._v__ast__ParExpr).expr, default_typ); } else if (node._typ == 362 /* v.ast.InfixExpr */) { if (!v__ast__Expr_is_literal((*node._v__ast__InfixExpr).left) && ((*node._v__ast__InfixExpr).op == v__token__Kind__plus || (*node._v__ast__InfixExpr).op == v__token__Kind__minus || (*node._v__ast__InfixExpr).op == v__token__Kind__mul || (*node._v__ast__InfixExpr).op == v__token__Kind__div || (*node._v__ast__InfixExpr).op == v__token__Kind__mod)) { return v__type_resolver__TypeResolver_get_type_or_default(t, (*node._v__ast__InfixExpr).left, default_typ); } if (!v__ast__Expr_is_literal((*node._v__ast__InfixExpr).right) && ((*node._v__ast__InfixExpr).op == v__token__Kind__plus || (*node._v__ast__InfixExpr).op == v__token__Kind__minus || (*node._v__ast__InfixExpr).op == v__token__Kind__mul || (*node._v__ast__InfixExpr).op == v__token__Kind__div || (*node._v__ast__InfixExpr).op == v__token__Kind__mod)) { return v__type_resolver__TypeResolver_get_type_or_default(t, (*node._v__ast__InfixExpr).right, default_typ); } } else if (node._typ == 361 /* v.ast.IndexExpr */) { if (((*node._v__ast__IndexExpr).left)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*node._v__ast__IndexExpr).left)._v__ast__Ident,((*node._v__ast__IndexExpr).left)._typ, 358)).ct_expr) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(t, node); if (ctyp != _const_v__ast__void_type) { return ctyp; } } } else if (node._typ == 350 /* v.ast.ComptimeSelector */) { return v__type_resolver__TypeResolver_get_comptime_selector_type(t, (*node._v__ast__ComptimeSelector), _const_v__ast__void_type); } else if (node._typ == 345 /* v.ast.CastExpr */) { if (v__ast__Type_has_flag((*node._v__ast__CastExpr).typ, v__ast__TypeFlag__generic)) { return v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*node._v__ast__CastExpr).typ); } } else if (node._typ == 375 /* v.ast.PostfixExpr */) { if ((*node._v__ast__PostfixExpr).op == v__token__Kind__question && ((*node._v__ast__PostfixExpr).expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*node._v__ast__PostfixExpr).expr)._v__ast__Ident,((*node._v__ast__PostfixExpr).expr)._typ, 358)).ct_expr) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(t, node); return (ctyp != _const_v__ast__void_type ? (ctyp) : (default_typ)); } } else { return default_typ; } return default_typ; } inline v__ast__Type v__type_resolver__TypeResolver_get_type(v__type_resolver__TypeResolver* t, v__ast__Expr node) { if ((node)._typ == 358 /* v.ast.Ident */) { if (((*node._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { v__ast__Type _t2 = 0; switch ((*(*node._v__ast__Ident).obj._v__ast__Var).ct_type_var) { case v__ast__ComptimeVarKind__generic_param: { _t2 = (*(*node._v__ast__Ident).obj._v__ast__Var).typ; break; } case v__ast__ComptimeVarKind__generic_var: { v__ast__Type _t3; /* if prepend */ if ((*(*node._v__ast__Ident).obj._v__ast__Var).smartcasts.len > 0) { _t3 = (*(v__ast__Type*)array_last((*(*node._v__ast__Ident).obj._v__ast__Var).smartcasts)); } else { _t3 = (*(*node._v__ast__Ident).obj._v__ast__Var).typ; } _t2 = _t3; break; } case v__ast__ComptimeVarKind__smartcast: { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_ct_type_or_default(t, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = t->info.comptime_for_variant_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), (*(*node._v__ast__Ident).obj._v__ast__Var).typ); return (((*(*node._v__ast__Ident).obj._v__ast__Var)).is_unwrapped ? (v__ast__Type_clear_flag(ctyp, v__ast__TypeFlag__option)) : (ctyp)); } case v__ast__ComptimeVarKind__aggregate: { v__ast__Type _t5; /* if prepend */ if ((*(*node._v__ast__Ident).obj._v__ast__Var).smartcasts.len > 0) { _t5 = (*(v__ast__Type*)array_last((*(*node._v__ast__Ident).obj._v__ast__Var).smartcasts)); } else { _t5 = (*(*node._v__ast__Ident).obj._v__ast__Var).typ; } _t2 = v__type_resolver__TypeResolver_get_ct_type_or_default(t, (*node._v__ast__Ident).name, _t5); break; } case v__ast__ComptimeVarKind__key_var: case v__ast__ComptimeVarKind__value_var: { _t2 = v__type_resolver__TypeResolver_get_ct_type_or_default(t, (*node._v__ast__Ident).name, _const_v__ast__void_type); break; } case v__ast__ComptimeVarKind__field_var: { _t2 = ((*(*node._v__ast__Ident).obj._v__ast__Var).ct_type_unwrapped ? (v__ast__Type_clear_flag(t->info.comptime_for_field_type, v__ast__TypeFlag__option)) : (t->info.comptime_for_field_type)); break; } case v__ast__ComptimeVarKind__no_comptime: default: { { _t2 = _const_v__ast__void_type; break; } } } return _t2; } } else if ((node)._typ == 350 /* v.ast.ComptimeSelector */) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_comptime_selector_type(t, (*node._v__ast__ComptimeSelector), _const_v__ast__void_type); if ((*node._v__ast__ComptimeSelector).or_block.kind == v__ast__OrKind__propagate_option) { return v__ast__Type_clear_flag(ctyp, v__ast__TypeFlag__option); } return ctyp; } else if ((node)._typ == 379 /* v.ast.SelectorExpr */) { if ((*node._v__ast__SelectorExpr).is_field_typ) { return v__type_resolver__TypeResolver_get_type_from_comptime_var(t, *(v__ast__Ident*)__as_cast(((*node._v__ast__SelectorExpr).expr)._v__ast__Ident,((*node._v__ast__SelectorExpr).expr)._typ, 358)); } if (((*node._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*node._v__ast__SelectorExpr).expr)._v__ast__Ident,((*node._v__ast__SelectorExpr).expr)._typ, 358)).ct_expr) { v__ast__Type struct_typ = v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, v__type_resolver__TypeResolver_get_type(t, (*node._v__ast__SelectorExpr).expr)); v__ast__TypeSymbol* struct_sym = v__ast__Table_final_sym(t->table, struct_typ); if ((struct_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((struct_sym->info)._v__ast__Struct,(struct_sym->info)._typ, 518)).generic_types.len > 0) { _result_v__ast__StructField _t9; if (_t9 = v__ast__Table_find_field(t->table, struct_sym, (*node._v__ast__SelectorExpr).field_name), !_t9.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t9.data; v__ast__ScopeStructField* f_unwrap = v__ast__Scope_find_struct_field((*node._v__ast__SelectorExpr).scope, v__ast__Expr_str(ADDR(v__ast__Expr, (*node._v__ast__SelectorExpr).expr)), v__type_resolver__TypeResolver_get_type_or_default(t, (*node._v__ast__SelectorExpr).expr, (*node._v__ast__SelectorExpr).expr_type), (*node._v__ast__SelectorExpr).field_name); if (f_unwrap != ((void*)0)) { return (*(v__ast__Type*)array_last(f_unwrap->smartcasts)); } return field.typ; } } else { v__ast__TypeSymbol* sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*node._v__ast__SelectorExpr).expr_type)); _result_v__ast__StructField _t12; if (_t12 = v__ast__Table_find_field_with_embeds(t->table, sym, (*node._v__ast__SelectorExpr).field_name), !_t12.is_error) { v__ast__StructField f = *(v__ast__StructField*)_t12.data; return f.typ; } } } return (*node._v__ast__SelectorExpr).typ; } else if ((node)._typ == 349 /* v.ast.ComptimeCall */) { string method_name = t->info.comptime_for_method->name; v__ast__TypeSymbol* left_sym = v__ast__Table_sym(t->table, v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*node._v__ast__ComptimeCall).left_type)); _option_v__ast__Fn _t15 = v__ast__TypeSymbol_find_method(left_sym, method_name); if (_t15.state != 0) { IError err = _t15.err; v__type_resolver__TypeResolver_error(t, str_intp(2, _MOV((StrIntpData[]){{_S("could not find method `"), 0xfe10, {.d_s = method_name}}, {_S("` on compile-time resolution"), 0, { .d_c = 0 }}})), (*node._v__ast__ComptimeCall).method_pos); VUNREACHABLE(); return _const_v__ast__void_type; } v__ast__Fn f = (*(v__ast__Fn*)_t15.data); return f.return_type; } else if ((node)._typ == 361 /* v.ast.IndexExpr */ && v__type_resolver__ResolverInfo_is_comptime(&t->info, (*(v__ast__IndexExpr*)__as_cast((node)._v__ast__IndexExpr,(node)._typ, 361)).left)) { v__ast__Type nltype = v__type_resolver__TypeResolver_get_type(t, (*node._v__ast__IndexExpr).left); v__ast__Type nltype_unwrapped = v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, nltype); return v__ast__Table_value_type(t->table, nltype_unwrapped); } else if ((node)._typ == 374 /* v.ast.ParExpr */ && v__type_resolver__ResolverInfo_is_comptime(&t->info, (*(v__ast__ParExpr*)__as_cast((node)._v__ast__ParExpr,(node)._typ, 374)).expr)) { return v__type_resolver__TypeResolver_get_type(t, (*node._v__ast__ParExpr).expr); } else if ((node)._typ == 362 /* v.ast.InfixExpr */) { if ((*node._v__ast__InfixExpr).left_ct_expr) { return v__type_resolver__TypeResolver_get_type(t, (*node._v__ast__InfixExpr).left); } else if ((*node._v__ast__InfixExpr).right_ct_expr) { return v__type_resolver__TypeResolver_get_type(t, (*node._v__ast__InfixExpr).right); } } else if ((node)._typ == 345 /* v.ast.CastExpr */ && v__ast__Type_has_flag((*(v__ast__CastExpr*)__as_cast((node)._v__ast__CastExpr,(node)._typ, 345)).typ, v__ast__TypeFlag__generic)) { return v__type_resolver__IResolverType_name_table[t->resolver._typ]._method_unwrap_generic(t->resolver._object, (*node._v__ast__CastExpr).typ); } else if ((node)._typ == 375 /* v.ast.PostfixExpr */ && (*(v__ast__PostfixExpr*)__as_cast((node)._v__ast__PostfixExpr,(node)._typ, 375)).op == v__token__Kind__question && (((*(v__ast__PostfixExpr*)__as_cast((node)._v__ast__PostfixExpr,(node)._typ, 375)).expr)._typ == 358 /* v.ast.Ident */ || ((*(v__ast__PostfixExpr*)__as_cast((node)._v__ast__PostfixExpr,(node)._typ, 375)).expr)._typ == 350 /* v.ast.ComptimeSelector */)) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(t, (*node._v__ast__PostfixExpr).expr); return v__ast__Type_clear_flag(ctyp, v__ast__TypeFlag__option); } return _const_v__ast__void_type; } _result_v__scanner__Scanner_ptr v__scanner__new_scanner_file(string file_path, v__scanner__CommentsMode comments_mode, v__pref__Preferences* pref_) { if (!os__is_file(file_path)) { return (_result_v__scanner__Scanner_ptr){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = file_path}}, {_S(" is not a .v file"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } _result_string _t2 = v__util__read_file(file_path); if (_t2.is_error) { IError err = _t2.err; return (_result_v__scanner__Scanner_ptr){ .is_error=true, .err=err, .data={E_STRUCT} }; } string raw_text = (*(string*)_t2.data); if ((pref_->line_info).len != 0) { string abs_path = os__join_path(os__getwd(), new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){file_path}))); if (string__eq(pref_->linfo.path, file_path) || string__eq(pref_->linfo.path, abs_path)) { raw_text = v__pref__add_line_info_expr_to_program_text(raw_text, pref_->linfo); } } v__scanner__Scanner* s = ((v__scanner__Scanner*)memdup(&(v__scanner__Scanner){.file_path = file_path, .file_base = os__base(file_path), .text = raw_text, .pos = -1, .line_nr = 0, .last_nl_pos = -1, .is_crlf = 0, .is_inside_string = 0, .is_nested_string = 0, .is_inter_start = 0, .is_inter_end = 0, .is_enclosed_inter = 0, .is_nested_enclosed_inter = 0, .string_count = 0, .str_dollar_needs_rcbr = __new_array_with_default(0, 0, sizeof(bool), 0), .line_comment = (string){.str=(byteptr)"", .is_lit=1}, .last_lt = -1, .is_print_line_on_error = true, .is_print_colored_error = true, .is_print_rel_paths_on_error = true, .quote = 0, .inter_quote = 0, .just_closed_inter = 0, .nr_lines = 0, .is_vh = 0, .is_fmt = pref_->is_fmt, .comments_mode = comments_mode, .is_inside_toplvl_statement = 0, .all_tokens = __new_array_with_default(0, (int)(raw_text.len / 3), sizeof(v__token__Token), 0), .tidx = 0, .eofs = 0, .max_eofs = 50, .inter_cbr_count = 0, .pref = pref_, .error_details = __new_array(0, 0, sizeof(string)), .errors = __new_array(0, 0, sizeof(v__errors__Error)), .warnings = __new_array(0, 0, sizeof(v__errors__Warning)), .notices = __new_array(0, 0, sizeof(v__errors__Notice)), .should_abort = 0, .all_pos = __new_array(0, 0, sizeof(int)), .u16_escapes_pos = __new_array(0, 0, sizeof(int)), .u32_escapes_pos = __new_array(0, 0, sizeof(int)), .h_escapes_pos = __new_array(0, 0, sizeof(int)), .str_segments = __new_array(0, 0, sizeof(string)), }, sizeof(v__scanner__Scanner))); v__scanner__Scanner_scan_all_tokens_in_buffer(s); _result_v__scanner__Scanner_ptr _t4 = {0}; _result_ok(&(v__scanner__Scanner*[]) { s }, (_result*)(&_t4), sizeof(v__scanner__Scanner*)); return _t4; } v__scanner__Scanner* v__scanner__new_scanner(string text, v__scanner__CommentsMode comments_mode, v__pref__Preferences* pref_) { v__scanner__Scanner* s = ((v__scanner__Scanner*)memdup(&(v__scanner__Scanner){.file_path = _const_v__scanner__internally_generated_v_code, .file_base = _const_v__scanner__internally_generated_v_code, .text = text, .pos = -1, .line_nr = 0, .last_nl_pos = -1, .is_crlf = 0, .is_inside_string = 0, .is_nested_string = 0, .is_inter_start = 0, .is_inter_end = 0, .is_enclosed_inter = 0, .is_nested_enclosed_inter = 0, .string_count = 0, .str_dollar_needs_rcbr = __new_array_with_default(0, 0, sizeof(bool), 0), .line_comment = (string){.str=(byteptr)"", .is_lit=1}, .last_lt = -1, .is_print_line_on_error = true, .is_print_colored_error = true, .is_print_rel_paths_on_error = true, .quote = 0, .inter_quote = 0, .just_closed_inter = 0, .nr_lines = 0, .is_vh = 0, .is_fmt = pref_->is_fmt, .comments_mode = comments_mode, .is_inside_toplvl_statement = 0, .all_tokens = __new_array_with_default(0, (int)(text.len / 3), sizeof(v__token__Token), 0), .tidx = 0, .eofs = 0, .max_eofs = 50, .inter_cbr_count = 0, .pref = pref_, .error_details = __new_array(0, 0, sizeof(string)), .errors = __new_array(0, 0, sizeof(v__errors__Error)), .warnings = __new_array(0, 0, sizeof(v__errors__Warning)), .notices = __new_array(0, 0, sizeof(v__errors__Notice)), .should_abort = 0, .all_pos = __new_array(0, 0, sizeof(int)), .u16_escapes_pos = __new_array(0, 0, sizeof(int)), .u32_escapes_pos = __new_array(0, 0, sizeof(int)), .h_escapes_pos = __new_array(0, 0, sizeof(int)), .str_segments = __new_array(0, 0, sizeof(string)), }, sizeof(v__scanner__Scanner))); v__scanner__Scanner_scan_all_tokens_in_buffer(s); return s; } void v__scanner__Scanner_free(v__scanner__Scanner* s) { array_free(&s->all_tokens); } inline VV_LOC bool v__scanner__Scanner_should_parse_comment(v__scanner__Scanner* s) { return s->comments_mode == v__scanner__CommentsMode__parse_comments || (s->comments_mode == v__scanner__CommentsMode__toplevel_comments && !s->is_inside_toplvl_statement); } void v__scanner__Scanner_set_is_inside_toplevel_statement(v__scanner__Scanner* s, bool newstate) { s->is_inside_toplvl_statement = newstate; } void v__scanner__Scanner_set_current_tidx(v__scanner__Scanner* s, int cidx) { int tidx = (cidx < 0 ? (0) : (cidx)); tidx = (tidx > s->all_tokens.len ? (s->all_tokens.len) : (tidx)); s->tidx = tidx; } inline VV_LOC v__token__Token v__scanner__Scanner_new_token(v__scanner__Scanner* s, v__token__Kind tok_kind, string lit, int len) { int cidx = s->tidx; s->tidx++; int line_offset = (tok_kind == v__token__Kind__hash ? (0) : (1)); int max_column = (int)((int)(v__scanner__Scanner_current_column(s) - len) + 1); if (max_column < 1) { max_column = 1; } return ((v__token__Token){ .kind = tok_kind, .lit = lit, .line_nr = (int)(s->line_nr + line_offset), .col = max_column, .pos = (int)((int)(s->pos - len) + 1), .len = len, .tidx = cidx, }); } inline VV_LOC v__token__Token v__scanner__Scanner_new_eof_token(v__scanner__Scanner* s) { return ((v__token__Token){ .kind = v__token__Kind__eof, .lit = _S(""), .line_nr = (int)(s->line_nr + 1), .col = v__scanner__Scanner_current_column(s), .pos = s->pos, .len = 1, .tidx = s->tidx, }); } inline VV_LOC v__token__Token v__scanner__Scanner_new_multiline_token(v__scanner__Scanner* s, v__token__Kind tok_kind, string lit, int len, int start_line) { int cidx = s->tidx; s->tidx++; int max_column = (int)((int)(v__scanner__Scanner_current_column(s) - len) + 1); if (max_column < 1) { max_column = 1; } return ((v__token__Token){ .kind = tok_kind, .lit = lit, .line_nr = (int)(start_line + 1), .col = max_column, .pos = (int)((int)(s->pos - len) + 1), .len = len, .tidx = cidx, }); } inline VV_LOC string v__scanner__Scanner_ident_name(v__scanner__Scanner* s) { int start = s->pos; s->pos++; for (;;) { if (!(s->pos < s->text.len)) break; u8 c = s->text.str[ s->pos]; if (_const_v__util__func_char_table[c]) { s->pos++; continue; } break; } string name = string_substr(s->text, start, s->pos); s->pos--; return name; } VV_LOC string v__scanner__Scanner_num_lit(v__scanner__Scanner* s, int start, int end) { if (s->is_fmt) { return string_substr(s->text, start, end); } { // Unsafe block u8* txt = s->text.str; u8* b = malloc_noscan((int)((int)(end - start) + 1)); int i_no_sep = 0; for (int i = start; i < end; ++i) { if (txt[i] != _const_v__scanner__num_sep) { b[i_no_sep] = txt[i]; i_no_sep++; } } b[i_no_sep] = 0; return u8_vstring_with_len(b, i_no_sep); } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC string v__scanner__Scanner_ident_bin_number(v__scanner__Scanner* s) { bool has_wrong_digit = false; int first_wrong_digit_pos = 0; rune first_wrong_digit = '\0'; int start_pos = s->pos; s->pos += 2; if (s->pos < s->text.len && string_at(s->text, s->pos) == _const_v__scanner__num_sep) { v__scanner__Scanner_error(s, _S("separator `_` is only valid between digits in a numeric literal")); } for (;;) { if (!(s->pos < s->text.len)) break; u8 c = string_at(s->text, s->pos); if (c == _const_v__scanner__num_sep && string_at(s->text, (int)(s->pos - 1)) == _const_v__scanner__num_sep) { v__scanner__Scanner_error(s, _S("cannot use `_` consecutively")); } if (!u8_is_bin_digit(c) && c != _const_v__scanner__num_sep) { if ((!u8_is_digit(c) && !u8_is_letter(c)) || s->is_inside_string || s->is_nested_string) { break; } else if (!has_wrong_digit) { has_wrong_digit = true; first_wrong_digit_pos = s->pos; first_wrong_digit = c; } } s->pos++; } if (string_at(s->text, (int)(s->pos - 1)) == _const_v__scanner__num_sep) { s->pos--; v__scanner__Scanner_error(s, _S("cannot use `_` at the end of a numeric literal")); } else if ((int)(start_pos + 2) == s->pos) { s->pos--; v__scanner__Scanner_error(s, _S("number part of this binary is not provided")); } else if (has_wrong_digit) { s->pos = first_wrong_digit_pos; v__scanner__Scanner_error(s, str_intp(2, _MOV((StrIntpData[]){{_S("this binary number has unsuitable digit `"), 0xfe10, {.d_s = rune_str(first_wrong_digit)}}, {_S("`"), 0, { .d_c = 0 }}}))); } string number = v__scanner__Scanner_num_lit(s, start_pos, s->pos); s->pos--; return number; } VV_LOC string v__scanner__Scanner_ident_hex_number(v__scanner__Scanner* s) { bool has_wrong_digit = false; int first_wrong_digit_pos = 0; rune first_wrong_digit = '\0'; int start_pos = s->pos; if ((int)(s->pos + 2) >= s->text.len) { return _S("0x"); } s->pos += 2; if (s->pos < s->text.len && s->text.str[ s->pos] == _const_v__scanner__num_sep) { v__scanner__Scanner_error(s, _S("separator `_` is only valid between digits in a numeric literal")); } for (;;) { if (!(s->pos < s->text.len)) break; u8 c = s->text.str[ s->pos]; if (c == _const_v__scanner__num_sep && s->text.str[ (int)(s->pos - 1)] == _const_v__scanner__num_sep) { v__scanner__Scanner_error(s, _S("cannot use `_` consecutively")); } if (!u8_is_hex_digit(c) && c != _const_v__scanner__num_sep) { if (!u8_is_letter(c) || s->is_inside_string || s->is_nested_string) { break; } else if (!has_wrong_digit) { has_wrong_digit = true; first_wrong_digit_pos = s->pos; first_wrong_digit = c; } } s->pos++; } if (s->text.str[ (int)(s->pos - 1)] == _const_v__scanner__num_sep) { s->pos--; v__scanner__Scanner_error(s, _S("cannot use `_` at the end of a numeric literal")); } else if ((int)(start_pos + 2) == s->pos) { s->pos--; v__scanner__Scanner_error(s, _S("number part of this hexadecimal is not provided")); } else if (has_wrong_digit) { s->pos = first_wrong_digit_pos; v__scanner__Scanner_error(s, str_intp(2, _MOV((StrIntpData[]){{_S("this hexadecimal number has unsuitable digit `"), 0xfe10, {.d_s = rune_str(first_wrong_digit)}}, {_S("`"), 0, { .d_c = 0 }}}))); } string number = v__scanner__Scanner_num_lit(s, start_pos, s->pos); s->pos--; return number; } VV_LOC string v__scanner__Scanner_ident_oct_number(v__scanner__Scanner* s) { bool has_wrong_digit = false; int first_wrong_digit_pos = 0; rune first_wrong_digit = '\0'; int start_pos = s->pos; s->pos += 2; if (s->pos < s->text.len && string_at(s->text, s->pos) == _const_v__scanner__num_sep) { v__scanner__Scanner_error(s, _S("separator `_` is only valid between digits in a numeric literal")); } for (;;) { if (!(s->pos < s->text.len)) break; u8 c = string_at(s->text, s->pos); if (c == _const_v__scanner__num_sep && string_at(s->text, (int)(s->pos - 1)) == _const_v__scanner__num_sep) { v__scanner__Scanner_error(s, _S("cannot use `_` consecutively")); } if (!u8_is_oct_digit(c) && c != _const_v__scanner__num_sep) { if ((!u8_is_digit(c) && !u8_is_letter(c)) || s->is_inside_string || s->is_nested_string) { break; } else if (!has_wrong_digit) { has_wrong_digit = true; first_wrong_digit_pos = s->pos; first_wrong_digit = c; } } s->pos++; } if (string_at(s->text, (int)(s->pos - 1)) == _const_v__scanner__num_sep) { s->pos--; v__scanner__Scanner_error(s, _S("cannot use `_` at the end of a numeric literal")); } else if ((int)(start_pos + 2) == s->pos) { s->pos--; v__scanner__Scanner_error(s, _S("number part of this octal is not provided")); } else if (has_wrong_digit) { s->pos = first_wrong_digit_pos; v__scanner__Scanner_error(s, str_intp(2, _MOV((StrIntpData[]){{_S("this octal number has unsuitable digit `"), 0xfe10, {.d_s = rune_str(first_wrong_digit)}}, {_S("`"), 0, { .d_c = 0 }}}))); } string number = v__scanner__Scanner_num_lit(s, start_pos, s->pos); s->pos--; return number; } VV_LOC string v__scanner__Scanner_ident_dec_number(v__scanner__Scanner* s) { bool has_wrong_digit = false; int first_wrong_digit_pos = 0; rune first_wrong_digit = '\0'; int start_pos = s->pos; for (;;) { if (!(s->pos < s->text.len)) break; u8 c = s->text.str[ s->pos]; if (c == _const_v__scanner__num_sep && s->text.str[ (int)(s->pos - 1)] == _const_v__scanner__num_sep) { v__scanner__Scanner_error(s, _S("cannot use `_` consecutively")); } if (!u8_is_digit(c) && c != _const_v__scanner__num_sep) { if (!u8_is_letter(c) || (c == 'e' || c == 'E') || s->is_inside_string || s->is_nested_string) { break; } else if (!has_wrong_digit) { has_wrong_digit = true; first_wrong_digit_pos = s->pos; first_wrong_digit = c; } } s->pos++; } if (s->text.str[ (int)(s->pos - 1)] == _const_v__scanner__num_sep) { s->pos--; v__scanner__Scanner_error(s, _S("cannot use `_` at the end of a numeric literal")); } bool call_method = false; bool is_range = false; if (s->pos < s->text.len && s->text.str[ s->pos] == '.') { s->pos++; if (s->pos < s->text.len) { if (u8_is_digit(s->text.str[ s->pos])) { for (;;) { if (!(s->pos < s->text.len)) break; u8 c = s->text.str[ s->pos]; if (!u8_is_digit(c)) { if (!u8_is_letter(c) || (c == 'e' || c == 'E') || s->is_inside_string || s->is_nested_string) { if (c == '.' && (int)(s->pos + 1) < s->text.len && u8_is_letter(s->text.str[ (int)(s->pos + 1)])) { call_method = true; } break; } else if (!has_wrong_digit) { has_wrong_digit = true; first_wrong_digit_pos = s->pos; first_wrong_digit = c; } } s->pos++; } } else if (s->text.str[ s->pos] == '.') { is_range = true; s->pos--; } else if (s->text.str[ s->pos] == 'e' || s->text.str[ s->pos] == 'E') { } else if (u8_is_letter(s->text.str[ s->pos])) { call_method = true; s->pos--; } else { int symbol_length = 0; for (int i = (int)(s->pos - 2); i > 0 && u8_is_digit(s->text.str[ (int)(i - 1)]); i--) { symbol_length++; } string float_symbol = string_substr(s->text, (int)((int)(s->pos - 2) - symbol_length), (int)(s->pos - 1)); v__scanner__Scanner_warn(s, str_intp(2, _MOV((StrIntpData[]){{_S("float literals should have a digit after the decimal point, e.g. `"), 0xfe10, {.d_s = float_symbol}}, {_S(".0`"), 0, { .d_c = 0 }}}))); } } } bool has_exp = false; if (s->pos < s->text.len && (s->text.str[ s->pos] == 'e' || s->text.str[ s->pos] == 'E') && !s->is_inside_string) { has_exp = true; s->pos++; if (s->pos < s->text.len && (s->text.str[ s->pos] == '-' || s->text.str[ s->pos] == '+')) { s->pos++; } for (;;) { if (!(s->pos < s->text.len)) break; u8 c = s->text.str[ s->pos]; if (!u8_is_digit(c)) { if (!u8_is_letter(c) || s->is_inside_string || s->is_nested_string) { if (c == '.' && (int)(s->pos + 1) < s->text.len && u8_is_letter(s->text.str[ (int)(s->pos + 1)])) { call_method = true; } break; } else if (!has_wrong_digit) { has_wrong_digit = true; first_wrong_digit_pos = s->pos; first_wrong_digit = c; } } s->pos++; } } if (has_wrong_digit) { s->pos = first_wrong_digit_pos; if (!s->pref->translated) { v__scanner__Scanner_error(s, str_intp(2, _MOV((StrIntpData[]){{_S("this number has unsuitable digit `"), 0xfe10, {.d_s = rune_str(first_wrong_digit)}}, {_S("`"), 0, { .d_c = 0 }}}))); } } else if ((s->text.str[ (int)(s->pos - 1)] == 'e' || s->text.str[ (int)(s->pos - 1)] == 'E') && !s->is_inside_string) { s->pos--; v__scanner__Scanner_error(s, _S("exponent has no digits")); } else if (s->pos < s->text.len && s->text.str[ s->pos] == '.' && !is_range && !call_method) { if (has_exp) { v__scanner__Scanner_error(s, _S("exponential part should be integer")); } else { v__scanner__Scanner_error(s, _S("too many decimal points in number")); } } string number = v__scanner__Scanner_num_lit(s, start_pos, s->pos); s->pos--; return number; } VV_LOC string v__scanner__Scanner_ident_number(v__scanner__Scanner* s) { if (v__scanner__Scanner_expect(s, _S("0b"), s->pos)) { return v__scanner__Scanner_ident_bin_number(s); } else if (v__scanner__Scanner_expect(s, _S("0x"), s->pos)) { return v__scanner__Scanner_ident_hex_number(s); } else if (v__scanner__Scanner_expect(s, _S("0o"), s->pos)) { return v__scanner__Scanner_ident_oct_number(s); } else { return v__scanner__Scanner_ident_dec_number(s); } return (string){.str=(byteptr)"", .is_lit=1}; } inline VV_LOC void v__scanner__Scanner_skip_whitespace(v__scanner__Scanner* s) { for (;;) { if (!(s->pos < s->text.len)) break; u8 c = s->text.str[ s->pos]; if (c == 9) { s->pos++; continue; } if (_const_v__util__non_whitespace_table[c]) { return; } bool c_is_nl = c == 13 || c == 10; if (c_is_nl && s->is_vh) { return; } if ((int)(s->pos + 1) < s->text.len && c == 13 && s->text.str[ (int)(s->pos + 1)] == 10) { s->is_crlf = true; } if (c_is_nl && !(s->pos > 0 && s->text.str[ (int)(s->pos - 1)] == 13 && c == 10)) { v__scanner__Scanner_inc_line_number(s); } s->pos++; } } VV_LOC v__token__Token v__scanner__Scanner_end_of_file(v__scanner__Scanner* s) { s->eofs++; if (s->eofs > s->max_eofs) { s->line_nr--; if (fast_string_eq(s->file_path, _S("internally_generated_v_code"))) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> internally_generated_v_code, start: "), 0xfe10, {.d_s = string_substr_ni(s->text, 0, 50)}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> internally_generated_v_code, end: "), 0xfe10, {.d_s = string_substr_ni(s->text, -50, 2147483647)}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> internally_generated_v_code, len: "), 0xfe07, {.d_i32 = s->text.len}}, {_SLIT0, 0, { .d_c = 0 }}}))); } _v_panic(string__plus(string__plus(str_intp(3, _MOV((StrIntpData[]){{_S("the end of file `"), 0xfe10, {.d_s = s->file_path}}, {_S("` has been reached "), 0xfe07, {.d_i32 = s->max_eofs}}, {_S(" times already, the v parser is probably stuck.\n"), 0, { .d_c = 0 }}})), _S("This should not happen. Please report the bug here, and include the last 2-3 lines of your source code:\n")), _S("https://github.com/vlang/v/issues/new?labels=Bug&template=bug_report.md"))); VUNREACHABLE(); } if (s->pos != s->text.len && s->eofs == 1) { v__scanner__Scanner_inc_line_number(s); } s->pos = s->text.len; return v__scanner__Scanner_new_eof_token(s); } VV_LOC void v__scanner__Scanner_scan_all_tokens_in_buffer(v__scanner__Scanner* s) { bool v__scanner__Scanner_scan_all_tokens_in_buffer_defer_0 = false; v__util__Timers* timers; timers = v__util__get_timers(); v__util__Timers_measure_pause(timers, _S("PARSE")); v__util__timing_start(_S("SCAN")); v__scanner__Scanner_scan_all_tokens_in_buffer_defer_0 = true; v__scanner__Scanner_scan_remaining_text(s); s->tidx = 0; #if defined(CUSTOM_DEFINE_trace_scanner) { for (int _t2 = 0; _t2 < s->all_tokens.len; ++_t2) { v__token__Token t = ((v__token__Token*)s->all_tokens.data)[_t2]; eprintln(str_intp(5, _MOV((StrIntpData[]){{_S("> tidx:"), 0xafe07, {.d_i32 = t.tidx}}, {_S(" | kind: "), 0x14fe10, {.d_s = v__token__Kind_str(t.kind)}}, {_S(" | lit.len: "), 0xafe07, {.d_i32 = t.lit.len}}, {_S(" | lit: `"), 0xfe10, {.d_s = t.lit}}, {_S("`"), 0, { .d_c = 0 }}}))); } } #endif // Defer begin if (v__scanner__Scanner_scan_all_tokens_in_buffer_defer_0) { v__util__timing_measure_cumulative(_S("SCAN")); v__util__Timers_measure_resume(timers, _S("PARSE")); } // Defer end } VV_LOC void v__scanner__Scanner_scan_remaining_text(v__scanner__Scanner* s) { bool is_skip_comments = s->comments_mode == v__scanner__CommentsMode__skip_comments; for (;;) { v__token__Token t = v__scanner__Scanner_text_scan(s); if (!(is_skip_comments && t.kind == v__token__Kind__comment)) { array_push((array*)&s->all_tokens, _MOV((v__token__Token[]){ t })); if (t.kind == v__token__Kind__eof || s->should_abort) { break; } } } } v__token__Token v__scanner__Scanner_scan(v__scanner__Scanner* s) { for (;;) { int cidx = s->tidx; s->tidx++; if (cidx >= s->all_tokens.len || s->should_abort) { return v__scanner__Scanner_end_of_file(s); } if (((v__token__Token*)s->all_tokens.data)[cidx].kind == v__token__Kind__comment && !v__scanner__Scanner_should_parse_comment(s)) { continue; } return ((v__token__Token*)s->all_tokens.data)[cidx]; } return v__scanner__Scanner_new_eof_token(s); } inline v__token__Token v__scanner__Scanner_peek_token(v__scanner__Scanner* s, int n) { int idx = (int)(s->tidx + n); if (idx >= s->all_tokens.len || idx < 0) { return v__scanner__Scanner_new_eof_token(s); } v__token__Token t = ((v__token__Token*)s->all_tokens.data)[idx]; return t; } inline VV_LOC u8 v__scanner__Scanner_look_ahead(v__scanner__Scanner* s, int n) { if ((int)(s->pos + n) < s->text.len) { return s->text.str[ (int)(s->pos + n)]; } else { return '\0'; } return 0; } v__token__Token v__scanner__Scanner_text_scan(v__scanner__Scanner* s) { for (;;) { s->pos++; if (!s->is_inside_string) { v__scanner__Scanner_skip_whitespace(s); } if (s->pos >= s->text.len || s->should_abort) { return v__scanner__Scanner_end_of_file(s); } if (s->is_inter_end) { if (s->text.str[ s->pos] == s->quote || (s->text.str[ s->pos] == s->inter_quote && s->is_enclosed_inter)) { s->is_inter_end = false; return v__scanner__Scanner_new_token(s, v__token__Kind__string, _S(""), 1); } s->is_inter_end = false; string ident_string = v__scanner__Scanner_ident_string(s); return v__scanner__Scanner_new_token(s, v__token__Kind__string, ident_string, (int)(ident_string.len + 2)); } v__scanner__Scanner_skip_whitespace(s); if (s->pos >= s->text.len) { return v__scanner__Scanner_end_of_file(s); } u8 c = s->text.str[ s->pos]; u8 nextc = v__scanner__Scanner_look_ahead(s, 1); if (_const_v__util__name_char_table[c]) { string name = v__scanner__Scanner_ident_name(s); u8 next_char = v__scanner__Scanner_look_ahead(s, 1); int kind = v__token__KeywordsMatcherTrie_find(&_const_v__token__scanner_matcher, name); if (kind != -1 && !(s->is_inter_start && next_char == s->quote)) { return v__scanner__Scanner_new_token(s, ((v__token__Kind)(kind)), name, name.len); } if (s->is_inside_string) { if (next_char == s->quote) { s->is_inter_end = true; s->is_inter_start = false; s->is_inside_string = false; } } if (s->is_inter_start && next_char == '\\' && !(Array_rune_contains(new_array_from_c_array(8, 8, sizeof(rune), _MOV((rune[8]){'x', 'n', 'r', '\\', 't', 'e', '"', '\''})), v__scanner__Scanner_look_ahead(s, 2)))) { v__scanner__Scanner_warn(s, str_intp(2, _MOV((StrIntpData[]){{_S("unknown escape sequence \\"), 0xfe02, {.d_u8 = v__scanner__Scanner_look_ahead(s, 2)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (s->is_inter_start && next_char == '(') { if (v__scanner__Scanner_look_ahead(s, 2) != ')') { v__scanner__Scanner_warn(s, _S("use `${f(expr)}` instead of `$f(expr)`")); } } else if (s->is_inter_start && next_char != '.') { s->is_inter_end = true; s->is_inter_start = false; } return v__scanner__Scanner_new_token(s, v__token__Kind__name, name, name.len); } else if (u8_is_digit(c) || (c == '.' && u8_is_digit(nextc))) { if (!s->is_inside_string) { int start_pos = s->pos; for (;;) { if (!(start_pos < s->text.len && s->text.str[ start_pos] == '0')) break; start_pos++; } int prefix_zero_num = (int)(start_pos - s->pos); if (start_pos == s->text.len || (c == '0' && !u8_is_digit(s->text.str[ start_pos]))) { prefix_zero_num--; } s->pos += prefix_zero_num; } string num = v__scanner__Scanner_ident_number(s); return v__scanner__Scanner_new_token(s, v__token__Kind__number, num, num.len); } if (c == ')' && s->is_inter_start) { u8 next_char = v__scanner__Scanner_look_ahead(s, 1); if (next_char != '.') { s->is_inter_end = true; s->is_inter_start = false; if (next_char == s->quote) { s->is_inside_string = false; } return v__scanner__Scanner_new_token(s, v__token__Kind__rpar, _S(""), 1); } } if (c == ('+')) { if (nextc == '+') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__inc, _S(""), 2); } else if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__plus_assign, _S(""), 2); } return v__scanner__Scanner_new_token(s, v__token__Kind__plus, _S(""), 1); } else if (c == ('-')) { if (nextc == '-') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__dec, _S(""), 2); } else if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__minus_assign, _S(""), 2); } return v__scanner__Scanner_new_token(s, v__token__Kind__minus, _S(""), 1); } else if (c == ('*')) { if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__mult_assign, _S(""), 2); } return v__scanner__Scanner_new_token(s, v__token__Kind__mul, _S(""), 1); } else if (c == ('^')) { if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__xor_assign, _S(""), 2); } return v__scanner__Scanner_new_token(s, v__token__Kind__xor, _S(""), 1); } else if (c == ('%')) { if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__mod_assign, _S(""), 2); } return v__scanner__Scanner_new_token(s, v__token__Kind__mod, _S(""), 1); } else if (c == ('?')) { return v__scanner__Scanner_new_token(s, v__token__Kind__question, _S("?"), 1); } else if (c == (_const_v__scanner__single_quote) || c == (_const_v__scanner__double_quote)) { if (s->string_count == 1 && s->str_dollar_needs_rcbr.len == 0) { s->string_count = 0; return v__scanner__Scanner_new_token(s, v__token__Kind__string, _S(""), 1); } else { s->string_count++; } int start_line = s->line_nr; string ident_string = v__scanner__Scanner_ident_string(s); return v__scanner__Scanner_new_multiline_token(s, v__token__Kind__string, ident_string, (int)(ident_string.len + 2), start_line); } else if (c == ('`')) { string ident_char = v__scanner__Scanner_ident_char(s); return v__scanner__Scanner_new_token(s, v__token__Kind__chartoken, ident_char, (int)(ident_char.len + 2)); } else if (c == ('(')) { return v__scanner__Scanner_new_token(s, v__token__Kind__lpar, _S(""), 1); } else if (c == (')')) { return v__scanner__Scanner_new_token(s, v__token__Kind__rpar, _S(""), 1); } else if (c == ('[')) { return v__scanner__Scanner_new_token(s, v__token__Kind__lsbr, _S(""), 1); } else if (c == (']')) { return v__scanner__Scanner_new_token(s, v__token__Kind__rsbr, _S(""), 1); } else if (c == ('{')) { if (s->is_inside_string || s->is_enclosed_inter) { if (s->text.str[ (int)(s->pos - 1)] == '$') { array_push((array*)&s->str_dollar_needs_rcbr, _MOV((bool[]){ true })); continue; } else { array_push((array*)&s->str_dollar_needs_rcbr, _MOV((bool[]){ false })); s->inter_cbr_count++; } } else { array_push((array*)&s->str_dollar_needs_rcbr, _MOV((bool[]){ false })); } return v__scanner__Scanner_new_token(s, v__token__Kind__lcbr, _S(""), 1); } else if (c == ('$')) { if (s->is_inside_string || s->is_enclosed_inter) { return v__scanner__Scanner_new_token(s, v__token__Kind__str_dollar, _S(""), 1); } else { return v__scanner__Scanner_new_token(s, v__token__Kind__dollar, _S(""), 1); } } else if (c == ('}')) { bool _t36 = (((s->is_enclosed_inter || s->is_nested_enclosed_inter) && s->inter_cbr_count == 0)); bool _t37 = ((*(v__token__Token*)array_last(s->all_tokens)).kind != v__token__Kind__string && s->str_dollar_needs_rcbr.len > 0); bool _t35 = _t36 || ( _t37 && (*(bool*)array_last(s->str_dollar_needs_rcbr))); if (_t35) { if (s->str_dollar_needs_rcbr.len > 0) { array_delete_last(&s->str_dollar_needs_rcbr); } if (s->pos < (int)(s->text.len - 1)) { s->pos++; } else { v__scanner__Scanner_error(s, _S("unfinished string literal")); } if (s->text.str[ s->pos] == s->quote || (s->text.str[ s->pos] == s->inter_quote && s->is_nested_enclosed_inter)) { s->is_inside_string = false; if (s->is_nested_enclosed_inter) { s->is_nested_enclosed_inter = false; } else { s->is_enclosed_inter = false; } s->string_count--; return v__scanner__Scanner_new_token(s, v__token__Kind__string, _S(""), 1); } if (s->is_nested_enclosed_inter) { s->is_nested_enclosed_inter = false; } else { s->is_enclosed_inter = false; } s->just_closed_inter = true; string ident_string = v__scanner__Scanner_ident_string(s); return v__scanner__Scanner_new_token(s, v__token__Kind__string, ident_string, (int)(ident_string.len + 2)); } else { if (s->str_dollar_needs_rcbr.len > 0) { if ((*(bool*)array_last(s->str_dollar_needs_rcbr))) { array_delete_last(&s->str_dollar_needs_rcbr); s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__string, _S(""), 1); } array_delete_last(&s->str_dollar_needs_rcbr); } if (s->inter_cbr_count > 0) { s->inter_cbr_count--; } return v__scanner__Scanner_new_token(s, v__token__Kind__rcbr, _S(""), 1); } } else if (c == ('&')) { if (nextc == '&') { if (v__scanner__Scanner_look_ahead(s, 2) == '=') { s->pos += 2; return v__scanner__Scanner_new_token(s, v__token__Kind__boolean_and_assign, _S(""), 3); } } if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__and_assign, _S(""), 2); } u8 afternextc = v__scanner__Scanner_look_ahead(s, 2); if (nextc == '&' && (u8_is_space(afternextc) || afternextc == '!')) { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__and, _S(""), 2); } return v__scanner__Scanner_new_token(s, v__token__Kind__amp, _S(""), 1); } else if (c == ('|')) { if (nextc == '|') { if (v__scanner__Scanner_look_ahead(s, 2) == '=') { s->pos += 2; return v__scanner__Scanner_new_token(s, v__token__Kind__boolean_or_assign, _S(""), 3); } s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__logical_or, _S(""), 2); } if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__or_assign, _S(""), 2); } return v__scanner__Scanner_new_token(s, v__token__Kind__pipe, _S(""), 1); } else if (c == (',')) { return v__scanner__Scanner_new_token(s, v__token__Kind__comma, _S(""), 1); } else if (c == ('@')) { if (s->text.str[ (int)(s->pos + 1)] == '[') { return v__scanner__Scanner_new_token(s, v__token__Kind__at, _S(""), 1); } string name = _S(""); if (nextc != '\0') { s->pos++; name = v__scanner__Scanner_ident_name(s); } if (s->is_fmt) { return v__scanner__Scanner_new_token(s, v__token__Kind__name, string__plus(_S("@"), name), (int)(name.len + 1)); } if ((Array_string_contains(_const_v__token__valid_at_tokens, string__plus(_S("@"), name))) || string_starts_with(name, _S("cc"))) { return v__scanner__Scanner_new_token(s, v__token__Kind__at, string__plus(_S("@"), name), (int)(name.len + 1)); } if (!v__token__is_key(name)) { if (string_is_upper(name)) { string comptime_vars = Array_string_join(_const_v__token__valid_at_tokens, _S(", ")); v__scanner__Scanner_add_error_detail(s, string_wrap(str_intp(2, _MOV((StrIntpData[]){{_S("available compile time variables: "), 0xfe10, {.d_s = comptime_vars}}, {_SLIT0, 0, { .d_c = 0 }}})), ((WrapConfig){.width = 90,.end = _S("\n"),}))); } v__scanner__Scanner_error(s, _S("@ must be used before keywords or compile time variables (e.g. `@type string` or `@FN`)")); } else { } return v__scanner__Scanner_new_token(s, v__token__Kind__name, name, name.len); } else if (c == ('.')) { if (nextc == '.') { s->pos++; if ((int)(s->pos + 1) < s->text.len && s->text.str[ (int)(s->pos + 1)] == '.') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__ellipsis, _S(""), 3); } return v__scanner__Scanner_new_token(s, v__token__Kind__dotdot, _S(""), 2); } return v__scanner__Scanner_new_token(s, v__token__Kind__dot, _S(""), 1); } else if (c == ('#')) { if (nextc == '[') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__nilsbr, _S(""), 2); } int start = (int)(s->pos + 1); v__scanner__Scanner_ignore_line(s); if (nextc == '!') { string comment = string_trim_space(string_substr(s->text, (int)(start - 1), s->pos)); if (s->line_nr != 1) { v__token__Pos comment_pos = ((v__token__Pos){.len = comment.len,.line_nr = (int)(s->line_nr - 1),.pos = start,.col = (int)(v__scanner__Scanner_current_column(s) - comment.len),.last_line = 0,}); v__scanner__Scanner_error_with_pos(s, _S("a shebang is only valid at the top of the file"), comment_pos); } return v__scanner__Scanner_new_token(s, v__token__Kind__comment, comment, (int)(comment.len + 2)); } string hash = string_trim_space(string_substr(s->text, start, s->pos)); return v__scanner__Scanner_new_token(s, v__token__Kind__hash, hash, (int)(hash.len + 2)); } else if (c == ('>')) { if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__ge, _S(""), 2); } else if (nextc == '>') { if ((int)(s->pos + 2) < s->text.len) { bool _t62; /* if prepend */ if (s->last_lt >= 0 && (int)(s->pos - s->last_lt) < 100) { Array_string _t63 = {0}; Array_string _t63_orig = string_split(string_substr(s->text, (int)(s->last_lt + 1), s->pos), _S(",")); int _t63_len = _t63_orig.len; _t63 = __new_array(0, _t63_len, sizeof(string)); for (int _t65 = 0; _t65 < _t63_len; ++_t65) { string it = ((string*) _t63_orig.data)[_t65]; string _t64 = string_after(string_trim_right(string_trim_space(it), _S(">")), _S("]")); array_push((array*)&_t63, &_t64); } Array_string typs =_t63; bool _t66 = true; Array_string _t66_orig = typs; int _t66_len = _t66_orig.len; for (int _t67 = 0; _t67 < _t66_len; ++_t67) { string it = ((string*) _t66_orig.data)[_t67]; bool _t68 = (it.len > 0); bool _t69 = ((_t68) && u8_is_capital(it.str[ 0])); bool _t70 = true; if (_t69) { Array_u8 _t70_orig = string_bytes(string_substr(it, 1, 2147483647)); int _t70_len = _t70_orig.len; for (int _t71 = 0; _t71 < _t70_len; ++_t71) { u8 it = ((u8*) _t70_orig.data)[_t71]; if (!(u8_is_alnum(it) || it == '_')) { _t70 = false; break; } } } if (!( _t68 && (( _t69 &&_t70) || v__token__KeywordsMatcherTrie_matches(&_const_v__ast__builtin_type_names_matcher, it)))) { _t66 = false; break; } } _t62 =_t66; } else { _t62 = false; } bool is_generic = _t62; if (is_generic) { return v__scanner__Scanner_new_token(s, v__token__Kind__gt, _S(""), 1); } else if (s->text.str[ (int)(s->pos + 2)] == '=') { s->pos += 2; return v__scanner__Scanner_new_token(s, v__token__Kind__right_shift_assign, _S(""), 3); } else if (s->text.str[ (int)(s->pos + 2)] == '>') { if ((int)(s->pos + 3) < s->text.len && s->text.str[ (int)(s->pos + 3)] == '=') { s->pos += 3; return v__scanner__Scanner_new_token(s, v__token__Kind__unsigned_right_shift_assign, _S(""), 4); } s->pos += 2; return v__scanner__Scanner_new_token(s, v__token__Kind__unsigned_right_shift, _S(""), 3); } } s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__right_shift, _S(""), 2); } return v__scanner__Scanner_new_token(s, v__token__Kind__gt, _S(""), 1); } else if (c == ('<')) { if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__le, _S(""), 2); } else if (nextc == '<') { if ((int)(s->pos + 2) < s->text.len && s->text.str[ (int)(s->pos + 2)] == '=') { s->pos += 2; return v__scanner__Scanner_new_token(s, v__token__Kind__left_shift_assign, _S(""), 3); } s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__left_shift, _S(""), 2); } else if (nextc == '-') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__arrow, _S(""), 2); } else { s->last_lt = s->pos; return v__scanner__Scanner_new_token(s, v__token__Kind__lt, _S(""), 1); } } else if (c == ('=')) { if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__eq, _S(""), 2); } else { return v__scanner__Scanner_new_token(s, v__token__Kind__assign, _S(""), 1); } } else if (c == (':')) { if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__decl_assign, _S(""), 2); } else { return v__scanner__Scanner_new_token(s, v__token__Kind__colon, _S(""), 1); } } else if (c == (';')) { return v__scanner__Scanner_new_token(s, v__token__Kind__semicolon, _S(""), 1); } else if (c == ('!')) { if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__ne, _S(""), 2); } else if (s->text.len > (int)(s->pos + 3) && nextc == 'i' && s->text.str[ (int)(s->pos + 2)] == 'n' && u8_is_space(s->text.str[ (int)(s->pos + 3)])) { s->pos += 2; return v__scanner__Scanner_new_token(s, v__token__Kind__not_in, _S(""), 3); } else if (s->text.len > (int)(s->pos + 3) && nextc == 'i' && s->text.str[ (int)(s->pos + 2)] == 's' && u8_is_space(s->text.str[ (int)(s->pos + 3)])) { s->pos += 2; return v__scanner__Scanner_new_token(s, v__token__Kind__not_is, _S(""), 3); } else { return v__scanner__Scanner_new_token(s, v__token__Kind__not, _S("!"), 1); } } else if (c == ('~')) { return v__scanner__Scanner_new_token(s, v__token__Kind__bit_not, _S(""), 1); } else if (c == ('/')) { if (nextc == '=') { s->pos++; return v__scanner__Scanner_new_token(s, v__token__Kind__div_assign, _S(""), 2); } if (nextc == '/') { int start = (int)(s->pos + 1); v__scanner__Scanner_ignore_line(s); int comment_line_end = s->pos; if (s->text.str[ (int)(s->pos - 1)] == 13) { comment_line_end--; } else { s->pos--; s->line_nr--; } if (v__scanner__Scanner_should_parse_comment(s)) { s->line_comment = string_substr(s->text, (int)(start + 1), comment_line_end); string comment = s->line_comment; bool is_separate_line_comment = true; for (int j = (int)(start - 2); j >= 0 && s->text.str[ j] != 10; j--) { if (!(s->text.str[ j] == '\t' || s->text.str[ j] == ' ')) { is_separate_line_comment = false; } } if (is_separate_line_comment) { comment = string__plus(_S("\001"), comment); } return v__scanner__Scanner_new_token(s, v__token__Kind__comment, comment, (int)(s->line_comment.len + 2)); } continue; } else if (nextc == '*') { int start = (int)(s->pos + 2); int start_line = s->line_nr; int nest_count = 1; s->pos++; for (;;) { if (!(nest_count > 0 && s->pos < (int)(s->text.len - 1))) break; s->pos++; if (s->pos >= (int)(s->text.len - 1)) { s->line_nr = start_line; v__scanner__Scanner_error(s, _S("unterminated multiline comment")); } if (s->text.str[ s->pos] == 10) { v__scanner__Scanner_inc_line_number(s); continue; } if (v__scanner__Scanner_expect(s, _S("/*"), s->pos) && s->text.str[ (int)(s->pos + 2)] != '/') { nest_count++; continue; } if (v__scanner__Scanner_expect(s, _S("*/"), s->pos)) { nest_count--; } } s->pos++; if (v__scanner__Scanner_should_parse_comment(s)) { string comment = string_substr(s->text, start, ((int)(s->pos - 1))); if (!string_contains(comment, _S("\n"))) { v__token__Pos comment_pos = ((v__token__Pos){.len = (int)(comment.len + 4),.line_nr = start_line,.pos = start,.col = (int)((int)(v__scanner__Scanner_current_column(s) - comment.len) - 4),.last_line = 0,}); v__scanner__Scanner_error_with_pos(s, _S("inline comment is deprecated, please use line comment"), comment_pos); comment = string__plus(_S("\001"), string_trim(comment, _S(" "))); } return v__scanner__Scanner_new_multiline_token(s, v__token__Kind__comment, comment, (int)(comment.len + 4), start_line); } continue; } return v__scanner__Scanner_new_token(s, v__token__Kind__div, _S(""), 1); } else { } #if defined(_WIN32) { if (c == '\0') { return v__scanner__Scanner_end_of_file(s); } } #endif v__scanner__Scanner_invalid_character(s); break; } return v__scanner__Scanner_end_of_file(s); } VV_LOC void v__scanner__Scanner_invalid_character(v__scanner__Scanner* s) { int len = utf8_char_len(string_at(s->text, s->pos)); int end = int_min((int)(s->pos + len), s->text.len); string c = string_substr(s->text, s->pos, end); v__scanner__Scanner_error(s, str_intp(2, _MOV((StrIntpData[]){{_S("invalid character `"), 0xfe10, {.d_s = c}}, {_S("`"), 0, { .d_c = 0 }}}))); } inline VV_LOC int v__scanner__Scanner_current_column(v__scanner__Scanner* s) { return (int)(s->pos - s->last_nl_pos); } VV_LOC int v__scanner__Scanner_count_symbol_before(v__scanner__Scanner* s, int p, u8 sym) { int count = 0; for (int i = p; i >= 0; i--) { if (s->text.str[ i] != sym) { break; } count++; } return count; } string v__scanner__Scanner_ident_string(v__scanner__Scanner* s) { if (s->is_inside_string) { s->is_nested_string = true; } else { s->is_nested_string = false; } v__token__Pos lspos = ((v__token__Pos){.len = 0,.line_nr = s->line_nr,.pos = s->pos,.col = (int)((int)(s->pos - s->last_nl_pos) - 1),.last_line = 0,}); u8 q = s->text.str[ s->pos]; bool is_quote = (q == _const_v__scanner__single_quote || q == _const_v__scanner__double_quote); bool is_raw = is_quote && s->pos > 0 && s->text.str[ (int)(s->pos - 1)] == 'r' && !s->is_inside_string; bool is_cstr = is_quote && s->pos > 0 && s->text.str[ (int)(s->pos - 1)] == 'c' && !s->is_inside_string; if (is_quote && !s->just_closed_inter) { if (s->is_inside_string || s->is_enclosed_inter || s->is_inter_start) { s->inter_quote = q; } else { s->quote = q; } } s->just_closed_inter = false; int n_cr_chars = 0; int start = s->pos; u8 start_char = s->text.str[ start]; if (start_char == s->quote || (start_char == s->inter_quote && (s->is_inter_start || s->is_enclosed_inter))) { start++; } else if (start_char == 10) { v__scanner__Scanner_inc_line_number(s); } s->is_inside_string = false; array_clear(&s->u16_escapes_pos); array_clear(&s->u32_escapes_pos); array_clear(&s->h_escapes_pos); int backslash_count = (start_char == _const_v__scanner__backslash ? (1) : (0)); for (;;) { s->pos++; if (s->pos >= s->text.len) { if ((int)(lspos.line_nr + 1) < s->line_nr) { v__scanner__Scanner_add_error_detail_with_pos(s, _S("literal started here"), lspos); } v__scanner__Scanner_error(s, _S("unfinished string literal")); break; } u8 c = s->text.str[ s->pos]; u8 prevc = s->text.str[ (int)(s->pos - 1)]; if (c == _const_v__scanner__backslash) { backslash_count++; } if (c == s->quote && (is_raw || (backslash_count & 1) == 0)) { s->string_count--; break; } if (c == s->inter_quote && (s->is_inter_start || s->is_enclosed_inter)) { s->string_count--; break; } if (c == s->quote && s->string_count == 0) { break; } if (c == 13) { n_cr_chars++; } if (c == 10) { v__scanner__Scanner_inc_line_number(s); } if ((backslash_count & 1) == 1 && !is_raw && !is_cstr) { if (c == 'x') { if (s->text.str[ (int)(s->pos + 1)] == s->quote || !(u8_is_hex_digit(s->text.str[ (int)(s->pos + 1)]) && u8_is_hex_digit(s->text.str[ (int)(s->pos + 2)]))) { v__scanner__Scanner_error(s, _S("`\\x` used without two following hex digits")); } array_push((array*)&s->h_escapes_pos, _MOV((int[]){ (int)(s->pos - 1) })); } if (c == 'u') { if (s->text.str[ (int)(s->pos + 1)] == s->quote || s->text.str[ (int)(s->pos + 2)] == s->quote || s->text.str[ (int)(s->pos + 3)] == s->quote || s->text.str[ (int)(s->pos + 4)] == s->quote || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 1)]) || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 2)]) || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 3)]) || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 4)])) { v__scanner__Scanner_error(s, _S("`\\u` incomplete 16 bit unicode character value")); } array_push((array*)&s->u16_escapes_pos, _MOV((int[]){ (int)(s->pos - 1) })); } if (c == 'U') { if (s->text.str[ (int)(s->pos + 1)] == s->quote || s->text.str[ (int)(s->pos + 2)] == s->quote || s->text.str[ (int)(s->pos + 3)] == s->quote || s->text.str[ (int)(s->pos + 4)] == s->quote || s->text.str[ (int)(s->pos + 5)] == s->quote || s->text.str[ (int)(s->pos + 6)] == s->quote || s->text.str[ (int)(s->pos + 7)] == s->quote || s->text.str[ (int)(s->pos + 8)] == s->quote || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 1)]) || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 2)]) || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 3)]) || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 4)]) || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 5)]) || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 6)]) || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 7)]) || !u8_is_hex_digit(s->text.str[ (int)(s->pos + 8)])) { v__scanner__Scanner_error(s, _S("`\\U` incomplete 32 bit unicode character value")); } array_push((array*)&s->u32_escapes_pos, _MOV((int[]){ (int)(s->pos - 1) })); } if (!v__util__is_escape_sequence(c) && !u8_is_digit(c) && c != '\n') { v__scanner__Scanner_error(s, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = u8_ascii_str(c)}}, {_S("` unknown escape sequence"), 0, { .d_c = 0 }}}))); } } if (prevc == '$' && c == '{' && !is_raw && (v__scanner__Scanner_count_symbol_before(s, (int)(s->pos - 2), _const_v__scanner__backslash) & 1) == 0) { s->is_inside_string = true; if (s->is_enclosed_inter) { s->is_nested_enclosed_inter = true; } else { s->is_enclosed_inter = true; } s->pos -= 2; break; } if (prevc == '$' && _const_v__util__name_char_table[c] && !is_raw && (v__scanner__Scanner_count_symbol_before(s, (int)(s->pos - 2), _const_v__scanner__backslash) & 1) == 0) { s->is_inside_string = true; s->is_inter_start = true; s->pos -= 2; break; } if (c != _const_v__scanner__backslash) { backslash_count = 0; } } string lit = _S(""); int end = s->pos; if (s->is_inside_string) { end++; } if (start <= s->pos) { string string_so_far = string_substr(s->text, start, end); if (!s->is_fmt) { int segment_idx = 0; array_clear(&s->str_segments); if ((int)((int)(s->u16_escapes_pos.len + s->h_escapes_pos.len) + s->u32_escapes_pos.len) > 0) { array_clear(&s->all_pos); _PUSH_MANY(&s->all_pos, (s->u16_escapes_pos), _t4, Array_int); _PUSH_MANY(&s->all_pos, (s->u32_escapes_pos), _t5, Array_int); _PUSH_MANY(&s->all_pos, (s->h_escapes_pos), _t6, Array_int); if (s->all_pos.len > 0) { qsort(s->all_pos.data, s->all_pos.len, s->all_pos.element_size, (voidptr)compare_2358202099351622853_int); } ; for (int _t7 = 0; _t7 < s->all_pos.len; ++_t7) { int pos = ((int*)s->all_pos.data)[_t7]; array_push((array*)&s->str_segments, _MOV((string[]){ string_substr(string_so_far, segment_idx, ((int)(pos - start))) })); segment_idx = (int)(pos - start); if ((Array_int_contains(s->u16_escapes_pos, pos))) { multi_return_int_string mr_40821 = v__scanner__Scanner_decode_u16_escape_single(s, string_so_far, segment_idx); int end_idx = mr_40821.arg0; string segment = mr_40821.arg1; array_push((array*)&s->str_segments, _MOV((string[]){ string_clone(segment) })); segment_idx = end_idx; } if ((Array_int_contains(s->u32_escapes_pos, pos))) { multi_return_int_string mr_41011 = v__scanner__Scanner_decode_u32_escape_single(s, string_so_far, segment_idx); int end_idx = mr_41011.arg0; string segment = mr_41011.arg1; array_push((array*)&s->str_segments, _MOV((string[]){ string_clone(segment) })); segment_idx = end_idx; } if ((Array_int_contains(s->h_escapes_pos, pos))) { multi_return_int_string mr_41199 = v__scanner__Scanner_decode_h_escape_single(s, string_so_far, segment_idx); int end_idx = mr_41199.arg0; string segment = mr_41199.arg1; array_push((array*)&s->str_segments, _MOV((string[]){ string_clone(segment) })); segment_idx = end_idx; } } } if (segment_idx < string_so_far.len) { array_push((array*)&s->str_segments, _MOV((string[]){ string_substr(string_so_far, segment_idx, 2147483647) })); } string_so_far = Array_string_join(s->str_segments, _S("")); } if (n_cr_chars > 0) { string_so_far = string_replace(string_so_far, _S("\r"), _S("")); } if (string_contains(string_so_far, _S("\\\n"))) { lit = v__scanner__trim_slash_line_break(string_so_far); } else { lit = string_so_far; } } return lit; } VV_LOC multi_return_int_string v__scanner__Scanner_decode_h_escape_single(v__scanner__Scanner* s, string str, int idx) { int end_idx = (int)(idx + 4); if ((int)(idx + 2) > str.len || end_idx > str.len) { v__scanner__Scanner_error_with_pos(s, _S("unfinished single hex escape started at"), v__scanner__Scanner_current_pos(s)); return (multi_return_int_string){.arg0=0, .arg1=_S("")}; } _result_u64 _t3 = strconv__parse_uint(string_substr(str, (int)(idx + 2), end_idx), 16, 8); if (_t3.is_error) { IError err = _t3.err; *(u64*) _t3.data = 0U; } return (multi_return_int_string){.arg0=end_idx, .arg1=Array_u8_bytestr(new_array_from_c_array(1, 1, sizeof(u8), _MOV((u8[1]){((u8)((*(u64*)_t3.data)))})))}; } VV_LOC string v__scanner__Scanner_decode_h_escapes(v__scanner__Scanner* s, string sinput, int start, Array_int escapes_pos) { if (escapes_pos.len == 0) { return sinput; } Array_string ss = __new_array_with_default(0, (int)((int)(escapes_pos.len * 2) + 1), sizeof(string), 0); array_push((array*)&ss, _MOV((string[]){ string_substr(sinput, 0, (int)((*(int*)array_first(escapes_pos)) - start)) })); for (int i = 0; i < escapes_pos.len; ++i) { int pos = ((int*)escapes_pos.data)[i]; int idx = (int)(pos - start); multi_return_int_string mr_42497 = v__scanner__Scanner_decode_h_escape_single(s, sinput, idx); int end_idx = mr_42497.arg0; string segment = mr_42497.arg1; if (end_idx > sinput.len) { v__scanner__Scanner_error_with_pos(s, _S("unfinished hex escape started at"), v__scanner__Scanner_current_pos(s)); return _S(""); } array_push((array*)&ss, _MOV((string[]){ string_clone(segment) })); if ((int)(i + 1) < escapes_pos.len) { array_push((array*)&ss, _MOV((string[]){ string_substr(sinput, end_idx, (int)((*(int*)array_get(escapes_pos, (int)(i + 1))) - start)) })); } else { array_push((array*)&ss, _MOV((string[]){ string_substr(sinput, end_idx, 2147483647) })); } } return Array_string_join(ss, _S("")); } VV_LOC string v__scanner__Scanner_decode_o_escapes(v__scanner__Scanner* s, string sinput, int start, Array_int escapes_pos) { if (escapes_pos.len == 0) { return sinput; } Array_string ss = __new_array_with_default(0, escapes_pos.len, sizeof(string), 0); array_push((array*)&ss, _MOV((string[]){ string_substr(sinput, 0, (int)((*(int*)array_first(escapes_pos)) - start)) })); for (int i = 0; i < escapes_pos.len; ++i) { int pos = ((int*)escapes_pos.data)[i]; int idx = (int)(pos - start); int end_idx = (int)(idx + 4); if (end_idx > sinput.len) { v__scanner__Scanner_error_with_pos(s, _S("unfinished octal escape started at"), v__scanner__Scanner_current_pos(s)); return _S(""); } _result_u64 _t5 = strconv__parse_uint(string_substr(sinput, (int)(idx + 1), end_idx), 8, 8); if (_t5.is_error) { IError err = _t5.err; *(u64*) _t5.data = 0U; } array_push((array*)&ss, _MOV((string[]){ Array_u8_bytestr(new_array_from_c_array(1, 1, sizeof(u8), _MOV((u8[1]){((u8)((*(u64*)_t5.data)))}))) })); if ((int)(i + 1) < escapes_pos.len) { array_push((array*)&ss, _MOV((string[]){ string_substr(sinput, end_idx, (int)((*(int*)array_get(escapes_pos, (int)(i + 1))) - start)) })); } else { array_push((array*)&ss, _MOV((string[]){ string_substr(sinput, end_idx, 2147483647) })); } } return Array_string_join(ss, _S("")); } VV_LOC multi_return_int_string v__scanner__Scanner_decode_u16_escape_single(v__scanner__Scanner* s, string str, int idx) { int end_idx = (int)(idx + 6); if ((int)(idx + 2) > str.len || end_idx > str.len) { v__scanner__Scanner_error_with_pos(s, _S("unfinished u16 escape started at"), v__scanner__Scanner_current_pos(s)); return (multi_return_int_string){.arg0=0, .arg1=_S("")}; } _result_u64 _t2 = strconv__parse_uint(string_substr(str, (int)(idx + 2), end_idx), 16, 32); if (_t2.is_error) { IError err = _t2.err; *(u64*) _t2.data = 0U; } u64 escaped_code_point = (*(u64*)_t2.data); if (rune_length_in_bytes(((rune)(escaped_code_point))) == -1) { v__scanner__Scanner_error(s, str_intp(2, _MOV((StrIntpData[]){{_S("invalid unicode point `"), 0xfe10, {.d_s = str}}, {_S("`"), 0, { .d_c = 0 }}}))); } return (multi_return_int_string){.arg0=end_idx, .arg1=utf32_to_str(((u32)(escaped_code_point)))}; } VV_LOC string v__scanner__Scanner_decode_u16erune(v__scanner__Scanner* s, string str) { multi_return_int_string mr_44389 = v__scanner__Scanner_decode_u16_escape_single(s, str, 0); int end_idx = mr_44389.arg0; string segment = mr_44389.arg1; if (str.len == end_idx) { return segment; } Array_string ss = __new_array_with_default(0, 2, sizeof(string), 0); array_push((array*)&ss, _MOV((string[]){ string_clone(segment) })); array_push((array*)&ss, _MOV((string[]){ string_substr(str, end_idx, 2147483647) })); return Array_string_join(ss, _S("")); } VV_LOC multi_return_int_string v__scanner__Scanner_decode_u32_escape_single(v__scanner__Scanner* s, string str, int idx) { int end_idx = (int)(idx + 10); if ((int)(idx + 2) > str.len || end_idx > str.len) { v__scanner__Scanner_error_with_pos(s, _S("unfinished u32 escape started at"), v__scanner__Scanner_current_pos(s)); return (multi_return_int_string){.arg0=0, .arg1=_S("")}; } _result_u64 _t2 = strconv__parse_uint(string_substr(str, (int)(idx + 2), end_idx), 16, 32); if (_t2.is_error) { IError err = _t2.err; *(u64*) _t2.data = 0U; } u64 escaped_code_point = (*(u64*)_t2.data); if (rune_length_in_bytes(((rune)(escaped_code_point))) == -1) { v__scanner__Scanner_error(s, str_intp(2, _MOV((StrIntpData[]){{_S("invalid unicode point `"), 0xfe10, {.d_s = str}}, {_S("`"), 0, { .d_c = 0 }}}))); } return (multi_return_int_string){.arg0=end_idx, .arg1=utf32_to_str(((u32)(escaped_code_point)))}; } VV_LOC string v__scanner__Scanner_decode_u32erune(v__scanner__Scanner* s, string str) { multi_return_int_string mr_45258 = v__scanner__Scanner_decode_u32_escape_single(s, str, 0); int end_idx = mr_45258.arg0; string segment = mr_45258.arg1; if (str.len == end_idx) { return segment; } Array_string ss = __new_array_with_default(0, 2, sizeof(string), 0); array_push((array*)&ss, _MOV((string[]){ string_clone(segment) })); array_push((array*)&ss, _MOV((string[]){ string_substr(str, end_idx, 2147483647) })); return Array_string_join(ss, _S("")); } VV_LOC string v__scanner__trim_slash_line_break(string s) { int start = 0; string ret_str = s; for (;;) { _option_int _t1 = string_index_after(ret_str, _S("\\\n"), start); if (_t1.state != 0) { IError err = _t1.err; break; } int idx = (*(int*)_t1.data); start = idx; int nbackslashes = 0; for (int eidx = idx; eidx >= 0 && string_at(ret_str, eidx) == '\\'; eidx--) { nbackslashes++; } if (idx == 0 || ((nbackslashes & 1)) == 1) { ret_str = string__plus(string_substr(ret_str, 0, idx), string_trim_left(string_substr(ret_str, (int)(idx + 2), 2147483647), _S(" \n\t\v\f\r"))); } else { start++; } } return ret_str; } string v__scanner__Scanner_ident_char(v__scanner__Scanner* s) { v__token__Pos lspos = ((v__token__Pos){.len = 0,.line_nr = s->line_nr,.pos = s->pos,.col = (int)((int)(s->pos - s->last_nl_pos) - 1),.last_line = 0,}); int start = s->pos; rune slash = '\\'; int len = 0; bool escaped_hex = v__scanner__Scanner_expect(s, _S("\\x"), (int)(start + 1)) && s->text.len > (int)(start + 3) && u8_is_hex_digit(string_at(s->text, (int)(start + 3))); bool escaped_unicode_16 = v__scanner__Scanner_expect(s, _S("\\u"), (int)(start + 1)) && s->text.len > (int)(start + 3) && u8_is_hex_digit(string_at(s->text, (int)(start + 3))); bool escaped_unicode_32 = v__scanner__Scanner_expect(s, _S("\\U"), (int)(start + 1)) && s->text.len > (int)(start + 3) && u8_is_hex_digit(string_at(s->text, (int)(start + 3))); bool escaped_octal = !escaped_hex && !escaped_unicode_16 && !escaped_unicode_32 && v__scanner__Scanner_expect(s, _S("\\"), (int)(start + 1)) && s->text.len > (int)(start + 2) && u8_is_oct_digit(string_at(s->text, (int)(start + 2))); for (;;) { s->pos++; if (s->pos >= s->text.len) { break; } if (string_at(s->text, s->pos) != slash) { len++; } bool double_slash = v__scanner__Scanner_expect(s, _S("\\\\"), (int)(s->pos - 2)); if (string_at(s->text, s->pos) == '`' && (string_at(s->text, (int)(s->pos - 1)) != slash || double_slash)) { if (double_slash) { len++; } break; } } len--; string c = string_substr(s->text, (int)(start + 1), s->pos); if (s->is_fmt) { return c; } if (len != 1) { string orig = c; if ((c.len & 1) == 0 && (escaped_hex || escaped_unicode_16 || escaped_unicode_32 || escaped_octal)) { if (escaped_unicode_16) { c = v__scanner__Scanner_decode_u16erune(s, c); } else if (escaped_unicode_32) { c = v__scanner__Scanner_decode_u32erune(s, c); } else { Array_int escapes_pos = __new_array_with_default(0, 0, sizeof(int), 0); for (int i = 0; i < c.len; ++i) { u8 v = c.str[i]; if (v == '\\') { array_push((array*)&escapes_pos, _MOV((int[]){ i })); } } if (escaped_hex) { c = v__scanner__Scanner_decode_h_escapes(s, c, 0, escapes_pos); } else { c = v__scanner__Scanner_decode_o_escapes(s, c, 0, escapes_pos); } } } Array_rune u = string_runes(c); if (u.len != 1) { Array_string err_info = __new_array_with_default(0, u.len, sizeof(string), 0); int i = 0; for (;;) { if (!(i < u.len)) break; if ((*(rune*)array_get(u, i)) != '\\' || i == (int)(u.len - 1)) { array_push((array*)&err_info, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = rune_str((*(rune*)array_get(u, i)))}}, {_S("`"), 0, { .d_c = 0 }}})) })); i++; continue; } array_push((array*)&err_info, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("`\\"), 0xfe10, {.d_s = rune_str((*(rune*)array_get(u, (int)(i + 1))))}}, {_S("`"), 0, { .d_c = 0 }}})) })); i += 2; } if (escaped_hex || escaped_unicode_16 || escaped_unicode_32) { v__scanner__Scanner_error_with_pos(s, str_intp(4, _MOV((StrIntpData[]){{_S("invalid character literal `"), 0xfe10, {.d_s = orig}}, {_S("` => `"), 0xfe10, {.d_s = c}}, {_S("` (["), 0xfe10, {.d_s = Array_string_join(err_info, _S(", "))}}, {_S("]) (escape sequence did not refer to a singular rune)"), 0, { .d_c = 0 }}})), lspos); } else if (u.len == 0) { v__scanner__Scanner_add_error_detail(s, _S("use quotes for strings, backticks for characters")); v__scanner__Scanner_error_with_pos(s, str_intp(2, _MOV((StrIntpData[]){{_S("invalid empty character literal `"), 0xfe10, {.d_s = orig}}, {_S("`"), 0, { .d_c = 0 }}})), lspos); } else { v__scanner__Scanner_add_error_detail(s, _S("use quotes for strings, backticks for characters")); v__scanner__Scanner_error_with_pos(s, str_intp(4, _MOV((StrIntpData[]){{_S("invalid character literal `"), 0xfe10, {.d_s = orig}}, {_S("` => `"), 0xfe10, {.d_s = c}}, {_S("` (["), 0xfe10, {.d_s = Array_string_join(err_info, _S(", "))}}, {_S("]) (more than one character)"), 0, { .d_c = 0 }}})), lspos); } } } else if (string_ends_with(c, _S("\n"))) { v__scanner__Scanner_add_error_detail(s, _S("use quotes for strings, backticks for characters")); v__scanner__Scanner_error_with_pos(s, _S("invalid character literal, use `\\n` instead"), lspos); } else if (c.len > len) { u8 ch = string_at(c, (int)(c.len - 1)); if (!v__util__is_escape_sequence(ch) && !u8_is_digit(ch)) { v__scanner__Scanner_error(s, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = u8_ascii_str(ch)}}, {_S("` unknown escape sequence"), 0, { .d_c = 0 }}}))); } } if (_SLIT_EQ(c.str, c.len, "'")) { return string__plus(_S("\\"), c); } return c; } inline VV_LOC bool v__scanner__Scanner_expect(v__scanner__Scanner* s, string want, int start_pos) { int end_pos = (int)(start_pos + want.len); if (start_pos < 0 || end_pos < 0 || start_pos >= s->text.len || end_pos > s->text.len) { return false; } for (int pos = start_pos; pos < end_pos; ++pos) { if (s->text.str[ pos] != want.str[ (int)(pos - start_pos)]) { return false; } } return true; } inline VV_LOC void v__scanner__Scanner_ignore_line(v__scanner__Scanner* s) { v__scanner__Scanner_eat_to_end_of_line(s); v__scanner__Scanner_inc_line_number(s); } inline VV_LOC void v__scanner__Scanner_eat_to_end_of_line(v__scanner__Scanner* s) { for (;;) { if (!(s->pos < s->text.len && s->text.str[ s->pos] != 10)) break; s->pos++; } } inline VV_LOC void v__scanner__Scanner_inc_line_number(v__scanner__Scanner* s) { s->last_nl_pos = (int)(s->text.len - 1); if (s->last_nl_pos > s->pos) { s->last_nl_pos = s->pos; } if (s->is_crlf) { s->last_nl_pos++; } s->line_nr++; if (s->line_nr > s->nr_lines) { s->nr_lines = s->line_nr; } } v__token__Pos v__scanner__Scanner_current_pos(v__scanner__Scanner* s) { return ((v__token__Pos){.len = 0,.line_nr = s->line_nr,.pos = s->pos,.col = (int)(v__scanner__Scanner_current_column(s) - 1),.last_line = 0,}); } void v__scanner__Scanner_add_error_detail(v__scanner__Scanner* s, string msg) { array_push((array*)&s->error_details, _MOV((string[]){ string_clone(msg) })); } void v__scanner__Scanner_add_error_detail_with_pos(v__scanner__Scanner* s, string msg, v__token__Pos pos) { v__scanner__Scanner_add_error_detail(s, string__plus(_S("\n"), v__util__formatted_error(_S("details:"), msg, s->file_path, pos))); } VV_LOC string v__scanner__Scanner_eat_details(v__scanner__Scanner* s) { string details = _S(""); if (s->error_details.len > 0) { details = Array_string_join(s->error_details, _S("\n")); s->error_details = __new_array_with_default(0, 0, sizeof(string), 0); } return details; } void v__scanner__Scanner_warn(v__scanner__Scanner* s, string msg) { v__scanner__Scanner_warn_with_pos(s, msg, v__scanner__Scanner_current_pos(s)); } void v__scanner__Scanner_warn_with_pos(v__scanner__Scanner* s, string msg, v__token__Pos pos) { if (s->pref->warns_are_errors) { v__scanner__Scanner_error_with_pos(s, msg, pos); return; } string details = v__scanner__Scanner_eat_details(s); if (s->pref->output_mode == v__pref__OutputMode__stdout && !s->pref->check_only) { v__util__show_compiler_message(_S("warning:"), ((v__errors__CompilerMessage){.message = msg,.details = details,.file_path = s->file_path,.pos = pos,.reporter = 0,})); } else { if (s->pref->message_limit >= 0 && s->warnings.len >= s->pref->message_limit) { s->should_abort = true; return; } array_push((array*)&s->warnings, _MOV((v__errors__Warning[]){ ((v__errors__Warning){.CompilerMessage = ((v__errors__CompilerMessage){.message = msg,.details = details,.file_path = s->file_path,.pos = pos,.reporter = v__errors__Reporter__scanner,}),}) })); } } void v__scanner__Scanner_error(v__scanner__Scanner* s, string msg) { v__scanner__Scanner_error_with_pos(s, msg, v__scanner__Scanner_current_pos(s)); } void v__scanner__Scanner_error_with_pos(v__scanner__Scanner* s, string msg, v__token__Pos pos) { string details = v__scanner__Scanner_eat_details(s); if (s->pref->output_mode == v__pref__OutputMode__stdout && !s->pref->check_only) { v__util__show_compiler_message(_S("error:"), ((v__errors__CompilerMessage){.message = msg,.details = details,.file_path = s->file_path,.pos = pos,.reporter = 0,})); _v_exit(1); VUNREACHABLE(); } else { if (s->pref->fatal_errors) { v__util__show_compiler_message(_S("error:"), ((v__errors__CompilerMessage){.message = msg,.details = details,.file_path = s->file_path,.pos = pos,.reporter = 0,})); _v_exit(1); VUNREACHABLE(); } if (s->pref->message_limit >= 0 && s->errors.len >= s->pref->message_limit) { s->should_abort = true; return; } array_push((array*)&s->errors, _MOV((v__errors__Error[]){ ((v__errors__Error){.CompilerMessage = ((v__errors__CompilerMessage){.message = msg,.details = details,.file_path = s->file_path,.pos = pos,.reporter = v__errors__Reporter__scanner,}),}) })); } } VV_LOC bool v__ast__walker__empty_callback(v__ast__Node* node, voidptr data) { _v_panic(str_intp(3, _MOV((StrIntpData[]){{_S("empty ast.walker, node: "), 0xfe11, {.d_p = (void*)(((voidptr)(node)))}}, {_S(", data: "), 0xfe11, {.d_p = (void*)(((voidptr)(data)))}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); return 0; } _result_void v__ast__walker__Inspector_visit(v__ast__walker__Inspector* i, v__ast__Node* node) { if (i->inspector_callback(node, i->data)) { return (_result_void){0}; } return (_result_void){ .is_error=true, .err=_v_error(_S("")), .data={E_STRUCT} }; } void v__ast__walker__walk(v__ast__walker__Visitor* visitor, v__ast__Node* node) { _result_void _t1 = v__ast__walker__Visitor_name_table[visitor->_typ]._method_visit(visitor->_object, node); if (_t1.is_error) { IError err = _t1.err; return; } ; Array_v__ast__Node children = v__ast__Node_children(*node); for (int _t2 = 0; _t2 < children.len; ++_t2) { v__ast__Node child_node = ((v__ast__Node*)children.data)[_t2]; v__ast__walker__walk(visitor, &child_node); } } VV_LOC void v__checker__Checker_assign_stmt(v__checker__Checker* c, v__ast__AssignStmt* node) { bool v__checker__Checker_assign_stmt_defer_0 = false; bool prev_inside_assign; bool v__checker__Checker_assign_stmt_defer_1 = false; bool old_recheck; bool v__checker__Checker_assign_stmt_defer_2 = false; prev_inside_assign = c->inside_assign; c->inside_assign = true; if ((node->attr.name).len != 0) { c->assign_stmt_attr = node->attr.name; } else { c->assign_stmt_attr = _S(""); } c->expected_type = _const_v__ast__none_type; v__checker__Checker_assign_stmt_defer_0 = true; bool is_decl = node->op == v__token__Kind__decl_assign; v__ast__Expr right_first = (*(v__ast__Expr*)array_get(node->right, 0)); node->left_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); int right_len = node->right.len; v__ast__Type right_first_type = _const_v__ast__void_type; old_recheck = c->inside_recheck; c->inside_recheck = old_recheck || node->right_types.len > 0; v__checker__Checker_assign_stmt_defer_1 = true; for (int i = 0; i < node->right.len; ++i) { v__ast__Expr* right = ((v__ast__Expr*)node->right.data) + i; if ((right)->_typ == 344 /* v.ast.CallExpr */ || (right)->_typ == 359 /* v.ast.IfExpr */ || (right)->_typ == 367 /* v.ast.LockExpr */ || (right)->_typ == 369 /* v.ast.MatchExpr */ || (right)->_typ == 353 /* v.ast.DumpExpr */ || (right)->_typ == 379 /* v.ast.SelectorExpr */ || (right)->_typ == 374 /* v.ast.ParExpr */ || (right)->_typ == 349 /* v.ast.ComptimeCall */) { if (((right)->_typ == 359 /* v.ast.IfExpr */ || (right)->_typ == 369 /* v.ast.MatchExpr */) && node->left.len == node->right.len && !is_decl && (((*(v__ast__Expr*)array_get(node->left, i)))._typ == 358 /* v.ast.Ident */ || ((*(v__ast__Expr*)array_get(node->left, i)))._typ == 379 /* v.ast.SelectorExpr */) && !v__ast__Expr_is_blank_ident((*(v__ast__Expr*)array_get(node->left, i)))) { v__ast__Expr expr = (*(v__ast__Expr*)array_get(node->left, i)); c->expected_type = v__checker__Checker_expr(c, &expr); } v__ast__Type right_type = v__checker__Checker_expr(c, right); if ((right)->_typ == 344 /* v.ast.CallExpr */ || (right)->_typ == 359 /* v.ast.IfExpr */ || (right)->_typ == 367 /* v.ast.LockExpr */ || (right)->_typ == 369 /* v.ast.MatchExpr */ || (right)->_typ == 353 /* v.ast.DumpExpr */) { v__checker__Checker_fail_if_unreadable(c, *right, right_type, _S("right-hand side of assignment")); } v__ast__TypeSymbol* right_type_sym = v__ast__Table_sym(c->table, right_type); if ((right_type_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { right_type = v__checker__Checker_cast_fixed_array_ret(c, right_type, *right_type_sym); } if (i == 0) { right_first_type = right_type; node->right_types = new_array_from_c_array(1, 1, sizeof(v__ast__Type), _MOV((v__ast__Type[1]){v__checker__Checker_check_expr_option_or_result_call(c, *right, right_first_type)})); } if (right_type_sym->kind == v__ast__Kind__multi_return) { if (node->right.len > 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use multi-value "), 0xfe10, {.d_s = right_type_sym->name}}, {_S(" in single-value context"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*right)); } Array_v__ast__Type _t1 = {0}; Array_v__ast__Type _t1_orig = v__ast__TypeSymbol_mr_info(right_type_sym).types; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t3]; v__ast__Type _t2 = v__checker__Checker_cast_fixed_array_ret(c, it, *v__ast__Table_sym(c->table, it)); array_push((array*)&_t1, &_t2); } node->right_types =_t1; right_len = node->right_types.len; } else if (right_type == _const_v__ast__void_type) { right_len = 0; if ((right)->_typ == 359 /* v.ast.IfExpr */) { v__ast__IfBranch last_branch = (*(v__ast__IfBranch*)array_last((*right->_v__ast__IfExpr).branches)); Array_v__ast__Stmt _t4 = {0}; Array_v__ast__Stmt _t4_orig = last_branch.stmts; int _t4_len = _t4_orig.len; _t4 = __new_array(0, _t4_len, sizeof(v__ast__Stmt)); for (int _t5 = 0; _t5 < _t4_len; ++_t5) { v__ast__Stmt it = ((v__ast__Stmt*) _t4_orig.data)[_t5]; if ((it)._typ == 401 /* v.ast.ExprStmt */) { array_push((array*)&_t4, &it); } } Array_v__ast__Stmt last_stmts =_t4; bool _t6 = false; Array_v__ast__Stmt _t6_orig = last_stmts; int _t6_len = _t6_orig.len; for (int _t7 = 0; _t7 < _t6_len; ++_t7) { v__ast__Stmt it = ((v__ast__Stmt*) _t6_orig.data)[_t7]; if (v__ast__Type_has_flag((*(v__ast__ExprStmt*)__as_cast((it)._v__ast__ExprStmt,(it)._typ, 401)).typ, v__ast__TypeFlag__generic)) { _t6 = true; break; } } if (_t6) { right_len = last_branch.stmts.len; Array_v__ast__Type _t8 = {0}; Array_v__ast__Stmt _t8_orig = last_stmts; int _t8_len = _t8_orig.len; _t8 = __new_array(0, _t8_len, sizeof(v__ast__Type)); for (int _t10 = 0; _t10 < _t8_len; ++_t10) { v__ast__Stmt it = ((v__ast__Stmt*) _t8_orig.data)[_t10]; v__ast__Type _t9 = (*(v__ast__ExprStmt*)__as_cast((it)._v__ast__ExprStmt,(it)._typ, 401)).typ; array_push((array*)&_t8, &_t9); } node->right_types =_t8; } } } } else if ((right)->_typ == 362 /* v.ast.InfixExpr */) { if ((*right->_v__ast__InfixExpr).op == v__token__Kind__arrow) { v__checker__Checker_error(c, _S("cannot use `<-` on the right-hand side of an assignment, as it does not return any values"), (*right->_v__ast__InfixExpr).pos); } else if (c->inside_recheck) { if (i < node->right_types.len) { c->expected_type = (*(v__ast__Type*)array_get(node->right_types, i)); } v__ast__Type right_type = v__checker__Checker_expr(c, right); v__ast__TypeSymbol* right_type_sym = v__ast__Table_sym(c->table, right_type); if ((right_type_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { right_type = v__checker__Checker_cast_fixed_array_ret(c, right_type, *right_type_sym); } if (i == 0) { right_first_type = right_type; node->right_types = new_array_from_c_array(1, 1, sizeof(v__ast__Type), _MOV((v__ast__Type[1]){v__checker__Checker_check_expr_option_or_result_call(c, v__ast__InfixExpr_to_sumtype_v__ast__Expr(&(*right->_v__ast__InfixExpr)), right_first_type)})); } } } if ((right)->_typ == 358 /* v.ast.Ident */) { if ((*right->_v__ast__Ident).is_mut) { v__checker__Checker_error(c, _S("unexpected `mut` on right-hand side of assignment"), (*right->_v__ast__Ident).mut_pos); } } if (is_decl && (right)->_typ == 371 /* v.ast.None */) { v__checker__Checker_error(c, _S("cannot assign a `none` value to a variable"), (*right->_v__ast__None).pos); } if ((right)->_typ == 388 /* v.ast.UnsafeExpr */ && ((*(v__ast__UnsafeExpr*)__as_cast((right)->_v__ast__UnsafeExpr,(right)->_typ, 388)).expr)._typ == 371 /* v.ast.None */) { v__checker__Checker_error(c, _S("cannot use `none` in `unsafe` blocks"), (*(*right->_v__ast__UnsafeExpr).expr._v__ast__None).pos); } if ((right)->_typ == 336 /* v.ast.AnonFn */) { if ((*right->_v__ast__AnonFn).decl.generic_names.len > 0) { v__checker__Checker_error(c, _S("cannot assign generic function to a variable"), (*right->_v__ast__AnonFn).decl.pos); } } } if (node->left.len != right_len) { if ((right_first)._typ == 344 /* v.ast.CallExpr */) { if (node->left_types.len > 0 && (*(v__ast__Type*)array_get(node->left_types, 0)) == _const_v__ast__void_type) { // Defer begin if (v__checker__Checker_assign_stmt_defer_1) { c->inside_recheck = old_recheck; } // Defer end // Defer begin if (v__checker__Checker_assign_stmt_defer_0) { c->expected_type = _const_v__ast__void_type; c->inside_assign = prev_inside_assign; } // Defer end return; } string str_variables = (node->left.len == 1 ? (_S("variable")) : (_S("variables"))); string str_values = (right_len == 1 ? (_S("value")) : (_S("values"))); v__checker__Checker_error(c, str_intp(6, _MOV((StrIntpData[]){{_S("assignment mismatch: "), 0xfe07, {.d_i32 = node->left.len}}, {_S(" "), 0xfe10, {.d_s = str_variables}}, {_S(" but `"), 0xfe10, {.d_s = v__ast__CallExpr_get_name(&(*right_first._v__ast__CallExpr))}}, {_S("()` returns "), 0xfe07, {.d_i32 = right_len}}, {_S(" "), 0xfe10, {.d_s = str_values}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else if ((right_first)._typ == 374 /* v.ast.ParExpr */) { v__ast__ParExpr right_next = (*right_first._v__ast__ParExpr); for (;;) { if ((right_next.expr)._typ == 344 /* v.ast.CallExpr */) { if ((*right_next.expr._v__ast__CallExpr).return_type == _const_v__ast__void_type) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("assignment mismatch: expected "), 0xfe07, {.d_i32 = node->left.len}}, {_S(" value(s) but `"), 0xfe10, {.d_s = v__ast__CallExpr_get_name(&(*right_next.expr._v__ast__CallExpr))}}, {_S("()` returns "), 0xfe07, {.d_i32 = right_len}}, {_S(" value(s)"), 0, { .d_c = 0 }}})), node->pos); } break; } else if ((right_next.expr)._typ == 374 /* v.ast.ParExpr */) { right_next = (*right_next.expr._v__ast__ParExpr); } else { break; } } } else { string str_variables = (node->left.len == 1 ? (_S("variable")) : (_S("variables"))); string str_values = (right_len == 1 ? (_S("value")) : (_S("values"))); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("assignment mismatch: "), 0xfe07, {.d_i32 = node->left.len}}, {_S(" "), 0xfe10, {.d_s = str_variables}}, {_S(" "), 0xfe07, {.d_i32 = right_len}}, {_S(" "), 0xfe10, {.d_s = str_values}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } // Defer begin if (v__checker__Checker_assign_stmt_defer_1) { c->inside_recheck = old_recheck; } // Defer end // Defer begin if (v__checker__Checker_assign_stmt_defer_0) { c->expected_type = _const_v__ast__void_type; c->inside_assign = prev_inside_assign; } // Defer end return; } for (int i = 0; i < node->left.len; ++i) { v__ast__Expr* left = ((v__ast__Expr*)node->left.data) + i; if ((left)->_typ == 344 /* v.ast.CallExpr */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot call function `"), 0xfe10, {.d_s = (*left->_v__ast__CallExpr).name}}, {_S("()` on the left side of an assignment"), 0, { .d_c = 0 }}})), (*left->_v__ast__CallExpr).pos); } else if ((left)->_typ == 376 /* v.ast.PrefixExpr */) { if (((*left->_v__ast__PrefixExpr).right)._typ == 344 /* v.ast.CallExpr */ && (*left->_v__ast__PrefixExpr).op == v__token__Kind__mul) { v__checker__Checker_error(c, _S("cannot dereference a function call on the left side of an assignment, use a temporary variable"), (*left->_v__ast__PrefixExpr).pos); } } else if ((left)->_typ == 361 /* v.ast.IndexExpr */ && ((*(v__ast__IndexExpr*)__as_cast((left)->_v__ast__IndexExpr,(left)->_typ, 361)).index)._typ == 377 /* v.ast.RangeExpr */) { v__checker__Checker_error(c, _S("cannot reassign using range expression on the left side of an assignment"), (*left->_v__ast__IndexExpr).pos); } else if ((left)->_typ == 358 /* v.ast.Ident */ && node->op == v__token__Kind__decl_assign) { if ((Array_string_contains(c->global_names, (*left->_v__ast__Ident).name))) { v__checker__Checker_note(c, str_intp(2, _MOV((StrIntpData[]){{_S("the global variable named `"), 0xfe10, {.d_s = (*left->_v__ast__Ident).name}}, {_S("` already exists"), 0, { .d_c = 0 }}})), (*left->_v__ast__Ident).pos); } } bool is_blank_ident = v__ast__Expr_is_blank_ident(*left); v__ast__Type left_type = _const_v__ast__void_type; bool var_option = false; bool is_shared_re_assign = false; if (!is_decl && !is_blank_ident) { if ((left)->_typ == 358 /* v.ast.Ident */ || (left)->_typ == 379 /* v.ast.SelectorExpr */) { c->prevent_sum_type_unwrapping_once = true; } if ((left)->_typ == 361 /* v.ast.IndexExpr */) { c->is_index_assign = true; } left_type = v__checker__Checker_expr(c, left); c->is_index_assign = false; c->expected_type = v__checker__Checker_unwrap_generic(c, left_type); is_shared_re_assign = (left)->_typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)).info)._typ == 477 /* v.ast.IdentVar */ && ((*(v__ast__IdentVar*)__as_cast(((*(v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)).info)._v__ast__IdentVar,((*(v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)).info)._typ, 477)).share == v__ast__ShareType__shared_t || v__ast__Type_has_flag(left_type, v__ast__TypeFlag__shared_f)) && (v__ast__Table_sym(c->table, left_type)->kind == v__ast__Kind__array || v__ast__Table_sym(c->table, left_type)->kind == v__ast__Kind__map || v__ast__Table_sym(c->table, left_type)->kind == v__ast__Kind__struct); } if ((c->comptime->comptime_for_field_var).len != 0 && (left)->_typ == 350 /* v.ast.ComptimeSelector */) { if (c->comptime->has_different_types && v__ast__Expr_is_literal((*(v__ast__Expr*)array_get(node->right, i))) && !c->comptime->inside_comptime_if) { v__checker__Checker_error(c, _S("mismatched types: check field type with $if to avoid this problem"), v__ast__Expr_pos((*(v__ast__Expr*)array_get(node->right, i)))); } left_type = c->comptime->comptime_for_field_type; c->expected_type = v__checker__Checker_unwrap_generic(c, left_type); } if (node->right_types.len < node->left.len) { bool old_inside_ref_lit = c->inside_ref_lit; if ((left)->_typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)).info)._typ == 477 /* v.ast.IdentVar */) { c->inside_ref_lit = c->inside_ref_lit || (*(*left->_v__ast__Ident).info._v__ast__IdentVar).share == v__ast__ShareType__shared_t; } c->inside_decl_rhs = is_decl; v__ast__Expr expr = (*(v__ast__Expr*)array_get(node->right, i)); if ((left)->_typ == 358 /* v.ast.Ident */ && v__ast__Ident_is_mut(((v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358))) && (expr)._typ == 385 /* v.ast.StructInit */ && (*(v__ast__StructInit*)__as_cast((expr)._v__ast__StructInit,(expr)._typ, 385)).is_anon) { c->anon_struct_should_be_mut = true; v__checker__Checker_assign_stmt_defer_2 = true; } v__ast__Type right_type = v__checker__Checker_expr(c, &expr); c->inside_decl_rhs = false; c->inside_ref_lit = old_inside_ref_lit; if (node->right_types.len == i) { array_push((array*)&node->right_types, _MOV((v__ast__Type[]){ v__checker__Checker_check_expr_option_or_result_call(c, (*(v__ast__Expr*)array_get(node->right, i)), right_type) })); } } else if (c->inside_recheck) { if (i < node->right.len && v__type_resolver__ResolverInfo_has_comptime_expr(c->comptime, (*(v__ast__Expr*)array_get(node->right, i)))) { v__ast__Expr expr = (*(v__ast__Expr*)array_get(node->right, i)); v__ast__Type right_type = v__checker__Checker_expr(c, &expr); array_set(&node->right_types, i, &(v__ast__Type[]) { v__checker__Checker_check_expr_option_or_result_call(c, (*(v__ast__Expr*)array_get(node->right, i)), right_type) }); } } v__ast__Expr right = (i < node->right.len ? ((*(v__ast__Expr*)array_get(node->right, i))) : ((*(v__ast__Expr*)array_get(node->right, 0)))); v__ast__Type right_type = (*(v__ast__Type*)array_get(node->right_types, i)); if ((right)._typ == 358 /* v.ast.Ident */) { if (v__ast__Type_has_flag(right_type, v__ast__TypeFlag__shared_f)) { if (v__checker__Checker_fail_if_unreadable(c, right, right_type, _S("right-hand side of assignment"))) { // Defer begin if (v__checker__Checker_assign_stmt_defer_2) { c->anon_struct_should_be_mut = false; } // Defer end // Defer begin if (v__checker__Checker_assign_stmt_defer_1) { c->inside_recheck = old_recheck; } // Defer end // Defer begin if (v__checker__Checker_assign_stmt_defer_0) { c->expected_type = _const_v__ast__void_type; c->inside_assign = prev_inside_assign; } // Defer end return; } } v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type); if ((right_sym->info)._typ == 518 /* v.ast.Struct */) { if ((*right_sym->info._v__ast__Struct).generic_types.len > 0) { _option_v__ast__ScopeObject _t12; if (_t12 = v__ast__Scope_find((*right._v__ast__Ident).scope, (*right._v__ast__Ident).name), _t12.state == 0) { v__ast__ScopeObject obj = *(v__ast__ScopeObject*)_t12.data; right_type = (*(obj.typ)); } } } if ((*right._v__ast__Ident).or_expr.kind == v__ast__OrKind__propagate_option || (*right._v__ast__Ident).or_expr.kind == v__ast__OrKind__block) { right_type = v__ast__Type_clear_flag(right_type, v__ast__TypeFlag__option); } } else if ((right)._typ == 350 /* v.ast.ComptimeSelector */) { right_type = c->comptime->comptime_for_field_type; } if (is_decl && (left)->_typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)).info)._typ == 477 /* v.ast.IdentVar */ && (*(v__ast__IdentVar*)__as_cast(((*(v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)).info)._v__ast__IdentVar,((*(v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)).info)._typ, 477)).share == v__ast__ShareType__shared_t && !(v__ast__Table_sym(c->table, right_type)->kind == v__ast__Kind__array || v__ast__Table_sym(c->table, right_type)->kind == v__ast__Kind__map || v__ast__Table_sym(c->table, right_type)->kind == v__ast__Kind__struct)) { v__checker__Checker_fatal(c, _S("shared variables must be structs, arrays or maps"), v__ast__Expr_pos(right)); } if (is_decl || is_shared_re_assign) { if ((right)._typ == 385 /* v.ast.StructInit */) { v__checker__Checker_expr(c, HEAP(v__ast__Expr, v__ast__StructInit_to_sumtype_v__ast__Expr(&(*right._v__ast__StructInit)))); if (v__ast__Type_has_flag((*right._v__ast__StructInit).typ, v__ast__TypeFlag__generic)) { right_type = (*right._v__ast__StructInit).typ; } } else if ((right)._typ == 376 /* v.ast.PrefixExpr */) { if ((*right._v__ast__PrefixExpr).op == v__token__Kind__amp && ((*right._v__ast__PrefixExpr).right)._typ == 385 /* v.ast.StructInit */) { right_type = v__checker__Checker_expr(c, HEAP(v__ast__Expr, v__ast__PrefixExpr_to_sumtype_v__ast__Expr(&(*right._v__ast__PrefixExpr)))); } else if ((*right._v__ast__PrefixExpr).op == v__token__Kind__arrow) { right_type = v__checker__Checker_expr(c, HEAP(v__ast__Expr, v__ast__PrefixExpr_to_sumtype_v__ast__Expr(&(*right._v__ast__PrefixExpr)))); right_type = v__checker__Checker_cast_fixed_array_ret(c, right_type, *v__ast__Table_sym(c->table, right_type)); } } else if ((right)._typ == 358 /* v.ast.Ident */) { if ((*right._v__ast__Ident).kind == v__ast__IdentKind__function) { v__checker__Checker_expr(c, HEAP(v__ast__Expr, v__ast__Ident_to_sumtype_v__ast__Expr(&(*right._v__ast__Ident)))); } } if (v__ast__Expr_is_auto_deref_var(right)) { left_type = v__ast__mktyp(v__ast__Type_deref(right_type)); } else { left_type = v__ast__mktyp(right_type); } if (left_type == _const_v__ast__int_type) { if ((right)._typ == 363 /* v.ast.IntegerLiteral */) { i64 val = string_i64((*right._v__ast__IntegerLiteral).val); if (v__checker__overflows_i32(val)) { v__checker__Checker_error(c, _S("overflow in implicit type `int`, use explicit type casting instead"), (*right._v__ast__IntegerLiteral).pos); } } } } else { v__checker__Checker_fail_if_immutable(c, left); if (!is_blank_ident && !v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option) && v__ast__Type_has_flag(right_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("cannot assign an Option value to a non-option variable"), v__ast__Expr_pos(right)); } } if (!c->inside_unsafe && !is_blank_ident && (node->op == v__token__Kind__decl_assign || node->op == v__token__Kind__assign) && (left)->_typ == 358 /* v.ast.Ident */ && v__ast__Ident_is_mut(((v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)))) { v__checker__Checker_fail_if_immutable_to_mutable(c, left_type, right_type, right); } if ((left)->_typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)).info)._typ == 477 /* v.ast.IdentVar */ && (right)._typ == 358 /* v.ast.Ident */ && (Array_string_contains(c->global_names, (*(v__ast__Ident*)__as_cast((right)._v__ast__Ident,(right)._typ, 358)).name))) { v__ast__IdentVar ident_var_info = (*(*left->_v__ast__Ident).info._v__ast__IdentVar); if (ident_var_info.share == v__ast__ShareType__shared_t) { v__checker__Checker_error(c, _S("cannot assign global variable to shared variable"), v__ast__Expr_pos(right)); } } if (v__ast__Type_is_ptr(right_type) && v__ast__Type_is_ptr(left_type)) { if ((right)._typ == 358 /* v.ast.Ident */) { v__checker__Checker_fail_if_stack_struct_action_outside_unsafe(c, &/*mut*/(*right._v__ast__Ident), _S("assigned")); } } if (!is_decl && (left)->_typ == 358 /* v.ast.Ident */ && !is_blank_ident && !v__ast__Type_is_any_kind_of_pointer(left_type) && v__ast__Type_is_any_kind_of_pointer(right_type) && !v__ast__Type_has_flag(right_type, v__ast__TypeFlag__shared_f)) { v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, left_type); if (!(left_sym->kind == v__ast__Kind__function || left_sym->kind == v__ast__Kind__array)) { v__checker__Checker_warn(c, string__plus(str_intp(3, _MOV((StrIntpData[]){{_S("cannot assign a reference to a value (this will be an error soon) left="), 0xfe10, {.d_s = v__ast__Table_type_str(c->table, left_type)}}, {_S(" "), 0xfe10, {.d_s = v__ast__Type_is_ptr(left_type) ? _S("true") : _S("false")}}, {_S(" "), 0, { .d_c = 0 }}})), str_intp(4, _MOV((StrIntpData[]){{_S("right="), 0xfe10, {.d_s = v__ast__Table_type_str(c->table, right_type)}}, {_S(" "), 0xfe10, {.d_s = v__ast__Type_is_any_kind_of_pointer(right_type) ? _S("true") : _S("false")}}, {_S(" ptr="), 0xfe10, {.d_s = v__ast__Type_is_ptr(right_type) ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))), node->pos); } } array_push((array*)&node->left_types, _MOV((v__ast__Type[]){ left_type })); if ((right)._typ == 385 /* v.ast.StructInit */) { v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type); v__checker__Checker_check_any_type(c, right_type, right_sym, v__ast__Expr_pos(right)); } if ((left)->_typ == 374 /* v.ast.ParExpr */ && is_decl) { v__checker__Checker_error(c, _S("parentheses are not supported on the left side of `:=`"), v__ast__Expr_pos(*left)); } *left = v__ast__Expr_remove_par(left); bool is_assign = (node->op == v__token__Kind__assign || node->op == v__token__Kind__decl_assign); if (left->_typ == 358 /* v.ast.Ident */) { if ((is_decl || (*left->_v__ast__Ident).kind == v__ast__IdentKind__blank_ident) && v__ast__Type_is_ptr(left_type) && (right)._typ == 376 /* v.ast.PrefixExpr */ && (*(v__ast__PrefixExpr*)__as_cast((right)._v__ast__PrefixExpr,(right)._typ, 376)).right_type == 28) { if (((*right._v__ast__PrefixExpr).right)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast(((*right._v__ast__PrefixExpr).right)._v__ast__Ident,((*right._v__ast__PrefixExpr).right)._typ, 358)).obj)._typ == 420 /* v.ast.ConstField */) { string const_name = string_all_after_last((*(*right._v__ast__PrefixExpr).right._v__ast__Ident).name, _S(".")); v__ast__Expr const_val = ((*(*(*right._v__ast__PrefixExpr).right._v__ast__Ident).obj._v__ast__ConstField)).expr; v__checker__Checker_add_error_detail(c, _S("Specify the type for the constant value. Example:")); v__checker__Checker_add_error_detail(c, str_intp(3, _MOV((StrIntpData[]){{_S(" `const "), 0xfe10, {.d_s = const_name}}, {_S(" = int("), 0xfe10, {.d_s = v__ast__Expr_str(&const_val)}}, {_S(")`"), 0, { .d_c = 0 }}}))); v__checker__Checker_error(c, _S("cannot assign a pointer to a constant with an integer literal value"), (*(*right._v__ast__PrefixExpr).right._v__ast__Ident).pos); } } else if ((*left->_v__ast__Ident).kind == v__ast__IdentKind__blank_ident) { if (!is_decl && (right)._typ == 371 /* v.ast.None */) { v__checker__Checker_error(c, _S("cannot assign a `none` value to blank `_` identifier"), (*right._v__ast__None).pos); } left_type = right_type; array_set(&node->left_types, i, &(v__ast__Type[]) { right_type }); if (!is_assign) { v__checker__Checker_error(c, _S("cannot modify blank `_` identifier"), (*left->_v__ast__Ident).pos); } } else if (((*left->_v__ast__Ident).info)._typ != 477 /* v.ast.IdentVar */) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot assign to "), 0xfe10, {.d_s = v__ast__IdentKind_str((*left->_v__ast__Ident).kind)}}, {_S(" `"), 0xfe10, {.d_s = (*left->_v__ast__Ident).name}}, {_S("`"), 0, { .d_c = 0 }}})), (*left->_v__ast__Ident).pos); } else { if (is_decl) { v__checker__Checker_check_valid_snake_case(c, (*left->_v__ast__Ident).name, _S("variable name"), (*left->_v__ast__Ident).pos); if (v__token__KeywordsMatcherTrie_matches(&_const_v__checker__reserved_type_names_chk, (*left->_v__ast__Ident).name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid use of reserved type `"), 0xfe10, {.d_s = (*left->_v__ast__Ident).name}}, {_S("` as a variable name"), 0, { .d_c = 0 }}})), (*left->_v__ast__Ident).pos); } } if ((is_decl || is_shared_re_assign) && (right)._typ == 370 /* v.ast.Nil */ && !c->inside_unsafe) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("use of untyped nil in assignment (use `unsafe` | "), 0xfe10, {.d_s = c->inside_unsafe ? _S("true") : _S("false")}}, {_S(")"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } v__ast__IdentVar ident_var_info = *(v__ast__IdentVar*)__as_cast(((*left->_v__ast__Ident).info)._v__ast__IdentVar,((*left->_v__ast__Ident).info)._typ, 477); if (ident_var_info.share == v__ast__ShareType__shared_t || is_shared_re_assign) { left_type = v__ast__Type_set_flag(left_type, v__ast__TypeFlag__shared_f); if (is_decl || is_shared_re_assign) { if (v__ast__Type_nr_muls(left_type) > 1) { v__checker__Checker_error(c, _S("shared cannot be multi level reference"), (*left->_v__ast__Ident).pos); } left_type = v__ast__Type_set_nr_muls(left_type, 1); } } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__shared_f)) { left_type = v__ast__Type_clear_flag(left_type, v__ast__TypeFlag__shared_f); if (v__ast__Type_is_ptr(left_type)) { left_type = v__ast__Type_deref(left_type); } } if (ident_var_info.share == v__ast__ShareType__atomic_t) { left_type = v__ast__Type_set_flag(left_type, v__ast__TypeFlag__atomic_f); } if (ident_var_info.is_option) { var_option = true; } array_set(&node->left_types, i, &(v__ast__Type[]) { left_type }); ident_var_info.typ = left_type; (*left->_v__ast__Ident).info = v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(&ident_var_info); if (left_type != 0) { if ((*left->_v__ast__Ident).obj._typ == 422 /* v.ast.Var */) { (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = left_type; if ((*(*left->_v__ast__Ident).obj._v__ast__Var).is_auto_deref) { (*(*left->_v__ast__Ident).obj._v__ast__Var).is_used = true; } if (!v__ast__Type_is_ptr(left_type)) { if (v__ast__TypeSymbol_is_heap(v__ast__Table_sym(c->table, left_type))) { (*(*left->_v__ast__Ident).obj._v__ast__Var).is_auto_heap = true; } } if ((Array_int_contains(_const_v__ast__unsigned_integer_type_idxs, left_type))) { if ((right)._typ == 363 /* v.ast.IntegerLiteral */) { if (string_at((*right._v__ast__IntegerLiteral).val, 0) == '-') { v__checker__Checker_error(c, _S("cannot assign negative value to unsigned integer type"), (*right._v__ast__IntegerLiteral).pos); } } } if (is_decl) { v__checker__Checker_change_flags_if_comptime_expr(c, &/*mut*/(*left->_v__ast__Ident), right); } } else if ((*left->_v__ast__Ident).obj._typ == 421 /* v.ast.GlobalField */) { (*(*left->_v__ast__Ident).obj._v__ast__GlobalField).typ = left_type; } else { } } if (is_decl) { string full_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*left->_v__ast__Ident).mod}}, {_S("."), 0xfe10, {.d_s = (*left->_v__ast__Ident).name}}, {_SLIT0, 0, { .d_c = 0 }}})); _option_v__ast__ConstField_ptr _t14; if (_t14 = v__ast__Scope_find_const(c->file->global_scope, full_name), _t14.state == 0) { v__checker__Checker_warn(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate of a const name `"), 0xfe10, {.d_s = full_name}}, {_S("`"), 0, { .d_c = 0 }}})), (*left->_v__ast__Ident).pos); } if (string__eq((*left->_v__ast__Ident).name, (*left->_v__ast__Ident).mod) && !fast_string_eq((*left->_v__ast__Ident).name, _S("main"))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate of a module name `"), 0xfe10, {.d_s = (*left->_v__ast__Ident).name}}, {_S("`"), 0, { .d_c = 0 }}})), (*left->_v__ast__Ident).pos); } if (v__checker__Checker_check_import_sym_conflict(c, (*left->_v__ast__Ident).name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate of an import symbol `"), 0xfe10, {.d_s = (*left->_v__ast__Ident).name}}, {_S("`"), 0, { .d_c = 0 }}})), (*left->_v__ast__Ident).pos); } } if (node->op == v__token__Kind__assign && v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option) && (right)._typ == 388 /* v.ast.UnsafeExpr */ && v__ast__Expr_is_nil((*(v__ast__UnsafeExpr*)__as_cast((right)._v__ast__UnsafeExpr,(right)._typ, 388)).expr)) { v__checker__Checker_error(c, _S("cannot assign `nil` to option value"), v__ast__Expr_pos(right)); } } } else if (left->_typ == 376 /* v.ast.PrefixExpr */) { if ((*left->_v__ast__PrefixExpr).op == v__token__Kind__mul) { if (!c->inside_unsafe && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, _S("modifying variables via dereferencing can only be done in `unsafe` blocks"), node->pos); } else if (((*left->_v__ast__PrefixExpr).right)._typ == 358 /* v.ast.Ident */) { if (((*(*left->_v__ast__PrefixExpr).right._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { (*(*(*left->_v__ast__PrefixExpr).right._v__ast__Ident).obj._v__ast__Var).is_used = true; } } } else if ((*left->_v__ast__PrefixExpr).op == v__token__Kind__amp) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use a reference on the left side of `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("`"), 0, { .d_c = 0 }}})), (*left->_v__ast__PrefixExpr).pos); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = v__token__Kind_str((*left->_v__ast__PrefixExpr).op)}}, {_S("` on the left of `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("`"), 0, { .d_c = 0 }}})), (*left->_v__ast__PrefixExpr).pos); } if (is_decl) { v__checker__Checker_error(c, _S("non-name on the left side of `:=`"), (*left->_v__ast__PrefixExpr).pos); } } else if (left->_typ == 379 /* v.ast.SelectorExpr */) { if (((*left->_v__ast__SelectorExpr).expr)._typ == 361 /* v.ast.IndexExpr */) { if ((*(*left->_v__ast__SelectorExpr).expr._v__ast__IndexExpr).is_map) { (*(*left->_v__ast__SelectorExpr).expr._v__ast__IndexExpr).is_setter = true; } } if ((Array_int_contains(_const_v__ast__unsigned_integer_type_idxs, left_type))) { if ((right)._typ == 363 /* v.ast.IntegerLiteral */) { if (string_at((*right._v__ast__IntegerLiteral).val, 0) == '-') { v__checker__Checker_error(c, _S("cannot assign negative value to unsigned integer type"), (*right._v__ast__IntegerLiteral).pos); } } } if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option) && (right)._typ == 388 /* v.ast.UnsafeExpr */ && v__ast__Expr_is_nil((*(v__ast__UnsafeExpr*)__as_cast((right)._v__ast__UnsafeExpr,(right)._typ, 388)).expr)) { v__checker__Checker_error(c, _S("cannot assign `nil` to option value"), v__ast__Expr_pos(right)); } } else { if ((left)->_typ == 361 /* v.ast.IndexExpr */) { if (((*left->_v__ast__IndexExpr).is_map || (*left->_v__ast__IndexExpr).is_farray) && (*left->_v__ast__IndexExpr).is_setter) { v__ast__IndexExpr_recursive_mapset_is_setter(&(*left->_v__ast__IndexExpr), true); } right_type = v__type_resolver__TypeResolver_get_type_or_default(&c->type_resolver, right, right_type); } if ((left)->_typ == 362 /* v.ast.InfixExpr */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use infix expression on the left side of `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("`"), 0, { .d_c = 0 }}})), (*left->_v__ast__InfixExpr).pos); } if (is_decl) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("non-name `"), 0xfe10, {.d_s = v__ast__Expr_str(left)}}, {_S("` on left side of `:=`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*left)); } if (node->op == v__token__Kind__assign && (v__ast__Expr_is_literal(*left) || (left)->_typ == 385 /* v.ast.StructInit */)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("non-name literal value `"), 0xfe10, {.d_s = v__ast__Expr_str(left)}}, {_S("` on left side of `=`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*left)); } } v__ast__Type left_type_unwrapped = v__checker__Checker_unwrap_generic(c, v__ast__mktyp(left_type)); v__ast__Type right_type_unwrapped = v__checker__Checker_unwrap_generic(c, right_type); if (right_type_unwrapped == 0) { continue; } if (c->pref->translated || c->file->is_translated) { continue; } if (left_type_unwrapped == 0) { continue; } v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, left_type_unwrapped); v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type_unwrapped); if (left_sym->kind == v__ast__Kind__array && !c->inside_unsafe && right_sym->kind == v__ast__Kind__array && (left)->_typ == 358 /* v.ast.Ident */ && !v__ast__Expr_is_blank_ident(*left) && ((right)._typ == 358 /* v.ast.Ident */ || (right)._typ == 379 /* v.ast.SelectorExpr */) && ((node->op == v__token__Kind__decl_assign && (*(v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)).is_mut) || node->op == v__token__Kind__assign)) { string mut_str = (node->op == v__token__Kind__decl_assign ? (_S("mut ")) : (_S(""))); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("use `"), 0xfe10, {.d_s = mut_str}}, {_S("array2 "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" array1.clone()` instead of `"), 0xfe10, {.d_s = mut_str}}, {_S("array2 "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" array1` (or use `unsafe`)"), 0, { .d_c = 0 }}})), node->pos); } if ((left)->_typ == 376 /* v.ast.PrefixExpr */ && (*(v__ast__PrefixExpr*)__as_cast((left)->_v__ast__PrefixExpr,(left)->_typ, 376)).op == v__token__Kind__mul) { if (v__ast__Type_nr_muls(left_type) != v__ast__Type_nr_muls(right_type) && !v__ast__Type_is_voidptr(left_type) && !v__ast__Type_is_voidptr(right_type) && right_type != _const_v__ast__nil_type) { string r = v__ast__TypeSymbol_str_with_correct_nr_muls(right_sym, v__ast__Type_nr_muls(right_type)); string l = v__ast__TypeSymbol_str_with_correct_nr_muls(left_sym, v__ast__Type_nr_muls(left_type)); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = r}}, {_S("` (right side) as `"), 0xfe10, {.d_s = l}}, {_S("` (left side) in assignment"), 0, { .d_c = 0 }}})), node->pos); } } if (left_sym->kind == v__ast__Kind__array && right_sym->kind == v__ast__Kind__array) { v__ast__Array right_info = *(v__ast__Array*)__as_cast((right_sym->info)._v__ast__Array,(right_sym->info)._typ, 513); v__ast__Type right_elem_type = v__ast__Table_unaliased_type(c->table, right_info.elem_type); if (node->op == v__token__Kind__decl_assign || node->op == v__token__Kind__assign) { if ((left)->_typ == 358 /* v.ast.Ident */ && v__ast__Type_is_ptr(right_elem_type)) { if (v__ast__Ident_is_mut(&(*left->_v__ast__Ident)) || (((*left->_v__ast__Ident).obj)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast(((*left->_v__ast__Ident).obj)._v__ast__Var,((*left->_v__ast__Ident).obj)._typ, 422)).is_mut)) { if ((right)._typ == 338 /* v.ast.ArrayInit */ && (*(v__ast__ArrayInit*)__as_cast((right)._v__ast__ArrayInit,(right)._typ, 338)).exprs.len > 0) { v__ast__Expr elem_expr = (*(v__ast__Expr*)array_get((*right._v__ast__ArrayInit).exprs, 0)); if ((elem_expr)._typ == 376 /* v.ast.PrefixExpr */ && (*(v__ast__PrefixExpr*)__as_cast((elem_expr)._v__ast__PrefixExpr,(elem_expr)._typ, 376)).op == v__token__Kind__amp) { v__ast__Expr r = (*elem_expr._v__ast__PrefixExpr).right; if ((r)._typ == 358 /* v.ast.Ident */) { v__ast__ScopeObject obj = (*r._v__ast__Ident).obj; if ((obj)._typ == 422 /* v.ast.Var */ && !(*(v__ast__Var*)__as_cast((obj)._v__ast__Var,(obj)._typ, 422)).is_mut) { v__checker__Checker_warn(c, _S("cannot add a reference to an immutable object to a mutable array"), (*elem_expr._v__ast__PrefixExpr).pos); } } } } } } else if ((left)->_typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)).kind != v__ast__IdentKind__blank_ident && (right)._typ == 361 /* v.ast.IndexExpr */) { v__ast__IndexExpr right_index_expr = *(v__ast__IndexExpr*)__as_cast((right)._v__ast__IndexExpr,(right)._typ, 361); if ((right_index_expr.left)._typ == 358 /* v.ast.Ident */ && (right_index_expr.index)._typ == 377 /* v.ast.RangeExpr */ && (v__ast__Ident_is_mut(((v__ast__Ident*)__as_cast((right_index_expr.left)._v__ast__Ident,(right_index_expr.left)._typ, 358))) || v__ast__Ident_is_mut(&(*left->_v__ast__Ident))) && !c->inside_unsafe) { v__checker__Checker_add_error_detail_with_pos(c, _S("To silence this notice, use either an explicit `a[..].clone()`,\nor use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice."), v__ast__Expr_pos(right)); v__checker__Checker_note(c, _S("an implicit clone of the slice was done here"), v__ast__Expr_pos(right)); right = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (((v__ast__CallExpr){ .pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .mod = (string){.str=(byteptr)"", .is_lit=1}, .name = _S("clone"), .is_method = true, .is_field = 0, .is_fn_var = 0, .is_fn_a_const = 0, .is_keep_alive = 0, .is_noreturn = 0, .is_ctor_new = 0, .is_file_translated = 0, .is_static_method = 0, .args = __new_array(0, 0, sizeof(v__ast__CallArg)), .expected_arg_types = __new_array(0, 0, sizeof(v__ast__Type)), .comptime_ret_val = 0, .language = 0, .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .left = right, .left_type = left_type, .receiver_type = left_type, .receiver_concrete_type = 0, .return_type = left_type, .return_type_generic = 0, .nr_ret_values = -1, .fn_var_type = 0, .const_name = (string){.str=(byteptr)"", .is_lit=1}, .should_be_skipped = 0, .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .concrete_list_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .raw_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .free_receiver = 0, .scope = c->fn_scope, .from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)), .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .is_return_used = true, .is_expand_simple_interpolation = 0, .is_unwrapped_fn_selector = 0, })))); right_type = v__checker__Checker_expr(c, &right); array_set(&node->right, i, &(v__ast__Expr[]) { right }); } } } if (node->op == v__token__Kind__assign) { v__ast__Array left_info = *(v__ast__Array*)__as_cast((left_sym->info)._v__ast__Array,(left_sym->info)._typ, 513); v__ast__Type left_elem_type = v__ast__Table_unaliased_type(c->table, left_info.elem_type); if (v__ast__Type_nr_muls(left_type_unwrapped) == v__ast__Type_nr_muls(right_type_unwrapped) && left_info.nr_dims == right_info.nr_dims && left_elem_type == right_elem_type) { continue; } } } if (left_sym->kind == v__ast__Kind__map && is_assign && right_sym->kind == v__ast__Kind__map && !v__ast__Expr_is_blank_ident(*left) && v__ast__Expr_is_lvalue(right) && (right)._typ != 350 /* v.ast.ComptimeSelector */ && (!v__ast__Type_is_ptr(right_type) || ((right)._typ == 358 /* v.ast.Ident */ && v__ast__Expr_is_auto_deref_var(right)))) { v__checker__Checker_error(c, _S("cannot copy map: call `move` or `clone` method (or use a reference)"), v__ast__Expr_pos(right)); } if (left_sym->kind == v__ast__Kind__function && (right_sym->info)._typ == 553 /* v.ast.FnType */) { v__ast__TypeSymbol* return_sym = v__ast__Table_sym(c->table, (*right_sym->info._v__ast__FnType).func.return_type); if (return_sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown return type: cannot assign `"), 0xfe10, {.d_s = v__ast__Expr_str(&right)}}, {_S("` as a function variable"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } else if ((!(*right_sym->info._v__ast__FnType).is_anon && return_sym->kind == v__ast__Kind__any) || ((return_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((return_sym->info)._v__ast__Struct,(return_sym->info)._typ, 518)).is_generic)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot assign `"), 0xfe10, {.d_s = v__ast__Expr_str(&right)}}, {_S("` as a generic function variable"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } } if (left_sym->kind == v__ast__Kind__array_fixed && !c->inside_unsafe && is_assign && right_sym->kind == v__ast__Kind__array_fixed && (left)->_typ == 358 /* v.ast.Ident */ && !v__ast__Expr_is_blank_ident(*left) && (right)._typ == 358 /* v.ast.Ident */) { if ((right_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { if (v__ast__Type_is_ptr((*right_sym->info._v__ast__ArrayFixed).elem_type)) { v__checker__Checker_error(c, _S("assignment from one fixed array to another with a pointer element type is prohibited outside of `unsafe`"), node->pos); } } } if (v__ast__Type_is_any_kind_of_pointer(left_type) && !v__ast__Expr_is_auto_deref_var(*left)) { if (!c->inside_unsafe && !(node->op == v__token__Kind__assign || node->op == v__token__Kind__decl_assign)) { if (!c->pref->translated && !c->file->is_translated) { v__checker__Checker_warn(c, _S("pointer arithmetic is only allowed in `unsafe` blocks"), node->pos); } } bool right_is_ptr = v__ast__Type_is_any_kind_of_pointer(right_type); if (!right_is_ptr && node->op == v__token__Kind__assign && v__ast__Type_is_number(right_type_unwrapped)) { v__checker__Checker_error(c, string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("cannot assign to `"), 0xfe10, {.d_s = v__ast__Expr_str(left)}}, {_S("`: "), 0, { .d_c = 0 }}})), v__checker__Checker_expected_msg(c, right_type_unwrapped, left_type_unwrapped)), v__ast__Expr_pos(right)); } if (!v__ast__TypeSymbol_is_number(right_sym) && !v__ast__Type_has_flag(left_type, v__ast__TypeFlag__shared_f) && ((right)._typ == 385 /* v.ast.StructInit */ || !right_is_ptr)) { string left_name = v__ast__Table_type_to_str(c->table, left_type_unwrapped); v__ast__Type rtype = right_type_unwrapped; if (v__ast__Type_is_ptr(rtype)) { rtype = v__ast__Type_deref(rtype); } string right_name = v__ast__Table_type_to_str(c->table, rtype); if (!(v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option) && right_type == _const_v__ast__none_type)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } } if ((left)->_typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((left)->_v__ast__Ident,(left)->_typ, 358)).info)._typ == 477 /* v.ast.IdentVar */) { if ((*(*left->_v__ast__Ident).info._v__ast__IdentVar).is_static && right_sym->kind == v__ast__Kind__map) { v__checker__Checker_error(c, _S("maps cannot be static"), (*left->_v__ast__Ident).pos); } } if (node->op == (v__token__Kind__assign)) { } else if (node->op == (v__token__Kind__plus_assign) || node->op == (v__token__Kind__minus_assign)) { v__ast__Type left_deref = (v__ast__Expr_is_auto_deref_var(*left) ? (v__ast__Type_deref(left_type)) : (left_type)); if (left_deref == _const_v__ast__string_type) { if (node->op != v__token__Kind__plus_assign) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("operator `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` not defined on left operand type `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*left)); } if (right_type != _const_v__ast__string_type) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("invalid right operand: "), 0xfe10, {.d_s = left_sym->name}}, {_S(" "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" "), 0xfe10, {.d_s = right_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } } else if (!v__ast__TypeSymbol_is_number(left_sym) && !(left_sym->kind == v__ast__Kind__byteptr || left_sym->kind == v__ast__Kind__charptr || left_sym->kind == v__ast__Kind__struct || left_sym->kind == v__ast__Kind__alias)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("operator `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` not defined on left operand type `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*left)); } else if (!v__ast__TypeSymbol_is_number(right_sym) && !(left_sym->kind == v__ast__Kind__byteptr || left_sym->kind == v__ast__Kind__charptr || left_sym->kind == v__ast__Kind__struct || left_sym->kind == v__ast__Kind__alias)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("invalid right operand: "), 0xfe10, {.d_s = left_sym->name}}, {_S(" "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" "), 0xfe10, {.d_s = right_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } } else if (node->op == (v__token__Kind__mult_assign) || node->op == (v__token__Kind__div_assign)) { if (!v__ast__TypeSymbol_is_number(left_sym) && !v__ast__TypeSymbol_is_int(v__ast__Table_final_sym(c->table, left_type_unwrapped)) && !(left_sym->kind == v__ast__Kind__struct || left_sym->kind == v__ast__Kind__alias)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("operator "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" not defined on left operand type `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*left)); } else if (!v__ast__TypeSymbol_is_number(right_sym) && !v__ast__TypeSymbol_is_int(v__ast__Table_final_sym(c->table, left_type_unwrapped)) && !(left_sym->kind == v__ast__Kind__struct || left_sym->kind == v__ast__Kind__alias)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("operator "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" not defined on right operand type `"), 0xfe10, {.d_s = right_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } } else if (node->op == (v__token__Kind__and_assign) || node->op == (v__token__Kind__or_assign) || node->op == (v__token__Kind__xor_assign) || node->op == (v__token__Kind__mod_assign) || node->op == (v__token__Kind__left_shift_assign) || node->op == (v__token__Kind__right_shift_assign)) { if (!v__ast__TypeSymbol_is_int(left_sym) && !v__ast__TypeSymbol_is_int(v__ast__Table_final_sym(c->table, left_type_unwrapped))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("operator "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" not defined on left operand type `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*left)); } else if (!v__ast__TypeSymbol_is_int(right_sym) && !v__ast__TypeSymbol_is_int(v__ast__Table_final_sym(c->table, right_type_unwrapped))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("operator "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" not defined on right operand type `"), 0xfe10, {.d_s = right_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } } else if (node->op == (v__token__Kind__boolean_and_assign) || node->op == (v__token__Kind__boolean_or_assign)) { if (v__ast__Table_final_sym(c->table, left_type_unwrapped)->kind != v__ast__Kind__bool) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("operator "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" not defined on left operand type `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*left)); } else if (v__ast__Table_final_sym(c->table, right_type_unwrapped)->kind != v__ast__Kind__bool) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("operator "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" not defined on right operand type `"), 0xfe10, {.d_s = right_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } } else if (node->op == (v__token__Kind__unsigned_right_shift_assign)) { if (node->left.len != 1 || node->right.len != 1) { v__checker__Checker_error(c, _S("unsupported operation: unable to lower expression for unsigned shift assignment."), node->pos); } v__ast__Type _t15; /* if prepend */ if (!v__ast__Type_is_int(left_type)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid operation: shift on type `"), 0xfe10, {.d_s = v__ast__Table_sym(c->table, left_type)->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); _t15 = _const_v__ast__void_type; } else if (v__ast__Type_is_int_literal(left_type)) { _t15 = _const_v__ast__u32_type; } else if (v__ast__Type_is_unsigned(left_type)) { _t15 = left_type; } else { _t15 = v__ast__idx_to_type((int)((int)(v__ast__Type_idx(left_type) + 13) - 8)); } v__ast__Type modified_left_type = _t15; *node = ((v__ast__AssignStmt){ .op = v__token__Kind__assign, .pos = node->pos, .end_comments = node->end_comments, .right = new_array_from_c_array(1, 1, sizeof(v__ast__Expr), _MOV((v__ast__Expr[1]){v__ast__InfixExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__InfixExpr, (((v__ast__InfixExpr){ .op = v__token__Kind__right_shift, .pos = node->pos, .is_stmt = 0, .left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = modified_left_type,.expr = (*(v__ast__Expr*)array_get(node->left, 0)),.typname = v__ast__Table_type_str(c->table, modified_left_type),.expr_type = left_type,.has_arg = 0,.pos = node->pos,})))), .right = (*(v__ast__Expr*)array_get(node->right, 0)), .left_type = modified_left_type, .right_type = right_type, .promoted_type = _const_v__ast__void_type, .auto_locked = (string){.str=(byteptr)"", .is_lit=1}, .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .ct_left_value_evaled = 0, .ct_left_value = _const_v__ast__empty_comptime_const_value, .left_ct_expr = 0, .ct_right_value_evaled = 0, .ct_right_value = _const_v__ast__empty_comptime_const_value, .right_ct_expr = 0, .before_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .after_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)), }))))})), .left = node->left, .left_types = node->left_types, .right_types = node->right_types, .is_static = node->is_static, .is_volatile = 0, .is_simple = node->is_simple, .has_cross_var = node->has_cross_var, .attr = ((v__ast__Attr){.name = (string){.str=(byteptr)"", .is_lit=1},.has_arg = 0,.arg = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.ct_opt = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_at = 0,.ct_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.ct_evaled = 0,.ct_skip = 0,}), }); } else { } if ((node->op == v__token__Kind__plus_assign || node->op == v__token__Kind__minus_assign || node->op == v__token__Kind__mod_assign || node->op == v__token__Kind__mult_assign || node->op == v__token__Kind__div_assign) && (left_sym->kind == v__ast__Kind__alias || (left_sym->kind == v__ast__Kind__struct && right_sym->kind == v__ast__Kind__struct))) { string left_name = v__ast__Table_type_to_str(c->table, left_type_unwrapped); string right_name = v__ast__Table_type_to_str(c->table, right_type_unwrapped); v__ast__TypeSymbol* parent_sym = v__ast__Table_final_sym(c->table, left_type_unwrapped); if (left_sym->kind == v__ast__Kind__alias && right_sym->kind != v__ast__Kind__alias) { if (!v__ast__TypeSymbol_is_primitive(parent_sym)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } string _t16 = (string){.str=(byteptr)"", .is_lit=1}; if (node->op == (v__token__Kind__plus_assign)) { _t16 = _S("+"); } else if (node->op == (v__token__Kind__minus_assign)) { _t16 = _S("-"); } else if (node->op == (v__token__Kind__div_assign)) { _t16 = _S("/"); } else if (node->op == (v__token__Kind__mod_assign)) { _t16 = _S("%"); } else if (node->op == (v__token__Kind__mult_assign)) { _t16 = _S("*"); } else { _t16 = _S("unknown op"); }string extracted_op = _t16; if (left_sym->kind == v__ast__Kind__struct && (*(v__ast__Struct*)__as_cast((left_sym->info)._v__ast__Struct,(left_sym->info)._typ, 518)).generic_types.len > 0) { continue; } _option_v__ast__Fn _t17; if (_t17 = v__ast__TypeSymbol_find_method_with_generic_parent(left_sym, extracted_op), _t17.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t17.data; if (method.return_type != left_type_unwrapped) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("operator `"), 0xfe10, {.d_s = extracted_op}}, {_S("` must return `"), 0xfe10, {.d_s = left_name}}, {_S("` to be used as an assignment operator"), 0, { .d_c = 0 }}})), node->pos); } } else { IError err = _t17.err; _option_v__ast__Fn _t18; if (_t18 = v__ast__TypeSymbol_find_method_with_generic_parent(parent_sym, extracted_op), _t18.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t18.data; if (parent_sym->kind == v__ast__Kind__alias && (*(v__ast__Alias*)__as_cast((parent_sym->info)._v__ast__Alias,(parent_sym->info)._typ, 539)).parent_type != method.return_type) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("operator `"), 0xfe10, {.d_s = extracted_op}}, {_S("` must return `"), 0xfe10, {.d_s = left_name}}, {_S("` to be used as an assignment operator"), 0, { .d_c = 0 }}})), node->pos); } } else { IError err = _t18.err; if (!v__ast__TypeSymbol_is_primitive(parent_sym)) { if (string__eq(left_name, right_name)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("undefined operation `"), 0xfe10, {.d_s = left_name}}, {_S("` "), 0xfe10, {.d_s = extracted_op}}, {_S(" `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } } } } if (!is_blank_ident && right_sym->kind != v__ast__Kind__placeholder && left_sym->kind != v__ast__Kind__interface && ((!v__ast__Type_has_flag(right_type, v__ast__TypeFlag__generic) && !v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic)) || right_sym->kind != left_sym->kind)) { if ((left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed) && (v__ast__Type_is_voidptr(right_type_unwrapped) || v__ast__Expr_is_nil(right))) { string left_str = v__ast__Table_type_to_str(c->table, left_type_unwrapped); string right_str = v__ast__Table_type_to_str(c->table, right_type_unwrapped); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("cannot assign to `"), 0xfe10, {.d_s = v__ast__Expr_str(left)}}, {_S("`: expected `"), 0xfe10, {.d_s = left_str}}, {_S("`, not `"), 0xfe10, {.d_s = right_str}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } _result_void _t19 = v__checker__Checker_check_expected(c, right_type_unwrapped, left_type_unwrapped); if (_t19.is_error) { IError err = _t19.err; if (v__ast__Expr_is_auto_deref_var(*left) || v__ast__Expr_is_auto_deref_var(right)) { v__ast__Type left_deref = (v__ast__Expr_is_auto_deref_var(*left) ? (v__ast__Type_deref(left_type)) : (left_type)); v__ast__Type right_deref = (v__ast__Expr_is_pure_literal(right) ? (v__ast__Expr_get_pure_type(right)) : v__ast__Expr_is_auto_deref_var(right) ? (v__ast__Type_deref(right_type)) : (right_type)); if (v__checker__Checker_check_types(c, left_deref, right_deref)) { continue; } } if (v__ast__Type_is_ptr(left_type_unwrapped) && v__ast__Type_is_int(right_type_unwrapped) && (node->op == v__token__Kind__plus_assign || node->op == v__token__Kind__minus_assign)) { if (!c->inside_unsafe) { v__checker__Checker_warn(c, _S("pointer arithmetic is only allowed in `unsafe` blocks"), node->pos); } } else { if ((c->comptime->comptime_for_field_var).len != 0 && (left)->_typ == 350 /* v.ast.ComptimeSelector */) { v__ast__Type field_type = v__checker__Checker_unwrap_generic(c, c->comptime->comptime_for_field_type); v__ast__TypeSymbol* field_sym = v__ast__Table_sym(c->table, field_type); if (field_sym->kind == v__ast__Kind__enum && !v__ast__Type_is_int(right_type)) { v__checker__Checker_error(c, _S("enums can only be assigned `int` values"), v__ast__Expr_pos(right)); } if (!v__checker__Checker_check_types(c, field_type, right_type) && !(c->inside_x_matches_type || field_sym->kind == v__ast__Kind__enum)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot assign to `"), 0xfe10, {.d_s = v__ast__Expr_str(left)}}, {_S("`: "), 0xfe10, {.d_s = v__checker__Checker_expected_msg(c, right_type, field_type)}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } } else { if (right_type_unwrapped != _const_v__ast__void_type) { if (!var_option || (var_option && right_type_unwrapped != _const_v__ast__none_type)) { if (left_sym->kind == v__ast__Kind__array_fixed && right_sym->kind == v__ast__Kind__array && (right)._typ == 338 /* v.ast.ArrayInit */) { v__checker__Checker_add_error_detail(c, str_intp(3, _MOV((StrIntpData[]){{_S("try `"), 0xfe10, {.d_s = v__ast__Expr_str(left)}}, {_S(" = "), 0xfe10, {.d_s = v__ast__Expr_str(&right)}}, {_S("!` instead (with `!` after the array literal)"), 0, { .d_c = 0 }}}))); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot assign to `"), 0xfe10, {.d_s = v__ast__Expr_str(left)}}, {_S("`: "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot assign to `"), 0xfe10, {.d_s = v__ast__Expr_str(left)}}, {_S("`: "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_pos(right)); } } } } } ; } ; } if (left_sym->kind == v__ast__Kind__interface) { if (v__checker__Checker_type_implements(c, right_type, left_type, v__ast__Expr_pos(right))) { if (!v__ast__Type_is_any_kind_of_pointer(right_type) && right_sym->kind != v__ast__Kind__interface && !c->inside_unsafe) { v__checker__Checker_mark_as_referenced(c, &(*(v__ast__Expr*)array_get(node->right, i)), true); } } } if ((left_sym->info)._typ == 518 /* v.ast.Struct */ && !(*(v__ast__Struct*)__as_cast((left_sym->info)._v__ast__Struct,(left_sym->info)._typ, 518)).is_anon && (right)._typ == 385 /* v.ast.StructInit */ && (*(v__ast__StructInit*)__as_cast((right)._v__ast__StructInit,(right)._typ, 385)).is_anon) { v__checker__Checker_error(c, _S("cannot assign anonymous `struct` to a typed `struct`"), v__ast__Expr_pos(right)); } if (right_sym->kind == v__ast__Kind__alias && fast_string_eq(right_sym->name, _S("byte"))) { v__checker__Checker_error(c, _S("byte is deprecated, use u8 instead"), v__ast__Expr_pos(right)); } } if ((right_first)._typ == 376 /* v.ast.PrefixExpr */) { v__ast__PrefixExpr right_node = (*right_first._v__ast__PrefixExpr); bool is_amp = (*right_first._v__ast__PrefixExpr).op == v__token__Kind__amp; v__ast__Expr left_first = (*(v__ast__Expr*)array_get(node->left, 0)); if ((left_first)._typ == 358 /* v.ast.Ident */) { v__ast__Ident assigned_var = (*left_first._v__ast__Ident); bool is_shared = false; if (((*left_first._v__ast__Ident).info)._typ == 477 /* v.ast.IdentVar */) { is_shared = (*(*left_first._v__ast__Ident).info._v__ast__IdentVar).share == v__ast__ShareType__shared_t; } bool old_inside_ref_lit = c->inside_ref_lit; c->inside_ref_lit = c->inside_ref_lit || right_node.op == v__token__Kind__amp || is_shared; v__checker__Checker_expr(c, &right_node.right); c->inside_ref_lit = old_inside_ref_lit; if (right_node.op == v__token__Kind__amp) { v__ast__Expr expr = right_node.right; expr = v__ast__Expr_remove_par(&expr); if ((expr)._typ == 358 /* v.ast.Ident */) { if (((*expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { v__ast__Var v = (*(*expr._v__ast__Ident).obj._v__ast__Var); right_first_type = v.typ; } if (is_amp && !v__ast__Expr_is_blank_ident((*(v__ast__Expr*)array_get(node->left, 0))) && ((*expr._v__ast__Ident).obj)._typ == 420 /* v.ast.ConstField */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot have mutable reference to const `"), 0xfe10, {.d_s = (*expr._v__ast__Ident).name}}, {_S("`"), 0, { .d_c = 0 }}})), right_node.pos); } if (!c->inside_unsafe && v__ast__Ident_is_mut(&assigned_var) && !v__ast__Ident_is_mut(&(*expr._v__ast__Ident))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = (*expr._v__ast__Ident).name}}, {_S("` is immutable, cannot have a mutable reference to it"), 0, { .d_c = 0 }}})), right_node.pos); } } } if (right_node.op == v__token__Kind__arrow) { if (assigned_var.is_mut) { v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_first_type); if (right_sym->kind == v__ast__Kind__chan) { v__ast__Chan chan_info = v__ast__TypeSymbol_chan_info(right_sym); if (v__ast__Type_is_ptr(chan_info.elem_type) && !chan_info.is_mut) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot have a mutable reference to object from `"), 0xfe10, {.d_s = right_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), right_node.pos); } } } } } } if (node->left_types.len != node->left.len) { v__checker__Checker_error(c, _S("assign statement left type number mismatch"), node->pos); } // Defer begin if (v__checker__Checker_assign_stmt_defer_2) { c->anon_struct_should_be_mut = false; } // Defer end // Defer begin if (v__checker__Checker_assign_stmt_defer_1) { c->inside_recheck = old_recheck; } // Defer end // Defer begin if (v__checker__Checker_assign_stmt_defer_0) { c->expected_type = _const_v__ast__void_type; c->inside_assign = prev_inside_assign; } // Defer end } VV_LOC void v__checker__Checker_change_flags_if_comptime_expr(v__checker__Checker* c, v__ast__Ident* left, v__ast__Expr right) { if ((left->obj)._typ == 422 /* v.ast.Var */) { if ((right)._typ == 350 /* v.ast.ComptimeSelector */) { (*left->obj._v__ast__Var).typ = c->comptime->comptime_for_field_type; if ((*right._v__ast__ComptimeSelector).or_block.kind == v__ast__OrKind__propagate_option) { (*left->obj._v__ast__Var).typ = v__ast__Type_clear_flag((*left->obj._v__ast__Var).typ, v__ast__TypeFlag__option); (*left->obj._v__ast__Var).ct_type_unwrapped = true; } (*left->obj._v__ast__Var).ct_type_var = v__ast__ComptimeVarKind__field_var; } else if ((right)._typ == 362 /* v.ast.InfixExpr */) { v__ast__ComptimeVarKind right_ct_var = v__type_resolver__ResolverInfo_get_ct_type_var(c->comptime, (*right._v__ast__InfixExpr).left); if (right_ct_var != v__ast__ComptimeVarKind__no_comptime) { (*left->obj._v__ast__Var).ct_type_var = right_ct_var; } } else if ((right)._typ == 385 /* v.ast.StructInit */ && (*(v__ast__StructInit*)__as_cast((right)._v__ast__StructInit,(right)._typ, 385)).unresolved && v__ast__Type_has_flag((*(v__ast__StructInit*)__as_cast((right)._v__ast__StructInit,(right)._typ, 385)).typ, v__ast__TypeFlag__generic)) { (*left->obj._v__ast__Var).ct_type_var = v__ast__ComptimeVarKind__generic_param; } else if ((right)._typ == 361 /* v.ast.IndexExpr */ && v__type_resolver__ResolverInfo_is_comptime(c->comptime, v__ast__IndexExpr_to_sumtype_v__ast__Expr((v__ast__IndexExpr*)__as_cast((right)._v__ast__IndexExpr,(right)._typ, 361)))) { v__ast__ComptimeVarKind right_ct_var = v__type_resolver__ResolverInfo_get_ct_type_var(c->comptime, (*right._v__ast__IndexExpr).left); if (right_ct_var != v__ast__ComptimeVarKind__no_comptime) { (*left->obj._v__ast__Var).ct_type_var = right_ct_var; } } else if ((right)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((right)._v__ast__Ident,(right)._typ, 358)).obj)._typ == 422 /* v.ast.Var */ && (*(v__ast__Ident*)__as_cast((right)._v__ast__Ident,(right)._typ, 358)).or_expr.kind == v__ast__OrKind__absent) { v__ast__Var right_obj_var = (*(*right._v__ast__Ident).obj._v__ast__Var); if (right_obj_var.ct_type_var != v__ast__ComptimeVarKind__no_comptime) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(&c->type_resolver, right); if (ctyp != _const_v__ast__void_type) { (*left->obj._v__ast__Var).ct_type_var = right_obj_var.ct_type_var; (*left->obj._v__ast__Var).typ = ctyp; } } } else if ((right)._typ == 353 /* v.ast.DumpExpr */ && ((*(v__ast__DumpExpr*)__as_cast((right)._v__ast__DumpExpr,(right)._typ, 353)).expr)._typ == 350 /* v.ast.ComptimeSelector */) { (*left->obj._v__ast__Var).ct_type_var = v__ast__ComptimeVarKind__field_var; (*left->obj._v__ast__Var).typ = c->comptime->comptime_for_field_type; } else if ((right)._typ == 344 /* v.ast.CallExpr */) { if ((*right._v__ast__CallExpr).left_type != 0 && v__ast__Table_type_kind(c->table, (*right._v__ast__CallExpr).left_type) == v__ast__Kind__array && fast_string_eq((*right._v__ast__CallExpr).name, _S("map")) && (*right._v__ast__CallExpr).args.len > 0 && ((*(v__ast__CallArg*)array_get((*right._v__ast__CallExpr).args, 0)).expr)._typ == 339 /* v.ast.AsCast */ && v__ast__Type_has_flag((*(v__ast__AsCast*)__as_cast(((*(v__ast__CallArg*)array_get((*right._v__ast__CallExpr).args, 0)).expr)._v__ast__AsCast,((*(v__ast__CallArg*)array_get((*right._v__ast__CallExpr).args, 0)).expr)._typ, 339)).typ, v__ast__TypeFlag__generic)) { (*left->obj._v__ast__Var).ct_type_var = v__ast__ComptimeVarKind__generic_var; } else if (((*left->obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__generic_var || (*left->obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__no_comptime) && c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len != 0 && !(*right._v__ast__CallExpr).comptime_ret_val && v__type_resolver__TypeResolver_is_generic_expr(&c->type_resolver, right)) { (*left->obj._v__ast__Var).ct_type_var = v__ast__ComptimeVarKind__generic_var; } } else if ((right)._typ == 375 /* v.ast.PostfixExpr */ && (*(v__ast__PostfixExpr*)__as_cast((right)._v__ast__PostfixExpr,(right)._typ, 375)).op == v__token__Kind__question) { if (((*right._v__ast__PostfixExpr).expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*right._v__ast__PostfixExpr).expr)._v__ast__Ident,((*right._v__ast__PostfixExpr).expr)._typ, 358)).ct_expr) { v__ast__Var right_obj_var = *(v__ast__Var*)__as_cast(((*(*right._v__ast__PostfixExpr).expr._v__ast__Ident).obj)._v__ast__Var,((*(*right._v__ast__PostfixExpr).expr._v__ast__Ident).obj)._typ, 422); v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(&c->type_resolver, right); if (ctyp != _const_v__ast__void_type) { (*left->obj._v__ast__Var).ct_type_unwrapped = true; (*left->obj._v__ast__Var).ct_type_var = right_obj_var.ct_type_var; (*left->obj._v__ast__Var).typ = v__ast__Type_clear_flag(ctyp, v__ast__TypeFlag__option); } } else if (((*right._v__ast__PostfixExpr).expr)._typ == 350 /* v.ast.ComptimeSelector */) { (*left->obj._v__ast__Var).ct_type_unwrapped = true; (*left->obj._v__ast__Var).ct_type_var = v__ast__ComptimeVarKind__field_var; (*left->obj._v__ast__Var).typ = v__ast__Type_clear_flag(c->comptime->comptime_for_field_type, v__ast__TypeFlag__option); } } } } VV_LOC void v__checker__Checker_ident_autocomplete(v__checker__Checker* c, v__ast__Ident node) { println(string__plus(string__plus(str_intp(3, _MOV((StrIntpData[]){{_S("checker.ident() info.line_nr="), 0xfe07, {.d_i32 = c->pref->linfo.line_nr}}, {_S(" node.line_nr="), 0xfe07, {.d_i32 = node.pos.line_nr}}, {_S(" "), 0, { .d_c = 0 }}})), str_intp(3, _MOV((StrIntpData[]){{_S(" pwd=\""), 0xfe10, {.d_s = os__getwd()}}, {_S("\" file=\""), 0xfe10, {.d_s = c->file->path}}, {_S("\", "), 0, { .d_c = 0 }}}))), str_intp(4, _MOV((StrIntpData[]){{_S(" pref.linfo.path=\""), 0xfe10, {.d_s = c->pref->linfo.path}}, {_S("\" node.name=\""), 0xfe10, {.d_s = node.name}}, {_S("\" expr=\""), 0xfe10, {.d_s = c->pref->linfo.expr}}, {_S("\""), 0, { .d_c = 0 }}})))); bool same_line = (node.pos.line_nr == (int)(c->pref->linfo.line_nr - 1) || node.pos.line_nr == (int)(c->pref->linfo.line_nr + 1) || node.pos.line_nr == c->pref->linfo.line_nr); if (!same_line) { return; } bool same_name = string__eq(c->pref->linfo.expr, node.name); if (!same_name) { return; } string abs_path = os__join_path(os__getwd(), new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){c->file->path}))); if (!(string__eq(c->pref->linfo.path, c->file->path) || string__eq(c->pref->linfo.path, abs_path))) { return; } strings__Builder sb = strings__new_builder(10); if (node.kind == v__ast__IdentKind__unresolved) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("unresolved type, maybe \""), 0xfe10, {.d_s = node.name}}, {_S("\" was not defined. otherwise this is a bug, should never happen; please report"), 0, { .d_c = 0 }}}))); _v_exit(1); VUNREACHABLE(); } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, (*(node.obj.typ)))); string nt = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.name}}, {_S(":"), 0xfe10, {.d_s = sym->name}}, {_SLIT0, 0, { .d_c = 0 }}})); if (!(*(bool*)map_get(ADDR(map, c->pref->linfo.vars_printed), &(string[]){nt}, &(bool[]){ 0 }))) { strings__Builder_writeln(&sb, _S("===")); strings__Builder_writeln(&sb, str_intp(2, _MOV((StrIntpData[]){{_S("VAR "), 0xfe10, {.d_s = nt}}, {_SLIT0, 0, { .d_c = 0 }}}))); Array_v__checker__ACFieldMethod fields = __new_array_with_default(0, 10, sizeof(v__checker__ACFieldMethod), 0); if (sym->kind == v__ast__Kind__struct) { v__ast__Struct struct_info = *(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518); for (int _t1 = 0; _t1 < struct_info.fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)struct_info.fields.data)[_t1]; v__ast__TypeSymbol* field_sym = v__ast__Table_sym(c->table, field.typ); array_push((array*)&fields, _MOV((v__checker__ACFieldMethod[]){ ((v__checker__ACFieldMethod){.name = field.name,.typ = field_sym->name,}) })); } } else if (sym->kind == v__ast__Kind__array) { if ((sym->info)._typ == 537 /* v.ast.Aggregate */) { } else if ((sym->info)._typ == 513 /* v.ast.Array */) { array_push((array*)&fields, _MOV((v__checker__ACFieldMethod[]){ ((v__checker__ACFieldMethod){.name = _S("len"),.typ = _S("int"),}) })); array_push((array*)&fields, _MOV((v__checker__ACFieldMethod[]){ ((v__checker__ACFieldMethod){.name = _S("cap"),.typ = _S("int"),}) })); } } for (int _t5 = 0; _t5 < sym->methods.len; ++_t5) { v__ast__Fn method = ((v__ast__Fn*)sym->methods.data)[_t5]; v__ast__TypeSymbol* method_ret_type = v__ast__Table_sym(c->table, method.return_type); array_push((array*)&fields, _MOV((v__checker__ACFieldMethod[]){ ((v__checker__ACFieldMethod){.name = v__checker__build_method_summary(method),.typ = method_ret_type->name,}) })); } if (fields.len > 0) { qsort(fields.data, fields.len, fields.element_size, (voidptr)compare_11428131622760361090_v__checker__ACFieldMethod_by_name); } ; for (int _t7 = 0; _t7 < fields.len; ++_t7) { v__checker__ACFieldMethod field = ((v__checker__ACFieldMethod*)fields.data)[_t7]; strings__Builder_writeln(&sb, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = field.name}}, {_S(":"), 0xfe10, {.d_s = field.typ}}, {_SLIT0, 0, { .d_c = 0 }}}))); } string res = string_trim_space(strings__Builder_str(&sb)); if ((res).len != 0) { println(res); map_set(&c->pref->linfo.vars_printed, &(string[]){nt}, &(bool[]) { true }); } } } VV_LOC string v__checker__build_method_summary(v__ast__Fn method) { string s = string__plus(method.name, _S("(")); for (int i = 0; i < method.params.len; ++i) { v__ast__Param param = ((v__ast__Param*)method.params.data)[i]; s = string__plus(s, param.name); if (i < (int)(method.params.len - 1)) { s = string__plus(s, _S(",")); } } return string__plus(s, _S(")")); } VV_LOC bool v__checker__Checker_check_types(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected) { if (got == expected) { return true; } int exp_idx = v__ast__Type_idx(expected); int got_idx = v__ast__Type_idx(got); if (exp_idx == got_idx) { return true; } bool got_is_ptr = v__ast__Type_is_ptr(got); bool exp_is_ptr = v__ast__Type_is_ptr(expected); if ((got == _const_v__ast__int_literal_type && v__ast__Type_is_pure_int(expected)) || (expected == _const_v__ast__int_literal_type && v__ast__Type_is_pure_int(got))) { return true; } bool got_is_any_kind_of_pointer = v__ast__Type_is_any_kind_of_pointer(got); bool exp_is_any_kind_of_pointer = v__ast__Type_is_any_kind_of_pointer(expected); if (c->pref->translated) { bool got_is_int = v__ast__Type_is_int(got); bool exp_is_int = v__ast__Type_is_int(expected); if (exp_is_int && got_is_int) { return true; } if (expected == _const_v__ast__byteptr_type) { return true; } if (expected == _const_v__ast__voidptr_type || expected == _const_v__ast__nil_type) { return true; } if ((expected == _const_v__ast__bool_type && (got_is_int || got_is_any_kind_of_pointer)) || ((exp_is_int || exp_is_any_kind_of_pointer) && got == _const_v__ast__bool_type)) { return true; } if (exp_is_any_kind_of_pointer) { v__ast__Type deref = v__ast__Type_deref(expected); v__ast__TypeSymbol* got_sym = v__ast__Table_sym(c->table, got); if (v__ast__Type_is_number(deref) && (v__ast__TypeSymbol_is_number(got_sym) || got_sym->kind == v__ast__Kind__enum)) { return true; } } if ((expected == _const_v__ast__rune_type && got_is_int) || (got == _const_v__ast__rune_type && exp_is_int)) { return true; } v__ast__TypeSymbol* got_sym = v__ast__Table_sym(c->table, got); v__ast__TypeSymbol* expected_sym = v__ast__Table_sym(c->table, expected); if ((got_sym->info)._typ == 513 /* v.ast.Array */ && (expected_sym->info)._typ == 513 /* v.ast.Array */) { if (v__ast__Type_is_any_kind_of_pointer((*got_sym->info._v__ast__Array).elem_type) && v__ast__Type_is_any_kind_of_pointer((*expected_sym->info._v__ast__Array).elem_type)) { return true; } } else if ((got_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && (expected_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { if (v__ast__Type_is_any_kind_of_pointer((*got_sym->info._v__ast__ArrayFixed).elem_type) && v__ast__Type_is_any_kind_of_pointer((*expected_sym->info._v__ast__ArrayFixed).elem_type)) { return true; } if (v__checker__Checker_check_types(c, (*got_sym->info._v__ast__ArrayFixed).elem_type, (*expected_sym->info._v__ast__ArrayFixed).elem_type)) { return true; } } if (got_sym->kind == v__ast__Kind__enum) { if (v__ast__TypeSymbol_is_number(expected_sym)) { return true; } } else if (got_sym->kind == v__ast__Kind__array_fixed) { if (v__ast__TypeSymbol_is_number(expected_sym) || exp_is_any_kind_of_pointer) { return true; } } else if (expected_sym->kind == v__ast__Kind__array_fixed) { if (v__ast__TypeSymbol_is_number(got_sym) && got_is_any_kind_of_pointer) { return true; } else if (got_sym->kind == v__ast__Kind__array) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((expected_sym->info)._v__ast__ArrayFixed,(expected_sym->info)._typ, 549); v__ast__Array info2 = *(v__ast__Array*)__as_cast((got_sym->info)._v__ast__Array,(got_sym->info)._typ, 513); if (v__checker__Checker_check_types(c, info.elem_type, info2.elem_type)) { return true; } } } else if (got_sym->kind == v__ast__Kind__array) { if (v__ast__TypeSymbol_is_number(expected_sym) || exp_is_any_kind_of_pointer) { return true; } } else if (expected_sym->kind == v__ast__Kind__array) { if (v__ast__TypeSymbol_is_number(got_sym) && got_is_any_kind_of_pointer) { return true; } } if (expected_sym->kind == v__ast__Kind__enum && v__ast__TypeSymbol_is_number(got_sym)) { return true; } if (got_is_ptr && exp_is_ptr && v__ast__TypeSymbol_is_number(expected_sym) && v__ast__TypeSymbol_is_number(got_sym)) { return true; } } if (got_is_ptr && exp_is_ptr && v__ast__Type_nr_muls(got) != v__ast__Type_nr_muls(expected)) { return false; } if (got_is_any_kind_of_pointer && (exp_idx == 2 || exp_idx == 31 || exp_idx == 3 || (exp_is_ptr && v__ast__Type_idx(v__ast__Type_deref(expected)) == 11))) { return true; } if ((exp_idx == 31 && got_idx == 21) || (got_idx == 31 && exp_idx == 21)) { if (v__ast__Type_is_ptr(expected) || v__ast__Type_is_ptr(got)) { return true; } v__ast__TypeSymbol* got_sym = v__ast__Table_sym(c->table, got); v__ast__TypeSymbol* exp_sym = v__ast__Table_sym(c->table, expected); if (got_sym->language != v__ast__Language__c || exp_sym->language != v__ast__Language__c) { return false; } } if (exp_is_any_kind_of_pointer && got == _const_v__ast__int_literal_type) { return true; } if (exp_is_any_kind_of_pointer && (got_idx == 2 || got_idx == 31 || got_idx == 3 || (got_idx == 11 && got_is_ptr))) { return true; } if (expected == _const_v__ast__charptr_type && got == v__ast__Type_ref(_const_v__ast__char_type)) { return true; } if (v__ast__Type_has_option_or_result(expected)) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, got); if (((sym->idx == 30 || (got == _const_v__ast__none_type || got == _const_v__ast__error_type)) && v__ast__Type_has_flag(expected, v__ast__TypeFlag__option)) || ((sym->idx == 30 || got == _const_v__ast__error_type) && v__ast__Type_has_flag(expected, v__ast__TypeFlag__result))) { return true; } else if (!v__checker__Checker_check_basic(c, got, v__ast__Type_clear_option_and_result(expected))) { return false; } } if (!v__checker__Checker_check_basic(c, got, expected)) { return false; } if (v__ast__Type_is_number(got) && v__ast__Type_is_number(expected)) { if ((got == _const_v__ast__rune_type && expected == _const_v__ast__u8_type) || (expected == _const_v__ast__rune_type && got == _const_v__ast__u8_type)) { return true; } if (v__checker__Checker_promote_num(c, expected, got) != expected) { return false; } } if (v__ast__Type_has_flag(expected, v__ast__TypeFlag__generic) && !v__ast__Type_has_flag(got, v__ast__TypeFlag__generic)) { return false; } return true; } VV_LOC bool v__checker__Checker_check_multiple_ptr_match(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected, v__ast__Param param, v__ast__CallArg arg) { int param_nr_muls = (param.is_mut && !v__ast__Type_is_ptr(expected) ? (1) : (v__ast__Type_nr_muls(expected))); if (v__ast__Type_is_ptr(got) && v__ast__Type_nr_muls(got) > 1 && v__ast__Type_nr_muls(got) != param_nr_muls) { if ((arg.expr)._typ == 376 /* v.ast.PrefixExpr */ && (*(v__ast__PrefixExpr*)__as_cast((arg.expr)._v__ast__PrefixExpr,(arg.expr)._typ, 376)).op == v__token__Kind__amp) { return false; } if ((arg.expr)._typ == 388 /* v.ast.UnsafeExpr */) { v__ast__Expr expr = (*arg.expr._v__ast__UnsafeExpr).expr; if ((expr)._typ == 376 /* v.ast.PrefixExpr */ && (*(v__ast__PrefixExpr*)__as_cast((expr)._v__ast__PrefixExpr,(expr)._typ, 376)).op == v__token__Kind__amp) { return false; } } } return true; } VV_LOC _result_void v__checker__Checker_check_expected_call_arg(v__checker__Checker* c, v__ast__Type got_, v__ast__Type expected_, v__ast__Language language, v__ast__CallArg arg) { if (got_ == 0) { return (_result_void){ .is_error=true, .err=_v_error(_S("unexpected 0 type")), .data={E_STRUCT} }; } if (got_ == expected_) { return (_result_void){0}; } v__ast__Type expected = v__ast__Table_unaliased_type(c->table, expected_); bool is_aliased = expected != expected_; bool is_exp_sumtype = v__ast__Table_type_kind(c->table, expected_) == v__ast__Kind__sum_type; v__ast__Type got = v__ast__Table_unaliased_type(c->table, got_); if (v__ast__Type_has_flag(expected_, v__ast__TypeFlag__variadic)) { v__ast__TypeSymbol* exp_type_sym = v__ast__Table_sym(c->table, expected_); v__ast__Array exp_info = *(v__ast__Array*)__as_cast((exp_type_sym->info)._v__ast__Array,(exp_type_sym->info)._typ, 513); expected = exp_info.elem_type; } if (expected == got) { return (_result_void){0}; } bool got_is_ptr = v__ast__Type_is_ptr(got); bool exp_is_ptr = v__ast__Type_is_ptr(expected); if (language == v__ast__Language__c) { if (v__ast__Type_is_number(got) && v__ast__Type_is_number(expected)) { return (_result_void){0}; } if ((v__ast__Type_idx(got) == 19 && (Array_int_contains(new_array_from_c_array(2, 2, sizeof(int), _MOV((int[2]){_const_v__ast__int_type_idx, _const_v__ast__int_literal_type_idx})), v__ast__Type_idx(expected)))) || (v__ast__Type_idx(expected) == 19 && (Array_int_contains(new_array_from_c_array(2, 2, sizeof(int), _MOV((int[2]){_const_v__ast__int_type_idx, _const_v__ast__int_literal_type_idx})), v__ast__Type_idx(got))))) { return (_result_void){0}; } v__ast__TypeSymbol* exp_sym = v__ast__Table_sym(c->table, expected); if (exp_is_ptr && exp_sym->language == v__ast__Language__c && (exp_sym->kind == v__ast__Kind__placeholder || exp_sym->kind == v__ast__Kind__struct) && got == 8) { return (_result_void){0}; } } else { if (expected != _const_v__ast__voidptr_type && !exp_is_ptr && got_is_ptr && v__ast__Expr_is_reference(arg.expr)) { multi_return_string_string mr_7788 = v__checker__Checker_get_string_names_of(c, got_, expected_); string got_typ_str = mr_7788.arg0; string expected_typ_str = mr_7788.arg1; return (_result_void){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } if (v__ast__Type_has_flag(expected, v__ast__TypeFlag__option)) { bool is_ptr = got_is_ptr || ((arg.expr)._typ == 358 /* v.ast.Ident */ && v__ast__Ident_is_mut(((v__ast__Ident*)__as_cast((arg.expr)._v__ast__Ident,(arg.expr)._typ, 358)))) || (arg.expr)._typ == 371 /* v.ast.None */; if ((exp_is_ptr && !is_ptr) || (!exp_is_ptr && got_is_ptr)) { multi_return_string_string mr_8156 = v__checker__Checker_get_string_names_of(c, got_, expected_); string got_typ_str = mr_8156.arg0; string expected_typ_str = mr_8156.arg1; return (_result_void){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } if (arg.is_mut && v__ast__Type_nr_muls(expected) > 1 && v__ast__Type_nr_muls(got) < v__ast__Type_nr_muls(expected)) { multi_return_string_string mr_8458 = v__checker__Checker_get_string_names_of(c, got_, expected_); string got_typ_str = mr_8458.arg0; string expected_typ_str = mr_8458.arg1; return (_result_void){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } int exp_sym_idx = v__ast__Type_idx(expected); int got_sym_idx = v__ast__Type_idx(got); if (exp_is_ptr && got_is_ptr && exp_sym_idx != got_sym_idx && (exp_sym_idx == _const_v__ast__u8_type_idx || exp_sym_idx == _const_v__ast__byteptr_type_idx) && !(got_sym_idx == _const_v__ast__u8_type_idx || got_sym_idx == _const_v__ast__byteptr_type_idx)) { multi_return_string_string mr_8855 = v__checker__Checker_get_string_names_of(c, got_, expected_); string got_typ_str = mr_8855.arg0; string expected_typ_str = mr_8855.arg1; return (_result_void){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } bool is_expected_optional = (is_aliased ? (v__ast__Type_has_flag(expected_, v__ast__TypeFlag__option)) : (v__ast__Type_has_flag(expected, v__ast__TypeFlag__option))); if (!is_expected_optional && v__ast__Type_has_flag(got, v__ast__TypeFlag__option) && (!((arg.expr)._typ == 358 /* v.ast.Ident */ || (arg.expr)._typ == 350 /* v.ast.ComptimeSelector */) || ((arg.expr)._typ == 358 /* v.ast.Ident */ && v__type_resolver__ResolverInfo_get_ct_type_var(c->comptime, v__ast__Ident_to_sumtype_v__ast__Expr((v__ast__Ident*)__as_cast((arg.expr)._v__ast__Ident,(arg.expr)._typ, 358))) != v__ast__ComptimeVarKind__field_var))) { multi_return_string_string mr_9332 = v__checker__Checker_get_string_names_of(c, got_, expected_); string got_typ_str = mr_9332.arg0; string expected_typ_str = mr_9332.arg1; return (_result_void){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`, it must be unwrapped first"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } if (got == 28 && (Array_int_contains(_const_v__ast__unsigned_integer_type_idxs, expected)) && (arg.expr)._typ == 363 /* v.ast.IntegerLiteral */ && string_i64((*(v__ast__IntegerLiteral*)__as_cast((arg.expr)._v__ast__IntegerLiteral,(arg.expr)._typ, 363)).val) < 0) { string expected_typ_str = v__ast__Table_type_to_str(c->table, v__ast__Type_clear_flag(expected, v__ast__TypeFlag__variadic)); return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("cannot use literal signed integer as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } int idx_got = v__ast__Type_idx(got); int idx_expected = v__ast__Type_idx(expected); if ((idx_got == _const_v__ast__byteptr_type_idx || idx_got == _const_v__ast__charptr_type_idx) || (idx_expected == _const_v__ast__byteptr_type_idx || idx_expected == _const_v__ast__charptr_type_idx)) { int muls_got = v__ast__Type_nr_muls(got); int muls_expected = v__ast__Type_nr_muls(expected); if (idx_got == 3 && idx_expected == 11 && (int)(muls_got + 1) == muls_expected) { return (_result_void){0}; } if (idx_expected == 3 && idx_got == 11 && (int)(muls_expected + 1) == muls_got) { return (_result_void){0}; } if (idx_got == 4 && idx_expected == 18 && (int)(muls_got + 1) == muls_expected) { return (_result_void){0}; } if (idx_expected == 4 && idx_got == 18 && (int)(muls_expected + 1) == muls_got) { return (_result_void){0}; } } v__ast__Type exp_type = (!is_aliased || v__ast__Type_has_flag(expected_, v__ast__TypeFlag__variadic) ? (expected) : (expected_)); if (v__checker__Checker_check_types(c, (is_exp_sumtype ? (got_) : (got)), exp_type)) { if (language == v__ast__Language__v && idx_got == 2) { if (v__ast__Type_is_int_valptr(expected) || v__ast__Type_is_int(expected) || exp_is_ptr) { return (_result_void){0}; } v__ast__TypeSymbol* exp_sym = v__ast__Table_final_sym(c->table, expected); if (exp_sym->language == v__ast__Language__v && !(exp_sym->kind == v__ast__Kind__voidptr || exp_sym->kind == v__ast__Kind__charptr || exp_sym->kind == v__ast__Kind__byteptr || exp_sym->kind == v__ast__Kind__function || exp_sym->kind == v__ast__Kind__placeholder || exp_sym->kind == v__ast__Kind__array_fixed || exp_sym->kind == v__ast__Kind__sum_type || exp_sym->kind == v__ast__Kind__struct)) { multi_return_string_string mr_11104 = v__checker__Checker_get_string_names_of(c, got_, exp_type); string got_typ_str = mr_11104.arg0; string expected_typ_str = mr_11104.arg1; return (_result_void){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } } if (language != v__ast__Language__v || exp_is_ptr == got_is_ptr || arg.is_mut || v__ast__Expr_is_auto_deref_var(arg.expr) || v__ast__Type_has_flag(got, v__ast__TypeFlag__shared_f) || !(v__ast__Table_sym(c->table, expected_)->kind == v__ast__Kind__array || v__ast__Table_sym(c->table, expected_)->kind == v__ast__Kind__map)) { return (_result_void){0}; } } else { v__ast__TypeSymbol* got_typ_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, got)); v__ast__TypeSymbol* expected_typ_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, expected)); if (expected_typ_sym->kind == v__ast__Kind__interface && v__checker__Checker_type_implements(c, got, expected, ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}))) { return (_result_void){0}; } if (string__eq(v__ast__TypeSymbol_symbol_name_except_generic(got_typ_sym), v__ast__TypeSymbol_symbol_name_except_generic(expected_typ_sym))) { if (got_is_ptr != exp_is_ptr || !v__checker__Checker_check_same_module(c, got, expected) || (!got_is_ptr && !exp_is_ptr && !string__eq(got_typ_sym->name, expected_typ_sym->name))) { multi_return_string_string mr_12284 = v__checker__Checker_get_string_names_of(c, got_, exp_type); string got_typ_str = mr_12284.arg0; string expected_typ_str = mr_12284.arg1; return (_result_void){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } return (_result_void){0}; } if (got == _const_v__ast__void_type) { return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__ast__Expr_str(&arg.expr)}}, {_S("` (no value) used as value"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } if (expected == _const_v__ast__voidptr_type && got_typ_sym->kind == v__ast__Kind__array_fixed) { return (_result_void){0}; } multi_return_string_string mr_12625 = v__checker__Checker_get_string_names_of(c, got_, exp_type); string got_typ_str = mr_12625.arg0; string expected_typ_str = mr_12625.arg1; return (_result_void){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } if (got != _const_v__ast__void_type) { multi_return_string_string mr_12800 = v__checker__Checker_get_string_names_of(c, got_, exp_type); string got_typ_str = mr_12800.arg0; string expected_typ_str = mr_12800.arg1; return (_result_void){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } return (_result_void){0}; } VV_LOC multi_return_string_string v__checker__Checker_get_string_names_of(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected) { string got_typ_str = v__ast__Table_type_to_str(c->table, v__ast__Type_clear_flag(got, v__ast__TypeFlag__variadic)); string expected_typ_str = v__ast__Table_type_to_str(c->table, v__ast__Type_clear_flag(expected, v__ast__TypeFlag__variadic)); return (multi_return_string_string){.arg0=got_typ_str, .arg1=expected_typ_str}; } VV_LOC bool v__checker__Checker_check_same_module(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected) { string clean_got_typ = string_all_before(v__ast__Table_clean_generics_type_str(c->table, v__ast__Type_clear_flag(got, v__ast__TypeFlag__variadic)), _S("<")); string clean_expected_typ = string_all_before(v__ast__Table_clean_generics_type_str(c->table, v__ast__Type_clear_flag(expected, v__ast__TypeFlag__variadic)), _S("<")); if (string__eq(clean_got_typ, clean_expected_typ)) { return true; } else if (string__eq(string_all_after(clean_expected_typ, _S(".")), string_all_after(clean_got_typ, _S(".")))) { return true; } return false; } VV_LOC bool v__checker__Checker_check_basic(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected) { if (got == expected) { return true; } v__ast__Type unalias_got = v__ast__Table_unalias_num_type(c->table, got); v__ast__Type unalias_expected = v__ast__Table_unalias_num_type(c->table, expected); if (v__ast__Type_idx(unalias_got) == v__ast__Type_idx(unalias_expected)) { return true; } if ((v__ast__Type_is_pointer(unalias_expected) || v__ast__Type_is_number(unalias_expected)) && (v__ast__Type_is_pointer(unalias_got) || v__ast__Type_is_number(unalias_got))) { return true; } if (v__ast__Type_is_ptr(expected) && unalias_got == _const_v__ast__int_literal_type) { return true; } if ((v__ast__Type_idx(expected) == 23 && v__ast__Table_final_sym(c->table, got)->kind == v__ast__Kind__array) || (v__ast__Type_idx(got) == 23 && v__ast__Table_final_sym(c->table, expected)->kind == v__ast__Kind__array)) { return true; } v__ast__TypeSymbol* got_sym = v__ast__Table_sym(c->table, got); v__ast__TypeSymbol* exp_sym = v__ast__Table_sym(c->table, expected); if (exp_sym->kind == v__ast__Kind__multi_return && got_sym->kind == v__ast__Kind__multi_return) { Array_v__ast__Type exp_types = v__ast__TypeSymbol_mr_info(exp_sym).types; Array_v__ast__Type _t6 = {0}; Array_v__ast__Type _t6_orig = v__ast__TypeSymbol_mr_info(got_sym).types; int _t6_len = _t6_orig.len; _t6 = __new_array(0, _t6_len, sizeof(v__ast__Type)); for (int _t8 = 0; _t8 < _t6_len; ++_t8) { v__ast__Type it = ((v__ast__Type*) _t6_orig.data)[_t8]; v__ast__Type _t7 = v__ast__mktyp(it); array_push((array*)&_t6, &_t7); } Array_v__ast__Type got_types =_t6; if (exp_types.len != got_types.len) { return false; } for (int i = 0; i < exp_types.len; ++i) { if (!v__checker__Checker_check_types(c, (*(v__ast__Type*)array_get(got_types, i)), (*(v__ast__Type*)array_get(exp_types, i)))) { return false; } } return true; } if ((got_sym->kind == v__ast__Kind__array || got_sym->kind == v__ast__Kind__map || got_sym->kind == v__ast__Kind__array_fixed) && exp_sym->kind == got_sym->kind) { if (string__eq(v__ast__Table_type_to_str(c->table, got), string_trim(v__ast__Table_type_to_str(c->table, expected), _S("&")))) { return true; } } if (!v__ast__Type_is_ptr(unalias_got) && got_sym->kind == v__ast__Kind__array_fixed && v__ast__Type_is_any_kind_of_pointer(unalias_expected)) { return false; } if ((exp_sym->kind == v__ast__Kind__voidptr || exp_sym->kind == v__ast__Kind__any) || (got_sym->kind == v__ast__Kind__voidptr || got_sym->kind == v__ast__Kind__any)) { return true; } if (v__ast__Table_sumtype_has_variant(c->table, expected, v__ast__mktyp(got), false)) { return true; } if (exp_sym->kind == v__ast__Kind__struct && got_sym->kind == v__ast__Kind__struct) { if (string__eq(v__ast__Table_type_to_str(c->table, expected), v__ast__Table_type_to_str(c->table, got))) { return true; } } if ((got_sym->kind == v__ast__Kind__alias && got_sym->parent_idx == v__ast__Type_idx(expected)) || (exp_sym->kind == v__ast__Kind__alias && exp_sym->parent_idx == v__ast__Type_idx(got))) { return true; } if (got_sym->kind == v__ast__Kind__function && exp_sym->kind == v__ast__Kind__function) { return v__checker__Checker_check_matching_function_symbols(c, got_sym, exp_sym); } v__ast__Type expected_nonflagged = v__ast__Type_clear_flags(expected, __new_array(0, 0, sizeof(v__ast__TypeFlag))); if (got == _const_v__ast__int_literal_type && v__ast__Type_is_int(expected_nonflagged)) { return true; } if (got == _const_v__ast__float_literal_type && v__ast__Type_is_float(expected_nonflagged)) { return true; } if (got_sym->kind == v__ast__Kind__array && (exp_sym->info)._typ == 513 /* v.ast.Array */) { v__ast__TypeSymbol* exp_elem_sym = v__ast__Table_sym(c->table, (*exp_sym->info._v__ast__Array).elem_type); if ((exp_elem_sym->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* parent_elem_sym = v__ast__Table_sym(c->table, (*exp_elem_sym->info._v__ast__Alias).parent_type); if ((parent_elem_sym->info)._typ == 513 /* v.ast.Array */) { v__ast__Array array_info = v__ast__TypeSymbol_array_info(parent_elem_sym); int elem_type = v__ast__Table_find_or_register_array_with_dims(c->table, array_info.elem_type, (int)(array_info.nr_dims + (*exp_sym->info._v__ast__Array).nr_dims)); if (string__eq(v__ast__Table_type_to_str(c->table, got), v__ast__Table_type_to_str(c->table, v__ast__idx_to_type(elem_type)))) { return true; } } } } return false; } VV_LOC bool v__checker__Checker_check_matching_function_symbols(v__checker__Checker* c, v__ast__TypeSymbol* got_type_sym, v__ast__TypeSymbol* exp_type_sym) { if (c->pref->translated) { return true; } v__ast__FnType got_info = *(v__ast__FnType*)__as_cast((got_type_sym->info)._v__ast__FnType,(got_type_sym->info)._typ, 553); v__ast__FnType exp_info = *(v__ast__FnType*)__as_cast((exp_type_sym->info)._v__ast__FnType,(exp_type_sym->info)._typ, 553); v__ast__Fn got_fn = got_info.func; v__ast__Fn exp_fn = exp_info.func; if (got_fn.params.len != exp_fn.params.len) { return false; } if (v__ast__Type_has_flag(got_fn.return_type, v__ast__TypeFlag__option) != v__ast__Type_has_flag(exp_fn.return_type, v__ast__TypeFlag__option)) { return false; } if (v__ast__Type_has_flag(got_fn.return_type, v__ast__TypeFlag__result) != v__ast__Type_has_flag(exp_fn.return_type, v__ast__TypeFlag__result)) { return false; } if (!v__checker__Checker_check_basic(c, got_fn.return_type, exp_fn.return_type)) { return false; } if (v__ast__Table_final_sym(c->table, exp_fn.return_type)->kind == v__ast__Kind__sum_type && v__ast__Type_idx(got_fn.return_type) != v__ast__Type_idx(exp_fn.return_type)) { return false; } for (int i = 0; i < got_fn.params.len; ++i) { v__ast__Param got_arg = ((v__ast__Param*)got_fn.params.data)[i]; v__ast__Param exp_arg = (*(v__ast__Param*)array_get(exp_fn.params, i)); v__ast__Type exp_arg_typ = v__checker__Checker_unwrap_generic(c, exp_arg.typ); v__ast__Type got_arg_typ = v__checker__Checker_unwrap_generic(c, got_arg.typ); bool exp_arg_is_ptr = v__ast__Type_is_any_kind_of_pointer(exp_arg_typ); bool got_arg_is_ptr = v__ast__Type_is_any_kind_of_pointer(got_arg_typ); if (exp_arg.is_mut && !got_arg.is_mut) { return false; } if (exp_arg_is_ptr != got_arg_is_ptr) { string exp_arg_pointedness = (exp_arg_is_ptr ? (_S("a pointer")) : (_S("NOT a pointer"))); string got_arg_pointedness = (got_arg_is_ptr ? (_S("a pointer")) : (_S("NOT a pointer"))); if ((exp_fn.name).len == 0) { v__checker__Checker_add_error_detail(c, str_intp(5, _MOV((StrIntpData[]){{_S("expected argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to be "), 0xfe10, {.d_s = exp_arg_pointedness}}, {_S(", but the passed argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" is "), 0xfe10, {.d_s = got_arg_pointedness}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else { v__checker__Checker_add_error_detail(c, str_intp(6, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = exp_fn.name}}, {_S("`\'s expected argument `"), 0xfe10, {.d_s = exp_arg.name}}, {_S("` to be "), 0xfe10, {.d_s = exp_arg_pointedness}}, {_S(", but the passed argument `"), 0xfe10, {.d_s = got_arg.name}}, {_S("` is "), 0xfe10, {.d_s = got_arg_pointedness}}, {_SLIT0, 0, { .d_c = 0 }}}))); } return false; } else if (exp_arg_is_ptr && got_arg_is_ptr) { if (v__ast__Type_is_pointer(exp_arg_typ) || v__ast__Type_is_pointer(got_arg_typ)) { continue; } } if (v__ast__Type_idx(v__ast__Table_unaliased_type(c->table, got_arg_typ)) != v__ast__Type_idx(v__ast__Table_unaliased_type(c->table, exp_arg_typ))) { return false; } } return true; } VV_LOC v__ast__Type v__checker__Checker_check_shift(v__checker__Checker* c, v__ast__InfixExpr* node, v__ast__Type left_type_, v__ast__Type right_type_) { v__ast__Type left_type = v__checker__Checker_unwrap_generic(c, left_type_); v__ast__Type right_type = v__checker__Checker_unwrap_generic(c, right_type_); if (!v__ast__Type_is_int(left_type)) { v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, left_type); if (left_sym->kind == v__ast__Kind__alias && v__ast__Type_is_int((*(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 539)).parent_type)) { return left_type; } if (c->pref->translated && left_type == _const_v__ast__bool_type) { return _const_v__ast__int_type; } v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid operation: shift on type `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); return _const_v__ast__void_type; } if (!v__ast__Type_is_int(right_type) && !c->pref->translated) { v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, left_type); v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot shift non-integer type `"), 0xfe10, {.d_s = right_sym->name}}, {_S("` into type `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->right)); return _const_v__ast__void_type; } if (!node->ct_left_value_evaled) { _option_v__ast__ComptTimeConstValue _t5; if (_t5 = v__checker__Checker_eval_comptime_const_expr(c, node->left, 0), _t5.state == 0) { v__ast__ComptTimeConstValue lval = *(v__ast__ComptTimeConstValue*)_t5.data; node->ct_left_value_evaled = true; node->ct_left_value = lval; } } if (!node->ct_right_value_evaled) { _option_v__ast__ComptTimeConstValue _t6; if (_t6 = v__checker__Checker_eval_comptime_const_expr(c, node->right, 0), _t6.state == 0) { v__ast__ComptTimeConstValue rval = *(v__ast__ComptTimeConstValue*)_t6.data; node->ct_right_value_evaled = true; node->ct_right_value = rval; } } if (node->op == (v__token__Kind__left_shift) || node->op == (v__token__Kind__right_shift) || node->op == (v__token__Kind__unsigned_right_shift)) { v__ast__TypeSymbol* left_sym_final = v__ast__Table_final_sym(c->table, left_type); v__ast__Type left_type_final = v__ast__idx_to_type(left_sym_final->idx); if (!(c->is_generated || c->inside_unsafe || c->file->is_translated || c->pref->translated)) { if (node->op == v__token__Kind__left_shift && v__ast__Type_is_signed(left_type_final)) { v__checker__Checker_note(c, str_intp(2, _MOV((StrIntpData[]){{_S("shifting a value from a signed type `"), 0xfe10, {.d_s = left_sym_final->name}}, {_S("` can change the sign"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); } } if (node->ct_right_value_evaled) { if ((node->ct_right_value)._typ != 354 /* v.ast.EmptyExpr */) { _option_i64 _t7 = v__ast__ComptTimeConstValue_i64(node->ct_right_value); if (_t7.state != 0) { IError err = _t7.err; *(i64*) _t7.data = -999; } i64 ival = (*(i64*)_t7.data); if (ival < 0) { v__checker__Checker_error(c, _S("invalid negative shift count"), v__ast__Expr_pos(node->right)); return left_type; } int moffset = ((left_type_final == (_const_v__ast__char_type))? (7) : (left_type_final == (_const_v__ast__i8_type))? (7) : (left_type_final == (_const_v__ast__i16_type))? (15) : (left_type_final == (_const_v__ast__int_type))? (31) : (left_type_final == (_const_v__ast__i64_type))? (63) : (left_type_final == (_const_v__ast__u8_type))? (7) : (left_type_final == (_const_v__ast__u16_type))? (15) : (left_type_final == (_const_v__ast__u32_type))? (31) : (left_type_final == (_const_v__ast__u64_type))? (63) : (64)); if (ival > moffset && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("shift count for type `"), 0xfe10, {.d_s = left_sym_final->name}}, {_S("` too large (maximum: "), 0xfe07, {.d_i32 = moffset}}, {_S(" bits)"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->right)); return left_type; } if (!c->inside_unsafe) { if (node->ct_left_value_evaled) { _option_i64 _t10; if (_t10 = v__ast__ComptTimeConstValue_i64(node->ct_left_value), _t10.state == 0) { i64 lval = *(i64*)_t10.data; if (lval < 0) { v__checker__Checker_error(c, _S("invalid bitshift of a negative number"), v__ast__Expr_pos(node->left)); return left_type; } } } } } else { return left_type; } } } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown shift operator: "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); return left_type; } return left_type; } VV_LOC v__ast__Type v__checker__Checker_promote_keeping_aliases(v__checker__Checker* c, v__ast__Type left_type, v__ast__Type right_type, v__ast__Kind left_kind, v__ast__Kind right_kind) { if (left_type == right_type && left_kind == v__ast__Kind__alias && right_kind == v__ast__Kind__alias) { return left_type; } return v__checker__Checker_promote(c, left_type, right_type); } VV_LOC v__ast__Type v__checker__Checker_promote(v__checker__Checker* c, v__ast__Type left_type, v__ast__Type right_type) { if (left_type == right_type) { return left_type; } if (v__ast__Type_is_any_kind_of_pointer(left_type)) { if (v__ast__Type_is_int(right_type) || c->pref->translated) { return left_type; } else { return _const_v__ast__void_type; } } else if (v__ast__Type_is_any_kind_of_pointer(right_type)) { if (v__ast__Type_is_int(left_type) || c->pref->translated) { return right_type; } else { return _const_v__ast__void_type; } } if (v__ast__Type_is_number(right_type) && v__ast__Type_is_number(left_type)) { return v__checker__Checker_promote_num(c, left_type, right_type); } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option) != v__ast__Type_has_flag(right_type, v__ast__TypeFlag__option)) { return _const_v__ast__void_type; } else if ((left_type == _const_v__ast__void_type && right_type != _const_v__ast__void_type) || (right_type == _const_v__ast__void_type && left_type != _const_v__ast__void_type)) { return _const_v__ast__void_type; } else { return left_type; } return 0; } VV_LOC v__ast__Type v__checker__Checker_promote_num(v__checker__Checker* c, v__ast__Type left_type, v__ast__Type right_type) { v__ast__Type type_hi = left_type; v__ast__Type type_lo = right_type; if (v__ast__Type_idx(type_hi) < v__ast__Type_idx(type_lo)) { v__ast__Type _var_25570 = type_hi; v__ast__Type _var_25579 = type_lo; type_hi = _var_25579; type_lo = _var_25570; } int idx_hi = v__ast__Type_idx(type_hi); int idx_lo = v__ast__Type_idx(type_lo); if (idx_hi == 28) { return type_lo; } else if (idx_hi == 27) { if ((Array_int_contains(_const_v__ast__float_type_idxs, idx_lo))) { return type_lo; } else { return _const_v__ast__void_type; } } else if (v__ast__Type_is_float(type_hi)) { if (idx_hi == 16) { if (idx_lo == _const_v__ast__i64_type_idx || idx_lo == _const_v__ast__u64_type_idx) { return _const_v__ast__void_type; } else { return type_hi; } } else { return type_hi; } } else if (idx_lo >= 11) { return type_hi; } else if (idx_lo >= 5 && (idx_hi <= 10 || idx_hi == 22)) { return (idx_lo == 9 ? (type_lo) : (type_hi)); } else if (idx_hi == 11 && idx_lo > 5) { return type_lo; } else if (idx_hi == 12 && idx_lo > 6) { return type_lo; } else if (idx_hi == 13 && idx_lo > 8) { return type_lo; } else if (idx_hi == 14 && idx_lo >= 9) { return type_lo; } else if (idx_hi == 15 && idx_lo >= 10) { return type_lo; } else if (c->pref->translated) { return type_hi; } else { return _const_v__ast__void_type; } return 0; } VV_LOC _result_void v__checker__Checker_check_expected(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected) { if (!v__checker__Checker_check_types(c, got, expected)) { return (_result_void){ .is_error=true, .err=_v_error(v__checker__Checker_expected_msg(c, got, expected)), .data={E_STRUCT} }; } return (_result_void){0}; } VV_LOC string v__checker__Checker_expected_msg(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected) { string exps = v__ast__Table_type_to_str(c->table, expected); string gots = v__ast__Table_type_to_str(c->table, got); return str_intp(3, _MOV((StrIntpData[]){{_S("expected `"), 0xfe10, {.d_s = exps}}, {_S("`, not `"), 0xfe10, {.d_s = gots}}, {_S("`"), 0, { .d_c = 0 }}})); } VV_LOC bool v__checker__Checker_symmetric_check(v__checker__Checker* c, v__ast__Type left, v__ast__Type right) { if (v__ast__Type_is_any_kind_of_pointer(right)) { if (left == _const_v__ast__int_literal_type) { return true; } } if (v__ast__Type_is_any_kind_of_pointer(left)) { if (right == _const_v__ast__int_literal_type) { return true; } } return v__checker__Checker_check_basic(c, left, right); } VV_LOC Array_v__ast__Type v__checker__Checker_infer_struct_generic_types(v__checker__Checker* c, v__ast__Type typ, v__ast__StructInit node) { Array_v__ast__Type concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); if ((sym->info)._typ == 518 /* v.ast.Struct */) { Array_string _t1 = {0}; Array_v__ast__Type _t1_orig = (*sym->info._v__ast__Struct).generic_types; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t3]; string _t2 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t1, &_t2); } Array_string generic_names =_t1; gname: {} for (int _t4 = 0; _t4 < generic_names.len; ++_t4) { string gt_name = ((string*)generic_names.data)[_t4]; for (int _t5 = 0; _t5 < (*sym->info._v__ast__Struct).fields.len; ++_t5) { v__ast__StructField ft = ((v__ast__StructField*)(*sym->info._v__ast__Struct).fields.data)[_t5]; v__ast__TypeSymbol* field_sym = v__ast__Table_sym(c->table, ft.typ); if (string__eq(field_sym->name, gt_name)) { for (int _t6 = 0; _t6 < node.init_fields.len; ++_t6) { v__ast__StructInitField t = ((v__ast__StructInitField*)node.init_fields.data)[_t6]; if (string__eq(ft.name, t.name) && t.typ != 0) { array_push((array*)&concrete_types, _MOV((v__ast__Type[]){ v__ast__mktyp(t.typ) })); goto gname__continue; } } } if ((field_sym->info)._typ == 513 /* v.ast.Array */) { for (int _t8 = 0; _t8 < node.init_fields.len; ++_t8) { v__ast__StructInitField t = ((v__ast__StructInitField*)node.init_fields.data)[_t8]; if (string__eq(ft.name, t.name)) { v__ast__TypeSymbol* init_sym = v__ast__Table_sym(c->table, t.typ); if ((init_sym->info)._typ == 513 /* v.ast.Array */) { v__ast__Type init_elem_typ = (*init_sym->info._v__ast__Array).elem_type; v__ast__Type field_elem_typ = (*field_sym->info._v__ast__Array).elem_type; v__ast__TypeSymbol* init_elem_sym = v__ast__Table_sym(c->table, init_elem_typ); v__ast__TypeSymbol* field_elem_sym = v__ast__Table_sym(c->table, field_elem_typ); for (;;) { if ((init_elem_sym->info)._typ == 513 /* v.ast.Array */ && (field_elem_sym->info)._typ == 513 /* v.ast.Array */) { init_elem_typ = (*init_elem_sym->info._v__ast__Array).elem_type; field_elem_typ = (*field_elem_sym->info._v__ast__Array).elem_type; init_elem_sym = v__ast__Table_sym(c->table, init_elem_typ); field_elem_sym = v__ast__Table_sym(c->table, field_elem_typ); } else { if (string__eq(field_elem_sym->name, gt_name)) { v__ast__Type elem_typ = init_elem_typ; if (v__ast__Type_nr_muls(field_elem_typ) > 0 && v__ast__Type_nr_muls(elem_typ) > 0) { elem_typ = v__ast__Type_set_nr_muls(elem_typ, 0); } array_push((array*)&concrete_types, _MOV((v__ast__Type[]){ v__ast__mktyp(elem_typ) })); goto gname__continue; } break; } } } } } } else if ((field_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { for (int _t10 = 0; _t10 < node.init_fields.len; ++_t10) { v__ast__StructInitField t = ((v__ast__StructInitField*)node.init_fields.data)[_t10]; if (string__eq(ft.name, t.name)) { v__ast__TypeSymbol* init_sym = v__ast__Table_sym(c->table, t.typ); if ((init_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { v__ast__Type init_elem_typ = (*init_sym->info._v__ast__ArrayFixed).elem_type; v__ast__Type field_elem_typ = (*field_sym->info._v__ast__ArrayFixed).elem_type; v__ast__TypeSymbol* init_elem_sym = v__ast__Table_sym(c->table, init_elem_typ); v__ast__TypeSymbol* field_elem_sym = v__ast__Table_sym(c->table, field_elem_typ); for (;;) { if ((init_elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && (field_elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { init_elem_typ = (*init_elem_sym->info._v__ast__ArrayFixed).elem_type; field_elem_typ = (*field_elem_sym->info._v__ast__ArrayFixed).elem_type; init_elem_sym = v__ast__Table_sym(c->table, init_elem_typ); field_elem_sym = v__ast__Table_sym(c->table, field_elem_typ); } else { if (string__eq(field_elem_sym->name, gt_name)) { v__ast__Type elem_typ = init_elem_typ; if (v__ast__Type_nr_muls(field_elem_typ) > 0 && v__ast__Type_nr_muls(elem_typ) > 0) { elem_typ = v__ast__Type_set_nr_muls(elem_typ, 0); } array_push((array*)&concrete_types, _MOV((v__ast__Type[]){ v__ast__mktyp(elem_typ) })); goto gname__continue; } break; } } } } } } else if ((field_sym->info)._typ == 514 /* v.ast.Map */) { for (int _t12 = 0; _t12 < node.init_fields.len; ++_t12) { v__ast__StructInitField t = ((v__ast__StructInitField*)node.init_fields.data)[_t12]; if (string__eq(ft.name, t.name)) { v__ast__TypeSymbol* init_sym = v__ast__Table_sym(c->table, t.typ); if ((init_sym->info)._typ == 514 /* v.ast.Map */) { if (v__ast__Type_has_flag((*field_sym->info._v__ast__Map).key_type, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_sym(c->table, (*field_sym->info._v__ast__Map).key_type)->name, gt_name)) { v__ast__Type key_typ = (*init_sym->info._v__ast__Map).key_type; if (v__ast__Type_nr_muls((*field_sym->info._v__ast__Map).key_type) > 0 && v__ast__Type_nr_muls(key_typ) > 0) { key_typ = v__ast__Type_set_nr_muls(key_typ, 0); } array_push((array*)&concrete_types, _MOV((v__ast__Type[]){ v__ast__mktyp(key_typ) })); goto gname__continue; } if (v__ast__Type_has_flag((*field_sym->info._v__ast__Map).value_type, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_sym(c->table, (*field_sym->info._v__ast__Map).value_type)->name, gt_name)) { v__ast__Type val_typ = (*init_sym->info._v__ast__Map).value_type; if (v__ast__Type_nr_muls((*field_sym->info._v__ast__Map).value_type) > 0 && v__ast__Type_nr_muls(val_typ) > 0) { val_typ = v__ast__Type_set_nr_muls(val_typ, 0); } array_push((array*)&concrete_types, _MOV((v__ast__Type[]){ v__ast__mktyp(val_typ) })); goto gname__continue; } } } } } else if ((field_sym->info)._typ == 553 /* v.ast.FnType */) { for (int _t15 = 0; _t15 < node.init_fields.len; ++_t15) { v__ast__StructInitField t = ((v__ast__StructInitField*)node.init_fields.data)[_t15]; if (string__eq(ft.name, t.name)) { v__ast__TypeSymbol* init_sym = v__ast__Table_sym(c->table, t.typ); if ((init_sym->info)._typ == 553 /* v.ast.FnType */) { if ((*field_sym->info._v__ast__FnType).func.params.len == (*init_sym->info._v__ast__FnType).func.params.len) { for (int n = 0; n < (*field_sym->info._v__ast__FnType).func.params.len; ++n) { v__ast__Param fn_param = ((v__ast__Param*)(*field_sym->info._v__ast__FnType).func.params.data)[n]; if (v__ast__Type_has_flag(fn_param.typ, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_sym(c->table, fn_param.typ)->name, gt_name)) { v__ast__Type arg_typ = (*(v__ast__Param*)array_get((*init_sym->info._v__ast__FnType).func.params, n)).typ; if (v__ast__Type_nr_muls(fn_param.typ) > 0 && v__ast__Type_nr_muls(arg_typ) > 0) { arg_typ = v__ast__Type_set_nr_muls(arg_typ, 0); } array_push((array*)&concrete_types, _MOV((v__ast__Type[]){ v__ast__mktyp(arg_typ) })); goto gname__continue; } } if (v__ast__Type_has_flag((*field_sym->info._v__ast__FnType).func.return_type, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_sym(c->table, (*field_sym->info._v__ast__FnType).func.return_type)->name, gt_name)) { v__ast__Type ret_typ = (*init_sym->info._v__ast__FnType).func.return_type; if (v__ast__Type_nr_muls((*field_sym->info._v__ast__FnType).func.return_type) > 0 && v__ast__Type_nr_muls(ret_typ) > 0) { ret_typ = v__ast__Type_set_nr_muls(ret_typ, 0); } array_push((array*)&concrete_types, _MOV((v__ast__Type[]){ v__ast__mktyp(ret_typ) })); goto gname__continue; } } } } } } } v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("could not infer generic type `"), 0xfe10, {.d_s = gt_name}}, {_S("` in generic struct `"), 0xfe10, {.d_s = sym->name}}, {_S("["), 0xfe10, {.d_s = Array_string_join(generic_names, _S(", "))}}, {_S("]`"), 0, { .d_c = 0 }}})), node.pos); return concrete_types; gname__continue: {} } gname__break: {} } return concrete_types; } VV_LOC void v__checker__Checker_infer_fn_generic_types(v__checker__Checker* c, v__ast__Fn* func, v__ast__CallExpr* node) { Array_v__ast__Type inferred_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); Array_int arg_inferred = __new_array_with_default(0, 0, sizeof(int), 0); for (int gi = 0; gi < func->generic_names.len; ++gi) { string gt_name = ((string*)func->generic_names.data)[gi]; if (gi < node->concrete_types.len) { array_push((array*)&inferred_types, _MOV((v__ast__Type[]){ (*(v__ast__Type*)array_get(node->concrete_types, gi)) })); continue; } v__ast__Type typ = _const_v__ast__void_type; for (int i = 0; i < func->params.len; ++i) { v__ast__Param param = ((v__ast__Param*)func->params.data)[i]; if (node->is_method && i == 0 && v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* sym = v__ast__Table_final_sym(c->table, node->left_type); if (v__ast__Type_has_flag(node->left_type, v__ast__TypeFlag__generic)) { if (sym->info._typ == 518 /* v.ast.Struct */) { Array_string _t2 = {0}; Array_v__ast__Type _t2_orig = (*sym->info._v__ast__Struct).generic_types; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Type it = ((v__ast__Type*) _t2_orig.data)[_t4]; string _t3 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t2, &_t3); } Array_string receiver_generic_names =_t2; if ((Array_string_contains(receiver_generic_names, gt_name))) { int idx = Array_string_index(receiver_generic_names, gt_name); typ = (*(v__ast__Type*)array_get((*sym->info._v__ast__Struct).generic_types, idx)); } } else if (sym->info._typ == 542 /* v.ast.Interface */) { Array_string _t5 = {0}; Array_v__ast__Type _t5_orig = (*sym->info._v__ast__Interface).generic_types; int _t5_len = _t5_orig.len; _t5 = __new_array(0, _t5_len, sizeof(string)); for (int _t7 = 0; _t7 < _t5_len; ++_t7) { v__ast__Type it = ((v__ast__Type*) _t5_orig.data)[_t7]; string _t6 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t5, &_t6); } Array_string receiver_generic_names =_t5; if ((Array_string_contains(receiver_generic_names, gt_name))) { int idx = Array_string_index(receiver_generic_names, gt_name); typ = (*(v__ast__Type*)array_get((*sym->info._v__ast__Interface).generic_types, idx)); } } else if (sym->info._typ == 544 /* v.ast.SumType */) { Array_string _t8 = {0}; Array_v__ast__Type _t8_orig = (*sym->info._v__ast__SumType).generic_types; int _t8_len = _t8_orig.len; _t8 = __new_array(0, _t8_len, sizeof(string)); for (int _t10 = 0; _t10 < _t8_len; ++_t10) { v__ast__Type it = ((v__ast__Type*) _t8_orig.data)[_t10]; string _t9 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t8, &_t9); } Array_string receiver_generic_names =_t8; if ((Array_string_contains(receiver_generic_names, gt_name))) { int idx = Array_string_index(receiver_generic_names, gt_name); typ = (*(v__ast__Type*)array_get((*sym->info._v__ast__SumType).generic_types, idx)); } } else { } } else { if (sym->info._typ == 518 /* v.ast.Struct */) { if (c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len > 0) { if ((Array_string_contains(c->table->cur_fn->generic_names, gt_name)) && c->table->cur_fn->generic_names.len == c->table->cur_concrete_types.len) { int idx = Array_string_index(c->table->cur_fn->generic_names, gt_name); typ = (*(v__ast__Type*)array_get(c->table->cur_concrete_types, idx)); } } else { Array_string _t11 = {0}; Array_v__ast__Type _t11_orig = (*sym->info._v__ast__Struct).generic_types; int _t11_len = _t11_orig.len; _t11 = __new_array(0, _t11_len, sizeof(string)); for (int _t13 = 0; _t13 < _t11_len; ++_t13) { v__ast__Type it = ((v__ast__Type*) _t11_orig.data)[_t13]; string _t12 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t11, &_t12); } Array_string receiver_generic_names =_t11; if ((Array_string_contains(receiver_generic_names, gt_name)) && (*sym->info._v__ast__Struct).generic_types.len == (*sym->info._v__ast__Struct).concrete_types.len) { int idx = Array_string_index(receiver_generic_names, gt_name); typ = (*(v__ast__Type*)array_get((*sym->info._v__ast__Struct).concrete_types, idx)); } } } else if (sym->info._typ == 542 /* v.ast.Interface */) { if (c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len > 0) { if ((Array_string_contains(c->table->cur_fn->generic_names, gt_name)) && c->table->cur_fn->generic_names.len == c->table->cur_concrete_types.len) { int idx = Array_string_index(c->table->cur_fn->generic_names, gt_name); typ = (*(v__ast__Type*)array_get(c->table->cur_concrete_types, idx)); } } else { Array_string _t14 = {0}; Array_v__ast__Type _t14_orig = (*sym->info._v__ast__Interface).generic_types; int _t14_len = _t14_orig.len; _t14 = __new_array(0, _t14_len, sizeof(string)); for (int _t16 = 0; _t16 < _t14_len; ++_t16) { v__ast__Type it = ((v__ast__Type*) _t14_orig.data)[_t16]; string _t15 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t14, &_t15); } Array_string receiver_generic_names =_t14; if ((Array_string_contains(receiver_generic_names, gt_name)) && (*sym->info._v__ast__Interface).generic_types.len == (*sym->info._v__ast__Interface).concrete_types.len) { int idx = Array_string_index(receiver_generic_names, gt_name); typ = (*(v__ast__Type*)array_get((*sym->info._v__ast__Interface).concrete_types, idx)); } } } else if (sym->info._typ == 544 /* v.ast.SumType */) { if (c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len > 0) { if ((Array_string_contains(c->table->cur_fn->generic_names, gt_name)) && c->table->cur_fn->generic_names.len == c->table->cur_concrete_types.len) { int idx = Array_string_index(c->table->cur_fn->generic_names, gt_name); typ = (*(v__ast__Type*)array_get(c->table->cur_concrete_types, idx)); } } else { Array_string _t17 = {0}; Array_v__ast__Type _t17_orig = (*sym->info._v__ast__SumType).generic_types; int _t17_len = _t17_orig.len; _t17 = __new_array(0, _t17_len, sizeof(string)); for (int _t19 = 0; _t19 < _t17_len; ++_t19) { v__ast__Type it = ((v__ast__Type*) _t17_orig.data)[_t19]; string _t18 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t17, &_t18); } Array_string receiver_generic_names =_t17; if ((Array_string_contains(receiver_generic_names, gt_name)) && (*sym->info._v__ast__SumType).generic_types.len == (*sym->info._v__ast__SumType).concrete_types.len) { int idx = Array_string_index(receiver_generic_names, gt_name); typ = (*(v__ast__Type*)array_get((*sym->info._v__ast__SumType).concrete_types, idx)); } } } else { } } } int arg_i = (i != 0 && node->is_method ? ((int)(i - 1)) : (i)); if (node->args.len <= arg_i || typ != _const_v__ast__void_type) { break; } v__ast__CallArg arg = (*(v__ast__CallArg*)array_get(node->args, arg_i)); v__ast__TypeSymbol* param_sym = v__ast__Table_sym(c->table, param.typ); if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic) && string__eq(param_sym->name, gt_name)) { typ = v__ast__mktyp(arg.typ); v__ast__TypeSymbol* sym = v__ast__Table_final_sym(c->table, arg.typ); if ((sym->info)._typ == 553 /* v.ast.FnType */) { v__ast__Fn func_ = (*sym->info._v__ast__FnType).func; func_.name = _S(""); int idx = v__ast__Table_find_or_register_fn_type(c->table, func_, true, false); typ = v__ast__Type_derive(v__ast__new_type(idx), arg.typ); } else if ((c->comptime->comptime_for_field_var).len != 0 && (sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__any) && (arg.expr)._typ == 350 /* v.ast.ComptimeSelector */) { v__ast__Type comptime_typ = v__type_resolver__TypeResolver_get_comptime_selector_type(&c->type_resolver, (*arg.expr._v__ast__ComptimeSelector), _const_v__ast__void_type); if (comptime_typ != _const_v__ast__void_type) { typ = comptime_typ; if (v__ast__Type_has_flag(func->return_type, v__ast__TypeFlag__generic) && string__eq(gt_name, v__ast__Table_type_to_str(c->table, func->return_type))) { node->comptime_ret_val = true; } } } if (v__ast__Expr_is_auto_deref_var(arg.expr)) { typ = v__ast__Type_deref(typ); } if (v__ast__Type_nr_muls(param.typ) > 0 && v__ast__Type_nr_muls(typ) > 0) { typ = v__ast__Type_set_nr_muls(typ, 0); } } else if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { v__ast__Type arg_typ = (v__ast__Table_sym(c->table, arg.typ)->kind == v__ast__Kind__any ? (v__checker__Checker_unwrap_generic(c, arg.typ)) : (arg.typ)); v__ast__TypeSymbol* arg_sym = v__ast__Table_final_sym(c->table, arg_typ); if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__variadic)) { typ = v__ast__mktyp(arg_typ); } else if ((arg_sym->info)._typ == 513 /* v.ast.Array */ && (param_sym->info)._typ == 513 /* v.ast.Array */) { v__ast__Type arg_elem_typ = (*arg_sym->info._v__ast__Array).elem_type; v__ast__Type param_elem_typ = (*param_sym->info._v__ast__Array).elem_type; v__ast__TypeSymbol* arg_elem_sym = v__ast__Table_sym(c->table, arg_elem_typ); v__ast__TypeSymbol* param_elem_sym = v__ast__Table_sym(c->table, param_elem_typ); for (;;) { if ((arg_elem_sym->info)._typ == 513 /* v.ast.Array */ && (param_elem_sym->info)._typ == 513 /* v.ast.Array */ && c->table->cur_fn != ((void*)0) && !(Array_string_contains(c->table->cur_fn->generic_names, param_elem_sym->name))) { arg_elem_typ = (*arg_elem_sym->info._v__ast__Array).elem_type; param_elem_typ = (*param_elem_sym->info._v__ast__Array).elem_type; arg_elem_sym = v__ast__Table_sym(c->table, arg_elem_typ); param_elem_sym = v__ast__Table_sym(c->table, param_elem_typ); } else { if (string__eq(param_elem_sym->name, gt_name)) { typ = arg_elem_typ; if (v__ast__Type_nr_muls(param_elem_typ) > 0 && v__ast__Type_nr_muls(typ) > 0) { typ = v__ast__Type_set_nr_muls(typ, 0); } } break; } } } else if ((arg_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && (param_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { v__ast__Type arg_elem_typ = (*arg_sym->info._v__ast__ArrayFixed).elem_type; v__ast__Type param_elem_typ = (*param_sym->info._v__ast__ArrayFixed).elem_type; v__ast__TypeSymbol* arg_elem_sym = v__ast__Table_sym(c->table, arg_elem_typ); v__ast__TypeSymbol* param_elem_sym = v__ast__Table_sym(c->table, param_elem_typ); for (;;) { if ((arg_elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && (param_elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && c->table->cur_fn != ((void*)0) && !(Array_string_contains(c->table->cur_fn->generic_names, param_elem_sym->name))) { arg_elem_typ = (*arg_elem_sym->info._v__ast__ArrayFixed).elem_type; param_elem_typ = (*param_elem_sym->info._v__ast__ArrayFixed).elem_type; arg_elem_sym = v__ast__Table_sym(c->table, arg_elem_typ); param_elem_sym = v__ast__Table_sym(c->table, param_elem_typ); } else { if (string__eq(param_elem_sym->name, gt_name)) { typ = arg_elem_typ; if (v__ast__Type_nr_muls(param_elem_typ) > 0 && v__ast__Type_nr_muls(typ) > 0) { typ = v__ast__Type_set_nr_muls(typ, 0); } } break; } } } else if ((arg_sym->info)._typ == 514 /* v.ast.Map */ && (param_sym->info)._typ == 514 /* v.ast.Map */) { if (v__ast__Type_has_flag((*param_sym->info._v__ast__Map).key_type, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_sym(c->table, (*param_sym->info._v__ast__Map).key_type)->name, gt_name)) { typ = (*arg_sym->info._v__ast__Map).key_type; if (v__ast__Type_nr_muls((*param_sym->info._v__ast__Map).key_type) > 0 && v__ast__Type_nr_muls(typ) > 0) { typ = v__ast__Type_set_nr_muls(typ, 0); } } if (v__ast__Type_has_flag((*param_sym->info._v__ast__Map).value_type, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_sym(c->table, (*param_sym->info._v__ast__Map).value_type)->name, gt_name)) { typ = (*arg_sym->info._v__ast__Map).value_type; if (v__ast__Type_nr_muls((*param_sym->info._v__ast__Map).value_type) > 0 && v__ast__Type_nr_muls(typ) > 0) { typ = v__ast__Type_set_nr_muls(typ, 0); } } } else if ((arg_sym->info)._typ == 553 /* v.ast.FnType */ && (param_sym->info)._typ == 553 /* v.ast.FnType */) { if ((*param_sym->info._v__ast__FnType).func.params.len == (*arg_sym->info._v__ast__FnType).func.params.len) { for (int n = 0; n < (*param_sym->info._v__ast__FnType).func.params.len; ++n) { v__ast__Param fn_param = ((v__ast__Param*)(*param_sym->info._v__ast__FnType).func.params.data)[n]; if (v__ast__Type_has_flag(fn_param.typ, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_sym(c->table, fn_param.typ)->name, gt_name)) { typ = (*(v__ast__Param*)array_get((*arg_sym->info._v__ast__FnType).func.params, n)).typ; if (v__ast__Type_nr_muls(fn_param.typ) > 0 && v__ast__Type_nr_muls(typ) > 0) { typ = v__ast__Type_set_nr_muls(typ, 0); } } } if (v__ast__Type_has_flag((*param_sym->info._v__ast__FnType).func.return_type, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_sym(c->table, (*param_sym->info._v__ast__FnType).func.return_type)->name, gt_name)) { typ = (*arg_sym->info._v__ast__FnType).func.return_type; if (v__ast__Type_nr_muls((*param_sym->info._v__ast__FnType).func.return_type) > 0 && v__ast__Type_nr_muls(typ) > 0) { typ = v__ast__Type_set_nr_muls(typ, 0); } if ((arg.expr)._typ == 365 /* v.ast.LambdaExpr */ && v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { typ = v__type_resolver__TypeResolver_unwrap_generic_expr(&c->type_resolver, (*arg.expr._v__ast__LambdaExpr).expr, typ); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { string lambda_ret_gt_name = v__ast__Table_type_to_str(c->table, typ); int idx = Array_string_index(func->generic_names, lambda_ret_gt_name); if (idx < node->concrete_types.len) { typ = (*(v__ast__Type*)array_get(node->concrete_types, idx)); } else { typ = _const_v__ast__void_type; } } } } } } else if (arg_sym->kind == v__ast__Kind__struct || arg_sym->kind == v__ast__Kind__interface || arg_sym->kind == v__ast__Kind__sum_type) { Array_v__ast__Type generic_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); Array_v__ast__Type concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); if (arg_sym->info._typ == 518 /* v.ast.Struct */) { if (param_sym->generic_types.len > 0) { generic_types = array_clone_to_depth(¶m_sym->generic_types, 0); } else { generic_types = array_clone_to_depth(&(*arg_sym->info._v__ast__Struct).generic_types, 0); } concrete_types = array_clone_to_depth(&(*arg_sym->info._v__ast__Struct).concrete_types, 0); } else if (arg_sym->info._typ == 542 /* v.ast.Interface */) { if (param_sym->generic_types.len > 0) { generic_types = array_clone_to_depth(¶m_sym->generic_types, 0); } else { generic_types = array_clone_to_depth(&(*arg_sym->info._v__ast__Interface).generic_types, 0); } concrete_types = array_clone_to_depth(&(*arg_sym->info._v__ast__Interface).concrete_types, 0); } else if (arg_sym->info._typ == 544 /* v.ast.SumType */) { if (param_sym->generic_types.len > 0) { generic_types = array_clone_to_depth(¶m_sym->generic_types, 0); } else { generic_types = array_clone_to_depth(&(*arg_sym->info._v__ast__SumType).generic_types, 0); } concrete_types = array_clone_to_depth(&(*arg_sym->info._v__ast__SumType).concrete_types, 0); } else { } Array_string _t20 = {0}; Array_v__ast__Type _t20_orig = generic_types; int _t20_len = _t20_orig.len; _t20 = __new_array(0, _t20_len, sizeof(string)); for (int _t22 = 0; _t22 < _t20_len; ++_t22) { v__ast__Type it = ((v__ast__Type*) _t20_orig.data)[_t22]; string _t21 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t20, &_t21); } Array_string generic_names =_t20; if ((Array_string_contains(generic_names, gt_name)) && generic_types.len == concrete_types.len) { int idx = Array_string_index(generic_names, gt_name); typ = (*(v__ast__Type*)array_get(concrete_types, idx)); } } else if (arg_sym->kind == v__ast__Kind__any && c->table->cur_fn->generic_names.len > 0 && c->table->cur_fn->params.len > 0 && func->generic_names.len > 0 && (arg.expr)._typ == 358 /* v.ast.Ident */ && !(Array_int_contains(arg_inferred, arg_i))) { string var_name = (*arg.expr._v__ast__Ident).name; for (int k = 0; k < c->table->cur_fn->params.len; ++k) { v__ast__Param cur_param = ((v__ast__Param*)c->table->cur_fn->params.data)[k]; if (!v__ast__Type_has_flag(cur_param.typ, v__ast__TypeFlag__generic) || k < gi || !string__eq(cur_param.name, var_name)) { continue; } typ = cur_param.typ; v__ast__TypeSymbol* cparam_type_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, typ)); if (cparam_type_sym->kind == v__ast__Kind__array) { typ = v__type_resolver__TypeResolver_get_generic_array_element_type(&c->type_resolver, *(v__ast__Array*)__as_cast((cparam_type_sym->info)._v__ast__Array,(cparam_type_sym->info)._typ, 513)); } else if (cparam_type_sym->kind == v__ast__Kind__array_fixed) { typ = v__type_resolver__TypeResolver_get_generic_array_fixed_element_type(&c->type_resolver, *(v__ast__ArrayFixed*)__as_cast((cparam_type_sym->info)._v__ast__ArrayFixed,(cparam_type_sym->info)._typ, 549)); } typ = v__checker__Checker_unwrap_generic(c, typ); break; } } } if (typ != _const_v__ast__void_type) { array_push((array*)&arg_inferred, _MOV((int[]){ arg_i })); } } if (typ == _const_v__ast__void_type) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("could not infer generic type `"), 0xfe10, {.d_s = gt_name}}, {_S("` in call to `"), 0xfe10, {.d_s = func->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); return; } if (c->pref->is_verbose) { string s = v__ast__Table_type_to_str(c->table, typ); println(str_intp(3, _MOV((StrIntpData[]){{_S("inferred `"), 0xfe10, {.d_s = func->name}}, {_S("["), 0xfe10, {.d_s = s}}, {_S("]`"), 0, { .d_c = 0 }}}))); } array_push((array*)&inferred_types, _MOV((v__ast__Type[]){ v__checker__Checker_unwrap_generic(c, typ) })); array_push((array*)&node->concrete_types, _MOV((v__ast__Type[]){ typ })); } if (v__ast__Table_register_fn_concrete_types(c->table, v__ast__Fn_fkey(func), inferred_types)) { c->need_recheck_generic_fns = true; } } VV_LOC bool v__checker__Checker_is_contains_any_kind_of_pointer(v__checker__Checker* c, v__ast__Type typ, Array_v__ast__Type* checked_types) { if (v__ast__Type_is_any_kind_of_pointer(typ)) { return true; } if ((Array_v__ast__Type_contains(*checked_types, typ))) { return false; } array_push((array*)checked_types, _MOV((v__ast__Type[]){ typ })); v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); if (sym->info._typ == 513 /* v.ast.Array */) { return v__checker__Checker_is_contains_any_kind_of_pointer(c, (*sym->info._v__ast__Array).elem_type, checked_types); } else if (sym->info._typ == 549 /* v.ast.ArrayFixed */) { return v__checker__Checker_is_contains_any_kind_of_pointer(c, (*sym->info._v__ast__ArrayFixed).elem_type, checked_types); } else if (sym->info._typ == 514 /* v.ast.Map */) { return v__checker__Checker_is_contains_any_kind_of_pointer(c, (*sym->info._v__ast__Map).value_type, checked_types); } else if (sym->info._typ == 539 /* v.ast.Alias */) { return v__checker__Checker_is_contains_any_kind_of_pointer(c, (*sym->info._v__ast__Alias).parent_type, checked_types); } else if (sym->info._typ == 518 /* v.ast.Struct */) { if (sym->kind == v__ast__Kind__struct && sym->language == v__ast__Language__v) { Array_v__ast__StructField fields = v__ast__Table_struct_fields(c->table, sym); for (int _t8 = 0; _t8 < fields.len; ++_t8) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t8]; bool ret = v__checker__Checker_is_contains_any_kind_of_pointer(c, field.typ, checked_types); if (ret) { return true; } } } } else { } return false; } v__checker__Checker* v__checker__new_checker(v__ast__Table* table, v__pref__Preferences* pref_) { bool timers_should_print = false; #if defined(CUSTOM_DEFINE_time_checking) { timers_should_print = true; } #endif string _t2; /* if prepend */ if (pref_->building_v) { _result_string _t3 = v__util__version__githash(pref_->vroot); if (_t3.is_error) { IError err = _t3.err; vcurrent_hash(); } _t2 = (*(string*)_t3.data); } else { _t2 = vcurrent_hash(); } string v_current_commit_hash = _t2; v__checker__Checker* checker = ((v__checker__Checker*)memdup(&(v__checker__Checker){.pref = pref_,.table = table,.file = ((void*)0),.nr_errors = 0,.nr_warnings = 0,.nr_notices = 0,.errors = __new_array(0, 0, sizeof(v__errors__Error)),.warnings = __new_array(0, 0, sizeof(v__errors__Warning)),.notices = __new_array(0, 0, sizeof(v__errors__Notice)),.error_lines = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.warning_lines = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.notice_lines = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.error_details = __new_array(0, 0, sizeof(string)),.should_abort = 0,.expected_type = 0,.expected_or_type = 0,.expected_expr_type = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.const_var = ((void*)0),.const_deps = __new_array(0, 0, sizeof(string)),.const_names = __new_array(0, 0, sizeof(string)),.global_names = __new_array(0, 0, sizeof(string)),.locked_names = __new_array(0, 0, sizeof(string)),.rlocked_names = __new_array(0, 0, sizeof(string)),.in_for_count = 0,.returns = 0,.scope_returns = 0,.is_builtin_mod = 0,.is_just_builtin_mod = 0,.is_generated = 0,.unresolved_fixed_sizes = __new_array(0, 0, sizeof(v__ast__Stmt*)),.inside_recheck = 0,.inside_unsafe = 0,.inside_const = 0,.inside_anon_fn = 0,.inside_lambda = 0,.inside_ref_lit = 0,.inside_defer = 0,.inside_return = 0,.inside_fn_arg = 0,.inside_ct_attr = 0,.inside_x_is_type = 0,.inside_x_matches_type = 0,.anon_struct_should_be_mut = 0,.inside_generic_struct_init = 0,.inside_integer_literal_cast = 0,.cur_struct_generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.cur_struct_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.skip_flags = 0,.fn_level = 0,.smartcast_mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.smartcast_cond_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.ct_cond_stack = __new_array(0, 0, sizeof(v__ast__Expr)),.ct_user_defines = new_map(sizeof(string), sizeof(v__checker__ComptimeBranchSkipState), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.ct_system_defines = new_map(sizeof(string), sizeof(v__checker__ComptimeBranchSkipState), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.stmt_level = 0,.expr_level = 0,.type_level = 0,.ensure_generic_type_level = 0,.cur_orm_ts = ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.cname = (string){.str=(byteptr)"", .is_lit=1},.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,}),.cur_anon_fn = ((void*)0),.vmod_file_content = (string){.str=(byteptr)"", .is_lit=1},.loop_labels = __new_array(0, 0, sizeof(string)),.vweb_gen_types = __new_array(0, 0, sizeof(v__ast__Type)),.timers = v__util__new_timers(((v__util__TimerParams){.should_print = timers_should_print,.label = _S("checker"),})),.type_resolver = ((v__type_resolver__TypeResolver){.resolver = I_v__type_resolver__DummyResolver_to_Interface_v__type_resolver__IResolverType(((v__type_resolver__DummyResolver*)memdup(&(v__type_resolver__DummyResolver){.file = ((void*)0),}, sizeof(v__type_resolver__DummyResolver)))),.table = ((void*)0),.info = ((v__type_resolver__ResolverInfo){.saved_type_map = new_map(sizeof(string), sizeof(v__ast__Type), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.comptime_loop_id = 0,.inside_comptime_for = 0,.inside_comptime_if = 0,.has_different_types = 0,.comptime_for_variant_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_field_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_field_type = 0,.comptime_for_field_value = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.comptime_for_enum_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_attr_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_method_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_method = ((void*)0),.comptime_for_method_ret_type = 0,.comptime_for_method_param_var = (string){.str=(byteptr)"", .is_lit=1},}),.info_stack = __new_array(0, 0, sizeof(v__type_resolver__ResolverInfo)),.type_map = new_map(sizeof(string), sizeof(v__ast__Type), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}),.comptime = ((void*)0),.fn_scope = ((void*)0),.main_fn_decl_node = ((v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_method = 0,.is_static_type_method = 0,.static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_expand_simple_interpolation = 0,}),.match_exhaustive_cutoff_limit = pref_->checker_match_exhaustive_cutoff_limit,.is_last_stmt = 0,.prevent_sum_type_unwrapping_once = 0,.using_new_err_struct = 0,.need_recheck_generic_fns = 0,.generic_fns = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.inside_sql = 0,.inside_selector_expr = 0,.inside_or_block_value = 0,.inside_interface_deref = 0,.inside_decl_rhs = 0,.inside_if_guard = 0,.inside_assign = 0,.is_index_assign = 0,.comptime_call_pos = 0,.goto_labels = new_map(sizeof(string), sizeof(v__ast__GotoLabel), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.enum_data_type = 0,.field_data_type = 0,.variant_data_type = 0,.fn_return_type = 0,.orm_table_fields = new_map(sizeof(string), sizeof(Array_v__ast__StructField), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.v_current_commit_hash = v_current_commit_hash,.assign_stmt_attr = (string){.str=(byteptr)"", .is_lit=1},.js_string = _const_v__ast__void_type,}, sizeof(v__checker__Checker))); checker->type_resolver = *v__type_resolver__TypeResolver__static__new(table, HEAP(v__type_resolver__IResolverType, I_v__checker__Checker_to_Interface_v__type_resolver__IResolverType(checker))); checker->comptime = &checker->type_resolver.info; return checker; } VV_LOC void v__checker__Checker_reset_checker_state_at_start_of_new_file(v__checker__Checker* c) { c->expected_type = _const_v__ast__void_type; c->expected_or_type = _const_v__ast__void_type; c->const_var = ((void*)0); c->in_for_count = 0; c->returns = false; c->scope_returns = false; c->mod = _S(""); c->is_builtin_mod = false; c->is_just_builtin_mod = false; c->inside_unsafe = false; c->inside_const = false; c->inside_anon_fn = false; c->inside_ref_lit = false; c->inside_defer = false; c->inside_fn_arg = false; c->inside_ct_attr = false; c->inside_x_is_type = false; c->inside_x_matches_type = false; c->inside_integer_literal_cast = false; c->skip_flags = false; c->fn_level = 0; c->expr_level = 0; c->stmt_level = 0; c->inside_sql = false; c->cur_orm_ts = ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.cname = (string){.str=(byteptr)"", .is_lit=1},.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,}); c->prevent_sum_type_unwrapping_once = false; c->loop_labels = __new_array_with_default(0, 0, sizeof(string), 0); c->using_new_err_struct = false; c->inside_selector_expr = false; c->inside_interface_deref = false; c->inside_decl_rhs = false; c->inside_if_guard = false; array_clear(&c->error_details); } void v__checker__Checker_check(v__checker__Checker* c, v__ast__File* ast_file) { #if defined(CUSTOM_DEFINE_trace_checker) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("start checking file: "), 0xfe10, {.d_s = ast_file->path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__checker__Checker_reset_checker_state_at_start_of_new_file(c); v__checker__Checker_change_current_file(c, ast_file); for (int i = 0; i < ast_file->imports.len; ++i) { v__ast__Import ast_import = ((v__ast__Import*)ast_file->imports.data)[i]; if (string__eq(c->mod, ast_import.mod)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot import `"), 0xfe10, {.d_s = ast_import.mod}}, {_S("` into a module with the same name"), 0, { .d_c = 0 }}})), ast_import.mod_pos); } if (string__eq(c->mod, ast_import.alias)) { if (string__eq(c->mod, string_all_after_last(ast_import.mod, _S(".")))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot import `"), 0xfe10, {.d_s = ast_import.mod}}, {_S("` into a module with the same name"), 0, { .d_c = 0 }}})), ast_import.mod_pos); } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot import `"), 0xfe10, {.d_s = ast_import.mod}}, {_S("` as `"), 0xfe10, {.d_s = ast_import.alias}}, {_S("` into a module with the same name"), 0, { .d_c = 0 }}})), ast_import.alias_pos); } for (int _t2 = 0; _t2 < ast_import.syms.len; ++_t2) { v__ast__ImportSymbol sym = ((v__ast__ImportSymbol*)ast_import.syms.data)[_t2]; string full_name = string__plus(string__plus(ast_import.mod, _S(".")), sym.name); if ((Array_string_contains(c->const_names, full_name))) { v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("cannot selectively import constant `"), 0xfe10, {.d_s = sym.name}}, {_S("` from `"), 0xfe10, {.d_s = ast_import.mod}}, {_S("`, import `"), 0xfe10, {.d_s = ast_import.mod}}, {_S("` and use `"), 0xfe10, {.d_s = full_name}}, {_S("` instead"), 0, { .d_c = 0 }}})), sym.pos); } } string cmp_mod_name = (!string__eq(ast_import.mod, ast_import.alias) && !fast_string_eq(ast_import.alias, _S("_")) ? (ast_import.alias) : (ast_import.mod)); for (int j = 0; j < i; ++j) { if (string__eq(cmp_mod_name, (!string__eq((*(v__ast__Import*)array_get(ast_file->imports, j)).mod, (*(v__ast__Import*)array_get(ast_file->imports, j)).alias) && !fast_string_eq((*(v__ast__Import*)array_get(ast_file->imports, j)).alias, _S("_")) ? ((*(v__ast__Import*)array_get(ast_file->imports, j)).alias) : ((*(v__ast__Import*)array_get(ast_file->imports, j)).mod)))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("A module `"), 0xfe10, {.d_s = cmp_mod_name}}, {_S("` was already imported on line "), 0xfe07, {.d_i32 = (int)((*(v__ast__Import*)array_get(ast_file->imports, j)).mod_pos.line_nr + 1)}}, {_S("`."), 0, { .d_c = 0 }}})), ast_import.mod_pos); } } } c->stmt_level = 0; for (int _t3 = 0; _t3 < ast_file->stmts.len; ++_t3) { v__ast__Stmt* stmt = ((v__ast__Stmt*)ast_file->stmts.data) + _t3; if ((stmt)->_typ == 396 /* v.ast.ConstDecl */ || (stmt)->_typ == 401 /* v.ast.ExprStmt */) { c->expr_level = 0; v__checker__Checker_stmt(c, stmt); } if (c->should_abort) { return; } } c->stmt_level = 0; for (int _t4 = 0; _t4 < ast_file->stmts.len; ++_t4) { v__ast__Stmt* stmt = ((v__ast__Stmt*)ast_file->stmts.data) + _t4; if ((stmt)->_typ == 405 /* v.ast.GlobalDecl */) { c->expr_level = 0; v__checker__Checker_stmt(c, stmt); } if (c->should_abort) { return; } } c->stmt_level = 0; for (int _t5 = 0; _t5 < ast_file->stmts.len; ++_t5) { v__ast__Stmt* stmt = ((v__ast__Stmt*)ast_file->stmts.data) + _t5; if (!((stmt)->_typ == 396 /* v.ast.ConstDecl */ || (stmt)->_typ == 405 /* v.ast.GlobalDecl */ || (stmt)->_typ == 401 /* v.ast.ExprStmt */)) { c->expr_level = 0; v__checker__Checker_stmt(c, stmt); } if (c->should_abort) { return; } } v__checker__Checker_check_scope_vars(c, c->file->scope); v__checker__Checker_check_unused_labels(c); } void v__checker__Checker_check_scope_vars(v__checker__Checker* c, v__ast__Scope* sc) { if (!c->pref->is_repl && !c->file->is_test) { Map_string_v__ast__ScopeObject _t1 = sc->objects; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} v__ast__ScopeObject obj = (*(v__ast__ScopeObject*)DenseArray_value(&_t1.key_values, _t2)); if (obj._typ == 422 /* v.ast.Var */) { if (!(*obj._v__ast__Var).is_used && string_at((*obj._v__ast__Var).name, 0) != '_') { if (!c->pref->translated && !c->file->is_translated) { if ((*obj._v__ast__Var).is_arg) { if (c->pref->show_unused_params) { v__checker__Checker_note(c, str_intp(2, _MOV((StrIntpData[]){{_S("unused parameter: `"), 0xfe10, {.d_s = (*obj._v__ast__Var).name}}, {_S("`"), 0, { .d_c = 0 }}})), (*obj._v__ast__Var).pos); } } else { v__checker__Checker_warn(c, str_intp(2, _MOV((StrIntpData[]){{_S("unused variable: `"), 0xfe10, {.d_s = (*obj._v__ast__Var).name}}, {_S("`"), 0, { .d_c = 0 }}})), (*obj._v__ast__Var).pos); } } } if ((*obj._v__ast__Var).is_mut && !(*obj._v__ast__Var).is_changed && !c->is_builtin_mod && !fast_string_eq((*obj._v__ast__Var).name, _S("it"))) { } } else { } } } for (int _t5 = 0; _t5 < sc->children.len; ++_t5) { v__ast__Scope* child = ((v__ast__Scope**)sc->children.data)[_t5]; v__checker__Checker_check_scope_vars(c, child); } } void v__checker__Checker_change_current_file(v__checker__Checker* c, v__ast__File* file) { c->file = file; c->vmod_file_content = _S(""); c->mod = file->mod.name; c->is_generated = file->is_generated; } void v__checker__Checker_check_files(v__checker__Checker* c, Array_v__ast__File_ptr ast_files) { bool has_main_mod_file = false; bool has_no_main_mod_file = false; bool has_main_fn = false; { // Unsafe block Array_v__ast__File_ptr files_from_main_module = __new_array_with_default(0, 0, sizeof(v__ast__File*), 0); for (int i = 0; i < ast_files.len; ++i) { v__ast__File* file = (*(v__ast__File**)array_get(ast_files, i)); v__util__Timers_start(c->timers, str_intp(2, _MOV((StrIntpData[]){{_S("checker_check "), 0xfe10, {.d_s = file->path}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__checker__Checker_check(c, file); if (fast_string_eq(file->mod.name, _S("no_main"))) { has_no_main_mod_file = true; } if (fast_string_eq(file->mod.name, _S("main"))) { array_push((array*)&files_from_main_module, _MOV((v__ast__File*[]){ file })); has_main_mod_file = true; if (v__checker__Checker_file_has_main_fn(c, file)) { has_main_fn = true; } } v__util__Timers_show(c->timers, str_intp(2, _MOV((StrIntpData[]){{_S("checker_check "), 0xfe10, {.d_s = file->path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (has_main_mod_file && !has_main_fn && files_from_main_module.len > 0) { if (c->pref->is_script && !c->pref->is_test) { v__ast__File* the_main_file = (*(v__ast__File**)array_last(files_from_main_module)); array_push((array*)&the_main_file->stmts, _MOV((v__ast__Stmt[]){ v__ast__FnDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__FnDecl, (((v__ast__FnDecl){ .name = _S("main.main"), .short_name = (string){.str=(byteptr)"", .is_lit=1}, .mod = _S("main"), .is_deprecated = 0, .is_pub = 0, .is_c_variadic = 0, .is_c_extern = 0, .is_variadic = 0, .is_anon = 0, .is_noreturn = 0, .is_manualfree = 0, .is_main = true, .is_test = 0, .is_conditional = 0, .is_exported = 0, .is_keep_alive = 0, .is_unsafe = 0, .is_must_use = 0, .is_markused = 0, .is_file_translated = 0, .receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}), .receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_method = 0, .is_static_type_method = 0, .static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .method_idx = 0, .rec_mut = 0, .has_prev_newline = 0, .has_break_line = 0, .rec_share = 0, .language = 0, .file_mode = 0, .no_body = 0, .is_builtin = 0, .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .file = the_main_file->path, .generic_names = __new_array(0, 0, sizeof(string)), .is_direct_arr = 0, .attrs = __new_array(0, 0, sizeof(v__ast__Attr)), .ctdefine_idx = -1, .idx = 0, .params = __new_array(0, 0, sizeof(v__ast__Param)), .stmts = __new_array(0, 0, sizeof(v__ast__Stmt)), .defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)), .trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .return_type = _const_v__ast__void_type, .return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .has_return = 0, .should_be_skipped = 0, .ninstances = 0, .has_await = 0, .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .end_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .next_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .source_file = ((void*)0), .scope = ((v__ast__Scope*)memdup(&(v__ast__Scope){.objects = new_map(sizeof(string), sizeof(v__ast__ScopeObject), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.struct_fields = new_map(sizeof(string), sizeof(v__ast__ScopeStructField), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.parent = ((void*)0),.detached_from_parent = 0,.children = __new_array(0, 0, sizeof(v__ast__Scope*)),.start_pos = 0,.end_pos = 0,}, sizeof(v__ast__Scope))), .label_names = __new_array(0, 0, sizeof(string)), .pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_expand_simple_interpolation = 0, })))) })); has_main_fn = true; } } } v__util__Timers_start(c->timers, _S("checker_post_process_generic_fns")); v__ast__File* last_file = c->file; int post_process_generic_fns_iterations = 0; post_process_iterations_loop: for (;;) { if (!(post_process_generic_fns_iterations <= 1000000)) break; #if defined(CUSTOM_DEFINE_trace_post_process_generic_fns_loop) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">>>>>>>>> recheck_generic_fns loop iteration: "), 0xfe07, {.d_i32 = post_process_generic_fns_iterations}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif for (int _t4 = 0; _t4 < ast_files.len; ++_t4) { v__ast__File* file = ((v__ast__File**)ast_files.data)[_t4]; if (file->generic_fns.len > 0) { #if defined(CUSTOM_DEFINE_trace_post_process_generic_fns_loop) { Array_string _t6 = {0}; Array_v__ast__FnDecl_ptr _t6_orig = file->generic_fns; int _t6_len = _t6_orig.len; _t6 = __new_array(0, _t6_len, sizeof(string)); for (int _t8 = 0; _t8 < _t6_len; ++_t8) { v__ast__FnDecl* it = ((v__ast__FnDecl**) _t6_orig.data)[_t8]; string _t7 = it->name; array_push((array*)&_t6, &_t7); } eprintln(string__plus(str_intp(2, _MOV((StrIntpData[]){{_S(">> file.path: "), 0x50fe10, {.d_s = file->path}}, {_S(" | file.generic_fns:"), 0, { .d_c = 0 }}})), Array_string_str(_t6))); } #endif v__checker__Checker_change_current_file(c, file); _result_void _t9 = v__checker__Checker_post_process_generic_fns(c); if (_t9.is_error) { IError err = _t9.err; goto post_process_iterations_loop__break; } ; } } if (!c->need_recheck_generic_fns) { break; } c->need_recheck_generic_fns = false; post_process_generic_fns_iterations++; post_process_iterations_loop__continue: {} } post_process_iterations_loop__break: {} #if defined(CUSTOM_DEFINE_trace_post_process_generic_fns_loop) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">>>>>>>>> recheck_generic_fns loop done, iteration: "), 0xfe07, {.d_i32 = post_process_generic_fns_iterations}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__checker__Checker_change_current_file(c, last_file); v__util__Timers_show(c->timers, _S("checker_post_process_generic_fns")); v__util__Timers_start(c->timers, _S("checker_verify_all_vweb_routes")); v__checker__Checker_verify_all_vweb_routes(c); v__util__Timers_show(c->timers, _S("checker_verify_all_vweb_routes")); if (c->pref->is_test) { int n_test_fns = 0; Map_string_v__ast__Fn _t11 = c->table->fns; int _t13 = _t11.key_values.len; for (int _t12 = 0; _t12 < _t13; ++_t12 ) { int _t14 = _t11.key_values.len - _t13; _t13 = _t11.key_values.len; if (_t14 < 0) { _t12 = -1; continue; } if (!DenseArray_has_index(&_t11.key_values, _t12)) {continue;} v__ast__Fn f = (*(v__ast__Fn*)DenseArray_value(&_t11.key_values, _t12)); if (f.is_test) { n_test_fns++; } } if (n_test_fns == 0) { v__checker__Checker_add_error_detail(c, _S("The name of a test function in V, should start with `test_`.")); v__checker__Checker_add_error_detail(c, _S("The test function should take 0 parameters, and no return type. Example:")); v__checker__Checker_add_error_detail(c, _S("fn test_xyz(){ assert 2 + 2 == 4 }")); v__checker__Checker_error(c, _S("a _test.v file should have *at least* one `test_` function"), ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,})); } } if (!c->pref->linfo.is_running && (c->pref->line_info).len != 0) { println(string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("setting is_running=true, pref.path="), 0xfe10, {.d_s = c->pref->linfo.path}}, {_S(" curdir"), 0, { .d_c = 0 }}})), os__getwd())); c->pref->linfo.is_running = true; for (int i = 0; i < ast_files.len; ++i) { v__ast__File* file = ((v__ast__File**)ast_files.data)[i]; if (string__eq(file->path, c->pref->linfo.path)) { println(_S("running c.check_files")); v__checker__Checker_check_files(c, new_array_from_c_array(1, 1, sizeof(v__ast__File*), _MOV((v__ast__File*[1]){(*(v__ast__File**)array_get(ast_files, i))}))); _v_exit(0); VUNREACHABLE(); } else if (string_starts_with(file->path, _S("./"))) { string abs_path = string_replace(os__join_path(os__getwd(), new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){file->path}))), _S("/./"), _S("/")); if (string__eq(abs_path, c->pref->linfo.path)) { v__checker__Checker_check_files(c, new_array_from_c_array(1, 1, sizeof(v__ast__File*), _MOV((v__ast__File*[1]){(*(v__ast__File**)array_get(ast_files, i))}))); _v_exit(0); VUNREACHABLE(); } } } println(str_intp(2, _MOV((StrIntpData[]){{_S("failed to find file \""), 0xfe10, {.d_s = c->pref->linfo.path}}, {_S("\""), 0, { .d_c = 0 }}}))); _v_exit(0); VUNREACHABLE(); } if (c->pref->build_mode == v__pref__BuildMode__build_module || c->pref->is_test) { return; } if (c->pref->is_shared) { return; } if (c->pref->no_builtin) { return; } if (has_no_main_mod_file) { return; } if (!has_main_mod_file) { v__checker__Checker_error(c, _S("project must include a `main` module or be a shared library (compile with `v -shared`)"), ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,})); } else if (!has_main_fn && !c->pref->is_o) { v__checker__Checker_error(c, _S("function `main` must be declared in the main module"), ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,})); } } VV_LOC bool v__checker__Checker_file_has_main_fn(v__checker__Checker* c, v__ast__File* file) { bool has_main_fn = false; for (int _t1 = 0; _t1 < file->stmts.len; ++_t1) { v__ast__Stmt stmt = ((v__ast__Stmt*)file->stmts.data)[_t1]; if ((stmt)._typ == 237 /* v.ast.FnDecl */) { bool _t2 = fast_string_eq((*stmt._v__ast__FnDecl).name, _S("main.main")); bool _t3; if (!(_t2)) { _t3 = Array_v__ast__Attr_contains((*stmt._v__ast__FnDecl).attrs, _S("console")); } if (_t2) { if (has_main_fn) { v__checker__Checker_error(c, _S("function `main` is already defined"), (*stmt._v__ast__FnDecl).pos); } has_main_fn = true; if ((*stmt._v__ast__FnDecl).params.len > 0) { v__checker__Checker_error(c, _S("function `main` cannot have arguments"), (*stmt._v__ast__FnDecl).pos); } if ((*stmt._v__ast__FnDecl).return_type != _const_v__ast__void_type) { v__checker__Checker_error(c, _S("function `main` cannot return values"), (*stmt._v__ast__FnDecl).pos); } if ((*stmt._v__ast__FnDecl).no_body) { v__checker__Checker_error(c, _S("function `main` must declare a body"), (*stmt._v__ast__FnDecl).pos); } } else if (_t3) { v__checker__Checker_error(c, _S("only `main` can have the `@[console]` attribute"), (*stmt._v__ast__FnDecl).pos); } } } return has_main_fn; } VV_LOC void v__checker__Checker_check_valid_snake_case(v__checker__Checker* c, string name, string identifier, v__token__Pos pos) { if (c->pref->translated || c->file->is_translated) { return; } if (!c->pref->is_vweb && name.len > 1 && (name.str[ 0] == '_' || string_contains(name, _S("._")))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = identifier}}, {_S(" `"), 0xfe10, {.d_s = name}}, {_S("` cannot start with `_`"), 0, { .d_c = 0 }}})), pos); } if (v__util__contains_capital(name)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = identifier}}, {_S(" `"), 0xfe10, {.d_s = name}}, {_S("` cannot contain uppercase letters, use snake_case instead"), 0, { .d_c = 0 }}})), pos); } } VV_LOC string v__checker__stripped_name(string name) { _option_int _t1 = string_last_index(name, _S(".")); if (_t1.state != 0) { IError err = _t1.err; *(int*) _t1.data = -1; } int idx = (*(int*)_t1.data); return string_substr(name, ((int)(idx + 1)), 2147483647); } VV_LOC void v__checker__Checker_check_valid_pascal_case(v__checker__Checker* c, string name, string identifier, v__token__Pos pos) { if (c->pref->translated || c->file->is_translated) { return; } string sname = v__checker__stripped_name(name); if (sname.len > 0 && !u8_is_capital(string_at(sname, 0))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = identifier}}, {_S(" `"), 0xfe10, {.d_s = name}}, {_S("` must begin with capital letter"), 0, { .d_c = 0 }}})), pos); } } VV_LOC void v__checker__Checker_type_decl(v__checker__Checker* c, v__ast__TypeDecl* node) { if ((*(node->typ)) == _const_v__ast__invalid_type && ((node)->_typ == 331 /* v.ast.AliasTypeDecl */ || (node)->_typ == 333 /* v.ast.SumTypeDecl */)) { string typ_desc = ((node)->_typ == 331 /* v.ast.AliasTypeDecl */ ? (_S("alias")) : (_S("sum type"))); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot register "), 0xfe10, {.d_s = typ_desc}}, {_S(" `"), 0xfe10, {.d_s = (*(node->name))}}, {_S("`, another type with this name exists"), 0, { .d_c = 0 }}})), (*(node->pos))); return; } if (node->_typ == 331 /* v.ast.AliasTypeDecl */) { v__checker__Checker_alias_type_decl(c, &/*mut*/(*node->_v__ast__AliasTypeDecl)); } else if (node->_typ == 332 /* v.ast.FnTypeDecl */) { v__checker__Checker_fn_type_decl(c, &/*mut*/(*node->_v__ast__FnTypeDecl)); } else if (node->_typ == 333 /* v.ast.SumTypeDecl */) { v__checker__Checker_sum_type_decl(c, &/*mut*/(*node->_v__ast__SumTypeDecl)); } } VV_LOC void v__checker__Checker_alias_type_decl(v__checker__Checker* c, v__ast__AliasTypeDecl* node) { if (!fast_string_eq(c->file->mod.name, _S("builtin")) && !string_starts_with(node->name, _S("C."))) { v__checker__Checker_check_valid_pascal_case(c, node->name, _S("type alias"), node->pos); } if (!v__checker__Checker_ensure_type_exists(c, node->parent_type, node->type_pos)) { return; } v__ast__TypeSymbol* parent_typ_sym = v__ast__Table_sym(c->table, node->parent_type); if (v__ast__Type_has_flag(node->parent_type, v__ast__TypeFlag__result)) { v__checker__Checker_add_error_detail(c, _S("Result types cannot be stored and have to be unwrapped immediately")); v__checker__Checker_error(c, _S("cannot make an alias of Result type"), node->type_pos); } switch (parent_typ_sym->kind) { case v__ast__Kind__placeholder: case v__ast__Kind__int_literal: case v__ast__Kind__float_literal: case v__ast__Kind__any: { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown aliased type `"), 0xfe10, {.d_s = parent_typ_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->type_pos); break; } case v__ast__Kind__alias: { v__ast__TypeSymbol* orig_sym = v__ast__Table_sym(c->table, (*(v__ast__Alias*)__as_cast((parent_typ_sym->info)._v__ast__Alias,(parent_typ_sym->info)._typ, 539)).parent_type); if (!string_starts_with(node->name, _S("C."))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("type `"), 0xfe10, {.d_s = v__ast__TypeSymbol_str(parent_typ_sym)}}, {_S("` is an alias, use the original alias type `"), 0xfe10, {.d_s = orig_sym->name}}, {_S("` instead"), 0, { .d_c = 0 }}})), node->type_pos); } break; } case v__ast__Kind__chan: { v__checker__Checker_error(c, _S("aliases of `chan` types are not allowed"), node->type_pos); break; } case v__ast__Kind__thread: { v__checker__Checker_error(c, _S("aliases of `thread` types are not allowed"), node->type_pos); break; } case v__ast__Kind__multi_return: { v__checker__Checker_error(c, _S("aliases of function multi return types are not allowed"), node->type_pos); break; } case v__ast__Kind__void: { v__checker__Checker_error(c, _S("aliases of the void type are not allowed"), node->type_pos); break; } case v__ast__Kind__function: { string orig_sym = v__ast__Table_type_to_str(c->table, node->parent_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("type `"), 0xfe10, {.d_s = v__ast__TypeSymbol_str(parent_typ_sym)}}, {_S("` is an alias, use the original alias type `"), 0xfe10, {.d_s = orig_sym}}, {_S("` instead"), 0, { .d_c = 0 }}})), node->type_pos); break; } case v__ast__Kind__struct: { if ((parent_typ_sym->info)._typ == 518 /* v.ast.Struct */) { for (int _t1 = 0; _t1 < (*parent_typ_sym->info._v__ast__Struct).concrete_types.len; ++_t1) { v__ast__Type ct = ((v__ast__Type*)(*parent_typ_sym->info._v__ast__Struct).concrete_types.data)[_t1]; v__ast__TypeSymbol* ct_sym = v__ast__Table_sym(c->table, ct); if (ct_sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = ct_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->type_pos); } } if ((*parent_typ_sym->info._v__ast__Struct).is_generic && (*parent_typ_sym->info._v__ast__Struct).concrete_types.len == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = parent_typ_sym->name}}, {_S(" type is generic struct, must specify the generic type names, e.g. "), 0xfe10, {.d_s = parent_typ_sym->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), node->type_pos); } for (int _t2 = 0; _t2 < (*parent_typ_sym->info._v__ast__Struct).embeds.len; ++_t2) { v__ast__Type embed_type = ((v__ast__Type*)(*parent_typ_sym->info._v__ast__Struct).embeds.data)[_t2]; v__ast__TypeSymbol* final_embed_sym = v__ast__Table_final_sym(c->table, embed_type); if (final_embed_sym->kind != v__ast__Kind__struct) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot embed non-struct `"), 0xfe10, {.d_s = v__ast__Table_sym(c->table, embed_type)->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->type_pos); } } if ((*parent_typ_sym->info._v__ast__Struct).is_anon) { for (int _t3 = 0; _t3 < (*parent_typ_sym->info._v__ast__Struct).fields.len; ++_t3) { v__ast__StructField field = ((v__ast__StructField*)(*parent_typ_sym->info._v__ast__Struct).fields.data)[_t3]; bool is_embed = false; v__ast__TypeSymbol* field_sym = v__ast__Table_sym(c->table, field.typ); if ((field_sym->info)._typ == 539 /* v.ast.Alias */) { if (v__ast__Table_sym(c->table, (*field_sym->info._v__ast__Alias).parent_type)->kind != v__ast__Kind__struct) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot embed non-struct `"), 0xfe10, {.d_s = field_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), field.type_pos); is_embed = true; } } if (!is_embed) { v__checker__Checker_check_valid_snake_case(c, field.name, _S("field name"), field.pos); } } } } break; } case v__ast__Kind__array: { v__checker__Checker_check_alias_vs_element_type_of_parent(c, *node, (*(v__ast__Array*)__as_cast((parent_typ_sym->info)._v__ast__Array,(parent_typ_sym->info)._typ, 513)).elem_type, _S("array")); break; } case v__ast__Kind__array_fixed: { v__ast__ArrayFixed array_fixed_info = *(v__ast__ArrayFixed*)__as_cast((parent_typ_sym->info)._v__ast__ArrayFixed,(parent_typ_sym->info)._typ, 549); if (v__checker__Checker_array_fixed_has_unresolved_size(c, (voidptr)&array_fixed_info)) { array_push((array*)&c->unresolved_fixed_sizes, _MOV((v__ast__Stmt*[]){ HEAP(v__ast__Stmt, v__ast__TypeDecl_to_sumtype_v__ast__Stmt(HEAP(v__ast__TypeDecl, v__ast__AliasTypeDecl_to_sumtype_v__ast__TypeDecl(node)))) })); } v__checker__Checker_check_alias_vs_element_type_of_parent(c, *node, array_fixed_info.elem_type, _S("fixed array")); break; } case v__ast__Kind__map: { v__ast__Map info = *(v__ast__Map*)__as_cast((parent_typ_sym->info)._v__ast__Map,(parent_typ_sym->info)._typ, 514); v__checker__Checker_check_alias_vs_element_type_of_parent(c, *node, info.key_type, _S("map key")); v__checker__Checker_check_alias_vs_element_type_of_parent(c, *node, info.value_type, _S("map value")); v__checker__Checker_markused_used_maps(c, c->table->used_features->used_maps == 0); break; } case v__ast__Kind__sum_type: { break; } case v__ast__Kind__none: { v__checker__Checker_error(c, _S("cannot create a type alias of `none` as it is a value"), node->type_pos); break; } case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__i32: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__isize: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__usize: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__bool: case v__ast__Kind__string: case v__ast__Kind__generic_inst: case v__ast__Kind__enum: case v__ast__Kind__interface: case v__ast__Kind__aggregate: default: { { v__checker__Checker_check_any_type(c, node->parent_type, parent_typ_sym, node->type_pos); break; } } } } VV_LOC void v__checker__Checker_check_alias_vs_element_type_of_parent(v__checker__Checker* c, v__ast__AliasTypeDecl node, v__ast__Type element_type_of_parent, string label) { if (v__ast__Type_idx(node.typ) != v__ast__Type_idx(element_type_of_parent)) { return; } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("recursive declarations of aliases are not allowed - the alias `"), 0xfe10, {.d_s = node.name}}, {_S("` is used in the "), 0xfe10, {.d_s = label}}, {_SLIT0, 0, { .d_c = 0 }}})), node.type_pos); } VV_LOC void v__checker__Checker_check_any_type(v__checker__Checker* c, v__ast__Type typ, v__ast__TypeSymbol* sym, v__token__Pos pos) { if (sym->kind == v__ast__Kind__any && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic) && sym->language != v__ast__Language__js && !fast_string_eq(c->file->mod.name, _S("builtin"))) { v__checker__Checker_error(c, _S("cannot use type `any` here"), pos); } } VV_LOC void v__checker__Checker_fn_type_decl(v__checker__Checker* c, v__ast__FnTypeDecl* node) { v__checker__Checker_check_valid_pascal_case(c, node->name, _S("fn type"), node->pos); v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, node->typ); v__ast__FnType fn_typ_info = *(v__ast__FnType*)__as_cast((typ_sym->info)._v__ast__FnType,(typ_sym->info)._typ, 553); v__ast__Fn fn_info = fn_typ_info.func; v__checker__Checker_ensure_type_exists(c, fn_info.return_type, fn_info.return_type_pos); v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, fn_info.return_type); if (ret_sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = ret_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), fn_info.return_type_pos); } for (int _t1 = 0; _t1 < fn_info.params.len; ++_t1) { v__ast__Param arg = ((v__ast__Param*)fn_info.params.data)[_t1]; if (!v__checker__Checker_ensure_type_exists(c, arg.typ, arg.type_pos)) { return; } v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(c->table, arg.typ); if (arg_sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = arg_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), arg.type_pos); } } } VV_LOC void v__checker__Checker_sum_type_decl(v__checker__Checker* c, v__ast__SumTypeDecl* node) { v__checker__Checker_check_valid_pascal_case(c, node->name, _S("sum type"), node->pos); Array_string names_used = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < node->variants.len; ++_t1) { v__ast__TypeNode variant = ((v__ast__TypeNode*)node->variants.data)[_t1]; v__checker__Checker_ensure_type_exists(c, variant.typ, variant.pos); v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, variant.typ); if (v__ast__Type_is_ptr(variant.typ) || ((sym->info)._typ == 539 /* v.ast.Alias */ && v__ast__Type_is_ptr((*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type))) { string variant_name = string_all_after_last(sym->name, _S(".")); multi_return_string_string mr_27487 = (sym->kind == v__ast__Kind__struct ? ((multi_return_string_string){.arg0=_S("{"),.arg1=_S("}")}) : ((multi_return_string_string){.arg0=_S("("),.arg1=_S(")")})); string lb = mr_27487.arg0; string rb = mr_27487.arg1; string msg = ((sym->info)._typ == 539 /* v.ast.Alias */ && v__ast__Type_is_ptr((*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type) ? (_S("alias as non-reference type")) : (_S("the sum type with non-reference types"))); v__checker__Checker_add_error_detail(c, str_intp(8, _MOV((StrIntpData[]){{_S("declare "), 0xfe10, {.d_s = msg}}, {_S(": `"), 0xfe10, {.d_s = node->name}}, {_S(" = "), 0xfe10, {.d_s = variant_name}}, {_S(" | ...`\nand use a reference to the sum type instead: `var := &"), 0xfe10, {.d_s = node->name}}, {_S("("), 0xfe10, {.d_s = variant_name}}, {_SLIT0, 0xfe10, {.d_s = lb}}, {_S("val"), 0xfe10, {.d_s = rb}}, {_S(")`"), 0, { .d_c = 0 }}}))); v__checker__Checker_error(c, _S("sum type cannot hold a reference type"), variant.pos); } string variant_name = v__ast__Table_type_to_str(c->table, variant.typ); if ((Array_string_contains(names_used, variant_name))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("sum type "), 0xfe10, {.d_s = node->name}}, {_S(" cannot hold the type `"), 0xfe10, {.d_s = sym->name}}, {_S("` more than once"), 0, { .d_c = 0 }}})), variant.pos); } else if (sym->kind == v__ast__Kind__placeholder || sym->kind == v__ast__Kind__int_literal || sym->kind == v__ast__Kind__float_literal) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), variant.pos); } else if (sym->kind == v__ast__Kind__interface && sym->language != v__ast__Language__js) { v__checker__Checker_error(c, _S("sum type cannot hold an interface"), variant.pos); } else if (sym->kind == v__ast__Kind__struct && sym->language == v__ast__Language__js) { v__checker__Checker_error(c, _S("sum type cannot hold a JS struct"), variant.pos); } else if ((sym->info)._typ == 518 /* v.ast.Struct */) { if ((*sym->info._v__ast__Struct).is_generic) { if (!v__ast__Type_has_flag(variant.typ, v__ast__TypeFlag__generic)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic struct `"), 0xfe10, {.d_s = sym->name}}, {_S("` must specify generic type names, e.g. "), 0xfe10, {.d_s = sym->name}}, {_S("[T]"), 0, { .d_c = 0 }}})), variant.pos); } if (node->generic_types.len == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic sumtype `"), 0xfe10, {.d_s = node->name}}, {_S("` must specify generic type names, e.g. "), 0xfe10, {.d_s = node->name}}, {_S("[T]"), 0, { .d_c = 0 }}})), node->name_pos); } else { for (int _t2 = 0; _t2 < (*sym->info._v__ast__Struct).generic_types.len; ++_t2) { v__ast__Type typ = ((v__ast__Type*)(*sym->info._v__ast__Struct).generic_types.data)[_t2]; if (!(Array_v__ast__Type_contains(node->generic_types, typ))) { Array_string _t3 = {0}; Array_v__ast__Type _t3_orig = node->generic_types; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(string)); for (int _t5 = 0; _t5 < _t3_len; ++_t5) { v__ast__Type it = ((v__ast__Type*) _t3_orig.data)[_t5]; string _t4 = v__ast__Table_type_to_str(c->table, it); array_push((array*)&_t3, &_t4); } string sumtype_type_names = Array_string_join(_t3, _S(", ")); string generic_sumtype_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->name}}, {_S("["), 0xfe10, {.d_s = sumtype_type_names}}, {_S("]"), 0, { .d_c = 0 }}})); Array_string _t6 = {0}; Array_v__ast__Type _t6_orig = (*sym->info._v__ast__Struct).generic_types; int _t6_len = _t6_orig.len; _t6 = __new_array(0, _t6_len, sizeof(string)); for (int _t8 = 0; _t8 < _t6_len; ++_t8) { v__ast__Type it = ((v__ast__Type*) _t6_orig.data)[_t8]; string _t7 = v__ast__Table_type_to_str(c->table, it); array_push((array*)&_t6, &_t7); } string variant_type_names = Array_string_join(_t6, _S(", ")); string generic_variant_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sym->name}}, {_S("["), 0xfe10, {.d_s = variant_type_names}}, {_S("]"), 0, { .d_c = 0 }}})); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("generic type name `"), 0xfe10, {.d_s = v__ast__Table_sym(c->table, typ)->name}}, {_S("` of generic struct `"), 0xfe10, {.d_s = generic_variant_name}}, {_S("` is not mentioned in sumtype `"), 0xfe10, {.d_s = generic_sumtype_name}}, {_S("`"), 0, { .d_c = 0 }}})), variant.pos); } } } } } else if ((sym->info)._typ == 553 /* v.ast.FnType */) { if ((*sym->info._v__ast__FnType).func.generic_names.len > 0) { if (!v__ast__Type_has_flag(variant.typ, v__ast__TypeFlag__generic)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic fntype `"), 0xfe10, {.d_s = sym->name}}, {_S("` must specify generic type names, e.g. "), 0xfe10, {.d_s = sym->name}}, {_S("[T]"), 0, { .d_c = 0 }}})), variant.pos); } if (node->generic_types.len == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic sumtype `"), 0xfe10, {.d_s = node->name}}, {_S("` must specify generic type names, e.g. "), 0xfe10, {.d_s = node->name}}, {_S("[T]"), 0, { .d_c = 0 }}})), node->name_pos); } } if (string_ends_with(v__ast__Table_sym(c->table, (*sym->info._v__ast__FnType).func.return_type)->name, str_intp(2, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("sum type `"), 0xfe10, {.d_s = node->name}}, {_S("` cannot be defined recursively"), 0, { .d_c = 0 }}})), variant.pos); } for (int _t9 = 0; _t9 < (*sym->info._v__ast__FnType).func.params.len; ++_t9) { v__ast__Param param = ((v__ast__Param*)(*sym->info._v__ast__FnType).func.params.data)[_t9]; if (string_ends_with(v__ast__Table_sym(c->table, param.typ)->name, str_intp(2, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("sum type `"), 0xfe10, {.d_s = node->name}}, {_S("` cannot be defined recursively"), 0, { .d_c = 0 }}})), variant.pos); } } } else if (v__ast__Type_has_flag(variant.typ, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("sum type cannot hold a Result type"), variant.pos); } v__checker__Checker_check_any_type(c, variant.typ, sym, variant.pos); if (string__eq(string_trim_string_left(sym->name, string__plus(sym->mod, _S("."))), node->name)) { v__checker__Checker_error(c, _S("sum type cannot hold itself"), variant.pos); } array_push((array*)&names_used, _MOV((string[]){ string_clone(variant_name) })); } } VV_LOC Array_v__ast__InterfaceEmbedding v__checker__Checker_expand_iface_embeds(v__checker__Checker* c, v__ast__InterfaceDecl* idecl, int level, Array_v__ast__InterfaceEmbedding iface_embeds) { if (level > 100) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("too many interface embedding levels: "), 0xfe07, {.d_i32 = level}}, {_S(", for interface `"), 0xfe10, {.d_s = idecl->name}}, {_S("`"), 0, { .d_c = 0 }}})), idecl->pos); return __new_array_with_default(0, 0, sizeof(v__ast__InterfaceEmbedding), 0); } if (iface_embeds.len == 0) { return __new_array_with_default(0, 0, sizeof(v__ast__InterfaceEmbedding), 0); } Map_int_v__ast__InterfaceEmbedding res = new_map(sizeof(int), sizeof(v__ast__InterfaceEmbedding), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop) ; Array_v__ast__InterfaceEmbedding ares = __new_array_with_default(0, 0, sizeof(v__ast__InterfaceEmbedding), 0); for (int _t3 = 0; _t3 < iface_embeds.len; ++_t3) { v__ast__InterfaceEmbedding ie = ((v__ast__InterfaceEmbedding*)iface_embeds.data)[_t3]; v__ast__InterfaceDecl* _t5 = (v__ast__InterfaceDecl*)(map_get_check(ADDR(map, c->table->interfaces), &(int[]){ie.typ})); _option_v__ast__InterfaceDecl _t4 = {0}; if (_t5) { *((v__ast__InterfaceDecl*)&_t4.data) = *((v__ast__InterfaceDecl*)_t5); } else { _t4.state = 2; _t4.err = _v_error(_S("map key does not exist")); } if (_t4.state == 0) { v__ast__InterfaceDecl iface_decl = (*(v__ast__InterfaceDecl*)_t4.data); Array_v__ast__InterfaceEmbedding list = array_clone_to_depth(&iface_decl.embeds, 0); if (!iface_decl.are_embeds_expanded) { list = v__checker__Checker_expand_iface_embeds(c, idecl, (int)(level + 1), iface_decl.embeds); { // Unsafe block (*(v__ast__InterfaceDecl*)map_get_and_set((map*)&c->table->interfaces, &(int[]){ie.typ}, &(v__ast__InterfaceDecl[]){ (v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,} })).embeds = list; } { // Unsafe block (*(v__ast__InterfaceDecl*)map_get_and_set((map*)&c->table->interfaces, &(int[]){ie.typ}, &(v__ast__InterfaceDecl[]){ (v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,} })).are_embeds_expanded = true; } } for (int _t6 = 0; _t6 < list.len; ++_t6) { v__ast__InterfaceEmbedding partial = ((v__ast__InterfaceEmbedding*)list.data)[_t6]; (*(v__ast__InterfaceEmbedding*)map_get_and_set((map*)&res, &(int[]){partial.typ}, &(v__ast__InterfaceEmbedding[]){ (v__ast__InterfaceEmbedding){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.comments = __new_array(0, 0, sizeof(v__ast__Comment)),} })) = partial; } } (*(v__ast__InterfaceEmbedding*)map_get_and_set((map*)&res, &(int[]){ie.typ}, &(v__ast__InterfaceEmbedding[]){ (v__ast__InterfaceEmbedding){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.comments = __new_array(0, 0, sizeof(v__ast__Comment)),} })) = ie; } int _t8 = res.key_values.len; for (int _t7 = 0; _t7 < _t8; ++_t7 ) { int _t9 = res.key_values.len - _t8; _t8 = res.key_values.len; if (_t9 < 0) { _t7 = -1; continue; } if (!DenseArray_has_index(&res.key_values, _t7)) {continue;} v__ast__InterfaceEmbedding v = (*(v__ast__InterfaceEmbedding*)DenseArray_value(&res.key_values, _t7)); array_push((array*)&ares, _MOV((v__ast__InterfaceEmbedding[]){ v })); } return ares; } VV_LOC bool v__checker__Checker_fail_if_immutable_to_mutable(v__checker__Checker* c, v__ast__Type left_type, v__ast__Type right_type, v__ast__Expr right) { if (right._typ == 358 /* v.ast.Ident */) { if (c->inside_unsafe || c->pref->translated || c->file->is_translated) { return true; } if (((*right._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { if (v__ast__Type_is_ptr(left_type) && !v__ast__Ident_is_mut(&(*right._v__ast__Ident)) && v__ast__Type_is_ptr(right_type)) { v__checker__Checker_note(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = (*right._v__ast__Ident).name}}, {_S("` is immutable, cannot have a mutable reference to an immutable object"), 0, { .d_c = 0 }}})), (*right._v__ast__Ident).pos); return false; } if (!(*(*right._v__ast__Ident).obj._v__ast__Var).is_mut && (v__ast__Table_final_sym(c->table, right_type)->kind == v__ast__Kind__array || v__ast__Table_final_sym(c->table, right_type)->kind == v__ast__Kind__array_fixed || v__ast__Table_final_sym(c->table, right_type)->kind == v__ast__Kind__map)) { v__checker__Checker_note(c, str_intp(2, _MOV((StrIntpData[]){{_S("left-side of assignment expects a mutable reference, but variable `"), 0xfe10, {.d_s = (*right._v__ast__Ident).name}}, {_S("` is immutable, declare it with `mut` to make it mutable or clone it"), 0, { .d_c = 0 }}})), (*right._v__ast__Ident).pos); return false; } } } else if (right._typ == 359 /* v.ast.IfExpr */) { if (c->inside_unsafe || c->pref->translated || c->file->is_translated) { return true; } for (int _t5 = 0; _t5 < (*right._v__ast__IfExpr).branches.len; ++_t5) { v__ast__IfBranch branch = ((v__ast__IfBranch*)(*right._v__ast__IfExpr).branches.data)[_t5]; Array_v__ast__Stmt _t6 = {0}; Array_v__ast__Stmt _t6_orig = branch.stmts; int _t6_len = _t6_orig.len; _t6 = __new_array(0, _t6_len, sizeof(v__ast__Stmt)); for (int _t7 = 0; _t7 < _t6_len; ++_t7) { v__ast__Stmt it = ((v__ast__Stmt*) _t6_orig.data)[_t7]; if ((it)._typ == 401 /* v.ast.ExprStmt */) { array_push((array*)&_t6, &it); } } Array_v__ast__Stmt stmts =_t6; if (stmts.len > 0) { v__ast__ExprStmt last_expr = ({ v__ast__Stmt _t8 = (*(v__ast__Stmt*)array_last(stmts)); *(v__ast__ExprStmt*)__as_cast(_t8._v__ast__ExprStmt,_t8._typ, 401); }); v__checker__Checker_fail_if_immutable_to_mutable(c, left_type, right_type, last_expr.expr); } } } else if (right._typ == 369 /* v.ast.MatchExpr */) { if (c->inside_unsafe || c->pref->translated || c->file->is_translated) { return true; } for (int _t10 = 0; _t10 < (*right._v__ast__MatchExpr).branches.len; ++_t10) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)(*right._v__ast__MatchExpr).branches.data)[_t10]; Array_v__ast__Stmt _t11 = {0}; Array_v__ast__Stmt _t11_orig = branch.stmts; int _t11_len = _t11_orig.len; _t11 = __new_array(0, _t11_len, sizeof(v__ast__Stmt)); for (int _t12 = 0; _t12 < _t11_len; ++_t12) { v__ast__Stmt it = ((v__ast__Stmt*) _t11_orig.data)[_t12]; if ((it)._typ == 401 /* v.ast.ExprStmt */) { array_push((array*)&_t11, &it); } } Array_v__ast__Stmt stmts =_t11; if (stmts.len > 0) { v__ast__ExprStmt last_expr = ({ v__ast__Stmt _t13 = (*(v__ast__Stmt*)array_last(stmts)); *(v__ast__ExprStmt*)__as_cast(_t13._v__ast__ExprStmt,_t13._typ, 401); }); v__checker__Checker_fail_if_immutable_to_mutable(c, left_type, right_type, last_expr.expr); } } } else if (right._typ == 385 /* v.ast.StructInit */) { v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, (*right._v__ast__StructInit).typ); for (int _t14 = 0; _t14 < (*right._v__ast__StructInit).init_fields.len; ++_t14) { v__ast__StructInitField init_field = ((v__ast__StructInitField*)(*right._v__ast__StructInit).init_fields.data)[_t14]; _result_v__ast__StructField _t15; if (_t15 = v__ast__Table_find_field_with_embeds(c->table, typ_sym, init_field.name), !_t15.is_error) { v__ast__StructField field_info = *(v__ast__StructField*)_t15.data; if (field_info.is_mut) { if ((init_field.expr)._typ == 358 /* v.ast.Ident */ && !v__ast__Ident_is_mut(((v__ast__Ident*)__as_cast((init_field.expr)._v__ast__Ident,(init_field.expr)._typ, 358))) && v__ast__Type_is_ptr(init_field.typ)) { v__checker__Checker_note(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = (*init_field.expr._v__ast__Ident).name}}, {_S("` is immutable, cannot have a mutable reference to an immutable object"), 0, { .d_c = 0 }}})), init_field.pos); } else if ((init_field.expr)._typ == 376 /* v.ast.PrefixExpr */) { if ((*init_field.expr._v__ast__PrefixExpr).op == v__token__Kind__amp && ((*init_field.expr._v__ast__PrefixExpr).right)._typ == 358 /* v.ast.Ident */ && !v__ast__Ident_is_mut(((v__ast__Ident*)__as_cast(((*init_field.expr._v__ast__PrefixExpr).right)._v__ast__Ident,((*init_field.expr._v__ast__PrefixExpr).right)._typ, 358)))) { v__checker__Checker_note(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = (*(*init_field.expr._v__ast__PrefixExpr).right._v__ast__Ident).name}}, {_S("` is immutable, cannot have a mutable reference to an immutable object"), 0, { .d_c = 0 }}})), (*(*init_field.expr._v__ast__PrefixExpr).right._v__ast__Ident).pos); } } } } } } else { return true; } return true; } VV_LOC multi_return_string_v__token__Pos v__checker__Checker_fail_if_immutable(v__checker__Checker* c, v__ast__Expr* expr) { string to_lock = _S(""); v__token__Pos pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); bool explicit_lock_needed = false; if (expr->_typ == 345 /* v.ast.CastExpr */) { return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__CastExpr).pos}; } else if (expr->_typ == 350 /* v.ast.ComptimeSelector */) { v__ast__Expr expr_left = (*expr->_v__ast__ComptimeSelector).left; if (((*expr->_v__ast__ComptimeSelector).left)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast(((*expr->_v__ast__ComptimeSelector).left)._v__ast__Ident,((*expr->_v__ast__ComptimeSelector).left)._typ, 358)).obj)._typ == 422 /* v.ast.Var */) { v__checker__Checker_fail_if_immutable(c, &expr_left); } return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__ComptimeSelector).pos}; } else if (expr->_typ == 358 /* v.ast.Ident */) { if (((*expr->_v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { if (!(*(*expr->_v__ast__Ident).obj._v__ast__Var).is_mut && !c->pref->translated && !c->file->is_translated && !c->inside_unsafe) { if (c->inside_anon_fn) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("the closure copy of `"), 0xfe10, {.d_s = (*expr->_v__ast__Ident).name}}, {_S("` is immutable, declare it with `mut` to make it mutable"), 0, { .d_c = 0 }}})), (*expr->_v__ast__Ident).pos); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = (*expr->_v__ast__Ident).name}}, {_S("` is immutable, declare it with `mut` to make it mutable"), 0, { .d_c = 0 }}})), (*expr->_v__ast__Ident).pos); } } (*(*expr->_v__ast__Ident).obj._v__ast__Var).is_changed = true; if (v__ast__Type_share((*(*expr->_v__ast__Ident).obj._v__ast__Var).typ) == v__ast__ShareType__shared_t) { if (!(Array_string_contains(c->locked_names, (*expr->_v__ast__Ident).name))) { if (c->locked_names.len > 0 || c->rlocked_names.len > 0) { if ((Array_string_contains(c->rlocked_names, (*expr->_v__ast__Ident).name))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*expr->_v__ast__Ident).name}}, {_S(" has an `rlock` but needs a `lock`"), 0, { .d_c = 0 }}})), (*expr->_v__ast__Ident).pos); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*expr->_v__ast__Ident).name}}, {_S(" must be added to the `lock` list above"), 0, { .d_c = 0 }}})), (*expr->_v__ast__Ident).pos); } } to_lock = (*expr->_v__ast__Ident).name; pos = (*expr->_v__ast__Ident).pos; } } } else if (((*expr->_v__ast__Ident).obj)._typ == 420 /* v.ast.ConstField */ && (Array_string_contains(c->const_names, (*expr->_v__ast__Ident).name))) { if (!c->pref->translated) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot modify constant `"), 0xfe10, {.d_s = (*expr->_v__ast__Ident).name}}, {_S("`"), 0, { .d_c = 0 }}})), (*expr->_v__ast__Ident).pos); } } } else if (expr->_typ == 361 /* v.ast.IndexExpr */) { if ((*expr->_v__ast__IndexExpr).left_type == 0) { return (multi_return_string_v__token__Pos){.arg0=to_lock, .arg1=pos}; } v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, (*expr->_v__ast__IndexExpr).left_type); v__ast__Type elem_type = _const_v__ast__no_type; string kind = _S(""); if (left_sym->info._typ == 513 /* v.ast.Array */) { elem_type = (*left_sym->info._v__ast__Array).elem_type; kind = _S("array"); } else if (left_sym->info._typ == 549 /* v.ast.ArrayFixed */) { elem_type = (*left_sym->info._v__ast__ArrayFixed).elem_type; kind = _S("fixed array"); } else if (left_sym->info._typ == 514 /* v.ast.Map */) { elem_type = (*left_sym->info._v__ast__Map).value_type; kind = _S("map"); } else { } if (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__shared_f)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("you have to create a handle and `lock` it to modify `shared` "), 0xfe10, {.d_s = kind}}, {_S(" element"), 0, { .d_c = 0 }}})), v__token__Pos_extend(v__ast__Expr_pos((*expr->_v__ast__IndexExpr).left), (*expr->_v__ast__IndexExpr).pos)); } multi_return_string_v__token__Pos mr_36568 = v__checker__Checker_fail_if_immutable(c, &(*expr->_v__ast__IndexExpr).left); to_lock = mr_36568.arg0; pos = mr_36568.arg1; } else if (expr->_typ == 374 /* v.ast.ParExpr */) { multi_return_string_v__token__Pos mr_36641 = v__checker__Checker_fail_if_immutable(c, &(*expr->_v__ast__ParExpr).expr); to_lock = mr_36641.arg0; pos = mr_36641.arg1; } else if (expr->_typ == 376 /* v.ast.PrefixExpr */) { if ((*expr->_v__ast__PrefixExpr).op == v__token__Kind__mul && ((*expr->_v__ast__PrefixExpr).right)._typ == 358 /* v.ast.Ident */) { } else { multi_return_string_v__token__Pos mr_36868 = v__checker__Checker_fail_if_immutable(c, &(*expr->_v__ast__PrefixExpr).right); to_lock = mr_36868.arg0; pos = mr_36868.arg1; } } else if (expr->_typ == 375 /* v.ast.PostfixExpr */) { multi_return_string_v__token__Pos mr_36951 = v__checker__Checker_fail_if_immutable(c, &(*expr->_v__ast__PostfixExpr).expr); to_lock = mr_36951.arg0; pos = mr_36951.arg1; } else if (expr->_typ == 379 /* v.ast.SelectorExpr */) { if ((*expr->_v__ast__SelectorExpr).expr_type == 0) { return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__SelectorExpr).pos}; } if (!v__checker__Checker_ensure_type_exists(c, (*expr->_v__ast__SelectorExpr).expr_type, (*expr->_v__ast__SelectorExpr).pos)) { return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__SelectorExpr).pos}; } v__ast__TypeSymbol* typ_sym = v__ast__Table_final_sym(c->table, v__checker__Checker_unwrap_generic(c, (*expr->_v__ast__SelectorExpr).expr_type)); switch (typ_sym->kind) { case v__ast__Kind__struct: { bool has_field = true; _result_v__ast__StructField _t6 = v__ast__Table_find_field_with_embeds(c->table, typ_sym, (*expr->_v__ast__SelectorExpr).field_name); if (_t6.is_error) { IError err = _t6.err; has_field = false; *(v__ast__StructField*) _t6.data = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}); } v__ast__StructField field_info = (*(v__ast__StructField*)_t6.data); if (!has_field) { string type_str = v__ast__Table_type_to_str(c->table, (*expr->_v__ast__SelectorExpr).expr_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("unknown field `"), 0xfe10, {.d_s = type_str}}, {_S("."), 0xfe10, {.d_s = (*expr->_v__ast__SelectorExpr).field_name}}, {_S("`"), 0, { .d_c = 0 }}})), (*expr->_v__ast__SelectorExpr).pos); return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__SelectorExpr).pos}; } if (v__ast__Type_has_flag(field_info.typ, v__ast__TypeFlag__shared_f)) { string expr_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*expr->_v__ast__SelectorExpr).expr)}}, {_S("."), 0xfe10, {.d_s = (*expr->_v__ast__SelectorExpr).field_name}}, {_SLIT0, 0, { .d_c = 0 }}})); if (!(Array_string_contains(c->locked_names, expr_name))) { if (c->locked_names.len > 0 || c->rlocked_names.len > 0) { if ((Array_string_contains(c->rlocked_names, expr_name))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = expr_name}}, {_S(" has an `rlock` but needs a `lock`"), 0, { .d_c = 0 }}})), (*expr->_v__ast__SelectorExpr).pos); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = expr_name}}, {_S(" must be added to the `lock` list above"), 0, { .d_c = 0 }}})), (*expr->_v__ast__SelectorExpr).pos); } return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__SelectorExpr).pos}; } to_lock = expr_name; pos = (*expr->_v__ast__SelectorExpr).pos; } } else { if (!field_info.is_mut && !c->pref->translated && !c->file->is_translated) { string type_str = v__ast__Table_type_to_str(c->table, (*expr->_v__ast__SelectorExpr).expr_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = (*expr->_v__ast__SelectorExpr).field_name}}, {_S("` of struct `"), 0xfe10, {.d_s = type_str}}, {_S("` is immutable"), 0, { .d_c = 0 }}})), (*expr->_v__ast__SelectorExpr).pos); } multi_return_string_v__token__Pos mr_38452 = v__checker__Checker_fail_if_immutable(c, &(*expr->_v__ast__SelectorExpr).expr); to_lock = mr_38452.arg0; pos = mr_38452.arg1; } if ((to_lock).len != 0) { explicit_lock_needed = true; } break; } case v__ast__Kind__interface: { v__ast__Interface interface_info = *(v__ast__Interface*)__as_cast((typ_sym->info)._v__ast__Interface,(typ_sym->info)._typ, 542); _option_v__ast__StructField _t9 = v__ast__Interface_find_field(&interface_info, (*expr->_v__ast__SelectorExpr).field_name); if (_t9.state != 0) { IError err = _t9.err; string type_str = v__ast__Table_type_to_str(c->table, (*expr->_v__ast__SelectorExpr).expr_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("unknown field `"), 0xfe10, {.d_s = type_str}}, {_S("."), 0xfe10, {.d_s = (*expr->_v__ast__SelectorExpr).field_name}}, {_S("`"), 0, { .d_c = 0 }}})), (*expr->_v__ast__SelectorExpr).pos); return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__SelectorExpr).pos}; } v__ast__StructField field_info = (*(v__ast__StructField*)_t9.data); if (!field_info.is_mut) { string type_str = v__ast__Table_type_to_str(c->table, (*expr->_v__ast__SelectorExpr).expr_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = (*expr->_v__ast__SelectorExpr).field_name}}, {_S("` of interface `"), 0xfe10, {.d_s = type_str}}, {_S("` is immutable"), 0, { .d_c = 0 }}})), (*expr->_v__ast__SelectorExpr).pos); return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__SelectorExpr).pos}; } v__checker__Checker_fail_if_immutable(c, &(*expr->_v__ast__SelectorExpr).expr); break; } case v__ast__Kind__sum_type: { v__ast__SumType sumtype_info = *(v__ast__SumType*)__as_cast((typ_sym->info)._v__ast__SumType,(typ_sym->info)._typ, 544); _option_v__ast__StructField _t12 = v__ast__SumType_find_sum_type_field(&sumtype_info, (*expr->_v__ast__SelectorExpr).field_name); if (_t12.state != 0) { IError err = _t12.err; string type_str = v__ast__Table_type_to_str(c->table, (*expr->_v__ast__SelectorExpr).expr_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("unknown field `"), 0xfe10, {.d_s = type_str}}, {_S("."), 0xfe10, {.d_s = (*expr->_v__ast__SelectorExpr).field_name}}, {_S("`"), 0, { .d_c = 0 }}})), (*expr->_v__ast__SelectorExpr).pos); return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__SelectorExpr).pos}; } v__ast__StructField field_info = (*(v__ast__StructField*)_t12.data); if (!field_info.is_mut) { string type_str = v__ast__Table_type_to_str(c->table, (*expr->_v__ast__SelectorExpr).expr_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = (*expr->_v__ast__SelectorExpr).field_name}}, {_S("` of sumtype `"), 0xfe10, {.d_s = type_str}}, {_S("` is immutable"), 0, { .d_c = 0 }}})), (*expr->_v__ast__SelectorExpr).pos); return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__SelectorExpr).pos}; } v__checker__Checker_fail_if_immutable(c, &(*expr->_v__ast__SelectorExpr).expr); break; } case v__ast__Kind__array: case v__ast__Kind__string: { bool inside_builtin = fast_string_eq(c->file->mod.name, _S("builtin")); if (!inside_builtin && !c->inside_unsafe) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__ast__Kind_str(typ_sym->kind)}}, {_S("` can not be modified"), 0, { .d_c = 0 }}})), (*expr->_v__ast__SelectorExpr).pos); return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__SelectorExpr).pos}; } break; } case v__ast__Kind__aggregate: case v__ast__Kind__placeholder: { v__checker__Checker_fail_if_immutable(c, &(*expr->_v__ast__SelectorExpr).expr); break; } case v__ast__Kind__void: case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__i32: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__isize: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__usize: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__bool: case v__ast__Kind__none: case v__ast__Kind__array_fixed: case v__ast__Kind__map: case v__ast__Kind__chan: case v__ast__Kind__any: case v__ast__Kind__generic_inst: case v__ast__Kind__multi_return: case v__ast__Kind__alias: case v__ast__Kind__enum: case v__ast__Kind__function: case v__ast__Kind__float_literal: case v__ast__Kind__int_literal: case v__ast__Kind__thread: default: { { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unexpected symbol `"), 0xfe10, {.d_s = v__ast__Kind_str(typ_sym->kind)}}, {_S("`"), 0, { .d_c = 0 }}})), (*expr->_v__ast__SelectorExpr).pos); return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__SelectorExpr).pos}; } } } } else if (expr->_typ == 344 /* v.ast.CallExpr */) { if (fast_string_eq((*expr->_v__ast__CallExpr).name, _S("slice"))) { multi_return_string_v__token__Pos mr_40325 = v__checker__Checker_fail_if_immutable(c, &(*expr->_v__ast__CallExpr).left); to_lock = mr_40325.arg0; pos = mr_40325.arg1; if ((to_lock).len != 0) { explicit_lock_needed = true; } } } else if (expr->_typ == 338 /* v.ast.ArrayInit */) { v__checker__Checker_error(c, _S("array literal can not be modified"), (*expr->_v__ast__ArrayInit).pos); return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__ArrayInit).pos}; } else if (expr->_typ == 385 /* v.ast.StructInit */) { return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__StructInit).pos}; } else if (expr->_typ == 362 /* v.ast.InfixExpr */) { return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__InfixExpr).pos}; } else if (expr->_typ == 359 /* v.ast.IfExpr */) { for (int _t20 = 0; _t20 < (*expr->_v__ast__IfExpr).branches.len; ++_t20) { v__ast__IfBranch* branch = ((v__ast__IfBranch*)(*expr->_v__ast__IfExpr).branches.data) + _t20; v__ast__Expr last_expr = (({ v__ast__Stmt _t21 = (*(v__ast__Stmt*)array_last(branch->stmts)); *(v__ast__ExprStmt*)__as_cast(_t21._v__ast__ExprStmt,_t21._typ, 401); })).expr; v__checker__Checker_fail_if_immutable(c, &last_expr); } return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=(*expr->_v__ast__IfExpr).pos}; } else if (expr->_typ == 339 /* v.ast.AsCast */) { multi_return_string_v__token__Pos mr_40898 = v__checker__Checker_fail_if_immutable(c, &(*expr->_v__ast__AsCast).expr); to_lock = mr_40898.arg0; pos = mr_40898.arg1; } else { if (!v__ast__Expr_is_pure_literal(*expr)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unexpected expression `"), 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_sumtype_v__ast__Expr( (expr)->_typ ))}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*expr)); return (multi_return_string_v__token__Pos){.arg0=_S(""), .arg1=v__ast__Expr_pos(*expr)}; } } if (explicit_lock_needed) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = to_lock}}, {_S("` is `shared` and needs explicit lock for `"), 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_sumtype_v__ast__Expr( (expr)->_typ ))}}, {_S("`"), 0, { .d_c = 0 }}})), pos); to_lock = _S(""); } return (multi_return_string_v__token__Pos){.arg0=to_lock, .arg1=pos}; } VV_LOC bool v__checker__Checker_type_implements(v__checker__Checker* c, v__ast__Type typ, v__ast__Type interface_type, v__token__Pos pos) { if (typ == interface_type) { return true; } #if defined(CUSTOM_DEFINE_debug_interface_type_implements) { eprintln(str_intp(5, _MOV((StrIntpData[]){{_S("> type_implements typ: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(typ))}}, {_S(" (`"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, typ)}}, {_S("`) | inter_typ: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(interface_type))}}, {_S(" (`"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, interface_type)}}, {_S("`)"), 0, { .d_c = 0 }}}))); } #endif v__ast__Type utyp = v__checker__Checker_unwrap_generic(c, typ); string styp = v__ast__Table_type_to_str(c->table, utyp); v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, utyp); v__ast__TypeSymbol* inter_sym = v__ast__Table_sym(c->table, interface_type); if (!inter_sym->is_pub && !(string__eq(inter_sym->mod, typ_sym->mod) || string__eq(inter_sym->mod, c->mod)) && !fast_string_eq(typ_sym->mod, _S("builtin"))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = styp}}, {_S("` cannot implement private interface `"), 0xfe10, {.d_s = inter_sym->name}}, {_S("` of other module"), 0, { .d_c = 0 }}})), pos); return false; } if (fast_string_eq(typ_sym->name, _S("JS.Any"))) { return true; } if ((inter_sym->info)._typ == 542 /* v.ast.Interface */) { v__ast__Type generic_type = interface_type; v__ast__Interface generic_info = (*inter_sym->info._v__ast__Interface); if (v__ast__Type_has_flag((*inter_sym->info._v__ast__Interface).parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(c->table, (*inter_sym->info._v__ast__Interface).parent_type); if ((parent_sym->info)._typ == 542 /* v.ast.Interface */) { generic_type = (*inter_sym->info._v__ast__Interface).parent_type; generic_info = (*parent_sym->info._v__ast__Interface); } } v__ast__Type inferred_type = interface_type; if (generic_info.is_generic) { inferred_type = v__checker__Checker_unwrap_generic_interface(c, typ, generic_type, pos); if (inferred_type == 0) { return false; } } if ((*inter_sym->info._v__ast__Interface).is_generic) { if (inferred_type == interface_type) { return false; } return v__checker__Checker_type_implements(c, typ, inferred_type, pos); } } if ((inter_sym->info)._typ == 542 /* v.ast.Interface */) { for (int _t8 = 0; _t8 < (*inter_sym->info._v__ast__Interface).types.len; ++_t8) { v__ast__Type t = ((v__ast__Type*)(*inter_sym->info._v__ast__Interface).types.data)[_t8]; if (v__ast__Type_idx(t) == v__ast__Type_idx(utyp)) { return true; } } } if (v__ast__Type_idx(utyp) == v__ast__Type_idx(interface_type)) { return true; } if (v__ast__Type_idx(interface_type) == 30 && v__ast__Type_idx(utyp) == 20) { return true; } if (typ_sym->kind == v__ast__Kind__interface && inter_sym->kind == v__ast__Kind__interface && !string_starts_with(styp, _S("JS.")) && !string_starts_with(inter_sym->name, _S("JS."))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot implement interface `"), 0xfe10, {.d_s = inter_sym->name}}, {_S("` with a different interface `"), 0xfe10, {.d_s = styp}}, {_S("`"), 0, { .d_c = 0 }}})), pos); } Array_v__ast__Fn imethods = (inter_sym->kind == v__ast__Kind__interface ? ((*(v__ast__Interface*)__as_cast((inter_sym->info)._v__ast__Interface,(inter_sym->info)._typ, 542)).methods) : (inter_sym->methods)); if (utyp != _const_v__ast__voidptr_type && utyp != _const_v__ast__nil_type && !(v__ast__Type_has_flag(interface_type, v__ast__TypeFlag__option) && utyp == _const_v__ast__none_type)) { bool are_methods_implemented = true; for (int _t12 = 0; _t12 < imethods.len; ++_t12) { v__ast__Fn imethod = ((v__ast__Fn*)imethods.data)[_t12]; _result_v__ast__Fn _t13 = v__ast__Table_find_method_with_embeds(c->table, typ_sym, imethod.name); if (_t13.is_error) { IError err = _t13.err; _option_v__ast__Fn _t14 = v__ast__TypeSymbol_find_method_with_generic_parent(typ_sym, imethod.name); if (_t14.state != 0) { IError err = _t14.err; v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = styp}}, {_S("` doesn't implement method `"), 0xfe10, {.d_s = imethod.name}}, {_S("` of interface `"), 0xfe10, {.d_s = inter_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), pos); are_methods_implemented = false; continue; } *(v__ast__Fn*) _t13.data = (*(v__ast__Fn*)_t14.data); } v__ast__Fn method = (*(v__ast__Fn*)_t13.data); string msg = v__ast__Table_is_same_method(c->table, (voidptr)&imethod, (voidptr)&method); if (msg.len > 0) { string sig = v__ast__Table_fn_signature(c->table, (voidptr)&imethod, ((v__ast__FnSignatureOpts){.skip_receiver = false,.type_only = 0,})); string typ_sig = v__ast__Table_fn_signature(c->table, (voidptr)&method, ((v__ast__FnSignatureOpts){.skip_receiver = false,.type_only = 0,})); v__checker__Checker_add_error_detail(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = inter_sym->name}}, {_S(" has `"), 0xfe10, {.d_s = sig}}, {_S("`"), 0, { .d_c = 0 }}}))); v__checker__Checker_add_error_detail(c, str_intp(3, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = typ_sym->name}}, {_S(" has `"), 0xfe10, {.d_s = typ_sig}}, {_S("`"), 0, { .d_c = 0 }}}))); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = styp}}, {_S("` incorrectly implements method `"), 0xfe10, {.d_s = imethod.name}}, {_S("` of interface `"), 0xfe10, {.d_s = inter_sym->name}}, {_S("`: "), 0xfe10, {.d_s = msg}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); return false; } } if (!are_methods_implemented) { return false; } } if ((inter_sym->info)._typ == 542 /* v.ast.Interface */) { for (int _t17 = 0; _t17 < (*inter_sym->info._v__ast__Interface).fields.len; ++_t17) { v__ast__StructField ifield = ((v__ast__StructField*)(*inter_sym->info._v__ast__Interface).fields.data)[_t17]; _result_v__ast__StructField _t18; if (_t18 = v__ast__Table_find_field_with_embeds(c->table, typ_sym, ifield.name), !_t18.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t18.data; if (ifield.typ != field.typ) { string exp = v__ast__Table_type_to_str(c->table, ifield.typ); string got = v__ast__Table_type_to_str(c->table, field.typ); v__checker__Checker_error(c, str_intp(6, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = styp}}, {_S("` incorrectly implements field `"), 0xfe10, {.d_s = ifield.name}}, {_S("` of interface `"), 0xfe10, {.d_s = inter_sym->name}}, {_S("`, expected `"), 0xfe10, {.d_s = exp}}, {_S("`, got `"), 0xfe10, {.d_s = got}}, {_S("`"), 0, { .d_c = 0 }}})), pos); return false; } else if (ifield.is_mut && !(field.is_mut || field.is_global)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = styp}}, {_S("` incorrectly implements interface `"), 0xfe10, {.d_s = inter_sym->name}}, {_S("`, field `"), 0xfe10, {.d_s = ifield.name}}, {_S("` must be mutable"), 0, { .d_c = 0 }}})), pos); return false; } continue; } if (utyp != _const_v__ast__voidptr_type && utyp != _const_v__ast__nil_type) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = styp}}, {_S("` doesn't implement field `"), 0xfe10, {.d_s = ifield.name}}, {_S("` of interface `"), 0xfe10, {.d_s = inter_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), pos); } } bool _t21 = (utyp != _const_v__ast__voidptr_type && utyp != _const_v__ast__nil_type && utyp != _const_v__ast__none_type); if ( _t21 && !Array_v__ast__Type_contains((*inter_sym->info._v__ast__Interface).types, utyp)) { array_push((array*)&(*inter_sym->info._v__ast__Interface).types, _MOV((v__ast__Type[]){ utyp })); } if (!Array_v__ast__Type_contains((*inter_sym->info._v__ast__Interface).types, _const_v__ast__voidptr_type)) { array_push((array*)&(*inter_sym->info._v__ast__Interface).types, _MOV((v__ast__Type[]){ _const_v__ast__voidptr_type })); } } return true; } VV_LOC string v__checker__is_field_to_description(string expr_name, bool is_field) { return (is_field ? (str_intp(2, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = expr_name}}, {_S("` is not"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("function `"), 0xfe10, {.d_s = expr_name}}, {_S("` does not return"), 0, { .d_c = 0 }}})))); } VV_LOC void v__checker__Checker_expr_or_block_err(v__checker__Checker* c, v__ast__OrKind kind, string expr_name, v__token__Pos pos, bool is_field) { if (kind == (v__ast__OrKind__absent)) { } else if (kind == (v__ast__OrKind__block)) { string obj_does_not_return_or_is_not = v__checker__is_field_to_description(expr_name, is_field); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unexpected `or` block, the "), 0xfe10, {.d_s = obj_does_not_return_or_is_not}}, {_S(" an Option or a Result"), 0, { .d_c = 0 }}})), pos); } else if (kind == (v__ast__OrKind__propagate_option)) { string obj_does_not_return_or_is_not = v__checker__is_field_to_description(expr_name, is_field); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unexpected `?`, the "), 0xfe10, {.d_s = obj_does_not_return_or_is_not}}, {_S(" an Option"), 0, { .d_c = 0 }}})), pos); } else if (kind == (v__ast__OrKind__propagate_result)) { string obj_does_not_return_or_is_not = v__checker__is_field_to_description(expr_name, is_field); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unexpected `!`, the "), 0xfe10, {.d_s = obj_does_not_return_or_is_not}}, {_S(" a Result"), 0, { .d_c = 0 }}})), pos); } } VV_LOC v__ast__Type v__checker__Checker_check_expr_option_or_result_call(v__checker__Checker* c, v__ast__Expr expr, v__ast__Type ret_type) { if (expr._typ == 344 /* v.ast.CallExpr */) { v__ast__Type expr_ret_type = (*expr._v__ast__CallExpr).return_type; if (expr_ret_type != 0 && v__ast__Table_sym(c->table, expr_ret_type)->kind == v__ast__Kind__alias) { v__ast__Type unaliased_ret_type = v__ast__Table_unaliased_type(c->table, expr_ret_type); if (v__ast__Type_has_option_or_result(unaliased_ret_type)) { expr_ret_type = unaliased_ret_type; } } if ((*expr._v__ast__CallExpr).is_fn_var && v__ast__Type_has_option_or_result((*expr._v__ast__CallExpr).fn_var_type) && (*expr._v__ast__CallExpr).or_block.kind == v__ast__OrKind__absent) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, (*expr._v__ast__CallExpr).fn_var_type); if (v__ast__Type_has_flag((*expr._v__ast__CallExpr).fn_var_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type `?"), 0xfe10, {.d_s = ret_sym->name}}, {_S("` is an Option, it must be unwrapped first"), 0, { .d_c = 0 }}})), (*expr._v__ast__CallExpr).pos); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type `?"), 0xfe10, {.d_s = ret_sym->name}}, {_S("` is an Result, it must be unwrapped first"), 0, { .d_c = 0 }}})), (*expr._v__ast__CallExpr).pos); } } if (v__ast__Type_has_option_or_result(expr_ret_type)) { if ((*expr._v__ast__CallExpr).or_block.kind == v__ast__OrKind__absent) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, expr_ret_type); if (v__ast__Type_has_flag(expr_ret_type, v__ast__TypeFlag__result) || (v__ast__Type_has_flag(expr_ret_type, v__ast__TypeFlag__option) && ret_sym->kind == v__ast__Kind__multi_return)) { string ret_typ_tok = (v__ast__Type_has_flag(expr_ret_type, v__ast__TypeFlag__option) ? (_S("?")) : (_S("!"))); if (c->inside_defer) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*expr._v__ast__CallExpr).name}}, {_S("() returns `"), 0xfe10, {.d_s = ret_typ_tok}}, {_SLIT0, 0xfe10, {.d_s = ret_sym->name}}, {_S("`, so it should have an `or {}` block at the end"), 0, { .d_c = 0 }}})), (*expr._v__ast__CallExpr).pos); } else { v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*expr._v__ast__CallExpr).name}}, {_S("() returns `"), 0xfe10, {.d_s = ret_typ_tok}}, {_SLIT0, 0xfe10, {.d_s = ret_sym->name}}, {_S("`, so it should have either an `or {}` block, or `"), 0xfe10, {.d_s = ret_typ_tok}}, {_S("` at the end"), 0, { .d_c = 0 }}})), (*expr._v__ast__CallExpr).pos); } } } else { v__checker__Checker_check_or_expr(c, (*expr._v__ast__CallExpr).or_block, ret_type, expr_ret_type, expr); } return v__ast__Type_clear_flag(ret_type, v__ast__TypeFlag__result); } else { v__checker__Checker_expr_or_block_err(c, (*expr._v__ast__CallExpr).or_block.kind, (*expr._v__ast__CallExpr).name, (*expr._v__ast__CallExpr).or_block.pos, false); } } else if (expr._typ == 379 /* v.ast.SelectorExpr */) { if (v__ast__Table_sym(c->table, ret_type)->kind != v__ast__Kind__chan) { if (v__ast__Type_has_option_or_result((*expr._v__ast__SelectorExpr).typ)) { string with_modifier_kind = (v__ast__Type_has_flag((*expr._v__ast__SelectorExpr).typ, v__ast__TypeFlag__option) ? (_S("an Option")) : (_S("a Result"))); string with_modifier = (v__ast__Type_has_flag((*expr._v__ast__SelectorExpr).typ, v__ast__TypeFlag__option) ? (_S("?")) : (_S("!"))); if (v__ast__Type_has_flag((*expr._v__ast__SelectorExpr).typ, v__ast__TypeFlag__result) && (*expr._v__ast__SelectorExpr).or_block.kind == v__ast__OrKind__absent) { if (c->inside_defer) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = (*expr._v__ast__SelectorExpr).field_name}}, {_S("` is "), 0xfe10, {.d_s = with_modifier_kind}}, {_S(", so it should have an `or {}` block at the end"), 0, { .d_c = 0 }}})), (*expr._v__ast__SelectorExpr).pos); } else { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = (*expr._v__ast__SelectorExpr).field_name}}, {_S("` is "), 0xfe10, {.d_s = with_modifier_kind}}, {_S(", so it should have either an `or {}` block, or `"), 0xfe10, {.d_s = with_modifier}}, {_S("` at the end"), 0, { .d_c = 0 }}})), (*expr._v__ast__SelectorExpr).pos); } } else { if ((*expr._v__ast__SelectorExpr).or_block.kind != v__ast__OrKind__absent) { v__checker__Checker_check_or_expr(c, (*expr._v__ast__SelectorExpr).or_block, ret_type, (*expr._v__ast__SelectorExpr).typ, expr); } } return v__ast__Type_clear_flag(ret_type, v__ast__TypeFlag__result); } else { v__checker__Checker_expr_or_block_err(c, (*expr._v__ast__SelectorExpr).or_block.kind, (*expr._v__ast__SelectorExpr).field_name, (*expr._v__ast__SelectorExpr).or_block.pos, true); } } } else if (expr._typ == 361 /* v.ast.IndexExpr */) { if ((*expr._v__ast__IndexExpr).or_expr.kind != v__ast__OrKind__absent) { bool return_none_or_error = false; if ((*expr._v__ast__IndexExpr).or_expr.stmts.len > 0) { v__ast__Stmt last_stmt = (*(v__ast__Stmt*)array_last((*expr._v__ast__IndexExpr).or_expr.stmts)); if ((last_stmt)._typ == 401 /* v.ast.ExprStmt */) { if (c->inside_return && ((*last_stmt._v__ast__ExprStmt).typ == _const_v__ast__none_type || (*last_stmt._v__ast__ExprStmt).typ == _const_v__ast__error_type)) { return_none_or_error = true; } } } if (return_none_or_error) { v__checker__Checker_check_expr_option_or_result_call(c, v__ast__OrExpr_to_sumtype_v__ast__Expr(&(*expr._v__ast__IndexExpr).or_expr), c->table->cur_fn->return_type); } else { v__checker__Checker_check_or_expr(c, (*expr._v__ast__IndexExpr).or_expr, ret_type, v__ast__Type_set_flag(ret_type, v__ast__TypeFlag__result), expr); } } else if (((*expr._v__ast__IndexExpr).left)._typ == 379 /* v.ast.SelectorExpr */ && v__ast__Type_has_option_or_result((*expr._v__ast__IndexExpr).left_type)) { string with_modifier_kind = (v__ast__Type_has_flag((*expr._v__ast__IndexExpr).left_type, v__ast__TypeFlag__option) ? (_S("an Option")) : (_S("a Result"))); string with_modifier = (v__ast__Type_has_flag((*expr._v__ast__IndexExpr).left_type, v__ast__TypeFlag__option) ? (_S("?")) : (_S("!"))); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = (*(*expr._v__ast__IndexExpr).left._v__ast__SelectorExpr).field_name}}, {_S("` is "), 0xfe10, {.d_s = with_modifier_kind}}, {_S(", so it should have either an `or {}` block, or `"), 0xfe10, {.d_s = with_modifier}}, {_S("` at the end"), 0, { .d_c = 0 }}})), (*(*expr._v__ast__IndexExpr).left._v__ast__SelectorExpr).pos); } } else if (expr._typ == 345 /* v.ast.CastExpr */) { v__checker__Checker_check_expr_option_or_result_call(c, (*expr._v__ast__CastExpr).expr, ret_type); } else if (expr._typ == 339 /* v.ast.AsCast */) { v__checker__Checker_check_expr_option_or_result_call(c, (*expr._v__ast__AsCast).expr, ret_type); } else if (expr._typ == 374 /* v.ast.ParExpr */) { v__checker__Checker_check_expr_option_or_result_call(c, (*expr._v__ast__ParExpr).expr, ret_type); } else { } return ret_type; } VV_LOC void v__checker__Checker_check_or_expr(v__checker__Checker* c, v__ast__OrExpr node, v__ast__Type ret_type, v__ast__Type expr_return_type, v__ast__Expr expr) { if (node.kind == v__ast__OrKind__propagate_option) { if (c->table->cur_fn != ((void*)0) && !v__ast__Type_has_flag(c->table->cur_fn->return_type, v__ast__TypeFlag__option) && !c->table->cur_fn->is_main && !c->table->cur_fn->is_test && !c->inside_const) { v__checker__Checker_add_instruction_for_option_type(c); if ((expr)._typ == 358 /* v.ast.Ident */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("to propagate the Option, `"), 0xfe10, {.d_s = c->table->cur_fn->name}}, {_S("` must return an Option type"), 0, { .d_c = 0 }}})), (*expr._v__ast__Ident).pos); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("to propagate the call, `"), 0xfe10, {.d_s = c->table->cur_fn->name}}, {_S("` must return an Option type"), 0, { .d_c = 0 }}})), node.pos); } } if (!((expr)._typ == 358 /* v.ast.Ident */ || (expr)._typ == 379 /* v.ast.SelectorExpr */) && !v__ast__Type_has_flag(expr_return_type, v__ast__TypeFlag__option)) { if (v__ast__Type_has_flag(expr_return_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("propagating a Result like an Option is deprecated, use `foo()!` instead of `foo()?`"), node.pos); } else { v__checker__Checker_error(c, _S("to propagate an Option, the call must also return an Option type"), node.pos); } } return; } if (node.kind == v__ast__OrKind__propagate_result) { if (c->table->cur_fn != ((void*)0) && !v__ast__Type_has_flag(c->table->cur_fn->return_type, v__ast__TypeFlag__result) && !c->table->cur_fn->is_main && !c->table->cur_fn->is_test && !c->inside_const) { v__checker__Checker_add_instruction_for_result_type(c); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("to propagate the call, `"), 0xfe10, {.d_s = c->table->cur_fn->name}}, {_S("` must return a Result type"), 0, { .d_c = 0 }}})), node.pos); } if (!v__ast__Type_has_flag(expr_return_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("to propagate a Result, the call must also return a Result type"), node.pos); } return; } if (node.stmts.len == 0) { if ((expr)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast((expr)._v__ast__CallExpr,(expr)._typ, 344)).is_return_used) { v__checker__Checker_error(c, _S("expression requires a non empty `or {}` block"), node.pos); } else if ((expr)._typ != 344 /* v.ast.CallExpr */ && ret_type != _const_v__ast__void_type) { v__checker__Checker_error(c, _S("expression requires a non empty `or {}` block"), node.pos); } return; } Array_v__ast__Stmt _t1 = {0}; Array_v__ast__Stmt _t1_orig = node.stmts; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Stmt)); for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__Stmt it = ((v__ast__Stmt*) _t1_orig.data)[_t2]; if ((it)._typ != 413 /* v.ast.SemicolonStmt */) { array_push((array*)&_t1, &it); } } Array_v__ast__Stmt valid_stmts =_t1; v__ast__Stmt _t3; /* if prepend */ if (valid_stmts.len > 0) { _t3 = (*(v__ast__Stmt*)array_last(valid_stmts)); } else { _t3 = (*(v__ast__Stmt*)array_last(node.stmts)); } v__ast__Stmt last_stmt = _t3; if ((expr)._typ != 344 /* v.ast.CallExpr */ || ((expr)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast((expr)._v__ast__CallExpr,(expr)._typ, 344)).is_return_used)) { v__checker__Checker_check_or_last_stmt(c, &last_stmt, ret_type, v__ast__Type_clear_option_and_result(expr_return_type)); } else { v__checker__Checker_check_or_last_stmt(c, &last_stmt, _const_v__ast__void_type, v__ast__Type_clear_option_and_result(expr_return_type)); } } VV_LOC void v__checker__Checker_check_or_last_stmt(v__checker__Checker* c, v__ast__Stmt* stmt, v__ast__Type ret_type, v__ast__Type expr_return_type) { if (ret_type != _const_v__ast__void_type) { if (stmt->_typ == 401 /* v.ast.ExprStmt */) { c->expected_type = ret_type; c->expected_or_type = v__ast__Type_clear_option_and_result(ret_type); if (c->inside_or_block_value && ((*stmt->_v__ast__ExprStmt).expr)._typ == 371 /* v.ast.None */ && v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__option)) { return; } v__ast__Type last_stmt_typ = v__checker__Checker_expr(c, &(*stmt->_v__ast__ExprStmt).expr); (*stmt->_v__ast__ExprStmt).typ = last_stmt_typ; if (v__ast__Type_has_flag(last_stmt_typ, v__ast__TypeFlag__option) || last_stmt_typ == _const_v__ast__none_type) { if (((*stmt->_v__ast__ExprStmt).expr)._typ == 358 /* v.ast.Ident */ || ((*stmt->_v__ast__ExprStmt).expr)._typ == 379 /* v.ast.SelectorExpr */ || ((*stmt->_v__ast__ExprStmt).expr)._typ == 344 /* v.ast.CallExpr */ || ((*stmt->_v__ast__ExprStmt).expr)._typ == 371 /* v.ast.None */ || ((*stmt->_v__ast__ExprStmt).expr)._typ == 345 /* v.ast.CastExpr */) { string expected_type_name = v__ast__Table_type_to_str(c->table, v__ast__Type_clear_option_and_result(ret_type)); string got_type_name = v__ast__Table_type_to_str(c->table, last_stmt_typ); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`or` block must provide a value of type `"), 0xfe10, {.d_s = expected_type_name}}, {_S("`, not `"), 0xfe10, {.d_s = got_type_name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos((*stmt->_v__ast__ExprStmt).expr)); return; } } c->expected_or_type = _const_v__ast__void_type; bool type_fits = v__checker__Checker_check_types(c, last_stmt_typ, ret_type) && v__ast__Type_nr_muls(last_stmt_typ) == v__ast__Type_nr_muls(ret_type); bool is_noreturn = v__checker__is_noreturn_callexpr((*stmt->_v__ast__ExprStmt).expr); if (type_fits || is_noreturn) { return; } if ((*stmt->_v__ast__ExprStmt).typ == _const_v__ast__void_type) { if (((*stmt->_v__ast__ExprStmt).expr)._typ == 359 /* v.ast.IfExpr */) { for (int _t1 = 0; _t1 < (*(*stmt->_v__ast__ExprStmt).expr._v__ast__IfExpr).branches.len; ++_t1) { v__ast__IfBranch* branch = ((v__ast__IfBranch*)(*(*stmt->_v__ast__ExprStmt).expr._v__ast__IfExpr).branches.data) + _t1; if (branch->stmts.len > 0) { v__ast__Stmt stmt_ = (*(v__ast__Stmt*)array_last(branch->stmts)); v__checker__Checker_check_or_last_stmt(c, &stmt_, ret_type, expr_return_type); } } return; } else if (((*stmt->_v__ast__ExprStmt).expr)._typ == 369 /* v.ast.MatchExpr */) { for (int _t2 = 0; _t2 < (*(*stmt->_v__ast__ExprStmt).expr._v__ast__MatchExpr).branches.len; ++_t2) { v__ast__MatchBranch* branch = ((v__ast__MatchBranch*)(*(*stmt->_v__ast__ExprStmt).expr._v__ast__MatchExpr).branches.data) + _t2; if (branch->stmts.len > 0) { v__ast__Stmt stmt_ = (*(v__ast__Stmt*)array_last(branch->stmts)); v__checker__Checker_check_or_last_stmt(c, &stmt_, ret_type, expr_return_type); } } return; } string expected_type_name = v__ast__Table_type_to_str(c->table, v__ast__Type_clear_option_and_result(ret_type)); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`or` block must provide a default value of type `"), 0xfe10, {.d_s = expected_type_name}}, {_S("`, or return/continue/break or call a @[noreturn] function like panic(err) or exit(1)"), 0, { .d_c = 0 }}})), v__ast__Expr_pos((*stmt->_v__ast__ExprStmt).expr)); } else { if (v__ast__Type_is_ptr(ret_type) && v__ast__Type_is_pointer(last_stmt_typ) && v__ast__Table_sym(c->table, last_stmt_typ)->kind == v__ast__Kind__voidptr) { return; } if (last_stmt_typ == 20 && v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__option)) { return; } string type_name = v__ast__Table_type_to_str(c->table, last_stmt_typ); string expected_type_name = v__ast__Table_type_to_str(c->table, v__ast__Type_clear_option_and_result(ret_type)); if (v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__generic)) { return; } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("wrong return type `"), 0xfe10, {.d_s = type_name}}, {_S("` in the `or {}` block, expected `"), 0xfe10, {.d_s = expected_type_name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos((*stmt->_v__ast__ExprStmt).expr)); } } else if (stmt->_typ == 394 /* v.ast.BranchStmt */) { if (!((*stmt->_v__ast__BranchStmt).kind == v__token__Kind__key_continue || (*stmt->_v__ast__BranchStmt).kind == v__token__Kind__key_break)) { v__checker__Checker_error(c, _S("only break/continue is allowed as a branch statement in the end of an `or {}` block"), (*stmt->_v__ast__BranchStmt).pos); return; } } else if (stmt->_typ == 412 /* v.ast.Return */) { } else { if ((stmt)->_typ != 391 /* v.ast.AssertStmt */ || c->inside_or_block_value) { string expected_type_name = v__ast__Table_type_to_str(c->table, v__ast__Type_clear_option_and_result(ret_type)); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("last statement in the `or {}` block should be an expression of type `"), 0xfe10, {.d_s = expected_type_name}}, {_S("` or exit parent scope"), 0, { .d_c = 0 }}})), (*(stmt->pos))); } } } else if ((stmt)->_typ == 401 /* v.ast.ExprStmt */) { if ((*stmt->_v__ast__ExprStmt).expr._typ == 359 /* v.ast.IfExpr */) { for (int _t3 = 0; _t3 < (*(*stmt->_v__ast__ExprStmt).expr._v__ast__IfExpr).branches.len; ++_t3) { v__ast__IfBranch* branch = ((v__ast__IfBranch*)(*(*stmt->_v__ast__ExprStmt).expr._v__ast__IfExpr).branches.data) + _t3; if (branch->stmts.len > 0) { v__ast__Stmt stmt_ = (*(v__ast__Stmt*)array_last(branch->stmts)); v__checker__Checker_check_or_last_stmt(c, &stmt_, ret_type, expr_return_type); } } } else if ((*stmt->_v__ast__ExprStmt).expr._typ == 369 /* v.ast.MatchExpr */) { for (int _t4 = 0; _t4 < (*(*stmt->_v__ast__ExprStmt).expr._v__ast__MatchExpr).branches.len; ++_t4) { v__ast__MatchBranch* branch = ((v__ast__MatchBranch*)(*(*stmt->_v__ast__ExprStmt).expr._v__ast__MatchExpr).branches.data) + _t4; if (branch->stmts.len > 0) { v__ast__Stmt stmt_ = (*(v__ast__Stmt*)array_last(branch->stmts)); v__checker__Checker_check_or_last_stmt(c, &stmt_, ret_type, expr_return_type); } } } else { if ((*stmt->_v__ast__ExprStmt).typ == _const_v__ast__void_type || expr_return_type == _const_v__ast__void_type) { return; } if (v__checker__is_noreturn_callexpr((*stmt->_v__ast__ExprStmt).expr)) { return; } if (v__checker__Checker_check_types(c, (*stmt->_v__ast__ExprStmt).typ, expr_return_type)) { if (v__ast__Type_is_ptr((*stmt->_v__ast__ExprStmt).typ) == v__ast__Type_is_ptr(expr_return_type) || (v__ast__Type_is_ptr(expr_return_type) && v__ast__Type_is_pointer((*stmt->_v__ast__ExprStmt).typ) && v__ast__Table_sym(c->table, (*stmt->_v__ast__ExprStmt).typ)->kind == v__ast__Kind__voidptr)) { return; } } if (v__ast__Type_has_flag(expr_return_type, v__ast__TypeFlag__generic)) { return; } string type_name = v__ast__Table_type_to_str(c->table, (*stmt->_v__ast__ExprStmt).typ); string expr_return_type_name = v__ast__Table_type_to_str(c->table, expr_return_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("the default expression type in the `or` block should be `"), 0xfe10, {.d_s = expr_return_type_name}}, {_S("`, instead you gave a value of type `"), 0xfe10, {.d_s = type_name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos((*stmt->_v__ast__ExprStmt).expr)); } } } VV_LOC v__ast__Type v__checker__Checker_selector_expr(v__checker__Checker* c, v__ast__SelectorExpr* node) { bool prevent_sum_type_unwrapping_once = c->prevent_sum_type_unwrapping_once; c->prevent_sum_type_unwrapping_once = false; bool using_new_err_struct_save = c->using_new_err_struct; if ((node->expr)._typ == 358 /* v.ast.Ident */ && fast_string_eq((*(v__ast__Ident*)__as_cast((node->expr)._v__ast__Ident,(node->expr)._typ, 358)).name, _S("err"))) { c->using_new_err_struct = true; } int name_type = 0; v__ast__Expr node_expr = node->expr; if (node->expr._typ == 358 /* v.ast.Ident */) { string name = (*node->expr._v__ast__Ident).name; bool valid_generic = v__util__is_generic_type_name(name) && c->table->cur_fn != ((void*)0) && (Array_string_contains(c->table->cur_fn->generic_names, name)); if (valid_generic) { name_type = v__ast__Type_set_flag(v__ast__Table_find_type(c->table, name), v__ast__TypeFlag__generic); } } else if (node->expr._typ == 387 /* v.ast.TypeOf */) { v__checker__Checker_expr(c, &node_expr); name_type = (*node->expr._v__ast__TypeOf).typ; } else if (node->expr._typ == 339 /* v.ast.AsCast */) { v__checker__Checker_add_error_detail(c, str_intp(4, _MOV((StrIntpData[]){{_S("for example `("), 0xfe10, {.d_s = v__ast__Expr_str(&(*node->expr._v__ast__AsCast).expr)}}, {_S(" as "), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, (*node->expr._v__ast__AsCast).typ)}}, {_S(")."), 0xfe10, {.d_s = node->field_name}}, {_S("`"), 0, { .d_c = 0 }}}))); v__checker__Checker_error(c, _S("indeterminate `as` cast, use parenthesis to clarity"), (*node->expr._v__ast__AsCast).pos); } else { } if (name_type > 0) { node->name_type = name_type; if (node->gkind_field == (v__ast__GenericKindField__name)) { return _const_v__ast__string_type; } else if (node->gkind_field == (v__ast__GenericKindField__unaliased_typ) || node->gkind_field == (v__ast__GenericKindField__typ) || node->gkind_field == (v__ast__GenericKindField__indirections)) { return _const_v__ast__int_type; } else { if (fast_string_eq(node->field_name, _S("name"))) { return _const_v__ast__string_type; } else if (fast_string_eq(node->field_name, _S("idx")) || fast_string_eq(node->field_name, _S("unaliased_typ")) || fast_string_eq(node->field_name, _S("key_type")) || fast_string_eq(node->field_name, _S("value_type")) || fast_string_eq(node->field_name, _S("element_type"))) { return _const_v__ast__int_type; } else if (fast_string_eq(node->field_name, _S("indirections"))) { return _const_v__ast__int_type; } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("invalid field `."), 0xfe10, {.d_s = node->field_name}}, {_S("` for type `"), 0xfe10, {.d_s = v__ast__Expr_str(&node->expr)}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__string_type; } } if (v__type_resolver__ResolverInfo_check_comptime_is_field_selector(c->comptime, *node)) { if (v__type_resolver__ResolverInfo_check_comptime_is_field_selector_bool(c->comptime, *node)) { node->expr_type = _const_v__ast__bool_type; return node->expr_type; } } node->is_field_typ = node->is_field_typ || v__type_resolver__ResolverInfo_is_comptime_selector_type(c->comptime, *node); bool old_selector_expr = c->inside_selector_expr; c->inside_selector_expr = true; v__ast__Type typ = v__checker__Checker_expr(c, &node->expr); if (v__ast__Expr_is_auto_deref_var(node->expr)) { if ((node->expr)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((node->expr)._v__ast__Ident,(node->expr)._typ, 358)).obj)._typ == 422 /* v.ast.Var */) { typ = (*(*node->expr._v__ast__Ident).obj._v__ast__Var).typ; } } c->inside_selector_expr = old_selector_expr; c->using_new_err_struct = using_new_err_struct_save; if (typ == 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__ast__Expr_str(&node->expr)}}, {_S("` does not return a value"), 0, { .d_c = 0 }}})), node->pos); node->expr_type = _const_v__ast__void_type; return _const_v__ast__void_type; } else if (c->comptime->inside_comptime_for && typ == c->enum_data_type && fast_string_eq(node->field_name, _S("value"))) { node->expr_type = v__type_resolver__TypeResolver_get_ct_type_or_default(&c->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->comptime->comptime_for_enum_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), node->expr_type); node->typ = typ; return node->expr_type; } node->expr_type = typ; if (!((node->expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node->expr)._v__ast__Ident,(node->expr)._typ, 358)).kind == v__ast__IdentKind__constant)) { if (v__ast__Type_has_flag(node->expr_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("cannot access fields of an Option, handle the error with `or {...}` or propagate it with `?`"), node->pos); } else if (v__ast__Type_has_flag(node->expr_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("cannot access fields of a Result, handle the error with `or {...}` or propagate it with `!`"), node->pos); } } string field_name = node->field_name; v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); v__ast__TypeSymbol* final_sym = v__ast__Table_final_sym(c->table, typ); if ((v__ast__Type_has_flag(typ, v__ast__TypeFlag__variadic) || final_sym->kind == v__ast__Kind__array_fixed) && _SLIT_EQ(field_name.str, field_name.len, "len")) { node->typ = _const_v__ast__int_type; return _const_v__ast__int_type; } if (sym->kind == v__ast__Kind__chan) { if (_SLIT_EQ(field_name.str, field_name.len, "closed")) { node->typ = _const_v__ast__bool_type; return _const_v__ast__bool_type; } else if (_SLIT_EQ(field_name.str, field_name.len, "len") || _SLIT_EQ(field_name.str, field_name.len, "cap")) { node->typ = _const_v__ast__u32_type; return _const_v__ast__u32_type; } } string unknown_field_msg = _S(""); bool has_field = false; v__ast__StructField field = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}); if (field_name.len > 0 && (sym->info)._typ == 518 /* v.ast.Struct */ && sym->language == v__ast__Language__v && u8_is_capital(string_at(field_name, 0))) { for (int _t13 = 0; _t13 < (*sym->info._v__ast__Struct).embeds.len; ++_t13) { v__ast__Type embed = ((v__ast__Type*)(*sym->info._v__ast__Struct).embeds.data)[_t13]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(c->table, embed); if (string__eq(v__ast__TypeSymbol_embed_name(embed_sym), field_name)) { node->typ = embed; return embed; } } } else { _result_v__ast__StructField _t15; if (_t15 = v__ast__Table_find_field(c->table, sym, field_name), !_t15.is_error) { v__ast__StructField f = *(v__ast__StructField*)_t15.data; has_field = true; field = f; } else { IError err = _t15.err; has_field = true; Array_v__ast__Type embed_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); _result_multi_return_v__ast__StructField_Array_v__ast__Type _t16 = v__ast__Table_find_field_from_embeds(c->table, sym, field_name); if (_t16.is_error) { IError err = _t16.err; if ((IError_name_table[err._typ]._method_msg(err._object)).len != 0) { v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); } has_field = false; *(multi_return_v__ast__StructField_Array_v__ast__Type*) _t16.data = (multi_return_v__ast__StructField_Array_v__ast__Type){.arg0=((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } multi_return_v__ast__StructField_Array_v__ast__Type mr_62940 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t16.data); field = mr_62940.arg0; embed_types = mr_62940.arg1; node->from_embed_types = embed_types; if (sym->kind == v__ast__Kind__aggregate || sym->kind == v__ast__Kind__sum_type) { unknown_field_msg = IError_name_table[err._typ]._method_msg(err._object); if (string_contains(unknown_field_msg, _S("does not exist or have the same type in all sumtype"))) { v__ast__SumType info = *(v__ast__SumType*)__as_cast((sym->info)._v__ast__SumType,(sym->info)._typ, 544); string missing_variants = v__ast__Table_find_missing_variants(c->table, (voidptr)&info, field_name); unknown_field_msg = string__plus(unknown_field_msg, missing_variants); } } } if (!c->inside_unsafe) { if ((sym->info)._typ == 518 /* v.ast.Struct */) { if ((*sym->info._v__ast__Struct).is_union && !(Array_v__token__Kind_contains(_const_v__token__assign_tokens, node->next_token))) { if (!c->pref->translated && !c->file->is_translated) { v__checker__Checker_warn(c, _S("reading a union field (or its address) requires `unsafe`"), node->pos); } } } } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic) && !has_field) { v__ast__TypeSymbol* gs = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, typ)); _result_v__ast__StructField _t17; if (_t17 = v__ast__Table_find_field(c->table, gs, field_name), !_t17.is_error) { v__ast__StructField f = *(v__ast__StructField*)_t17.data; has_field = true; field = f; } else { IError err = _t17.err; has_field = true; Array_v__ast__Type embed_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); _result_multi_return_v__ast__StructField_Array_v__ast__Type _t18 = v__ast__Table_find_field_from_embeds(c->table, gs, field_name); if (_t18.is_error) { IError err = _t18.err; if ((IError_name_table[err._typ]._method_msg(err._object)).len != 0) { v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); } has_field = false; *(multi_return_v__ast__StructField_Array_v__ast__Type*) _t18.data = (multi_return_v__ast__StructField_Array_v__ast__Type){.arg0=((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } multi_return_v__ast__StructField_Array_v__ast__Type mr_64170 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t18.data); field = mr_64170.arg0; embed_types = mr_64170.arg1; node->from_embed_types = embed_types; array_push((array*)&node->generic_from_embed_types, &embed_types); } } } if (has_field) { bool is_used_outside = !c->inside_recheck && !string__eq(sym->mod, c->mod); if (is_used_outside && !field.is_pub && sym->language != v__ast__Language__c) { v__ast__TypeSymbol* unwrapped_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, typ)); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = unwrapped_sym->name}}, {_S("."), 0xfe10, {.d_s = field_name}}, {_S("` is not public"), 0, { .d_c = 0 }}})), node->pos); } v__ast__TypeSymbol* field_sym = v__ast__Table_sym(c->table, field.typ); if (field.is_deprecated && is_used_outside) { v__checker__Checker_deprecate(c, _S("field"), field_name, field.attrs, node->pos); } if ((field_sym->kind == v__ast__Kind__sum_type || field_sym->kind == v__ast__Kind__interface) || v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { if (!prevent_sum_type_unwrapping_once) { v__ast__ScopeStructField* scope_field = v__ast__Scope_find_struct_field(node->scope, v__ast__Expr_str(&node->expr), typ, field_name); if (scope_field != ((void*)0)) { return (*(v__ast__Type*)array_last(scope_field->smartcasts)); } } } node->typ = field.typ; if (node->or_block.kind != v__ast__OrKind__absent) { v__ast__Type unwrapped_typ = v__checker__Checker_unwrap_generic(c, node->typ); c->expected_or_type = v__ast__Type_clear_option_and_result(unwrapped_typ); v__checker__Checker_stmts_ending_with_expression(c, &node->or_block.stmts, c->expected_or_type); v__checker__Checker_check_or_expr(c, node->or_block, unwrapped_typ, c->expected_or_type, v__ast__SelectorExpr_to_sumtype_v__ast__Expr(node)); c->expected_or_type = _const_v__ast__void_type; } return field.typ; } _option_v__ast__Fn _t22; if (_t22 = v__ast__TypeSymbol_find_method_with_generic_parent(v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, typ)), field_name), _t22.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t22.data; v__checker__Checker_markused_comptime_call(c, v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic), str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)((*(v__ast__Param*)array_get(method.params, 0)).typ))}}, {_S("."), 0xfe10, {.d_s = field_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (c->expected_type != 0 && c->expected_type != _const_v__ast__none_type) { v__ast__Type fn_type = v__ast__new_type(v__ast__Table_find_or_register_fn_type(c->table, method, false, true)); if (v__checker__Checker_check_types(c, fn_type, c->expected_type)) { c->table->used_features->anon_fn = true; return fn_type; } } v__ast__Type receiver = v__checker__Checker_unwrap_generic(c, (*(v__ast__Param*)array_get(method.params, 0)).typ); if (v__ast__Type_nr_muls(receiver) > 0) { if (!c->inside_unsafe) { v__ast__TypeSymbol* rec_sym = v__ast__Table_sym(c->table, v__ast__Type_set_nr_muls(receiver, 0)); if (!v__ast__TypeSymbol_is_heap(rec_sym)) { string suggestion = (rec_sym->kind == v__ast__Kind__struct ? (str_intp(2, _MOV((StrIntpData[]){{_S("declaring `"), 0xfe10, {.d_s = rec_sym->name}}, {_S("` as `@[heap]`"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("wrapping the `"), 0xfe10, {.d_s = rec_sym->name}}, {_S("` object in a `struct` declared as `@[heap]`"), 0, { .d_c = 0 }}})))); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("method `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, v__ast__Type_idx_type(receiver))}}, {_S("."), 0xfe10, {.d_s = method.name}}, {_S("` cannot be used as a variable outside `unsafe` blocks as its receiver might refer to an object stored on stack. Consider "), 0xfe10, {.d_s = suggestion}}, {_S("."), 0, { .d_c = 0 }}})), v__token__Pos_extend(v__ast__Expr_pos(node->expr), node->pos)); } } } method.params = array_slice(method.params, 1, 2147483647); node->has_hidden_receiver = true; method.name = _S(""); v__ast__Type fn_type = v__ast__new_type(v__ast__Table_find_or_register_fn_type(c->table, method, false, true)); node->typ = v__checker__Checker_unwrap_generic(c, fn_type); c->table->used_features->anon_fn = true; return fn_type; } if (!(sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__aggregate || sym->kind == v__ast__Kind__interface || sym->kind == v__ast__Kind__sum_type)) { if (sym->kind != v__ast__Kind__placeholder) { v__ast__TypeSymbol* unwrapped_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, typ)); if (unwrapped_sym->kind == v__ast__Kind__array_fixed && fast_string_eq(node->field_name, _S("len"))) { node->typ = _const_v__ast__int_type; return _const_v__ast__int_type; } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = unwrapped_sym->name}}, {_S("` has no property `"), 0xfe10, {.d_s = node->field_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } else { if ((unknown_field_msg).len == 0) { unknown_field_msg = str_intp(3, _MOV((StrIntpData[]){{_S("type `"), 0xfe10, {.d_s = sym->name}}, {_S("` has no field named `"), 0xfe10, {.d_s = field_name}}, {_S("`"), 0, { .d_c = 0 }}})); } if ((sym->info)._typ == 518 /* v.ast.Struct */) { if (!v__token__Pos_struct_eq(c->smartcast_mut_pos, ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}))) { v__checker__Checker_note(c, _S("smartcasting requires either an immutable value, or an explicit mut keyword before the value"), c->smartcast_mut_pos); } Array_string _t26 = {0}; Array_v__ast__StructField _t26_orig = (*sym->info._v__ast__Struct).fields; int _t26_len = _t26_orig.len; _t26 = __new_array(0, _t26_len, sizeof(string)); for (int _t28 = 0; _t28 < _t26_len; ++_t28) { v__ast__StructField it = ((v__ast__StructField*) _t26_orig.data)[_t28]; string _t27 = it.name; array_push((array*)&_t26, &_t27); } v__util__Suggestion suggestion = v__util__new_suggestion(field_name,_t26, ((v__util__SuggestionParams){.similarity_threshold = 0.5,.similarity_fn = strings__dice_coefficient,})); v__checker__Checker_error(c, v__util__Suggestion_say(suggestion, unknown_field_msg), node->pos); return _const_v__ast__void_type; } if (!v__token__Pos_struct_eq(c->smartcast_mut_pos, ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}))) { v__checker__Checker_note(c, _S("smartcasting requires either an immutable value, or an explicit mut keyword before the value"), c->smartcast_mut_pos); } if (!v__token__Pos_struct_eq(c->smartcast_cond_pos, ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}))) { v__checker__Checker_note(c, _S("smartcast can only be used on the ident or selector, e.g. match foo, match foo.bar"), c->smartcast_cond_pos); } v__checker__Checker_error(c, unknown_field_msg, node->pos); } return _const_v__ast__void_type; } VV_LOC void v__checker__Checker_const_decl(v__checker__Checker* c, v__ast__ConstDecl* node) { if (node->fields.len == 0) { v__checker__Checker_warn(c, _S("const block must have at least 1 declaration"), node->pos); } if (node->is_block) { v__checker__Checker_warn(c, _S("const () groups will be an error after 2025-01-01 (`v fmt -w source.v` will fix that for you)"), node->pos); } for (int _t1 = 0; _t1 < node->fields.len; ++_t1) { v__ast__ConstField* field = ((v__ast__ConstField*)node->fields.data) + _t1; if (v__token__KeywordsMatcherTrie_matches(&_const_v__checker__reserved_type_names_chk, v__util__no_cur_mod(field->name, c->mod))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid use of reserved type `"), 0xfe10, {.d_s = field->name}}, {_S("` as a const name"), 0, { .d_c = 0 }}})), field->pos); } if ((Array_string_contains(c->const_names, field->name))) { v__token__Pos name_pos = ((v__token__Pos){.len = v__util__no_cur_mod(field->name, c->mod).len,.line_nr = (field->pos).line_nr,.pos = (field->pos).pos,.col = (field->pos).col,.last_line = (field->pos).last_line,}); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate const `"), 0xfe10, {.d_s = field->name}}, {_S("`"), 0, { .d_c = 0 }}})), name_pos); } if ((field->expr)._typ == 344 /* v.ast.CallExpr */) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, v__checker__Checker_check_expr_option_or_result_call(c, field->expr, v__checker__Checker_expr(c, &field->expr))); if (sym->kind == v__ast__Kind__multi_return) { v__checker__Checker_error(c, _S("const declarations do not support multiple return values yet"), v__ast__Expr_pos(field->expr)); } } string const_name = string_all_after_last(field->name, _S(".")); if (string__eq(const_name, c->mod) && _SLIT_NE(const_name.str, const_name.len, "main")) { v__token__Pos name_pos = ((v__token__Pos){.len = v__util__no_cur_mod(field->name, c->mod).len,.line_nr = (field->pos).line_nr,.pos = (field->pos).pos,.col = (field->pos).col,.last_line = (field->pos).last_line,}); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate of a module name `"), 0xfe10, {.d_s = field->name}}, {_S("`"), 0, { .d_c = 0 }}})), name_pos); } if (_SLIT_EQ(const_name.str, const_name.len, "_")) { v__token__Pos name_pos = ((v__token__Pos){.len = v__util__no_cur_mod(field->name, c->mod).len,.line_nr = (field->pos).line_nr,.pos = (field->pos).pos,.col = (field->pos).col,.last_line = (field->pos).last_line,}); v__checker__Checker_error(c, _S("cannot use `_` as a const name"), name_pos); return; } array_push((array*)&c->const_names, _MOV((string[]){ string_clone(field->name) })); } for (int i = 0; i < node->fields.len; ++i) { v__ast__ConstField* field = ((v__ast__ConstField*)node->fields.data) + i; array_push((array*)&c->const_deps, _MOV((string[]){ string_clone(field->name) })); v__ast__ConstField* prev_const_var = c->const_var; c->const_var = field; v__ast__Type typ = v__checker__Checker_check_expr_option_or_result_call(c, field->expr, v__checker__Checker_expr(c, &field->expr)); typ = v__checker__Checker_cast_fixed_array_ret(c, typ, *v__ast__Table_sym(c->table, typ)); _option_v__ast__ComptTimeConstValue _t4; if (_t4 = v__checker__Checker_eval_comptime_const_expr(c, field->expr, 0), _t4.state == 0) { v__ast__ComptTimeConstValue ct_value = *(v__ast__ComptTimeConstValue*)_t4.data; field->comptime_expr_value = ct_value; if ((ct_value)._typ == 14 /* u64 */) { typ = _const_v__ast__u64_type; } } (*(v__ast__ConstField*)array_get(node->fields, i)).typ = v__ast__mktyp(typ); if ((field->expr)._typ == 359 /* v.ast.IfExpr */) { for (int _t5 = 0; _t5 < (*field->expr._v__ast__IfExpr).branches.len; ++_t5) { v__ast__IfBranch branch = ((v__ast__IfBranch*)(*field->expr._v__ast__IfExpr).branches.data)[_t5]; bool _t6 = (branch.stmts.len > 0); if ( _t6 && ((*(v__ast__Stmt*)array_last(branch.stmts)))._typ == 401 /* v.ast.ExprStmt */ && (({ v__ast__Stmt _t7 = (*(v__ast__Stmt*)array_last(branch.stmts)); *(v__ast__ExprStmt*)__as_cast(_t7._v__ast__ExprStmt,_t7._typ, 401); })).typ != _const_v__ast__void_type) { (*field->expr._v__ast__IfExpr).is_expr = true; (*field->expr._v__ast__IfExpr).typ = (({ v__ast__Stmt _t8 = (*(v__ast__Stmt*)array_last(branch.stmts)); *(v__ast__ExprStmt*)__as_cast(_t8._v__ast__ExprStmt,_t8._typ, 401); })).typ; field->typ = (*field->expr._v__ast__IfExpr).typ; _option_v__ast__ConstField_ptr _t9; if (_t9 = v__ast__Scope_find_const(c->file->global_scope, field->name), _t9.state == 0) { v__ast__ConstField* obj = *(v__ast__ConstField**)_t9.data; obj->typ = field->typ; } break; } } } if (field->typ == _const_v__ast__int_type) { if ((field->expr)._typ == 363 /* v.ast.IntegerLiteral */) { i64 val = string_i64((*field->expr._v__ast__IntegerLiteral).val); if (v__checker__overflows_i32(val)) { v__checker__Checker_error(c, _S("overflow in implicit type `int`, use explicit type casting instead"), (*field->expr._v__ast__IntegerLiteral).pos); } } } c->const_deps = __new_array_with_default(0, 0, sizeof(string), 0); c->const_var = prev_const_var; } } VV_LOC void v__checker__Checker_enum_decl(v__checker__Checker* c, v__ast__EnumDecl* node) { v__checker__Checker_check_valid_pascal_case(c, node->name, _S("enum name"), node->pos); if (node->typ == _const_v__ast__invalid_type) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot register enum `"), 0xfe10, {.d_s = node->name}}, {_S("`, another type with this name exists"), 0, { .d_c = 0 }}})), node->pos); return; } Array_u64 useen = __new_array_with_default(0, 0, sizeof(u64), 0); Array_i64 iseen = __new_array_with_default(0, 0, sizeof(i64), 0); Map_string_int seen_enum_field_names = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; if (node->fields.len == 0) { v__checker__Checker_error(c, _S("enum cannot be empty"), node->pos); } i64 enum_imin = ((i64)(0)); i64 enum_imax = ((i64)(0)); u64 enum_umin = ((u64)(0U)); u64 enum_umax = ((u64)(0U)); bool __v_signed = true; string senum_type = v__ast__Table_type_to_str(c->table, node->typ); if (node->typ == (_const_v__ast__i8_type)) { __v_signed = true; enum_imin = _const_min_i8; enum_imax = _const_max_i8; } else if (node->typ == (_const_v__ast__i16_type)) { __v_signed = true; enum_imin = _const_min_i16; enum_imax = _const_max_i16; } else if (node->typ == (_const_v__ast__int_type)) { __v_signed = true; enum_imin = _const_min_i32; enum_imax = _const_max_i32; } else if (node->typ == (_const_v__ast__i64_type)) { __v_signed = true; enum_imin = _const_min_i64; enum_imax = _const_max_i64; } else if (node->typ == (_const_v__ast__u8_type)) { __v_signed = false; enum_umin = _const_min_u8; enum_umax = _const_max_u8; } else if (node->typ == (_const_v__ast__u16_type)) { __v_signed = false; enum_umin = _const_min_u16; enum_umax = _const_max_u16; } else if (node->typ == (_const_v__ast__u32_type)) { __v_signed = false; enum_umin = _const_min_u32; enum_umax = _const_max_u32; } else if (node->typ == (_const_v__ast__u64_type)) { __v_signed = false; enum_umin = _const_min_u64; enum_umax = _const_max_u64; } else { if (_SLIT_EQ(senum_type.str, senum_type.len, "i32")) { __v_signed = true; enum_imin = _const_min_i32; enum_imax = _const_max_i32; } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = senum_type}}, {_S("` is not one of `i8`,`i16`,`i32`,`int`,`i64`,`u8`,`u16`,`u32`,`u64`"), 0, { .d_c = 0 }}})), node->typ_pos); } } if (enum_imin > 0) { enum_imin *= -1; } for (int i = 0; i < node->fields.len; ++i) { v__ast__EnumField* field = ((v__ast__EnumField*)node->fields.data) + i; if (!c->pref->experimental && v__util__contains_capital(field->name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("field name `"), 0xfe10, {.d_s = field->name}}, {_S("` cannot contain uppercase letters, use snake_case instead"), 0, { .d_c = 0 }}})), field->pos); } int* _t2 = (int*)(map_get_check(ADDR(map, seen_enum_field_names), &(string[]){field->name})); _option_int _t1 = {0}; if (_t2) { *((int*)&_t1.data) = *((int*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { int _dummy_1 = (*(int*)_t1.data); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate enum field name `"), 0xfe10, {.d_s = field->name}}, {_S("`"), 0, { .d_c = 0 }}})), field->pos); } map_set(&seen_enum_field_names, &(string[]){field->name}, &(int[]) { i }); if (field->has_expr) { if (field->expr._typ == 363 /* v.ast.IntegerLiteral */) { v__checker__Checker_check_enum_field_integer_literal(c, (*field->expr._v__ast__IntegerLiteral), __v_signed, node->is_multi_allowed, senum_type, (*field->expr._v__ast__IntegerLiteral).pos, &useen, enum_umin, enum_umax, &iseen, enum_imin, enum_imax); } else if (field->expr._typ == 362 /* v.ast.InfixExpr */) { v__checker__Checker_infix_expr(c, (voidptr)&(*field->expr._v__ast__InfixExpr)); v__transformer__Transformer* t = v__transformer__new_transformer_with_table(c->table, c->pref); v__ast__Expr folded_expr = v__transformer__Transformer_infix_expr(t, (voidptr)&(*field->expr._v__ast__InfixExpr)); if ((folded_expr)._typ == 363 /* v.ast.IntegerLiteral */) { v__checker__Checker_check_enum_field_integer_literal(c, (*folded_expr._v__ast__IntegerLiteral), __v_signed, node->is_multi_allowed, senum_type, (*field->expr._v__ast__InfixExpr).pos, &useen, enum_umin, enum_umax, &iseen, enum_imin, enum_imax); } } else if (field->expr._typ == 374 /* v.ast.ParExpr */) { v__checker__Checker_expr(c, &(*field->expr._v__ast__ParExpr).expr); v__transformer__Transformer* t = v__transformer__new_transformer_with_table(c->table, c->pref); v__ast__Expr folded_expr = v__transformer__Transformer_expr(t, &(*field->expr._v__ast__ParExpr).expr); if ((folded_expr)._typ == 363 /* v.ast.IntegerLiteral */) { v__checker__Checker_check_enum_field_integer_literal(c, (*folded_expr._v__ast__IntegerLiteral), __v_signed, node->is_multi_allowed, senum_type, (*field->expr._v__ast__ParExpr).pos, &useen, enum_umin, enum_umax, &iseen, enum_imin, enum_imax); } } else if (field->expr._typ == 345 /* v.ast.CastExpr */) { v__ast__Type fe_type = v__checker__Checker_cast_expr(c, (voidptr)&(*field->expr._v__ast__CastExpr)); if (node->typ != fe_type) { string sfe_type = v__ast__Table_type_to_str(c->table, fe_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("the type of the enum value `"), 0xfe10, {.d_s = sfe_type}}, {_S("` != the enum type itself `"), 0xfe10, {.d_s = senum_type}}, {_S("`"), 0, { .d_c = 0 }}})), (*field->expr._v__ast__CastExpr).pos); } if (!v__ast__Type_is_pure_int(fe_type)) { v__checker__Checker_error(c, _S("the type of an enum value must be an integer type, like i8, u8, int, u64 etc."), (*field->expr._v__ast__CastExpr).pos); } if (((*field->expr._v__ast__CastExpr).expr)._typ == 355 /* v.ast.EnumVal */) { if (string__eq((*(*field->expr._v__ast__CastExpr).expr._v__ast__EnumVal).enum_name, node->name)) { if (!_IN_MAP(ADDR(string, (*(*field->expr._v__ast__CastExpr).expr._v__ast__EnumVal).val), ADDR(map, seen_enum_field_names))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = (*(*field->expr._v__ast__CastExpr).expr._v__ast__EnumVal).enum_name}}, {_S("."), 0xfe10, {.d_s = (*(*field->expr._v__ast__CastExpr).expr._v__ast__EnumVal).val}}, {_S("` should be declared before using it"), 0, { .d_c = 0 }}})), (*field->expr._v__ast__CastExpr).pos); } } } } else { if ((field->expr)._typ == 358 /* v.ast.Ident */) { if ((*field->expr._v__ast__Ident).language == v__ast__Language__c) { continue; } if ((*field->expr._v__ast__Ident).kind == v__ast__IdentKind__unresolved) { v__checker__Checker_ident(c, (voidptr)&(*field->expr._v__ast__Ident)); } if ((*field->expr._v__ast__Ident).kind == v__ast__IdentKind__constant && v__ast__Type_is_int((*((*field->expr._v__ast__Ident).obj.typ)))) { if (((*field->expr._v__ast__Ident).obj)._typ == 420 /* v.ast.ConstField */) { v__transformer__Transformer* t = v__transformer__new_transformer_with_table(c->table, c->pref); v__ast__Expr folded_expr = v__transformer__Transformer_expr(t, &(*(*field->expr._v__ast__Ident).obj._v__ast__ConstField).expr); if ((folded_expr)._typ == 363 /* v.ast.IntegerLiteral */) { v__checker__Checker_check_enum_field_integer_literal(c, (*folded_expr._v__ast__IntegerLiteral), __v_signed, node->is_multi_allowed, senum_type, (*field->expr._v__ast__Ident).pos, &useen, enum_umin, enum_umax, &iseen, enum_imin, enum_imax); } } continue; } } v__token__Pos pos = v__ast__Expr_pos(field->expr); if (pos.pos == 0) { pos = field->pos; } v__checker__Checker_error(c, _S("the default value for an enum has to be an integer"), pos); } } else { if (__v_signed) { if (iseen.len > 0) { i64 ilast = (*(i64*)array_last(iseen)); if (ilast == enum_imax) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("enum value overflows type `"), 0xfe10, {.d_s = senum_type}}, {_S("`, which has a maximum value of "), 0xfe09, {.d_i64 = enum_imax}}, {_SLIT0, 0, { .d_c = 0 }}})), field->pos); } else if (!c->pref->translated && !c->file->is_translated && !node->is_multi_allowed && (Array_i64_contains(iseen, (i64)(ilast + 1)))) { v__checker__Checker_add_error_detail(c, _S("use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed")); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("enum value `"), 0xfe09, {.d_i64 = (i64)(ilast + 1)}}, {_S("` already exists"), 0, { .d_c = 0 }}})), field->pos); } array_push((array*)&iseen, _MOV((i64[]){ (i64)(ilast + 1) })); } else { array_push((array*)&iseen, _MOV((i64[]){ 0 })); } } else { if (useen.len > 0) { u64 ulast = (*(u64*)array_last(useen)); if (ulast == enum_umax) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("enum value overflows type `"), 0xfe10, {.d_s = senum_type}}, {_S("`, which has a maximum value of "), 0xfe08, {.d_u64 = enum_umax}}, {_SLIT0, 0, { .d_c = 0 }}})), field->pos); } else if (!c->pref->translated && !c->file->is_translated && !node->is_multi_allowed && (Array_u64_contains(useen, (u64)(ulast + 1U)))) { v__checker__Checker_add_error_detail(c, _S("use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed")); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("enum value `"), 0xfe08, {.d_u64 = (u64)(ulast + 1U)}}, {_S("` already exists"), 0, { .d_c = 0 }}})), field->pos); } array_push((array*)&useen, _MOV((u64[]){ (u64)(ulast + 1U) })); } else { array_push((array*)&useen, _MOV((u64[]){ 0U })); } } } } } VV_LOC void v__checker__Checker_check_enum_field_integer_literal(v__checker__Checker* c, v__ast__IntegerLiteral expr, bool is_signed, bool is_multi_allowed, string styp, v__token__Pos pos, Array_u64* useen, u64 umin, u64 umax, Array_i64* iseen, i64 imin, i64 imax) { bool overflows = false; u64 uval = ((u64)(0U)); i64 ival = ((i64)(0)); if (is_signed) { i64 val = string_i64(expr.val); ival = val; if (val < imin || val >= imax) { v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("enum value `"), 0xfe10, {.d_s = expr.val}}, {_S("` overflows the enum type `"), 0xfe10, {.d_s = styp}}, {_S("`, values of which have to be in ["), 0xfe09, {.d_i64 = imin}}, {_S(", "), 0xfe09, {.d_i64 = imax}}, {_S("]"), 0, { .d_c = 0 }}})), pos); overflows = true; } } else { u64 val = string_u64(expr.val); uval = val; if (val >= umax) { overflows = true; if (val == umax) { bool is_bin = string_starts_with(expr.val, _S("0b")); bool is_oct = string_starts_with(expr.val, _S("0o")); bool is_hex = string_starts_with(expr.val, _S("0x")); if (is_hex) { overflows = !string__eq(u64_hex(val), u64_hex(umax)); } else if (!is_bin && !is_oct && !is_hex) { overflows = !string__eq(string_str(expr.val), u64_str(umax)); } } if (overflows) { v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("enum value `"), 0xfe10, {.d_s = expr.val}}, {_S("` overflows the enum type `"), 0xfe10, {.d_s = styp}}, {_S("`, values of which have to be in ["), 0xfe08, {.d_u64 = umin}}, {_S(", "), 0xfe08, {.d_u64 = umax}}, {_S("]"), 0, { .d_c = 0 }}})), pos); } } } if (!overflows && !c->pref->translated && !c->file->is_translated && !is_multi_allowed) { if ((is_signed && (Array_i64_contains(*iseen, ival))) || (!is_signed && (Array_u64_contains(*useen, uval)))) { v__checker__Checker_add_error_detail(c, _S("use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed")); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("enum value `"), 0xfe10, {.d_s = expr.val}}, {_S("` already exists"), 0, { .d_c = 0 }}})), pos); } } if (is_signed) { array_push((array*)iseen, _MOV((i64[]){ ival })); } else { array_push((array*)useen, _MOV((u64[]){ uval })); } } inline VV_LOC void v__checker__Checker_check_loop_labels(v__checker__Checker* c, string label, v__token__Pos pos) { if ((label).len == 0) { return; } if ((Array_string_contains(c->loop_labels, label))) { v__checker__Checker_error(c, _S("the loop label was already defined before"), pos); return; } array_push((array*)&c->loop_labels, _MOV((string[]){ string_clone(label) })); } VV_LOC void v__checker__Checker_stmt(v__checker__Checker* c, v__ast__Stmt* node) { #if defined(CUSTOM_DEFINE_trace_checker) { string ntype = string_replace(charptr_vstring_literal(v_typeof_sumtype_v__ast__Stmt( (*node)._typ )), _S("v.ast."), _S("")); eprintln(str_intp(5, _MOV((StrIntpData[]){{_S("checking: "), 0x3cfe10, {.d_s = c->file->path}}, {_S(" | pos: "), 0x4efe10, {.d_s = v__token__Pos_line_str((*(node->pos)))}}, {_S(" | node: "), 0xfe10, {.d_s = ntype}}, {_S(" | "), 0xfe10, {.d_s = v__ast__Stmt_str(*node)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif c->expected_type = _const_v__ast__void_type; if (node->_typ == 401 /* v.ast.ExprStmt */) { (*node->_v__ast__ExprStmt).typ = v__checker__Checker_expr(c, &(*node->_v__ast__ExprStmt).expr); c->expected_type = _const_v__ast__void_type; v__ast__Type or_typ = _const_v__ast__void_type; if ((*node->_v__ast__ExprStmt).expr._typ == 361 /* v.ast.IndexExpr */) { if ((*(*node->_v__ast__ExprStmt).expr._v__ast__IndexExpr).or_expr.kind != v__ast__OrKind__absent) { (*node->_v__ast__ExprStmt).is_expr = true; or_typ = (*node->_v__ast__ExprStmt).typ; } } else if ((*node->_v__ast__ExprStmt).expr._typ == 376 /* v.ast.PrefixExpr */) { if ((*(*node->_v__ast__ExprStmt).expr._v__ast__PrefixExpr).or_block.kind != v__ast__OrKind__absent) { (*node->_v__ast__ExprStmt).is_expr = true; or_typ = (*node->_v__ast__ExprStmt).typ; } } else { } if (!c->pref->is_repl && (c->stmt_level == 1 || (c->stmt_level > 1 && !c->is_last_stmt))) { if (((*node->_v__ast__ExprStmt).expr)._typ == 362 /* v.ast.InfixExpr */) { if ((*(*node->_v__ast__ExprStmt).expr._v__ast__InfixExpr).op == v__token__Kind__left_shift) { v__ast__TypeSymbol* left_sym = v__ast__Table_final_sym(c->table, (*(*node->_v__ast__ExprStmt).expr._v__ast__InfixExpr).left_type); if (left_sym->kind != v__ast__Kind__array && v__ast__Table_final_sym(c->table, v__checker__Checker_unwrap_generic(c, (*(*node->_v__ast__ExprStmt).expr._v__ast__InfixExpr).left_type))->kind != v__ast__Kind__array) { v__checker__Checker_error(c, _S("unused expression"), (*node->_v__ast__ExprStmt).pos); } } } } if (!c->inside_return) { v__checker__Checker_check_expr_option_or_result_call(c, (*node->_v__ast__ExprStmt).expr, or_typ); } } else if (node->_typ == 392 /* v.ast.AssignStmt */) { v__checker__Checker_assign_stmt(c, &/*mut*/(*node->_v__ast__AssignStmt)); } else if (node->_typ == 393 /* v.ast.Block */) { v__checker__Checker_block(c, &/*mut*/(*node->_v__ast__Block)); } else if (node->_typ == 394 /* v.ast.BranchStmt */) { v__checker__Checker_branch_stmt(c, (*node->_v__ast__BranchStmt)); } else if (node->_typ == 395 /* v.ast.ComptimeFor */) { v__checker__Checker_comptime_for(c, &/*mut*/(*node->_v__ast__ComptimeFor)); } else if (node->_typ == 396 /* v.ast.ConstDecl */) { c->inside_const = true; v__checker__Checker_const_decl(c, &/*mut*/(*node->_v__ast__ConstDecl)); c->inside_const = false; } else if (node->_typ == 398 /* v.ast.DeferStmt */) { c->inside_defer = true; if ((*node->_v__ast__DeferStmt).idx_in_fn < 0 && c->table->cur_fn != ((void*)0)) { (*node->_v__ast__DeferStmt).idx_in_fn = c->table->cur_fn->defer_stmts.len; array_push((array*)&c->table->cur_fn->defer_stmts, _MOV((v__ast__DeferStmt[]){ *&(*node->_v__ast__DeferStmt) })); } if (c->locked_names.len != 0 || c->rlocked_names.len != 0) { v__checker__Checker_error(c, _S("defers are not allowed in lock statements"), (*node->_v__ast__DeferStmt).pos); } for (int i = 0; i < (*node->_v__ast__DeferStmt).defer_vars.len; ++i) { v__ast__Ident ident = ((v__ast__Ident*)(*node->_v__ast__DeferStmt).defer_vars.data)[i]; v__ast__Ident id = ident; if ((id.info)._typ == 477 /* v.ast.IdentVar */) { if (id.comptime && (id.tok_kind == v__token__Kind__question || (Array_string_contains(_const_v__ast__valid_comptime_not_user_defined, id.name)))) { array_set(&(*node->_v__ast__DeferStmt).defer_vars, i, &(v__ast__Ident[]) { ((v__ast__Ident){.language = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comptime = 0,.scope = ((void*)0),.obj = _const_v__ast__empty_scope_object,.mod = (string){.str=(byteptr)"", .is_lit=1},.name = _S(""),.full_name = (string){.str=(byteptr)"", .is_lit=1},.cached_name = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.info = (v__ast__IdentInfo){._v__ast__IdentFn=HEAP(v__ast__IdentFn, ((v__ast__IdentFn){.typ = 0,})),._typ=476},.is_mut = 0,.or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.ct_expr = 0,}) }); continue; } v__ast__Type typ = v__checker__Checker_ident(c, (voidptr)&id); if (typ == 30) { continue; } (*id.info._v__ast__IdentVar).typ = typ; array_set(&(*node->_v__ast__DeferStmt).defer_vars, i, &(v__ast__Ident[]) { id }); } } v__checker__Checker_stmts(c, &(*node->_v__ast__DeferStmt).stmts); c->inside_defer = false; } else if (node->_typ == 400 /* v.ast.EnumDecl */) { v__checker__Checker_enum_decl(c, &/*mut*/(*node->_v__ast__EnumDecl)); } else if (node->_typ == 237 /* v.ast.FnDecl */) { v__checker__Checker_fn_decl(c, &/*mut*/(*node->_v__ast__FnDecl)); } else if (node->_typ == 402 /* v.ast.ForCStmt */) { v__checker__Checker_for_c_stmt(c, &/*mut*/(*node->_v__ast__ForCStmt)); } else if (node->_typ == 403 /* v.ast.ForInStmt */) { v__checker__Checker_for_in_stmt(c, &/*mut*/(*node->_v__ast__ForInStmt)); } else if (node->_typ == 404 /* v.ast.ForStmt */) { v__checker__Checker_for_stmt(c, &/*mut*/(*node->_v__ast__ForStmt)); } else if (node->_typ == 405 /* v.ast.GlobalDecl */) { v__checker__Checker_global_decl(c, &/*mut*/(*node->_v__ast__GlobalDecl)); } else if (node->_typ == 406 /* v.ast.GotoLabel */) { v__checker__Checker_goto_label(c, (*node->_v__ast__GotoLabel)); } else if (node->_typ == 407 /* v.ast.GotoStmt */) { v__checker__Checker_goto_stmt(c, (*node->_v__ast__GotoStmt)); } else if (node->_typ == 408 /* v.ast.HashStmt */) { v__checker__Checker_hash_stmt(c, &/*mut*/(*node->_v__ast__HashStmt)); } else if (node->_typ == 409 /* v.ast.Import */) { v__checker__Checker_import_stmt(c, (*node->_v__ast__Import)); } else if (node->_typ == 410 /* v.ast.InterfaceDecl */) { v__checker__Checker_interface_decl(c, &/*mut*/(*node->_v__ast__InterfaceDecl)); } else if (node->_typ == 411 /* v.ast.Module */) { c->mod = (*node->_v__ast__Module).name; c->is_just_builtin_mod = (fast_string_eq((*node->_v__ast__Module).name, _S("builtin")) || fast_string_eq((*node->_v__ast__Module).name, _S("builtin.closure"))); c->is_builtin_mod = c->is_just_builtin_mod || (fast_string_eq((*node->_v__ast__Module).name, _S("os")) || fast_string_eq((*node->_v__ast__Module).name, _S("strconv"))); v__checker__Checker_check_valid_snake_case(c, (*node->_v__ast__Module).name, _S("module name"), (*node->_v__ast__Module).pos); } else if (node->_typ == 412 /* v.ast.Return */) { v__checker__Checker_return_stmt(c, &/*mut*/(*node->_v__ast__Return)); c->scope_returns = true; } else if (node->_typ == 413 /* v.ast.SemicolonStmt */) { } else if (node->_typ == 414 /* v.ast.SqlStmt */) { v__checker__Checker_sql_stmt(c, &/*mut*/(*node->_v__ast__SqlStmt)); } else if (node->_typ == 415 /* v.ast.StructDecl */) { v__checker__Checker_struct_decl(c, &/*mut*/(*node->_v__ast__StructDecl)); } else if (node->_typ == 334 /* v.ast.TypeDecl */) { v__checker__Checker_type_decl(c, &(*node->_v__ast__TypeDecl)); } else if (node->_typ == 399 /* v.ast.EmptyStmt */) { if (c->pref->is_verbose) { eprintln(_S("Checker.stmt() EmptyStmt")); print_backtrace(); } } else if (node->_typ == 335 /* v.ast.NodeError */) { } else if (node->_typ == 397 /* v.ast.DebuggerStmt */) { } else if (node->_typ == 390 /* v.ast.AsmStmt */) { v__checker__Checker_asm_stmt(c, &/*mut*/(*node->_v__ast__AsmStmt)); } else if (node->_typ == 391 /* v.ast.AssertStmt */) { v__checker__Checker_assert_stmt(c, &/*mut*/(*node->_v__ast__AssertStmt)); } } VV_LOC void v__checker__Checker_assert_stmt(v__checker__Checker* c, v__ast__AssertStmt* node) { v__ast__Type cur_exp_typ = c->expected_type; c->expected_type = _const_v__ast__bool_type; v__ast__Type assert_type = v__checker__Checker_check_expr_option_or_result_call(c, node->expr, v__checker__Checker_expr(c, &node->expr)); v__checker__Checker_markused_assertstmt_auto_str(c, node); if (assert_type != 19) { string atype_name = v__ast__Table_sym(c->table, assert_type)->name; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("assert can be used only with `bool` expressions, but found `"), 0xfe10, {.d_s = atype_name}}, {_S("` instead"), 0, { .d_c = 0 }}})), node->pos); } if ((node->extra)._typ != 354 /* v.ast.EmptyExpr */) { v__ast__Type extra_type = v__checker__Checker_expr(c, &node->extra); if (extra_type != _const_v__ast__string_type) { string extra_type_name = v__ast__Table_sym(c->table, extra_type)->name; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("assert allows only a single string as its second argument, but found `"), 0xfe10, {.d_s = extra_type_name}}, {_S("` instead"), 0, { .d_c = 0 }}})), node->extra_pos); } } v__checker__Checker_fail_if_unreadable(c, node->expr, _const_v__ast__bool_type_idx, _S("assertion")); c->expected_type = cur_exp_typ; } VV_LOC void v__checker__Checker_block(v__checker__Checker* c, v__ast__Block* node) { if (node->is_unsafe) { bool prev_unsafe = c->inside_unsafe; c->inside_unsafe = true; v__checker__Checker_stmts(c, &node->stmts); c->inside_unsafe = prev_unsafe; } else { bool _t1 = (node->stmts.len > 0); if ( _t1 && ((*(v__ast__Stmt*)array_last(node->stmts)))._typ == 401 /* v.ast.ExprStmt */) { v__ast__ExprStmt last_stmt = ({ v__ast__Stmt _t2 = (*(v__ast__Stmt*)array_last(node->stmts)); *(v__ast__ExprStmt*)__as_cast(_t2._v__ast__ExprStmt,_t2._typ, 401); }); if (!((last_stmt.expr)._typ == 344 /* v.ast.CallExpr */ || (last_stmt.expr)._typ == 359 /* v.ast.IfExpr */ || (last_stmt.expr)._typ == 369 /* v.ast.MatchExpr */ || (last_stmt.expr)._typ == 362 /* v.ast.InfixExpr */)) { v__checker__Checker_warn(c, _S("expression evaluated but not used"), (*((*(v__ast__Stmt*)array_last(node->stmts)).pos))); } } v__checker__Checker_stmts(c, &node->stmts); } } VV_LOC void v__checker__Checker_branch_stmt(v__checker__Checker* c, v__ast__BranchStmt node) { if (c->inside_defer) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__token__Kind_str(node.kind)}}, {_S("` is not allowed in defer statements"), 0, { .d_c = 0 }}})), node.pos); } if (c->in_for_count == 0) { if (c->comptime->inside_comptime_for) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__token__Kind_str(node.kind)}}, {_S(" is not allowed within a compile-time loop"), 0, { .d_c = 0 }}})), node.pos); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__token__Kind_str(node.kind)}}, {_S(" statement not within a loop"), 0, { .d_c = 0 }}})), node.pos); } } if (node.label.len > 0) { if (!(Array_string_contains(c->loop_labels, node.label))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid label name `"), 0xfe10, {.d_s = node.label}}, {_S("`"), 0, { .d_c = 0 }}})), node.pos); } } } VV_LOC void v__checker__Checker_global_decl(v__checker__Checker* c, v__ast__GlobalDecl* node) { Array_string required_args_attr = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("_linker_section")})); for (int _t1 = 0; _t1 < required_args_attr.len; ++_t1) { string attr_name = ((string*)required_args_attr.data)[_t1]; _option_v__ast__Attr _t2; if (_t2 = Array_v__ast__Attr_find_first(node->attrs, attr_name), _t2.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t2.data; if ((attr.arg).len == 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("missing argument for @["), 0xfe10, {.d_s = attr_name}}, {_S("] attribute"), 0, { .d_c = 0 }}})), attr.pos); } } } for (int _t3 = 0; _t3 < node->fields.len; ++_t3) { v__ast__GlobalField* field = ((v__ast__GlobalField*)node->fields.data) + _t3; v__checker__Checker_check_valid_snake_case(c, field->name, _S("global name"), field->pos); if ((Array_string_contains(_const_v__ast__global_reserved_type_names, field->name))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid use of reserved type `"), 0xfe10, {.d_s = field->name}}, {_S("` as a global name"), 0, { .d_c = 0 }}})), field->pos); } if (fast_string_eq(field->name, _S("_"))) { v__checker__Checker_error(c, _S("cannot use `_` as a global name"), field->pos); return; } if ((Array_string_contains(c->global_names, field->name))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate global `"), 0xfe10, {.d_s = field->name}}, {_S("`"), 0, { .d_c = 0 }}})), field->pos); } if ((Array_string_contains(c->const_names, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->mod}}, {_S("."), 0xfe10, {.d_s = field->name}}, {_SLIT0, 0, { .d_c = 0 }}}))))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate global and const `"), 0xfe10, {.d_s = field->name}}, {_S("`"), 0, { .d_c = 0 }}})), field->pos); } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, field->typ); if (sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), field->typ_pos); } if (field->has_expr) { if ((field->expr)._typ == 336 /* v.ast.AnonFn */ && fast_string_eq(field->name, _S("main"))) { v__checker__Checker_error(c, _S("the `main` function is the program entry point, cannot redefine it"), field->pos); } field->typ = v__checker__Checker_expr(c, &field->expr); _option_v__ast__GlobalField_ptr _t4 = v__ast__Scope_find_global(c->file->global_scope, field->name); if (_t4.state != 0) { IError err = _t4.err; _v_panic(_S("internal compiler error - could not find global in scope")); VUNREACHABLE(); ; } v__ast__GlobalField* v = (*(v__ast__GlobalField**)_t4.data); v->typ = v__ast__mktyp(field->typ); } else { v__ast__TypeSymbol* field_sym = v__ast__Table_sym(c->table, field->typ); if ((field_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && v__checker__Checker_array_fixed_has_unresolved_size(c, (v__ast__ArrayFixed*)__as_cast((field_sym->info)._v__ast__ArrayFixed,(field_sym->info)._typ, 549))) { v__ast__Expr size_expr = (*field_sym->info._v__ast__ArrayFixed).size_expr; field->typ = v__checker__Checker_eval_array_fixed_sizes(c, &size_expr, 0, (*field_sym->info._v__ast__ArrayFixed).elem_type); _option_v__ast__GlobalField_ptr _t5 = v__ast__Scope_find_global(c->file->global_scope, field->name); if (_t5.state != 0) { IError err = _t5.err; _v_panic(_S("internal compiler error - could not find global in scope")); VUNREACHABLE(); ; } v__ast__GlobalField* v = (*(v__ast__GlobalField**)_t5.data); v->typ = v__ast__mktyp(field->typ); } } array_push((array*)&c->global_names, _MOV((string[]){ string_clone(field->name) })); } } VV_LOC void v__checker__Checker_asm_stmt(v__checker__Checker* c, v__ast__AsmStmt* stmt) { if (stmt->is_goto) { v__checker__Checker_warn(c, _S("inline assembly goto is not supported, it will most likely not work"), stmt->pos); } if (v__pref__Backend_is_js(c->pref->backend)) { v__checker__Checker_error(c, _S("inline assembly is not supported in the js backend"), stmt->pos); } Array_string aliases = v__checker__Checker_asm_ios(c, &stmt->output, stmt->scope, true); Array_string aliases2 = v__checker__Checker_asm_ios(c, &stmt->input, stmt->scope, false); _PUSH_MANY(&aliases, (aliases2), _t1, Array_string); for (int _t2 = 0; _t2 < stmt->templates.len; ++_t2) { v__ast__AsmTemplate* __v_template = ((v__ast__AsmTemplate*)stmt->templates.data) + _t2; if (__v_template->is_directive) { if (!(fast_string_eq(__v_template->name, _S("skip")) || fast_string_eq(__v_template->name, _S("space")) || fast_string_eq(__v_template->name, _S("byte")) || fast_string_eq(__v_template->name, _S("word")) || fast_string_eq(__v_template->name, _S("short")) || fast_string_eq(__v_template->name, _S("int")) || fast_string_eq(__v_template->name, _S("long")) || fast_string_eq(__v_template->name, _S("quad")) || fast_string_eq(__v_template->name, _S("globl")) || fast_string_eq(__v_template->name, _S("global")) || fast_string_eq(__v_template->name, _S("section")) || fast_string_eq(__v_template->name, _S("text")) || fast_string_eq(__v_template->name, _S("data")) || fast_string_eq(__v_template->name, _S("bss")) || fast_string_eq(__v_template->name, _S("fill")) || fast_string_eq(__v_template->name, _S("org")) || fast_string_eq(__v_template->name, _S("previous")) || fast_string_eq(__v_template->name, _S("string")) || fast_string_eq(__v_template->name, _S("asciz")) || fast_string_eq(__v_template->name, _S("ascii")))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown assembler directive: `"), 0xfe10, {.d_s = __v_template->name}}, {_S("`"), 0, { .d_c = 0 }}})), __v_template->pos); } } for (int _t3 = 0; _t3 < __v_template->args.len; ++_t3) { v__ast__AsmArg* arg = ((v__ast__AsmArg*)__v_template->args.data) + _t3; v__checker__Checker_asm_arg(c, *arg, *stmt, aliases); } } for (int _t4 = 0; _t4 < stmt->clobbered.len; ++_t4) { v__ast__AsmClobbered* clob = ((v__ast__AsmClobbered*)stmt->clobbered.data) + _t4; v__checker__Checker_asm_arg(c, v__ast__AsmRegister_to_sumtype_v__ast__AsmArg(&clob->reg), *stmt, aliases); } } VV_LOC void v__checker__Checker_asm_arg(v__checker__Checker* c, v__ast__AsmArg arg, v__ast__AsmStmt stmt, Array_string aliases) { if (arg._typ == 497 /* v.ast.AsmAlias */) { } else if (arg._typ == 496 /* v.ast.AsmAddressing */) { if (!((*arg._v__ast__AsmAddressing).scale == -1 || (*arg._v__ast__AsmAddressing).scale == 1 || (*arg._v__ast__AsmAddressing).scale == 2 || (*arg._v__ast__AsmAddressing).scale == 4 || (*arg._v__ast__AsmAddressing).scale == 8)) { v__checker__Checker_error(c, _S("scale must be one of 1, 2, 4, or 8"), (*arg._v__ast__AsmAddressing).pos); } v__checker__Checker_asm_arg(c, (*arg._v__ast__AsmAddressing).displacement, stmt, aliases); v__checker__Checker_asm_arg(c, (*arg._v__ast__AsmAddressing).base, stmt, aliases); v__checker__Checker_asm_arg(c, (*arg._v__ast__AsmAddressing).index, stmt, aliases); } else if (arg._typ == 342 /* v.ast.BoolLiteral */) { } else if (arg._typ == 356 /* v.ast.FloatLiteral */) { } else if (arg._typ == 347 /* v.ast.CharLiteral */) { } else if (arg._typ == 363 /* v.ast.IntegerLiteral */) { } else if (arg._typ == 419 /* v.ast.AsmRegister */) { } else if (arg._typ == 498 /* v.ast.AsmDisp */) { } else if (arg._typ == 21 /* string */) { } } VV_LOC Array_string v__checker__Checker_asm_ios(v__checker__Checker* c, Array_v__ast__AsmIO* ios, v__ast__Scope* scope, bool output) { Array_string aliases = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < ios->len; ++_t1) { v__ast__AsmIO* io = ((v__ast__AsmIO*)ios->data) + _t1; v__ast__Type typ = v__checker__Checker_expr(c, &io->expr); if (output) { v__checker__Checker_fail_if_immutable(c, &io->expr); } if ((io->alias).len != 0) { array_push((array*)&aliases, _MOV((string[]){ string_clone(io->alias) })); if (_IN_MAP(ADDR(string, io->alias), ADDR(map, scope->objects))) { map_set(&scope->objects, &(string[]){io->alias}, &(v__ast__ScopeObject[]) { v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){ .name = io->alias, .share = 0, .is_mut = 0, .is_static = 0, .is_volatile = 0, .is_autofree_tmp = 0, .is_inherited = 0, .has_inherited = 0, .is_arg = true, .is_auto_deref = 0, .is_unwrapped = 0, .is_index_var = 0, .expr = io->expr, .typ = typ, .orig_type = typ, .smartcasts = __new_array(0, 0, sizeof(v__ast__Type)), .pos = io->pos, .is_used = 0, .is_changed = 0, .ct_type_var = 0, .ct_type_unwrapped = 0, .is_or = 0, .is_tmp = 0, .is_auto_heap = 0, .is_stack_obj = 0, })))) }); } } } return aliases; } VV_LOC void v__checker__Checker_hash_stmt(v__checker__Checker* c, v__ast__HashStmt* node) { if (c->skip_flags) { return; } if (c->ct_cond_stack.len > 0) { node->ct_conds = array_clone_to_depth(&c->ct_cond_stack, 0); } if (v__pref__Backend_is_js(c->pref->backend) || c->pref->backend == v__pref__Backend__golang) { if (!string_ends_with(c->file->path, _S(".js.v")) && !string_ends_with(c->file->path, _S(".go.v")) && !string_ends_with(c->file->path, _S(".go.vv"))) { v__checker__Checker_error(c, _S("hash statements are only allowed in backend specific files such \"x.js.v\" and \"x.go.v\""), node->pos); } if (c->pref->backend != v__pref__Backend__golang && fast_string_eq(c->mod, _S("main"))) { v__checker__Checker_error(c, _S("hash statements are not allowed in the main module. Place them in a separate module."), node->pos); } return; } if (_SLIT_EQ(node->kind.str, node->kind.len, "include") || _SLIT_EQ(node->kind.str, node->kind.len, "insert") || _SLIT_EQ(node->kind.str, node->kind.len, "preinclude") || _SLIT_EQ(node->kind.str, node->kind.len, "postinclude")) { string original_flag = node->main; string flag = node->main; if (string_contains(flag, _S("@DIR"))) { string vdir = v__checker__Checker_dir_path(c); string val = string_replace(flag, _S("@DIR"), vdir); node->val = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->kind}}, {_S(" "), 0xfe10, {.d_s = val}}, {_SLIT0, 0, { .d_c = 0 }}})); node->main = val; flag = val; } if (string_contains(flag, _S("@VROOT"))) { _result_string _t1 = v__util__resolve_vmodroot(string_replace(flag, _S("@VROOT"), _S("@VMODROOT")), c->file->path); if (_t1.is_error) { IError err = _t1.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return; } string vroot = (*(string*)_t1.data); node->val = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->kind}}, {_S(" "), 0xfe10, {.d_s = vroot}}, {_SLIT0, 0, { .d_c = 0 }}})); node->main = vroot; flag = vroot; } if (string_contains(flag, _S("@VEXEROOT"))) { string vroot = string_replace(flag, _S("@VEXEROOT"), c->pref->vroot); node->val = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->kind}}, {_S(" "), 0xfe10, {.d_s = vroot}}, {_SLIT0, 0, { .d_c = 0 }}})); node->main = vroot; flag = vroot; } if (string_contains(flag, _S("@VMODROOT"))) { _result_string _t2 = v__util__resolve_vmodroot(flag, c->file->path); if (_t2.is_error) { IError err = _t2.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return; } string vroot = (*(string*)_t2.data); node->val = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->kind}}, {_S(" "), 0xfe10, {.d_s = vroot}}, {_SLIT0, 0, { .d_c = 0 }}})); node->main = vroot; flag = vroot; } if (string_contains(flag, _S("$env("))) { _result_string _t3 = v__util__resolve_env_value(flag, true); if (_t3.is_error) { IError err = _t3.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return; } string env = (*(string*)_t3.data); node->main = env; } if (string_contains(flag, _S("$d("))) { _result_string _t4 = v__util__resolve_d_value(c->pref->compile_values, flag); if (_t4.is_error) { IError err = _t4.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return; } string d = (*(string*)_t4.data); node->main = d; } string flag_no_comment = string_trim_space(string_all_before(flag, _S("//"))); if (fast_string_eq(node->kind, _S("include")) || fast_string_eq(node->kind, _S("preinclude")) || fast_string_eq(node->kind, _S("postinclude"))) { if (!((string_starts_with(flag_no_comment, _S("\"")) && string_ends_with(flag_no_comment, _S("\""))) || (string_starts_with(flag_no_comment, _S("<")) && string_ends_with(flag_no_comment, _S(">"))))) { v__checker__Checker_error(c, _S("including C files should use either `\"header_file.h\"` or `` quoting"), node->pos); } } if (fast_string_eq(node->kind, _S("insert"))) { if (!(string_starts_with(flag_no_comment, _S("\"")) && string_ends_with(flag_no_comment, _S("\"")))) { v__checker__Checker_error(c, _S("inserting .c or .h files, should use `\"header_file.h\"` quoting"), node->pos); } node->main = string_trim(node->main, _S("\"")); _result_string _t5; if (_t5 = os__read_file(node->main), !_t5.is_error) { string fcontent = *(string*)_t5.data; node->val = fcontent; } else { IError err = _t5.err; string missing_message = str_intp(3, _MOV((StrIntpData[]){{_S("The file "), 0xfe10, {.d_s = original_flag}}, {_S(", needed for insertion by module `"), 0xfe10, {.d_s = node->mod}}, {_S("`,"), 0, { .d_c = 0 }}})); if (os__is_file(node->main)) { missing_message = string__plus(missing_message, _S(" is not readable.")); } else { missing_message = string__plus(missing_message, _S(" does not exist.")); } if ((node->msg).len != 0) { missing_message = string__plus(missing_message, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = node->msg}}, {_S("."), 0, { .d_c = 0 }}}))); } v__checker__Checker_error(c, missing_message, node->pos); } } } else if (_SLIT_EQ(node->kind.str, node->kind.len, "pkgconfig")) { if (c->pref->output_cross_c) { return; } Array_string args = (string_contains(node->main, _S("--")) ? (string_split(node->main, _S(" "))) : (string_split(str_intp(2, _MOV((StrIntpData[]){{_S("--cflags --libs "), 0xfe10, {.d_s = node->main}}, {_SLIT0, 0, { .d_c = 0 }}})), _S(" ")))); _result_v__pkgconfig__Main_ptr _t6 = v__pkgconfig__main(args); if (_t6.is_error) { IError err = _t6.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return; } v__pkgconfig__Main* m = (*(v__pkgconfig__Main**)_t6.data); _result_string _t7 = v__pkgconfig__Main_run(m); if (_t7.is_error) { IError err = _t7.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return; } string cflags = (*(string*)_t7.data); _result_void _t8 = v__ast__Table_parse_cflag(c->table, cflags, c->mod, c->pref->compile_defines_all); if (_t8.is_error) { IError err = _t8.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return; } ; } else if (_SLIT_EQ(node->kind.str, node->kind.len, "flag")) { string flag = node->main; if (_SLIT_EQ(flag.str, flag.len, "flag")) { v__checker__Checker_error(c, _S("no argument(s) provided for #flag"), node->pos); } if (string_contains(flag, _S("@VROOT"))) { _result_string _t9 = v__util__resolve_vmodroot(string_replace(flag, _S("@VROOT"), _S("@VMODROOT")), c->file->path); if (_t9.is_error) { IError err = _t9.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return; } flag = (*(string*)_t9.data); } if (string_contains(flag, _S("@DIR"))) { flag = string_replace(flag, _S("@DIR"), v__checker__Checker_dir_path(c)); } if (string_contains(flag, _S("@VEXEROOT"))) { flag = string_replace(flag, _S("@VEXEROOT"), c->pref->vroot); } if (string_contains(flag, _S("@VMODROOT"))) { _result_string _t10 = v__util__resolve_vmodroot(flag, c->file->path); if (_t10.is_error) { IError err = _t10.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return; } flag = (*(string*)_t10.data); } if (string_contains(flag, _S("$env("))) { _result_string _t11 = v__util__resolve_env_value(flag, true); if (_t11.is_error) { IError err = _t11.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return; } flag = (*(string*)_t11.data); } if (string_contains(flag, _S("$d("))) { _result_string _t12 = v__util__resolve_d_value(c->pref->compile_values, flag); if (_t12.is_error) { IError err = _t12.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return; } flag = (*(string*)_t12.data); } Array_string _t13 = new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S("@VMOD"), _S("@VMODULE"), _S("@VPATH"), _S("@VLIB_PATH")})); for (int _t14 = 0; _t14 < _t13.len; ++_t14) { string deprecated = ((string*)_t13.data)[_t14]; if (string_contains(flag, deprecated)) { if (!string_contains(flag, _S("@VMODROOT"))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = deprecated}}, {_S(" had been deprecated, use @VMODROOT instead."), 0, { .d_c = 0 }}})), node->pos); } } } _result_void _t15 = v__ast__Table_parse_cflag(c->table, flag, c->mod, c->pref->compile_defines_all); if (_t15.is_error) { IError err = _t15.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); ; } ; } else { if (fast_string_eq(node->kind, _S("define"))) { if (!c->is_builtin_mod && !string_ends_with(c->file->path, _S(".c.v")) && !string_contains(c->file->path, _S("vlib"))) { if (!c->pref->is_bare) { v__checker__Checker_error(c, _S("#define can only be used in vlib (V's standard library) and *.c.v files"), node->pos); } } } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expected `#define`, `#flag`, `#include`, `#insert` or `#pkgconfig` not "), 0xfe10, {.d_s = node->val}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } } } VV_LOC void v__checker__Checker_import_stmt(v__checker__Checker* c, v__ast__Import node) { if (fast_string_eq(node.mod, _S("x.vweb"))) { println(_S("`x.vweb` is now `veb`. The module is no longer experimental. Simply `import veb` instead of `import x.vweb`.")); } else if (fast_string_eq(node.mod, _S("vweb"))) { println(_S("`vweb` has been deprecated. Please use the more stable and fast `veb` instead.")); } v__checker__Checker_check_valid_snake_case(c, node.alias, _S("module alias"), node.pos); for (int _t1 = 0; _t1 < node.syms.len; ++_t1) { v__ast__ImportSymbol sym = ((v__ast__ImportSymbol*)node.syms.data)[_t1]; string name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.mod}}, {_S("."), 0xfe10, {.d_s = sym.name}}, {_SLIT0, 0, { .d_c = 0 }}})); if (u8_is_capital(string_at(sym.name, 0))) { _option_v__ast__TypeSymbol_ptr _t2; if (_t2 = v__ast__Table_find_sym(c->table, name), _t2.state == 0) { v__ast__TypeSymbol* type_sym = *(v__ast__TypeSymbol**)_t2.data; if (type_sym->kind != v__ast__Kind__placeholder) { if (!type_sym->is_pub) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("module `"), 0xfe10, {.d_s = node.mod}}, {_S("` type `"), 0xfe10, {.d_s = sym.name}}, {_S("` is private"), 0, { .d_c = 0 }}})), sym.pos); } continue; } } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("module `"), 0xfe10, {.d_s = node.mod}}, {_S("` has no type `"), 0xfe10, {.d_s = sym.name}}, {_S("`"), 0, { .d_c = 0 }}})), sym.pos); continue; } if ((Array_string_contains(_const_v__ast__builtin_type_names, sym.name))) { v__checker__Checker_error(c, _S("cannot import or override builtin type"), sym.pos); } _option_v__ast__Fn _t3; if (_t3 = v__ast__Table_find_fn(c->table, name), _t3.state == 0) { v__ast__Fn func = *(v__ast__Fn*)_t3.data; if (!func.is_pub) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("module `"), 0xfe10, {.d_s = node.mod}}, {_S("` function `"), 0xfe10, {.d_s = sym.name}}, {_S("()` is private"), 0, { .d_c = 0 }}})), sym.pos); } continue; } _option_v__ast__ConstField_ptr _t4; if (_t4 = v__ast__Scope_find_const(c->file->global_scope, name), _t4.state == 0) { continue; } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("module `"), 0xfe10, {.d_s = node.mod}}, {_S("` has no constant or function `"), 0xfe10, {.d_s = sym.name}}, {_S("`"), 0, { .d_c = 0 }}})), sym.pos); } if ((*(bool*)map_get(ADDR(map, c->table->module_deprecated), &(string[]){node.mod}, &(bool[]){ 0 }))) { v__checker__Checker_deprecate(c, _S("module"), node.mod, (*(Array_v__ast__Attr*)map_get(ADDR(map, c->table->module_attrs), &(string[]){node.mod}, &(Array_v__ast__Attr[]){ __new_array(0, 0, sizeof(v__ast__Attr)) })), node.pos); } } VV_LOC void v__checker__Checker_stmts(v__checker__Checker* c, Array_v__ast__Stmt* stmts) { int old_stmt_level = c->stmt_level; c->stmt_level = 0; v__checker__Checker_stmts_ending_with_expression(c, stmts, c->expected_or_type); c->stmt_level = old_stmt_level; } VV_LOC void v__checker__Checker_stmts_ending_with_expression(v__checker__Checker* c, Array_v__ast__Stmt* stmts, v__ast__Type expected_or_type) { if (stmts->len == 0) { c->scope_returns = false; return; } if (c->stmt_level > 40) { c->scope_returns = false; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("checker: too many stmt levels: "), 0xfe07, {.d_i32 = c->stmt_level}}, {_S(" "), 0, { .d_c = 0 }}})), (*((*(v__ast__Stmt*)array_get(*stmts, 0)).pos))); return; } v__token__Pos unreachable = ((v__token__Pos){.len = 0,.line_nr = -1,.pos = 0,.col = 0,.last_line = 0,}); c->stmt_level++; for (int i = 0; i < stmts->len; ++i) { v__ast__Stmt* stmt = ((v__ast__Stmt*)stmts->data) + i; c->is_last_stmt = i == (int)(stmts->len - 1); if (c->scope_returns && unreachable.line_nr == -1) { unreachable = (*(stmt->pos)); } v__ast__Type prev_expected_or_type = c->expected_or_type; c->expected_or_type = expected_or_type; v__checker__Checker_stmt(c, stmt); c->expected_or_type = prev_expected_or_type; if (!c->inside_anon_fn && c->in_for_count > 0 && (stmt)->_typ == 394 /* v.ast.BranchStmt */ && ((*(v__ast__BranchStmt*)__as_cast((stmt)->_v__ast__BranchStmt,(stmt)->_typ, 394)).kind == v__token__Kind__key_continue || (*(v__ast__BranchStmt*)__as_cast((stmt)->_v__ast__BranchStmt,(stmt)->_typ, 394)).kind == v__token__Kind__key_break)) { c->scope_returns = true; } else if ((stmt)->_typ == 406 /* v.ast.GotoLabel */) { unreachable = ((v__token__Pos){.len = 0,.line_nr = -1,.pos = 0,.col = 0,.last_line = 0,}); c->scope_returns = false; } if (c->should_abort) { return; } } c->stmt_level--; if (unreachable.line_nr >= 0) { v__checker__Checker_error(c, _S("unreachable code"), unreachable); } v__checker__Checker_find_unreachable_statements_after_noreturn_calls(c, *stmts); c->scope_returns = false; } VV_LOC v__ast__Type v__checker__Checker_unwrap_generic(v__checker__Checker* c, v__ast__Type typ) { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { if (c->inside_generic_struct_init) { Array_string _t1 = {0}; Array_v__ast__Type _t1_orig = c->cur_struct_generic_types; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t3]; string _t2 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t1, &_t2); } Array_string generic_names =_t1; _option_v__ast__Type _t4; if (_t4 = v__ast__Table_convert_generic_type(c->table, typ, generic_names, c->cur_struct_concrete_types), _t4.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t4.data; return t_typ; } } if (c->table->cur_fn != ((void*)0)) { _option_v__ast__Type _t6; if (_t6 = v__ast__Table_convert_generic_type(c->table, typ, c->table->cur_fn->generic_names, c->table->cur_concrete_types), _t6.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t6.data; return t_typ; } if (c->inside_lambda && c->table->cur_lambda->call_ctx != ((void*)0)) { _option_v__ast__Type _t8; if (_t8 = v__ast__Table_convert_generic_type(c->table, typ, c->table->cur_lambda->func->decl.generic_names, c->table->cur_lambda->call_ctx->concrete_types), _t8.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t8.data; return t_typ; } } } } return typ; } v__ast__Type v__checker__Checker_expr(v__checker__Checker* c, v__ast__Expr* node) { bool v__checker__Checker_expr_defer_0 = false; bool v__checker__Checker_expr_defer_1 = false; c->expr_level++; v__checker__Checker_expr_defer_0 = true; if (c->expr_level > 40) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("checker: too many expr levels: "), 0xfe07, {.d_i32 = c->expr_level}}, {_S(" "), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*node)); v__ast__Type _t1 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t1; } if (node->_typ == 359 /* v.ast.IfExpr */) { v__ast__Type _t2 = v__checker__Checker_if_expr(c, &/*mut*/(*node->_v__ast__IfExpr)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t2; } else if (node->_typ == 351 /* v.ast.ComptimeType */) { v__checker__Checker_error(c, _S("incorrect use of compile-time type"), (*node->_v__ast__ComptimeType).pos); } else if (node->_typ == 354 /* v.ast.EmptyExpr */) { if (c->pref->is_verbose) { print_backtrace(); } v__checker__Checker_error(c, _S("checker.expr(): unhandled EmptyExpr"), ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,})); v__ast__Type _t3 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t3; } else if (node->_typ == 343 /* v.ast.CTempVar */) { v__ast__Type _t4 = (*node->_v__ast__CTempVar).typ; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t4; } else if (node->_typ == 336 /* v.ast.AnonFn */) { v__ast__Type _t5 = v__checker__Checker_anon_fn(c, &/*mut*/(*node->_v__ast__AnonFn)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t5; } else if (node->_typ == 337 /* v.ast.ArrayDecompose */) { v__ast__Type typ = v__checker__Checker_expr(c, &(*node->_v__ast__ArrayDecompose).expr); v__ast__TypeSymbol* type_sym = v__ast__Table_sym(c->table, typ); if (type_sym->kind == v__ast__Kind__array_fixed) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("direct decomposition of fixed array is not allowed, convert the fixed array to normal array via "), 0xfe10, {.d_s = v__ast__Expr_str(&(*node->_v__ast__ArrayDecompose).expr)}}, {_S("[..]"), 0, { .d_c = 0 }}})), v__ast__Expr_pos((*node->_v__ast__ArrayDecompose).expr)); v__ast__Type _t6 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t6; } else if (type_sym->kind != v__ast__Kind__array) { v__checker__Checker_error(c, _S("decomposition can only be used on arrays"), v__ast__Expr_pos((*node->_v__ast__ArrayDecompose).expr)); v__ast__Type _t7 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t7; } v__ast__Array array_info = *(v__ast__Array*)__as_cast((type_sym->info)._v__ast__Array,(type_sym->info)._typ, 513); v__ast__Type elem_type = v__ast__Type_set_flag(array_info.elem_type, v__ast__TypeFlag__variadic); (*node->_v__ast__ArrayDecompose).expr_type = typ; (*node->_v__ast__ArrayDecompose).arg_type = elem_type; v__ast__Type _t8 = elem_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t8; } else if (node->_typ == 338 /* v.ast.ArrayInit */) { v__ast__Type _t9 = v__checker__Checker_array_init(c, &/*mut*/(*node->_v__ast__ArrayInit)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t9; } else if (node->_typ == 339 /* v.ast.AsCast */) { (*node->_v__ast__AsCast).expr_type = v__checker__Checker_expr(c, &(*node->_v__ast__AsCast).expr); v__ast__TypeSymbol* expr_type_sym = v__ast__Table_sym(c->table, (*node->_v__ast__AsCast).expr_type); v__ast__TypeSymbol* type_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, (*node->_v__ast__AsCast).typ)); if (((*node->_v__ast__AsCast).expr)._typ == 358 /* v.ast.Ident */) { if (((*(*node->_v__ast__AsCast).expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { v__ast__Type _t10; /* if prepend */ if ((*(*(*node->_v__ast__AsCast).expr._v__ast__Ident).obj._v__ast__Var).smartcasts.len > 0) { _t10 = (*(v__ast__Type*)array_last((*(*(*node->_v__ast__AsCast).expr._v__ast__Ident).obj._v__ast__Var).smartcasts)); } else { _t10 = (*(*(*node->_v__ast__AsCast).expr._v__ast__Ident).obj._v__ast__Var).typ; } v__ast__Type ident_typ = _t10; if (!v__ast__Type_has_flag((*node->_v__ast__AsCast).typ, v__ast__TypeFlag__option) && v__ast__Type_has_flag(ident_typ, v__ast__TypeFlag__option) && (*(*node->_v__ast__AsCast).expr._v__ast__Ident).or_expr.kind == v__ast__OrKind__absent) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("variable `"), 0xfe10, {.d_s = (*(*node->_v__ast__AsCast).expr._v__ast__Ident).name}}, {_S("` is an Option, it must be unwrapped first"), 0, { .d_c = 0 }}})), (*(*node->_v__ast__AsCast).expr._v__ast__Ident).pos); } } } if (expr_type_sym->kind == v__ast__Kind__sum_type) { v__checker__Checker_ensure_type_exists(c, (*node->_v__ast__AsCast).typ, (*node->_v__ast__AsCast).pos); if (!v__ast__Table_sumtype_has_variant(c->table, v__checker__Checker_unwrap_generic(c, (*node->_v__ast__AsCast).expr_type), v__checker__Checker_unwrap_generic(c, (*node->_v__ast__AsCast).typ), true)) { string addr = string_repeat(_S("&"), v__ast__Type_nr_muls((*node->_v__ast__AsCast).typ)); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("cannot cast `"), 0xfe10, {.d_s = expr_type_sym->name}}, {_S("` to `"), 0xfe10, {.d_s = addr}}, {_SLIT0, 0xfe10, {.d_s = type_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), (*node->_v__ast__AsCast).pos); } } else if (expr_type_sym->kind == v__ast__Kind__interface) { v__checker__Checker_ensure_type_exists(c, (*node->_v__ast__AsCast).typ, (*node->_v__ast__AsCast).pos); if (type_sym->kind != v__ast__Kind__interface) { v__checker__Checker_type_implements(c, (*node->_v__ast__AsCast).typ, (*node->_v__ast__AsCast).expr_type, (*node->_v__ast__AsCast).pos); } } else if (v__ast__Type_clear_flag((*node->_v__ast__AsCast).expr_type, v__ast__TypeFlag__option) != v__ast__Type_clear_flag((*node->_v__ast__AsCast).typ, v__ast__TypeFlag__option)) { string s = str_intp(2, _MOV((StrIntpData[]){{_S("cannot cast non-sum type `"), 0xfe10, {.d_s = expr_type_sym->name}}, {_S("` using `as`"), 0, { .d_c = 0 }}})); if (type_sym->kind == v__ast__Kind__sum_type) { s = string__plus(s, str_intp(2, _MOV((StrIntpData[]){{_S(" - use e.g. `"), 0xfe10, {.d_s = type_sym->name}}, {_S("(some_expr)` instead."), 0, { .d_c = 0 }}}))); } v__checker__Checker_error(c, s, (*node->_v__ast__AsCast).pos); } v__ast__Type _t11 = (*node->_v__ast__AsCast).typ; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t11; } else if (node->_typ == 340 /* v.ast.Assoc */) { _option_v__ast__Var_ptr _t12 = v__ast__Scope_find_var((*node->_v__ast__Assoc).scope, (*node->_v__ast__Assoc).var_name); if (_t12.state != 0) { IError err = _t12.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } v__ast__Var* v = (*(v__ast__Var**)_t12.data); for (int i = 0; i < (*node->_v__ast__Assoc).fields.len; ++i) { v__ast__Expr expr = (*(v__ast__Expr*)array_get((*node->_v__ast__Assoc).exprs, i)); v__checker__Checker_expr(c, &expr); } (*node->_v__ast__Assoc).typ = v->typ; v__ast__Type _t13 = v->typ; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t13; } else if (node->_typ == 342 /* v.ast.BoolLiteral */) { v__ast__Type _t14 = _const_v__ast__bool_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t14; } else if (node->_typ == 345 /* v.ast.CastExpr */) { v__ast__Type _t15 = v__checker__Checker_cast_expr(c, &/*mut*/(*node->_v__ast__CastExpr)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t15; } else if (node->_typ == 344 /* v.ast.CallExpr */) { v__ast__Type ret_type = v__checker__Checker_call_expr(c, &/*mut*/(*node->_v__ast__CallExpr)); if (ret_type != 0 && v__ast__Table_sym(c->table, ret_type)->kind == v__ast__Kind__alias) { v__ast__Type unaliased_type = v__ast__Table_unaliased_type(c->table, ret_type); if (v__ast__Type_has_option_or_result(unaliased_type)) { ret_type = unaliased_type; } } if (!v__ast__Type_has_option_or_result(ret_type)) { v__checker__Checker_expr_or_block_err(c, (*node->_v__ast__CallExpr).or_block.kind, (*node->_v__ast__CallExpr).name, (*node->_v__ast__CallExpr).or_block.pos, false); } if ((*node->_v__ast__CallExpr).or_block.kind != v__ast__OrKind__absent) { if (v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__option)) { ret_type = v__ast__Type_clear_flag(ret_type, v__ast__TypeFlag__option); } if (v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__result)) { ret_type = v__ast__Type_clear_flag(ret_type, v__ast__TypeFlag__result); } } v__ast__Type _t16 = ret_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t16; } else if (node->_typ == 346 /* v.ast.ChanInit */) { v__ast__Type _t17 = v__checker__Checker_chan_init(c, &/*mut*/(*node->_v__ast__ChanInit)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t17; } else if (node->_typ == 347 /* v.ast.CharLiteral */) { v__ast__Type _t18 = _const_v__ast__rune_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t18; } else if (node->_typ == 348 /* v.ast.Comment */) { v__ast__Type _t19 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t19; } else if (node->_typ == 341 /* v.ast.AtExpr */) { v__ast__Type _t20 = v__checker__Checker_at_expr(c, &/*mut*/(*node->_v__ast__AtExpr)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t20; } else if (node->_typ == 349 /* v.ast.ComptimeCall */) { v__ast__Type _t21 = v__checker__Checker_comptime_call(c, &/*mut*/(*node->_v__ast__ComptimeCall)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t21; } else if (node->_typ == 350 /* v.ast.ComptimeSelector */) { v__ast__Type _t22 = v__checker__Checker_comptime_selector(c, &/*mut*/(*node->_v__ast__ComptimeSelector)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t22; } else if (node->_typ == 352 /* v.ast.ConcatExpr */) { v__ast__Type _t23 = v__checker__Checker_concat_expr(c, &/*mut*/(*node->_v__ast__ConcatExpr)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t23; } else if (node->_typ == 353 /* v.ast.DumpExpr */) { c->table->used_features->dump = true; c->expected_type = _const_v__ast__string_type; (*node->_v__ast__DumpExpr).expr_type = v__checker__Checker_expr(c, &(*node->_v__ast__DumpExpr).expr); v__checker__Checker_markused_dumpexpr(c, &/*mut*/(*node->_v__ast__DumpExpr)); if (c->comptime->inside_comptime_for && ((*node->_v__ast__DumpExpr).expr)._typ == 358 /* v.ast.Ident */) { if ((*(*node->_v__ast__DumpExpr).expr._v__ast__Ident).ct_expr) { (*node->_v__ast__DumpExpr).expr_type = v__type_resolver__TypeResolver_get_type(&c->type_resolver, v__ast__Ident_to_sumtype_v__ast__Expr(&(*(*node->_v__ast__DumpExpr).expr._v__ast__Ident))); } else if (_IN_MAP(ADDR(string, ((*(*node->_v__ast__DumpExpr).expr._v__ast__Ident)).name), ADDR(map, c->type_resolver.type_map))) { (*node->_v__ast__DumpExpr).expr_type = v__type_resolver__TypeResolver_get_ct_type_or_default(&c->type_resolver, ((*(*node->_v__ast__DumpExpr).expr._v__ast__Ident)).name, (*node->_v__ast__DumpExpr).expr_type); } } v__checker__Checker_check_expr_option_or_result_call(c, (*node->_v__ast__DumpExpr).expr, (*node->_v__ast__DumpExpr).expr_type); int etidx = v__ast__Type_idx((*node->_v__ast__DumpExpr).expr_type); if (etidx == 1) { v__checker__Checker_error(c, _S("dump expression can not be void"), v__ast__Expr_pos((*node->_v__ast__DumpExpr).expr)); v__ast__Type _t24 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t24; } else if (etidx == 18 && v__ast__Type_nr_muls((*node->_v__ast__DumpExpr).expr_type) == 0) { v__checker__Checker_error(c, _S("`char` values cannot be dumped directly, use dump(u8(x)) or dump(int(x)) instead"), v__ast__Expr_pos((*node->_v__ast__DumpExpr).expr)); v__ast__Type _t25 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t25; } v__ast__Type unwrapped_expr_type = v__checker__Checker_unwrap_generic(c, (*node->_v__ast__DumpExpr).expr_type); v__ast__TypeSymbol* tsym = v__ast__Table_sym(c->table, unwrapped_expr_type); v__ast__TypeSymbol* tsym_final = v__ast__Table_final_sym(c->table, unwrapped_expr_type); if (tsym_final->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((tsym_final->info)._v__ast__ArrayFixed,(tsym_final->info)._typ, 549); if (!info.is_fn_ret) { v__ast__Table_find_or_register_array_fixed(c->table, info.elem_type, info.size, info.size_expr, true); } } string type_cname = (v__ast__Type_has_flag((*node->_v__ast__DumpExpr).expr_type, v__ast__TypeFlag__option) ? (str_intp(2, _MOV((StrIntpData[]){{_S("_option_"), 0xfe10, {.d_s = tsym->cname}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (tsym->cname)); map_set(&c->table->dumps, &(int[]){((int)(v__ast__Type_clear_flags(unwrapped_expr_type, new_array_from_c_array(2, 2, sizeof(v__ast__TypeFlag), _MOV((v__ast__TypeFlag[2]){v__ast__TypeFlag__result, v__ast__TypeFlag__atomic_f})))))}, &(string[]) { type_cname }); (*node->_v__ast__DumpExpr).cname = type_cname; v__ast__Type _t26 = (*node->_v__ast__DumpExpr).expr_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t26; } else if (node->_typ == 355 /* v.ast.EnumVal */) { v__ast__Type _t27 = v__checker__Checker_enum_val(c, &/*mut*/(*node->_v__ast__EnumVal)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t27; } else if (node->_typ == 356 /* v.ast.FloatLiteral */) { v__ast__Type _t28 = _const_v__ast__float_literal_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t28; } else if (node->_typ == 357 /* v.ast.GoExpr */) { v__ast__Type _t29 = v__checker__Checker_go_expr(c, &/*mut*/(*node->_v__ast__GoExpr)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t29; } else if (node->_typ == 381 /* v.ast.SpawnExpr */) { v__ast__Type _t30 = v__checker__Checker_spawn_expr(c, &/*mut*/(*node->_v__ast__SpawnExpr)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t30; } else if (node->_typ == 358 /* v.ast.Ident */) { v__ast__Type _t31 = v__checker__Checker_ident(c, &/*mut*/(*node->_v__ast__Ident)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t31; } else if (node->_typ == 360 /* v.ast.IfGuardExpr */) { bool old_inside_if_guard = c->inside_if_guard; c->inside_if_guard = true; (*node->_v__ast__IfGuardExpr).expr_type = v__checker__Checker_expr(c, &(*node->_v__ast__IfGuardExpr).expr); c->inside_if_guard = old_inside_if_guard; if (c->pref->skip_unused && v__ast__Type_has_flag((*node->_v__ast__IfGuardExpr).expr_type, v__ast__TypeFlag__generic)) { v__ast__Type unwrapped_type = v__checker__Checker_unwrap_generic(c, (*node->_v__ast__IfGuardExpr).expr_type); map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){unwrapped_type}, &(bool[]) { true }); } if (!v__ast__Type_has_flag((*node->_v__ast__IfGuardExpr).expr_type, v__ast__TypeFlag__option) && !v__ast__Type_has_flag((*node->_v__ast__IfGuardExpr).expr_type, v__ast__TypeFlag__result)) { bool no_opt_or_res = true; if ((*node->_v__ast__IfGuardExpr).expr._typ == 361 /* v.ast.IndexExpr */) { no_opt_or_res = false; (*node->_v__ast__IfGuardExpr).expr_type = v__ast__Type_set_flag((*node->_v__ast__IfGuardExpr).expr_type, v__ast__TypeFlag__option); (*(*node->_v__ast__IfGuardExpr).expr._v__ast__IndexExpr).is_option = true; } else if ((*node->_v__ast__IfGuardExpr).expr._typ == 376 /* v.ast.PrefixExpr */) { if ((*(*node->_v__ast__IfGuardExpr).expr._v__ast__PrefixExpr).op == v__token__Kind__arrow) { no_opt_or_res = false; (*node->_v__ast__IfGuardExpr).expr_type = v__ast__Type_set_flag((*node->_v__ast__IfGuardExpr).expr_type, v__ast__TypeFlag__option); (*(*node->_v__ast__IfGuardExpr).expr._v__ast__PrefixExpr).is_option = true; } } else { } if (no_opt_or_res) { v__checker__Checker_error(c, _S("expression should either return an Option or a Result"), v__ast__Expr_pos((*node->_v__ast__IfGuardExpr).expr)); } } v__ast__Type _t32 = _const_v__ast__bool_type; // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t32; } else if (node->_typ == 361 /* v.ast.IndexExpr */) { v__ast__Type _t33 = v__checker__Checker_index_expr(c, &/*mut*/(*node->_v__ast__IndexExpr)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t33; } else if (node->_typ == 362 /* v.ast.InfixExpr */) { v__ast__Type _t34 = v__checker__Checker_infix_expr(c, &/*mut*/(*node->_v__ast__InfixExpr)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t34; } else if (node->_typ == 363 /* v.ast.IntegerLiteral */) { v__ast__Type _t35 = v__checker__Checker_int_lit(c, &/*mut*/(*node->_v__ast__IntegerLiteral)); // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t35; } else if (node->_typ == 365 /* v.ast.LambdaExpr */) { c->inside_lambda = true; c->table->cur_lambda = &(*node->_v__ast__LambdaExpr); v__checker__Checker_expr_defer_1 = true; v__ast__Type _t36 = v__checker__Checker_lambda_expr(c, &/*mut*/(*node->_v__ast__LambdaExpr), c->expected_type); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t36; } else if (node->_typ == 367 /* v.ast.LockExpr */) { v__ast__Type _t37 = v__checker__Checker_lock_expr(c, &/*mut*/(*node->_v__ast__LockExpr)); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t37; } else if (node->_typ == 368 /* v.ast.MapInit */) { v__ast__Type _t38 = v__checker__Checker_map_init(c, &/*mut*/(*node->_v__ast__MapInit)); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t38; } else if (node->_typ == 369 /* v.ast.MatchExpr */) { v__ast__Type _t39 = v__checker__Checker_match_expr(c, &/*mut*/(*node->_v__ast__MatchExpr)); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t39; } else if (node->_typ == 370 /* v.ast.Nil */) { if (!c->inside_unsafe) { v__checker__Checker_error(c, _S("`nil` is only allowed in `unsafe` code"), (*node->_v__ast__Nil).pos); } v__ast__Type _t40 = _const_v__ast__nil_type; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t40; } else if (node->_typ == 375 /* v.ast.PostfixExpr */) { v__ast__Type _t41 = v__checker__Checker_postfix_expr(c, &/*mut*/(*node->_v__ast__PostfixExpr)); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t41; } else if (node->_typ == 376 /* v.ast.PrefixExpr */) { v__ast__Type _t42 = v__checker__Checker_prefix_expr(c, &/*mut*/(*node->_v__ast__PrefixExpr)); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t42; } else if (node->_typ == 371 /* v.ast.None */) { v__ast__Type _t43 = _const_v__ast__none_type; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t43; } else if (node->_typ == 373 /* v.ast.OrExpr */) { v__ast__Type _t44 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t44; } else if (node->_typ == 374 /* v.ast.ParExpr */) { if (((*node->_v__ast__ParExpr).expr)._typ == 374 /* v.ast.ParExpr */) { v__checker__Checker_warn(c, _S("redundant parentheses are used"), (*node->_v__ast__ParExpr).pos); } v__ast__Type _t45 = v__checker__Checker_expr(c, &(*node->_v__ast__ParExpr).expr); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t45; } else if (node->_typ == 377 /* v.ast.RangeExpr */) { v__ast__Type ltyp = v__checker__Checker_expr(c, &(*node->_v__ast__RangeExpr).low); v__ast__Type htyp = v__checker__Checker_expr(c, &(*node->_v__ast__RangeExpr).high); if (!v__checker__Checker_check_types(c, ltyp, htyp)) { string lstype = v__ast__Table_type_to_str(c->table, ltyp); string hstype = v__ast__Table_type_to_str(c->table, htyp); v__checker__Checker_add_error_detail(c, _S("")); v__checker__Checker_add_error_detail(c, str_intp(2, _MOV((StrIntpData[]){{_S(" low part type: "), 0xfe10, {.d_s = lstype}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__checker__Checker_add_error_detail(c, str_intp(2, _MOV((StrIntpData[]){{_S("high part type: "), 0xfe10, {.d_s = hstype}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__checker__Checker_error(c, _S("the low and high parts of a range expression, should have matching types"), (*node->_v__ast__RangeExpr).pos); } (*node->_v__ast__RangeExpr).typ = v__checker__Checker_promote(c, ltyp, htyp); v__ast__Type _t46 = ltyp; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t46; } else if (node->_typ == 378 /* v.ast.SelectExpr */) { v__ast__Type _t47 = v__checker__Checker_select_expr(c, &/*mut*/(*node->_v__ast__SelectExpr)); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t47; } else if (node->_typ == 379 /* v.ast.SelectorExpr */) { v__ast__Type ret_type = v__checker__Checker_selector_expr(c, &/*mut*/(*node->_v__ast__SelectorExpr)); if (v__ast__Table_sym(c->table, ret_type)->kind == v__ast__Kind__chan) { v__ast__Type _t48 = ret_type; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t48; } if (!v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__option) && !v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__result)) { v__checker__Checker_expr_or_block_err(c, (*node->_v__ast__SelectorExpr).or_block.kind, (*node->_v__ast__SelectorExpr).field_name, (*node->_v__ast__SelectorExpr).or_block.pos, true); } if ((*node->_v__ast__SelectorExpr).or_block.kind != v__ast__OrKind__absent) { if (v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__option)) { ret_type = v__ast__Type_clear_flag(ret_type, v__ast__TypeFlag__option); } if (v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__result)) { ret_type = v__ast__Type_clear_flag(ret_type, v__ast__TypeFlag__result); } } v__ast__Type _t49 = ret_type; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t49; } else if (node->_typ == 380 /* v.ast.SizeOf */) { if (!(*node->_v__ast__SizeOf).is_type) { (*node->_v__ast__SizeOf).typ = v__checker__Checker_expr(c, &(*node->_v__ast__SizeOf).expr); } v__ast__TypeSymbol* sym = v__ast__Table_final_sym(c->table, (*node->_v__ast__SizeOf).typ); if (sym->kind == v__ast__Kind__placeholder && sym->language != v__ast__Language__c) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), (*node->_v__ast__SizeOf).pos); } v__ast__Type _t50 = _const_v__ast__u32_type; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t50; } else if (node->_typ == 364 /* v.ast.IsRefType */) { if (!(*node->_v__ast__IsRefType).is_type) { (*node->_v__ast__IsRefType).typ = v__checker__Checker_expr(c, &(*node->_v__ast__IsRefType).expr); } v__ast__Type _t51 = _const_v__ast__bool_type; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t51; } else if (node->_typ == 372 /* v.ast.OffsetOf */) { v__ast__Type _t52 = v__checker__Checker_offset_of(c, (*node->_v__ast__OffsetOf)); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t52; } else if (node->_typ == 382 /* v.ast.SqlExpr */) { v__ast__Type _t53 = v__checker__Checker_sql_expr(c, &/*mut*/(*node->_v__ast__SqlExpr)); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t53; } else if (node->_typ == 384 /* v.ast.StringLiteral */) { if ((*node->_v__ast__StringLiteral).language == v__ast__Language__c) { v__ast__Type _t54 = v__ast__Type_set_nr_muls(_const_v__ast__u8_type, 1); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t54; } if ((*node->_v__ast__StringLiteral).language == v__ast__Language__js) { if (v__ast__Type_is_void(c->js_string)) { c->js_string = v__ast__Table_find_type(c->table, _S("JS.String")); } v__ast__Type _t55 = c->js_string; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t55; } if ((*node->_v__ast__StringLiteral).is_raw) { v__ast__Type _t56 = _const_v__ast__string_type; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t56; } v__ast__Type _t57 = v__checker__Checker_string_lit(c, &/*mut*/(*node->_v__ast__StringLiteral)); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t57; } else if (node->_typ == 383 /* v.ast.StringInterLiteral */) { v__ast__Type _t58 = v__checker__Checker_string_inter_lit(c, &/*mut*/(*node->_v__ast__StringInterLiteral)); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t58; } else if (node->_typ == 385 /* v.ast.StructInit */) { if ((*node->_v__ast__StructInit).unresolved) { v__ast__Expr expr_ = v__ast__Table_resolve_init(c->table, (*node->_v__ast__StructInit), v__checker__Checker_unwrap_generic(c, (*node->_v__ast__StructInit).typ)); v__checker__Checker_markused_used_maps(c, c->table->used_features->used_maps == 0 && (expr_)._typ == 368 /* v.ast.MapInit */); v__ast__Type _t59 = v__checker__Checker_expr(c, &expr_); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t59; } Array_string inited_fields = __new_array_with_default(0, 0, sizeof(string), 0); v__ast__Type _t60 = v__checker__Checker_struct_init(c, &/*mut*/(*node->_v__ast__StructInit), false, &inited_fields); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t60; } else if (node->_typ == 386 /* v.ast.TypeNode */) { if (!c->inside_x_is_type && v__ast__Type_has_flag((*node->_v__ast__TypeNode).typ, v__ast__TypeFlag__generic) && c->table->cur_fn != 0 && c->table->cur_fn->generic_names.len == 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unexpected generic variable in non-generic function `"), 0xfe10, {.d_s = c->table->cur_fn->name}}, {_S("`"), 0, { .d_c = 0 }}})), (*node->_v__ast__TypeNode).pos); } else if (!v__ast__Stmt_sumtype_eq((*node->_v__ast__TypeNode).stmt, _const_v__ast__empty_stmt) && (*node->_v__ast__TypeNode).typ == _const_v__ast__void_type) { v__checker__Checker_stmt(c, &(*node->_v__ast__TypeNode).stmt); (*node->_v__ast__TypeNode).typ = v__ast__Table_find_type(c->table, (*(v__ast__StructDecl*)__as_cast(((*node->_v__ast__TypeNode).stmt)._v__ast__StructDecl,((*node->_v__ast__TypeNode).stmt)._typ, 415)).name); } v__ast__Type _t61 = (*node->_v__ast__TypeNode).typ; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t61; } else if (node->_typ == 387 /* v.ast.TypeOf */) { if (!(*node->_v__ast__TypeOf).is_type) { (*node->_v__ast__TypeOf).typ = v__checker__Checker_expr(c, &(*node->_v__ast__TypeOf).expr); } v__ast__Type _t62 = _const_v__ast__string_type; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t62; } else if (node->_typ == 388 /* v.ast.UnsafeExpr */) { v__ast__Type _t63 = v__checker__Checker_unsafe_expr(c, &/*mut*/(*node->_v__ast__UnsafeExpr)); // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t63; } else if (node->_typ == 366 /* v.ast.Likely */) { v__ast__Type ltype = v__checker__Checker_expr(c, &(*node->_v__ast__Likely).expr); if (!v__checker__Checker_check_types(c, ltype, _const_v__ast__bool_type)) { v__ast__TypeSymbol* ltype_sym = v__ast__Table_sym(c->table, ltype); string lname = ((*node->_v__ast__Likely).is_likely ? (_S("_likely_")) : (_S("_unlikely_"))); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = lname}}, {_S("()` expects a boolean expression, instead it got `"), 0xfe10, {.d_s = ltype_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), (*node->_v__ast__Likely).pos); } v__ast__Type _t64 = _const_v__ast__bool_type; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t64; } else if (node->_typ == 335 /* v.ast.NodeError */) { } v__ast__Type _t65 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_expr_defer_1) { c->inside_lambda = false; c->table->cur_lambda = ((void*)0); } // Defer end // Defer begin if (v__checker__Checker_expr_defer_0) { c->expr_level--; } // Defer end return _t65; } VV_LOC v__ast__Type v__checker__Checker_cast_expr(v__checker__Checker* c, v__ast__CastExpr* node) { v__ast__Type to_type = v__checker__Checker_unwrap_generic(c, node->typ); bool old_inside_integer_literal_cast = c->inside_integer_literal_cast; c->inside_integer_literal_cast = v__ast__Type_is_int(to_type) && (node->expr)._typ == 363 /* v.ast.IntegerLiteral */; node->expr_type = v__checker__Checker_expr(c, &node->expr); c->inside_integer_literal_cast = old_inside_integer_literal_cast; if ((node->expr)._typ == 350 /* v.ast.ComptimeSelector */) { node->expr_type = v__type_resolver__TypeResolver_get_comptime_selector_type(&c->type_resolver, (*node->expr._v__ast__ComptimeSelector), node->expr_type); } else if ((node->expr)._typ == 358 /* v.ast.Ident */ && v__type_resolver__ResolverInfo_is_comptime_variant_var(c->comptime, *(v__ast__Ident*)__as_cast((node->expr)._v__ast__Ident,(node->expr)._typ, 358))) { node->expr_type = v__type_resolver__TypeResolver_get_ct_type_or_default(&c->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->comptime->comptime_for_variant_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), _const_v__ast__void_type); } v__ast__Type from_type = v__checker__Checker_unwrap_generic(c, node->expr_type); v__ast__TypeSymbol* from_sym = v__ast__Table_sym(c->table, from_type); v__ast__TypeSymbol* final_from_sym = v__ast__Table_final_sym(c->table, from_type); v__ast__TypeSymbol* to_sym = v__ast__Table_sym(c->table, to_type); v__ast__TypeSymbol* final_to_sym = v__ast__Table_final_sym(c->table, to_type); v__ast__Type final_to_type = ((to_sym->info)._typ == 539 /* v.ast.Alias */ ? ((*to_sym->info._v__ast__Alias).parent_type) : (to_type)); bool final_to_is_ptr = v__ast__Type_is_ptr(to_type) || v__ast__Type_is_ptr(final_to_type); v__checker__Checker_markused_castexpr(c, node, to_type, final_to_sym); if (v__ast__Type_has_flag(to_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("casting to Result type is forbidden"), node->pos); } v__checker__Checker_check_any_type(c, to_type, to_sym, node->pos); if (v__pref__Backend_is_js(c->pref->backend)) { if ((v__ast__TypeSymbol_is_number(to_sym) && fast_string_eq(from_sym->name, _S("JS.Number"))) || (v__ast__TypeSymbol_is_number(to_sym) && fast_string_eq(from_sym->name, _S("JS.BigInt"))) || (v__ast__TypeSymbol_is_string(to_sym) && fast_string_eq(from_sym->name, _S("JS.String"))) || (v__ast__Type_is_bool(to_type) && fast_string_eq(from_sym->name, _S("JS.Boolean"))) || (v__ast__Type_is_bool(from_type) && fast_string_eq(to_sym->name, _S("JS.Boolean"))) || (v__ast__TypeSymbol_is_number(from_sym) && fast_string_eq(to_sym->name, _S("JS.Number"))) || (v__ast__TypeSymbol_is_number(from_sym) && fast_string_eq(to_sym->name, _S("JS.BigInt"))) || (v__ast__TypeSymbol_is_string(from_sym) && fast_string_eq(to_sym->name, _S("JS.String")))) { return to_type; } } if (!v__ast__Type_has_flag(c->expected_type, v__ast__TypeFlag__generic) && to_sym->name.len == 1 && string_starts_with_capital(to_sym->name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = to_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } if (to_sym->language != v__ast__Language__c) { v__checker__Checker_ensure_type_exists(c, to_type, node->pos); if ((to_sym->info)._typ == 539 /* v.ast.Alias */ && v__ast__Type_has_flag((*(v__ast__Alias*)__as_cast((to_sym->info)._v__ast__Alias,(to_sym->info)._typ, 539)).parent_type, v__ast__TypeFlag__option) && !v__ast__Type_has_flag(to_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("alias to Option type requires to be used as Option type (?"), 0xfe10, {.d_s = to_sym->name}}, {_S("(...))"), 0, { .d_c = 0 }}})), node->pos); } } if (from_sym->kind == v__ast__Kind__u8 && v__ast__Type_is_ptr(from_type) && to_sym->kind == v__ast__Kind__string && !v__ast__Type_is_ptr(to_type)) { v__checker__Checker_error(c, _S("to convert a C string buffer pointer to a V string, use x.vstring() instead of string(x)"), node->pos); } if (from_type == _const_v__ast__void_type) { v__checker__Checker_error(c, _S("expression does not return a value so it cannot be cast"), v__ast__Expr_pos(node->expr)); } if (v__ast__Type_has_flag(to_type, v__ast__TypeFlag__option) && from_type == _const_v__ast__none_type) { } else if (to_sym->kind == v__ast__Kind__sum_type) { v__ast__SumType to_sym_info = *(v__ast__SumType*)__as_cast((to_sym->info)._v__ast__SumType,(to_sym->info)._typ, 544); if (c->pref->skip_unused && to_sym_info.concrete_types.len > 0) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){to_type}, &(bool[]) { true }); } if (to_sym_info.generic_types.len > 0 && to_sym_info.concrete_types.len == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic sumtype `"), 0xfe10, {.d_s = to_sym->name}}, {_S("` must specify type parameter, e.g. "), 0xfe10, {.d_s = to_sym->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), node->pos); } if (from_type == _const_v__ast__int_literal_type || from_type == _const_v__ast__float_literal_type) { v__ast__Type xx = (from_type == _const_v__ast__int_literal_type ? (_const_v__ast__int_type) : (_const_v__ast__f64_type)); node->expr_type = v__checker__Checker_promote_num(c, node->expr_type, xx); from_type = node->expr_type; } if (!v__ast__Table_sumtype_has_variant(c->table, to_type, from_type, false)) { string ft = v__ast__Table_type_to_str(c->table, from_type); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast `"), 0xfe10, {.d_s = ft}}, {_S("` to `"), 0xfe10, {.d_s = tt}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } else if ((to_sym->info)._typ == 539 /* v.ast.Alias */ && !(final_to_sym->kind == v__ast__Kind__struct && final_to_is_ptr)) { if ((!v__checker__Checker_check_types(c, from_type, (*to_sym->info._v__ast__Alias).parent_type) && !(v__ast__TypeSymbol_is_int(final_to_sym) && (final_from_sym->kind == v__ast__Kind__enum || final_from_sym->kind == v__ast__Kind__bool || final_from_sym->kind == v__ast__Kind__i8 || final_from_sym->kind == v__ast__Kind__u8 || final_from_sym->kind == v__ast__Kind__char))) || (final_to_sym->kind == v__ast__Kind__struct && (Array_int_contains(new_array_from_c_array(2, 2, sizeof(int), _MOV((int[2]){_const_v__ast__voidptr_type_idx, _const_v__ast__nil_type_idx})), v__ast__Type_idx(from_type))))) { string ft = v__ast__Table_type_to_str(c->table, from_type); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("cannot cast `"), 0xfe10, {.d_s = ft}}, {_S("` to `"), 0xfe10, {.d_s = tt}}, {_S("` (alias to `"), 0xfe10, {.d_s = final_to_sym->name}}, {_S("`)"), 0, { .d_c = 0 }}})), node->pos); } } else if (to_sym->kind == v__ast__Kind__struct && (to_sym->info)._typ == 518 /* v.ast.Struct */ && (!(*(v__ast__Struct*)__as_cast((to_sym->info)._v__ast__Struct,(to_sym->info)._typ, 518)).is_typedef || (Array_int_contains(new_array_from_c_array(2, 2, sizeof(int), _MOV((int[2]){_const_v__ast__voidptr_type_idx, _const_v__ast__nil_type_idx})), v__ast__Type_idx(from_type)))) && !final_to_is_ptr) { if (from_sym->kind == v__ast__Kind__struct && (from_sym->info)._typ == 518 /* v.ast.Struct */ && !v__ast__Type_is_ptr(from_type)) { if (!v__ast__Type_has_flag(to_type, v__ast__TypeFlag__option)) { v__checker__Checker_warn(c, _S("casting to struct is deprecated, use e.g. `Struct{...expr}` instead"), node->pos); } if (!v__checker__Checker_check_struct_signature(c, (*from_sym->info._v__ast__Struct), (*to_sym->info._v__ast__Struct))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot convert struct `"), 0xfe10, {.d_s = from_sym->name}}, {_S("` to struct `"), 0xfe10, {.d_s = to_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } else { string ft = v__ast__Table_type_to_str(c->table, from_type); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot cast `"), 0xfe10, {.d_s = ft}}, {_S("` to struct"), 0, { .d_c = 0 }}})), node->pos); } } else if (to_sym->kind == v__ast__Kind__struct && final_to_is_ptr) { if ((from_sym->info)._typ == 539 /* v.ast.Alias */) { from_type = v__ast__Type_derive_add_muls((*from_sym->info._v__ast__Alias).parent_type, from_type); } if ((node->expr)._typ == 363 /* v.ast.IntegerLiteral */) { if (string_int((*node->expr._v__ast__IntegerLiteral).val) == 0 && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot null cast a struct pointer, use &"), 0xfe10, {.d_s = to_sym->name}}, {_S("(unsafe { nil })"), 0, { .d_c = 0 }}})), node->pos); } else if (!c->inside_unsafe && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, _S("cannot cast int to a struct pointer outside `unsafe`"), node->pos); } } else if ((node->expr)._typ == 358 /* v.ast.Ident */) { if ((*node->expr._v__ast__Ident).obj._typ == 421 /* v.ast.GlobalField */) { if (((*(*node->expr._v__ast__Ident).obj._v__ast__GlobalField).expr)._typ == 363 /* v.ast.IntegerLiteral */) { if (string_int((*(*(*node->expr._v__ast__Ident).obj._v__ast__GlobalField).expr._v__ast__IntegerLiteral).val) == 0 && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot null cast a struct pointer, use &"), 0xfe10, {.d_s = to_sym->name}}, {_S("(unsafe { nil })"), 0, { .d_c = 0 }}})), node->pos); } else if (!c->inside_unsafe && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, _S("cannot cast int to a struct pointer outside `unsafe`"), node->pos); } } } else if ((*node->expr._v__ast__Ident).obj._typ == 420 /* v.ast.ConstField */) { if (((*(*node->expr._v__ast__Ident).obj._v__ast__ConstField).expr)._typ == 363 /* v.ast.IntegerLiteral */) { if (string_int((*(*(*node->expr._v__ast__Ident).obj._v__ast__ConstField).expr._v__ast__IntegerLiteral).val) == 0 && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot null cast a struct pointer, use &"), 0xfe10, {.d_s = to_sym->name}}, {_S("(unsafe { nil })"), 0, { .d_c = 0 }}})), node->pos); } else if (!c->inside_unsafe && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, _S("cannot cast int to a struct pointer outside `unsafe`"), node->pos); } } } else if ((*node->expr._v__ast__Ident).obj._typ == 422 /* v.ast.Var */) { if (((*(*node->expr._v__ast__Ident).obj._v__ast__Var).expr)._typ == 363 /* v.ast.IntegerLiteral */) { if (string_int((*(*(*node->expr._v__ast__Ident).obj._v__ast__Var).expr._v__ast__IntegerLiteral).val) == 0 && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot null cast a struct pointer, use &"), 0xfe10, {.d_s = to_sym->name}}, {_S("(unsafe { nil })"), 0, { .d_c = 0 }}})), node->pos); } else if (!c->inside_unsafe && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, _S("cannot cast int to a struct pointer outside `unsafe`"), node->pos); } } } else { } } if (from_type == 2 && !c->inside_unsafe && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, _S("cannot cast voidptr to a struct outside `unsafe`"), node->pos); } if (!v__ast__Type_is_int(from_type) && final_from_sym->kind != v__ast__Kind__enum && !v__ast__Type_is_any_kind_of_pointer(from_type)) { string ft = v__ast__Table_type_to_str(c->table, from_type); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast `"), 0xfe10, {.d_s = ft}}, {_S("` to `"), 0xfe10, {.d_s = tt}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } else if (!v__ast__Type_has_option_or_result(from_type) && (to_sym->info)._typ == 542 /* v.ast.Interface */) { if (v__checker__Checker_type_implements(c, from_type, to_type, node->pos)) { if (!v__ast__Type_is_any_kind_of_pointer(from_type) && from_sym->kind != v__ast__Kind__interface && !c->inside_unsafe && !v__ast__Type_is_number(from_type)) { v__checker__Checker_mark_as_referenced(c, &node->expr, true); } if ((*to_sym->info._v__ast__Interface).is_generic) { v__ast__Type inferred_type = v__checker__Checker_unwrap_generic_interface(c, from_type, to_type, node->pos); if (inferred_type != 0) { to_type = inferred_type; to_sym = v__ast__Table_sym(c->table, to_type); final_to_sym = v__ast__Table_final_sym(c->table, to_type); } } } else { string ft = v__ast__Table_type_to_str(c->table, from_type); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = ft}}, {_S("` does not implement interface `"), 0xfe10, {.d_s = tt}}, {_S("`, cannot cast `"), 0xfe10, {.d_s = ft}}, {_S("` to interface `"), 0xfe10, {.d_s = tt}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } else if (to_type == _const_v__ast__bool_type && from_type != _const_v__ast__bool_type && !c->inside_unsafe && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, _S("cannot cast to bool - use e.g. `some_int != 0` instead"), node->pos); } else if (from_type == _const_v__ast__none_type && !v__ast__Type_has_flag(to_type, v__ast__TypeFlag__option) && !v__ast__Type_has_flag(to_type, v__ast__TypeFlag__result)) { string type_name = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot cast `none` to `"), 0xfe10, {.d_s = type_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else if (!v__ast__Type_has_option_or_result(from_type) && from_sym->kind == v__ast__Kind__struct && !v__ast__Type_is_ptr(from_type)) { if ((final_to_is_ptr || !(to_sym->kind == v__ast__Kind__sum_type || to_sym->kind == v__ast__Kind__interface)) && !c->is_builtin_mod) { string from_type_name = v__ast__Table_type_to_str(c->table, from_type); string type_name = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast struct `"), 0xfe10, {.d_s = from_type_name}}, {_S("` to `"), 0xfe10, {.d_s = type_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } else if (to_sym->kind == v__ast__Kind__u8 && !v__ast__TypeSymbol_is_number(final_from_sym) && !v__ast__Type_is_any_kind_of_pointer(from_type) && !(final_from_sym->kind == v__ast__Kind__char || final_from_sym->kind == v__ast__Kind__enum || final_from_sym->kind == v__ast__Kind__bool)) { string ft = v__ast__Table_type_to_str(c->table, from_type); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast type `"), 0xfe10, {.d_s = ft}}, {_S("` to `"), 0xfe10, {.d_s = tt}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else if ((v__ast__Type_has_flag(from_type, v__ast__TypeFlag__option) && !v__ast__Type_has_flag(to_type, v__ast__TypeFlag__option)) || v__ast__Type_has_flag(from_type, v__ast__TypeFlag__result) || v__ast__Type_has_flag(from_type, v__ast__TypeFlag__variadic)) { string msg = (v__ast__Type_has_flag(from_type, v__ast__TypeFlag__option) ? (_S("an Option")) : v__ast__Type_has_flag(from_type, v__ast__TypeFlag__result) ? (_S("a Result")) : (_S("a variadic"))); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot type cast "), 0xfe10, {.d_s = msg}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else if (!c->inside_unsafe && v__ast__Type_is_ptr(to_type) && v__ast__Type_is_ptr(from_type) && to_type != from_type && v__ast__Type_deref(to_type) != _const_v__ast__char_type && v__ast__Type_deref(from_type) != _const_v__ast__char_type) { string ft = v__ast__Table_type_to_str(c->table, from_type); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_warn(c, str_intp(3, _MOV((StrIntpData[]){{_S("casting `"), 0xfe10, {.d_s = ft}}, {_S("` to `"), 0xfe10, {.d_s = tt}}, {_S("` is only allowed in `unsafe` code"), 0, { .d_c = 0 }}})), node->pos); } else if (from_sym->kind == v__ast__Kind__array_fixed && !v__ast__Type_is_ptr(from_type)) { if (!c->pref->translated && !c->file->is_translated && !c->inside_unsafe) { v__checker__Checker_warn(c, _S("cannot cast a fixed array (use e.g. `&arr[0]` instead)"), node->pos); } } else if (final_from_sym->kind == v__ast__Kind__string && v__ast__TypeSymbol_is_number(final_to_sym) && final_to_sym->kind != v__ast__Kind__rune) { string snexpr = v__ast__Expr_str(&node->expr); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("cannot cast string to `"), 0xfe10, {.d_s = tt}}, {_S("`, use `"), 0xfe10, {.d_s = snexpr}}, {_S("."), 0xfe10, {.d_s = final_to_sym->name}}, {_S("()` instead."), 0, { .d_c = 0 }}})), node->pos); } else if (final_from_sym->kind == v__ast__Kind__string && final_to_is_ptr && to_sym->kind != v__ast__Kind__string) { string snexpr = v__ast__Expr_str(&node->expr); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast string to `"), 0xfe10, {.d_s = tt}}, {_S("`, use `"), 0xfe10, {.d_s = snexpr}}, {_S(".str` instead."), 0, { .d_c = 0 }}})), node->pos); } else if (final_from_sym->kind == v__ast__Kind__string && to_sym->kind == v__ast__Kind__char) { string snexpr = v__ast__Expr_str(&node->expr); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast string to `"), 0xfe10, {.d_s = tt}}, {_S("`, use `"), 0xfe10, {.d_s = snexpr}}, {_S("[index]` instead."), 0, { .d_c = 0 }}})), node->pos); } else if (final_from_sym->kind == v__ast__Kind__string && v__ast__Type_is_voidptr(to_type) && !v__ast__Type_has_flag(node->expr_type, v__ast__TypeFlag__generic) && !v__ast__Type_is_ptr(from_type)) { v__checker__Checker_error(c, _S("cannot cast string to `voidptr`, use voidptr(s.str) instead"), node->pos); } else if (final_from_sym->kind == v__ast__Kind__string && v__ast__Type_is_pointer(to_type) && !c->inside_unsafe) { string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast string to `"), 0xfe10, {.d_s = tt}}, {_S("` outside `unsafe`, use "), 0xfe10, {.d_s = tt}}, {_S("(s.str) instead"), 0, { .d_c = 0 }}})), node->pos); } else if (final_from_sym->kind == v__ast__Kind__array && !v__ast__Type_is_ptr(from_type) && to_type != _const_v__ast__string_type && !(v__ast__Type_has_flag(to_type, v__ast__TypeFlag__option) && v__ast__Type_idx(from_type) == v__ast__Type_idx(to_type))) { string ft = v__ast__Table_type_to_str(c->table, from_type); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast array `"), 0xfe10, {.d_s = ft}}, {_S("` to `"), 0xfe10, {.d_s = tt}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else if (v__ast__Type_has_flag(from_type, v__ast__TypeFlag__option) && v__ast__Type_has_flag(to_type, v__ast__TypeFlag__option) && to_sym->kind != final_from_sym->kind) { string ft = v__ast__Table_type_to_str(c->table, from_type); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("cannot cast incompatible option "), 0xfe10, {.d_s = final_to_sym->name}}, {_S(" `"), 0xfe10, {.d_s = ft}}, {_S("` to `"), 0xfe10, {.d_s = tt}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else if (to_sym->kind == v__ast__Kind__rune && v__ast__TypeSymbol_is_string(from_sym)) { string snexpr = v__ast__Expr_str(&node->expr); string ft = v__ast__Table_type_to_str(c->table, from_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast `"), 0xfe10, {.d_s = ft}}, {_S("` to rune, use `"), 0xfe10, {.d_s = snexpr}}, {_S(".runes()` instead."), 0, { .d_c = 0 }}})), node->pos); } else if (!v__ast__Type_is_ptr(from_type) && from_type != _const_v__ast__string_type && (final_from_sym->info)._typ == 518 /* v.ast.Struct */ && !v__ast__Struct_is_empty_struct(((v__ast__Struct*)__as_cast((final_from_sym->info)._v__ast__Struct,(final_from_sym->info)._typ, 518))) && (v__ast__TypeSymbol_is_int(final_to_sym) || v__ast__TypeSymbol_is_float(final_to_sym))) { string ft = v__ast__Table_type_to_str(c->table, from_type); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast type `"), 0xfe10, {.d_s = ft}}, {_S("` to `"), 0xfe10, {.d_s = tt}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } if (v__ast__Type_is_number(from_type) && v__ast__Type_is_ptr(to_type) && !c->inside_unsafe && !c->pref->translated && !c->file->is_translated) { if (from_sym->language != v__ast__Language__c) { string ne_name = v__ast__Expr_str(&node->expr); if (!string_starts_with(ne_name, _S("C."))) { v__checker__Checker_warn(c, _S("cannot cast a number to a type reference, use `nil` or a voidptr cast first: `&Type(voidptr(123))`"), node->pos); } } } if (v__ast__Type_has_flag(node->typ, v__ast__TypeFlag__generic) && (to_sym->kind == v__ast__Kind__array || to_sym->kind == v__ast__Kind__map || to_sym->kind == v__ast__Kind__array_fixed) && v__ast__Expr_is_literal(node->expr)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot cast literal value to "), 0xfe10, {.d_s = to_sym->name}}, {_S(" type"), 0, { .d_c = 0 }}})), node->pos); } if (to_sym->kind == v__ast__Kind__enum && !(c->inside_unsafe || c->file->is_translated) && v__ast__TypeSymbol_is_int(from_sym)) { v__checker__Checker_error(c, _S("casting numbers to enums, should be done inside `unsafe{}` blocks"), node->pos); } if (final_to_sym->kind == v__ast__Kind__function && final_from_sym->kind == v__ast__Kind__function && !(c->inside_unsafe || c->file->is_translated) && !v__checker__Checker_check_matching_function_symbols(c, final_from_sym, final_to_sym)) { v__checker__Checker_error(c, _S("casting a function value from one function signature, to another function signature, should be done inside `unsafe{}` blocks"), node->pos); } else if (final_to_sym->kind == v__ast__Kind__function && final_from_sym->kind != v__ast__Kind__function) { if (v__ast__Type_has_flag(to_type, v__ast__TypeFlag__option) && (node->expr)._typ != 371 /* v.ast.None */) { v__checker__Checker_error(c, _S("casting number to Option function is not allowed, only compatible function or `none`"), node->pos); } else if (!(c->inside_unsafe || c->file->is_translated)) { if ((node->expr)._typ == 363 /* v.ast.IntegerLiteral */) { v__checker__Checker_warn(c, _S("casting number to function value should be done inside `unsafe{}` blocks"), node->pos); } else if ((node->expr)._typ == 370 /* v.ast.Nil */) { v__checker__Checker_warn(c, _S("casting `nil` to function value should be done inside `unsafe{}` blocks"), node->pos); } else if ((node->expr)._typ == 371 /* v.ast.None */) { if (v__ast__Type_has_flag(from_type, v__ast__TypeFlag__option)) { v__checker__Checker_warn(c, _S("cannot pass `none` to a non Option function type"), node->pos); } } else if (final_from_sym->kind != v__ast__Kind__voidptr) { v__checker__Checker_error(c, _S("invalid casting value to function"), node->pos); } } } if (v__ast__Type_is_ptr(to_type) && to_sym->kind == v__ast__Kind__alias && from_sym->kind == v__ast__Kind__map) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast to alias pointer `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, to_type)}}, {_S("` because `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, from_type)}}, {_S("` is a value"), 0, { .d_c = 0 }}})), node->pos); } if (to_type == _const_v__ast__string_type) { if (from_type == _const_v__ast__u8_type || from_type == _const_v__ast__bool_type) { string snexpr = v__ast__Expr_str(&node->expr); string ft = v__ast__Table_type_to_str(c->table, from_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast type `"), 0xfe10, {.d_s = ft}}, {_S("` to string, use `"), 0xfe10, {.d_s = snexpr}}, {_S(".str()` instead."), 0, { .d_c = 0 }}})), node->pos); } else if (v__ast__Type_is_any_kind_of_pointer(from_type)) { string snexpr = v__ast__Expr_str(&node->expr); string ft = v__ast__Table_type_to_str(c->table, from_type); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("cannot cast pointer type `"), 0xfe10, {.d_s = ft}}, {_S("` to string, use `&u8("), 0xfe10, {.d_s = snexpr}}, {_S(").vstring()` or `cstring_to_vstring("), 0xfe10, {.d_s = snexpr}}, {_S(")` instead."), 0, { .d_c = 0 }}})), node->pos); } else if (v__ast__Type_is_number(from_type)) { string snexpr = v__ast__Expr_str(&node->expr); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot cast number to string, use `"), 0xfe10, {.d_s = snexpr}}, {_S(".str()` instead."), 0, { .d_c = 0 }}})), node->pos); } else if (from_sym->kind == v__ast__Kind__alias && !fast_string_eq(final_from_sym->name, _S("string"))) { string ft = v__ast__Table_type_to_str(c->table, from_type); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot cast type `"), 0xfe10, {.d_s = ft}}, {_S("` to string, use `x.str()` instead."), 0, { .d_c = 0 }}})), node->pos); } else if (final_from_sym->kind == v__ast__Kind__array) { string snexpr = v__ast__Expr_str(&node->expr); if (fast_string_eq(final_from_sym->name, _S("[]u8"))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast []u8 to string, use `"), 0xfe10, {.d_s = snexpr}}, {_S(".bytestr()` or `"), 0xfe10, {.d_s = snexpr}}, {_S(".str()` instead."), 0, { .d_c = 0 }}})), node->pos); } else { string first_elem_idx = _S("[0]"); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast array to string, use `"), 0xfe10, {.d_s = snexpr}}, {_SLIT0, 0xfe10, {.d_s = first_elem_idx}}, {_S(".str()` instead."), 0, { .d_c = 0 }}})), node->pos); } } else if (final_from_sym->kind == v__ast__Kind__enum) { string snexpr = v__ast__Expr_str(&node->expr); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot cast enum to string, use "), 0xfe10, {.d_s = snexpr}}, {_S(".str() instead."), 0, { .d_c = 0 }}})), node->pos); } else if (final_from_sym->kind == v__ast__Kind__map) { v__checker__Checker_error(c, _S("cannot cast map to string."), node->pos); } else if (final_from_sym->kind == v__ast__Kind__sum_type) { string snexpr = v__ast__Expr_str(&node->expr); string ft = v__ast__Table_type_to_str(c->table, from_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast sumtype `"), 0xfe10, {.d_s = ft}}, {_S("` to string, use `"), 0xfe10, {.d_s = snexpr}}, {_S(".str()` instead."), 0, { .d_c = 0 }}})), node->pos); } else if (final_from_sym->kind == v__ast__Kind__function) { string fnexpr = v__ast__Expr_str(&node->expr); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot cast function `"), 0xfe10, {.d_s = fnexpr}}, {_S("` to string"), 0, { .d_c = 0 }}})), node->pos); } else if (to_type != _const_v__ast__string_type && from_type == _const_v__ast__string_type && (!(to_sym->kind == v__ast__Kind__alias && fast_string_eq(final_to_sym->name, _S("string"))))) { string error_msg = str_intp(2, _MOV((StrIntpData[]){{_S("cannot cast a string to a type `"), 0xfe10, {.d_s = final_to_sym->name}}, {_S("`, that is not an alias of string"), 0, { .d_c = 0 }}})); if ((node->expr)._typ == 384 /* v.ast.StringLiteral */) { if ((*node->expr._v__ast__StringLiteral).val.len == 1) { error_msg = string__plus(error_msg, str_intp(3, _MOV((StrIntpData[]){{_S(", for denoting characters use `"), 0xfe10, {.d_s = (*node->expr._v__ast__StringLiteral).val}}, {_S("` instead of '"), 0xfe10, {.d_s = (*node->expr._v__ast__StringLiteral).val}}, {_S("'"), 0, { .d_c = 0 }}}))); } } v__checker__Checker_error(c, error_msg, node->pos); } } else if (v__ast__Type_is_int(to_type) && (node->expr)._typ == 363 /* v.ast.IntegerLiteral */) { string tt = v__ast__Table_type_to_str(c->table, to_type); multi_return_int_int mr_127807 = v__ast__Table_type_size(c->table, v__ast__Type_idx_type(to_type)); int tsize = mr_127807.arg0; int bit_size = (int)(tsize * 8); bool __v_signed = string_at((*node->expr._v__ast__IntegerLiteral).val, 0) == '-'; u8 _t2 = string_at((*node->expr._v__ast__IntegerLiteral).val, 0); string value_string = ((_t2 == ('-') || _t2 == ('+'))? (string_substr((*node->expr._v__ast__IntegerLiteral).val, 1, 2147483647)) : ((*node->expr._v__ast__IntegerLiteral).val)); bool is_overflowed = false; multi_return_u64_int mr_128066 = strconv__common_parse_uint2(value_string, 0, bit_size); u64 v = mr_128066.arg0; int e = mr_128066.arg1; switch (e) { case 0: { break; } case -3: { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("value `"), 0xfe10, {.d_s = (*node->expr._v__ast__IntegerLiteral).val}}, {_S("` overflows `"), 0xfe10, {.d_s = tt}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); is_overflowed = true; break; } default: { { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast value `"), 0xfe10, {.d_s = (*node->expr._v__ast__IntegerLiteral).val}}, {_S("` to `"), 0xfe10, {.d_s = tt}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); break; } } } if (!is_overflowed && v__ast__Type_is_signed(to_type)) { int _t3 = v__ast__Type_idx(to_type); u64 _t4 = 0; if (_t3 == (_const_v__ast__char_type_idx) || _t3 == (_const_v__ast__i8_type_idx)) { _t4 = ((u64)(0xffU)); } else if (_t3 == (_const_v__ast__i16_type_idx)) { _t4 = ((u64)(0xffffU)); } else if (_t3 == (_const_v__ast__int_type_idx) || _t3 == (_const_v__ast__i32_type_idx)) { _t4 = ((u64)(0xffffffffU)); } else if (_t3 == (_const_v__ast__i64_type_idx)) { _t4 = ((u64)(0xffffffffffffffffU)); } else if (_t3 == (_const_v__ast__isize_type_idx)) { u64 _t5; #if defined(TARGET_IS_64BIT) _t5 = ((u64)(0xffffffffffffffffU)); ; #else _t5 = ((u64)(0xffffffffU)); ; #endif _t4 = _t5; } else { v__checker__Checker_error(c, _S("ICE: Not a valid signed type"), node->pos); _t4 = 0; }u64 signed_one = _t4; u64 max_signed = (u64)(((((u64)(1U)) << ((int)(bit_size - 1)))) - 1U); is_overflowed = v == signed_one || (__v_signed && (u64)(v - 2U) == max_signed) || (!__v_signed && (u64)(v - 1U) == max_signed); if (is_overflowed) { v__checker__Checker_warn(c, str_intp(3, _MOV((StrIntpData[]){{_S("value `"), 0xfe10, {.d_s = (*node->expr._v__ast__IntegerLiteral).val}}, {_S("` overflows `"), 0xfe10, {.d_s = tt}}, {_S("`, this will be considered hard error soon"), 0, { .d_c = 0 }}})), node->pos); } } } else if (v__ast__Type_is_float(to_type) && (node->expr)._typ == 356 /* v.ast.FloatLiteral */) { string tt = v__ast__Table_type_to_str(c->table, to_type); _result_f64 _t6 = strconv__atof64((*node->expr._v__ast__FloatLiteral).val, ((strconv__AtoF64Param){.allow_extra_chars = 0,})); if (_t6.is_error) { IError err = _t6.err; v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot cast value `"), 0xfe10, {.d_s = (*node->expr._v__ast__FloatLiteral).val}}, {_S("` to `"), 0xfe10, {.d_s = tt}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); ; } ; } if (from_sym->language == v__ast__Language__v && !v__ast__Type_is_ptr(from_type) && (final_from_sym->kind == v__ast__Kind__sum_type || final_from_sym->kind == v__ast__Kind__interface) && !(final_to_sym->kind == v__ast__Kind__sum_type || final_to_sym->kind == v__ast__Kind__interface)) { string ft = v__ast__Table_type_to_str(c->table, from_type); string tt = v__ast__Table_type_to_str(c->table, to_type); string kind_name = (from_sym->kind == v__ast__Kind__sum_type ? (_S("sum type")) : (_S("interface"))); v__checker__Checker_error(c, str_intp(6, _MOV((StrIntpData[]){{_S("cannot cast `"), 0xfe10, {.d_s = ft}}, {_S("` "), 0xfe10, {.d_s = kind_name}}, {_S(" value to `"), 0xfe10, {.d_s = tt}}, {_S("`, use `"), 0xfe10, {.d_s = v__ast__Expr_str(&node->expr)}}, {_S(" as "), 0xfe10, {.d_s = tt}}, {_S("` instead"), 0, { .d_c = 0 }}})), node->pos); } if (from_sym->language == v__ast__Language__v && v__ast__Type_is_ptr(from_type) && !v__ast__Type_is_ptr(to_type) && !v__ast__Type_is_ptr(final_to_type) && !v__ast__Expr_is_auto_deref_var(node->expr) && final_to_sym->kind == v__ast__Kind__struct && final_from_sym->kind == v__ast__Kind__struct) { if (v__checker__Checker_check_struct_signature(c, *(v__ast__Struct*)__as_cast((final_from_sym->info)._v__ast__Struct,(final_from_sym->info)._typ, 518), *(v__ast__Struct*)__as_cast((final_to_sym->info)._v__ast__Struct,(final_to_sym->info)._typ, 518))) { string ft = v__ast__Table_type_to_str(c->table, from_type); string tt = v__ast__Table_type_to_str(c->table, to_type); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("cannot cast `"), 0xfe10, {.d_s = ft}}, {_S("` to `"), 0xfe10, {.d_s = tt}}, {_S("`, you must dereference it first (e.g. "), 0xfe10, {.d_s = tt}}, {_S("(*var))"), 0, { .d_c = 0 }}})), node->pos); } } if (node->has_arg) { v__checker__Checker_expr(c, &node->arg); } if (to_sym->kind == v__ast__Kind__enum) { if ((node->expr)._typ == 363 /* v.ast.IntegerLiteral */) { string enum_typ_name = v__ast__Table_get_type_name(c->table, to_type); i64 node_val = string_i64((*node->expr._v__ast__IntegerLiteral).val); v__ast__EnumDecl* _t8 = (v__ast__EnumDecl*)(map_get_check(ADDR(map, c->table->enum_decls), &(string[]){to_sym->name})); _option_v__ast__EnumDecl _t7 = {0}; if (_t8) { *((v__ast__EnumDecl*)&_t7.data) = *((v__ast__EnumDecl*)_t8); } else { _t7.state = 2; _t7.err = _v_error(_S("map key does not exist")); } if (_t7.state == 0) { v__ast__EnumDecl enum_decl = (*(v__ast__EnumDecl*)_t7.data); bool in_range = false; if (enum_decl.is_flag) { if (enum_decl.fields.len == 64) { in_range = node_val >= 0 && ((u64)(node_val)) <= _const_max_u64; } else { u64 max_val = (u64)(((((u64)(1U)) << enum_decl.fields.len)) - 1U); in_range = node_val >= 0 && ((u64)(node_val)) <= max_val; } } else { i64 enum_val = ((i64)(0)); for (int _t9 = 0; _t9 < enum_decl.fields.len; ++_t9) { v__ast__EnumField enum_field = ((v__ast__EnumField*)enum_decl.fields.data)[_t9]; bool _t11 = (enum_field.expr)._typ == 363 /* v.ast.IntegerLiteral */; _option_v__ast__ComptTimeConstValue _t10; if (_t11) { enum_val = string_i64((*enum_field.expr._v__ast__IntegerLiteral).val); } else if (_t10 = v__checker__Checker_eval_comptime_const_expr(c, enum_field.expr, 0), _t10.state == 0) { v__ast__ComptTimeConstValue comptime_value = *(v__ast__ComptTimeConstValue*)_t10.data; _option_i64 _t12 = v__ast__ComptTimeConstValue_i64(comptime_value); if (_t12.state != 0) { IError err = _t12.err; *(i64*) _t12.data = -1; } enum_val = (*(i64*)_t12.data); } if (node_val == enum_val) { in_range = true; break; } enum_val += 1; } } if (!in_range) { v__checker__Checker_warn(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe09, {.d_i64 = node_val}}, {_S(" does not represent a value of enum "), 0xfe10, {.d_s = enum_typ_name}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } } } if (node->expr_type == 21) { v__checker__Checker_add_error_detail(c, str_intp(3, _MOV((StrIntpData[]){{_S("use "), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, node->typ)}}, {_S(".from_string("), 0xfe10, {.d_s = v__ast__Expr_str(&node->expr)}}, {_S(") instead"), 0, { .d_c = 0 }}}))); v__checker__Checker_error(c, _S("cannot cast `string` to `enum`"), node->pos); } } if (c->pref->warn_about_allocs && (to_sym->info)._typ == 542 /* v.ast.Interface */) { v__checker__Checker_warn_alloc(c, _S("cast to interface"), node->pos); } node->typname = v__ast__Table_sym(c->table, node->typ)->name; return node->typ; } VV_LOC v__ast__Type v__checker__Checker_at_expr(v__checker__Checker* c, v__ast__AtExpr* node) { switch (node->kind) { case v__token__AtKind__fn_name: { if (c->table->cur_fn == ((void*)0)) { return _const_v__ast__void_type; } if (c->table->cur_fn->is_static_type_method) { node->val = string_all_after_last(c->table->cur_fn->name, _S("__static__")); } else { node->val = string_all_after_last(c->table->cur_fn->name, _S(".")); } break; } case v__token__AtKind__method_name: { if (c->table->cur_fn == ((void*)0)) { return _const_v__ast__void_type; } string fname = string_all_after_last(c->table->cur_fn->name, _S(".")); if (c->table->cur_fn->is_method) { node->val = string__plus(string__plus(string_all_after_last(v__ast__Table_type_to_str(c->table, c->table->cur_fn->receiver.typ), _S(".")), _S(".")), fname); } else if (c->table->cur_fn->is_static_type_method) { node->val = string__plus(string__plus(string_all_before(fname, _S("__static__")), _S(".")), string_all_after(fname, _S("__static__"))); } else { node->val = fname; } break; } case v__token__AtKind__mod_name: { if (c->table->cur_fn == ((void*)0)) { return _const_v__ast__void_type; } node->val = c->table->cur_fn->mod; break; } case v__token__AtKind__struct_name: { if (c->table->cur_fn->is_method || c->table->cur_fn->is_static_type_method) { node->val = string_all_after_last(v__ast__Table_type_to_str(c->table, c->table->cur_fn->receiver.typ), _S(".")); } else { node->val = _S(""); } break; } case v__token__AtKind__vexe_path: { node->val = v__pref__vexe_path(); break; } case v__token__AtKind__file_path: { node->val = os__real_path(c->file->path); break; } case v__token__AtKind__file_dir: { node->val = os__real_path(os__dir(c->file->path)); break; } case v__token__AtKind__line_nr: { node->val = int_str(((int)(node->pos.line_nr + 1))); break; } case v__token__AtKind__file_path_line_nr: { node->val = string__plus(string__plus(os__file_name(c->file->path), _S(":")), int_str(((int)(node->pos.line_nr + 1)))); break; } case v__token__AtKind__column_nr: { node->val = int_str(((int)(node->pos.col + 1))); break; } case v__token__AtKind__location: { string mname = _S("unknown"); if (c->table->cur_fn != ((void*)0)) { if (c->table->cur_fn->is_method) { mname = string__plus(string__plus(v__ast__Table_type_to_str(c->table, c->table->cur_fn->receiver.typ), _S("{}.")), string_all_after_last(c->table->cur_fn->name, _S("."))); } else { mname = c->table->cur_fn->name; } if (c->table->cur_fn->is_static_type_method) { mname = string__plus(string_replace(mname, _S("__static__"), _S(".")), _S(" (static)")); } } node->val = string__plus(string__plus(string__plus(c->file->path, _S(":")), int_str(((int)(node->pos.line_nr + 1)))), str_intp(2, _MOV((StrIntpData[]){{_S(", "), 0xfe10, {.d_s = mname}}, {_SLIT0, 0, { .d_c = 0 }}}))); break; } case v__token__AtKind__vhash: { node->val = v__util__version__vhash(); break; } case v__token__AtKind__v_current_hash: { node->val = c->v_current_commit_hash; break; } case v__token__AtKind__vmod_file: { if (c->vmod_file_content.len == 0) { v__vmod__ModFileCacher* mcache = v__vmod__get_cache(); v__vmod__ModFileAndFolder vmod_file_location = v__vmod__ModFileCacher_get_by_file(mcache, c->file->path); if (vmod_file_location.vmod_file.len == 0) { v__checker__Checker_error(c, _S("@VMOD_FILE can only be used in projects that have a v.mod file"), node->pos); } _result_string _t4 = os__read_file(vmod_file_location.vmod_file); if (_t4.is_error) { IError err = _t4.err; *(string*) _t4.data = _S(""); } string vmod_content = (*(string*)_t4.data); c->vmod_file_content = string_replace(vmod_content, _S("\r\n"), _S("\n")); } node->val = c->vmod_file_content; break; } case v__token__AtKind__vroot_path: { node->val = c->pref->vroot; break; } case v__token__AtKind__vexeroot_path: { node->val = c->pref->vroot; break; } case v__token__AtKind__vmodroot_path: { v__vmod__ModFileCacher* mcache = v__vmod__get_cache(); v__vmod__ModFileAndFolder vmod_file_location = v__vmod__ModFileCacher_get_by_file(mcache, c->file->path); node->val = os__dir(vmod_file_location.vmod_file); break; } case v__token__AtKind__vmod_hash: { v__vmod__ModFileCacher* mcache = v__vmod__get_cache(); v__vmod__ModFileAndFolder vmod_file_location = v__vmod__ModFileCacher_get_by_file(mcache, c->file->path); if (vmod_file_location.vmod_file.len == 0) { v__checker__Checker_error(c, _S("@VMODHASH can only be used in projects that have a v.mod file"), node->pos); } _result_string _t5 = v__util__version__githash(os__dir(vmod_file_location.vmod_file)); if (_t5.is_error) { IError err = _t5.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); *(string*) _t5.data = _S(""); } string hash = (*(string*)_t5.data); node->val = hash; break; } case v__token__AtKind__build_date: { node->val = time__Time_strftime(_const_v__util__stable_build_time, _S("%Y-%m-%d")); break; } case v__token__AtKind__build_time: { node->val = time__Time_strftime(_const_v__util__stable_build_time, _S("%H:%M:%S")); break; } case v__token__AtKind__build_timestamp: { node->val = i64_str(time__Time_unix(_const_v__util__stable_build_time)); break; } case v__token__AtKind__unknown: { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("unknown @ identifier: "), 0xfe10, {.d_s = node->name}}, {_S(". Available identifiers: "), 0xfe10, {.d_s = Array_string_str(_const_v__token__valid_at_tokens)}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); break; } } return _const_v__ast__string_type; } VV_LOC v__ast__Type v__checker__Checker_resolve_var_fn(v__checker__Checker* c, v__ast__Fn* func, v__ast__Ident* node, string name) { int fn_type = v__ast__Table_find_or_register_fn_type(c->table, *func, false, true); if (fn_type < 0) { v__ast__Fn f = ((v__ast__Fn){.is_variadic = (func)->is_variadic,.is_c_variadic = (func)->is_c_variadic,.language = (func)->language,.is_pub = (func)->is_pub,.is_ctor_new = (func)->is_ctor_new,.is_deprecated = (func)->is_deprecated,.is_noreturn = (func)->is_noreturn,.is_unsafe = (func)->is_unsafe,.is_must_use = (func)->is_must_use,.is_placeholder = (func)->is_placeholder,.is_main = (func)->is_main,.is_test = (func)->is_test,.is_keep_alive = (func)->is_keep_alive,.is_method = (func)->is_method,.is_static_type_method = (func)->is_static_type_method,.no_body = (func)->no_body,.is_file_translated = (func)->is_file_translated,.mod = (func)->mod,.file = (func)->file,.file_mode = (func)->file_mode,.pos = (func)->pos,.name_pos = (func)->name_pos,.return_type_pos = (func)->return_type_pos,.return_type = (func)->return_type,.receiver_type = (func)->receiver_type,.name = (func)->name,.params = (func)->params,.source_fn = (func)->source_fn,.usages = (func)->usages,.generic_names = (func)->generic_names,.dep_names = (func)->dep_names,.attrs = (func)->attrs,.is_conditional = (func)->is_conditional,.ctdefine_idx = (func)->ctdefine_idx,.from_embedded_type = (func)->from_embedded_type,.is_expand_simple_interpolation = (func)->is_expand_simple_interpolation,}); f.name = _S(""); fn_type = v__ast__Table_find_or_register_fn_type(c->table, f, false, true); } if (func->generic_names.len > 0) { Array_v__ast__Type _t1 = {0}; Array_v__ast__Type _t1_orig = node->concrete_types; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t3]; v__ast__Type _t2 = v__checker__Checker_unwrap_generic(c, it); array_push((array*)&_t1, &_t2); } Array_v__ast__Type concrete_types =_t1; _option_v__ast__Type _t4; if (_t4 = v__ast__Table_convert_generic_type(c->table, fn_type, func->generic_names, concrete_types), _t4.state == 0) { v__ast__Type typ_ = *(v__ast__Type*)_t4.data; fn_type = typ_; bool _t5 = true; Array_v__ast__Type _t5_orig = concrete_types; int _t5_len = _t5_orig.len; for (int _t6 = 0; _t6 < _t5_len; ++_t6) { v__ast__Type it = ((v__ast__Type*) _t5_orig.data)[_t6]; if (!(!v__ast__Type_has_flag(it, v__ast__TypeFlag__generic))) { _t5 = false; break; } } if (_t5) { v__ast__Table_register_fn_concrete_types(c->table, v__ast__Fn_fkey(func), concrete_types); } } } node->name = name; node->kind = v__ast__IdentKind__function; node->info = v__ast__IdentFn_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentFn, (((v__ast__IdentFn){.typ = fn_type,})))); return fn_type; } VV_LOC v__ast__Type v__checker__Checker_ident(v__checker__Checker* c, v__ast__Ident* node) { if (c->pref->linfo.is_running) { v__checker__Checker_ident_autocomplete(c, *node); } if (c->const_deps.len > 0) { string name = node->name; if (!string_contains(name, _S(".")) && !fast_string_eq(node->mod, _S("builtin"))) { name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->mod}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})); } if (c->const_var != 0 && string__eq(name, c->const_var->name)) { if ((c->const_var->expr)._typ == 338 /* v.ast.ArrayInit */ && (*(v__ast__ArrayInit*)__as_cast((c->const_var->expr)._v__ast__ArrayInit,(c->const_var->expr)._typ, 338)).is_fixed && v__ast__Type_nr_muls(c->expected_type) > 0) { v__ast__Type elem_typ = v__ast__Type_deref(c->expected_type); node->kind = v__ast__IdentKind__constant; node->name = c->const_var->name; node->info = v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentVar, (((v__ast__IdentVar){.typ = elem_typ,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_option = 0,.share = 0,})))); node->obj = v__ast__ConstField_to_sumtype_v__ast__ScopeObject(c->const_var); return c->expected_type; } v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cycle in constant `"), 0xfe10, {.d_s = c->const_var->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__void_type; } array_push((array*)&c->const_deps, _MOV((string[]){ string_clone(name) })); } if (node->kind == v__ast__IdentKind__blank_ident) { if (!(node->tok_kind == v__token__Kind__assign || node->tok_kind == v__token__Kind__decl_assign)) { v__checker__Checker_error(c, _S("undefined ident: `_` (may only be used in assignments)"), node->pos); } return _const_v__ast__void_type; } else if (node->kind == v__ast__IdentKind__constant || node->kind == v__ast__IdentKind__global || node->kind == v__ast__IdentKind__variable) { v__ast__IdentVar info = *(v__ast__IdentVar*)__as_cast((node->info)._v__ast__IdentVar,(node->info)._typ, 477); v__ast__Type typ = v__type_resolver__TypeResolver_get_type_or_default(&c->type_resolver, v__ast__Ident_to_sumtype_v__ast__Expr(node), info.typ); if (node->or_expr.kind != v__ast__OrKind__absent) { if (!v__ast__Type_has_flag(info.typ, v__ast__TypeFlag__option)) { if (node->or_expr.kind == v__ast__OrKind__propagate_option) { v__checker__Checker_error(c, _S("cannot use `?` on non-option variable"), node->pos); } else if (node->or_expr.kind == v__ast__OrKind__block) { v__checker__Checker_error(c, _S("cannot use `or {}` block on non-option variable"), node->pos); } } v__ast__Type unwrapped_typ = v__ast__Type_clear_option_and_result(typ); c->expected_or_type = unwrapped_typ; v__checker__Checker_stmts_ending_with_expression(c, &node->or_expr.stmts, c->expected_or_type); v__checker__Checker_check_or_expr(c, node->or_expr, typ, c->expected_or_type, v__ast__Ident_to_sumtype_v__ast__Expr(node)); return unwrapped_typ; } return typ; } else if (node->kind == v__ast__IdentKind__function) { v__ast__IdentFn info = *(v__ast__IdentFn*)__as_cast((node->info)._v__ast__IdentFn,(node->info)._typ, 476); _option_v__ast__Fn _t7; if (_t7 = v__ast__Table_find_fn(c->table, node->name), _t7.state == 0) { v__ast__Fn func = *(v__ast__Fn*)_t7.data; if (func.generic_names.len > 0) { if (node->concrete_types.len == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = node->name}}, {_S("` is a generic fn, you should pass its concrete types, e.g. "), 0xfe10, {.d_s = node->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), node->pos); } Array_v__ast__Type _t8 = {0}; Array_v__ast__Type _t8_orig = node->concrete_types; int _t8_len = _t8_orig.len; _t8 = __new_array(0, _t8_len, sizeof(v__ast__Type)); for (int _t10 = 0; _t10 < _t8_len; ++_t10) { v__ast__Type it = ((v__ast__Type*) _t8_orig.data)[_t10]; v__ast__Type _t9 = v__checker__Checker_unwrap_generic(c, it); array_push((array*)&_t8, &_t9); } Array_v__ast__Type concrete_types =_t8; bool _t11 = true; Array_v__ast__Type _t11_orig = concrete_types; int _t11_len = _t11_orig.len; for (int _t12 = 0; _t12 < _t11_len; ++_t12) { v__ast__Type it = ((v__ast__Type*) _t11_orig.data)[_t12]; if (!(!v__ast__Type_has_flag(it, v__ast__TypeFlag__generic))) { _t11 = false; break; } } if (_t11) { v__ast__Table_register_fn_concrete_types(c->table, v__ast__Fn_fkey(&func), concrete_types); } } } return info.typ; } else if (node->kind == v__ast__IdentKind__unresolved) { if (node->tok_kind == v__token__Kind__assign && node->is_mut) { v__checker__Checker_error(c, _S("`mut` is not allowed with `=` (use `:=` to declare a variable)"), node->pos); } _option_v__ast__ScopeObject _t14; if (_t14 = v__ast__Scope_find(node->scope, node->name), _t14.state == 0) { v__ast__ScopeObject obj = *(v__ast__ScopeObject*)_t14.data; if (obj._typ == 421 /* v.ast.GlobalField */) { if ((node->mod).len == 0) { node->kind = v__ast__IdentKind__global; node->info = v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentVar, (((v__ast__IdentVar){.typ = (*obj._v__ast__GlobalField).typ,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_option = 0,.share = 0,})))); node->obj = obj; return (*obj._v__ast__GlobalField).typ; } } else if (obj._typ == 422 /* v.ast.Var */) { int node_pos = (c->pref->is_vweb && !_IN_MAP(ADDR(string, node->name), ADDR(map, node->scope->objects)) && node->scope->start_pos < c->comptime_call_pos ? (c->comptime_call_pos) : (node->pos.pos)); if (node_pos < (*obj._v__ast__Var).pos.pos) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("undefined variable `"), 0xfe10, {.d_s = node->name}}, {_S("` (used before declaration)"), 0, { .d_c = 0 }}})), node->pos); } bool is_sum_type_cast = (*obj._v__ast__Var).smartcasts.len != 0 && !c->prevent_sum_type_unwrapping_once; c->prevent_sum_type_unwrapping_once = false; v__ast__Type _t16; /* if prepend */ if (is_sum_type_cast) { _t16 = (*(v__ast__Type*)array_last((*obj._v__ast__Var).smartcasts)); } else { _t16 = (*obj._v__ast__Var).typ; } v__ast__Type typ = _t16; if (typ == 0) { if (((*obj._v__ast__Var).expr)._typ == 358 /* v.ast.Ident */) { if ((*(*obj._v__ast__Var).expr._v__ast__Ident).kind == v__ast__IdentKind__unresolved) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unresolved variable: `"), 0xfe10, {.d_s = node->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__void_type; } } if (((*obj._v__ast__Var).expr)._typ == 360 /* v.ast.IfGuardExpr */) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, (*(*obj._v__ast__Var).expr._v__ast__IfGuardExpr).expr_type); if (sym->kind == v__ast__Kind__multi_return) { v__ast__MultiReturn mr_info = *(v__ast__MultiReturn*)__as_cast((sym->info)._v__ast__MultiReturn,(sym->info)._typ, 552); if (mr_info.types.len == (*(*obj._v__ast__Var).expr._v__ast__IfGuardExpr).vars.len) { for (int vi = 0; vi < (*(*obj._v__ast__Var).expr._v__ast__IfGuardExpr).vars.len; ++vi) { v__ast__IfGuardVar var = ((v__ast__IfGuardVar*)(*(*obj._v__ast__Var).expr._v__ast__IfGuardExpr).vars.data)[vi]; if (string__eq(var.name, node->name)) { typ = (*(v__ast__Type*)array_get(mr_info.types, vi)); } } } } else { typ = v__ast__Type_clear_option_and_result((*(*obj._v__ast__Var).expr._v__ast__IfGuardExpr).expr_type); } } else if (((*obj._v__ast__Var).expr)._typ == 354 /* v.ast.EmptyExpr */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid variable `"), 0xfe10, {.d_s = node->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); typ = _const_v__ast__void_type; } else { typ = v__checker__Checker_expr(c, &(*obj._v__ast__Var).expr); } } if (c->inside_interface_deref && v__ast__Table_is_interface_var(c->table, obj)) { typ = v__ast__Type_deref(typ); } bool is_option = v__ast__Type_has_option_or_result(typ) || node->or_expr.kind != v__ast__OrKind__absent; node->kind = v__ast__IdentKind__variable; node->info = v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentVar, (((v__ast__IdentVar){.typ = typ,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_option = is_option,.share = 0,})))); if (!is_sum_type_cast) { (*obj._v__ast__Var).typ = typ; } node->obj = obj; node->ct_expr = (*obj._v__ast__Var).ct_type_var != v__ast__ComptimeVarKind__no_comptime; if (is_option) { if (node->or_expr.kind == v__ast__OrKind__absent) { return v__ast__Type_clear_flag(typ, v__ast__TypeFlag__result); } if (!v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { if (node->or_expr.kind == v__ast__OrKind__propagate_option) { v__checker__Checker_error(c, _S("cannot use `?` on non-option variable"), node->pos); } else if (node->or_expr.kind == v__ast__OrKind__block) { v__checker__Checker_error(c, _S("cannot use `or {}` block on non-option variable"), node->pos); } } v__ast__Type unwrapped_typ = v__ast__Type_clear_option_and_result(typ); c->expected_or_type = unwrapped_typ; v__checker__Checker_stmts_ending_with_expression(c, &node->or_expr.stmts, c->expected_or_type); v__checker__Checker_check_or_expr(c, node->or_expr, typ, c->expected_or_type, v__ast__Ident_to_sumtype_v__ast__Expr(node)); return unwrapped_typ; } return typ; } else { } } string name = node->name; if (_IN_MAP(ADDR(string, name), ADDR(map, c->file->imported_symbols))) { name = (*(string*)map_get(ADDR(map, c->file->imported_symbols), &(string[]){name}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })); } else if (!string_contains(name, _S(".")) && !fast_string_eq(node->mod, _S("builtin"))) { name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->mod}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})); } _option_v__ast__ScopeObject _t21; if (_t21 = v__ast__Scope_find(c->file->global_scope, name), _t21.state == 0) { v__ast__ScopeObject obj = *(v__ast__ScopeObject*)_t21.data; if (obj._typ == 421 /* v.ast.GlobalField */) { node->kind = v__ast__IdentKind__global; node->info = v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentVar, (((v__ast__IdentVar){.typ = (*obj._v__ast__GlobalField).typ,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_option = 0,.share = 0,})))); node->obj = obj; return (*obj._v__ast__GlobalField).typ; } else if (obj._typ == 420 /* v.ast.ConstField */) { if (!((*obj._v__ast__ConstField).is_pub || string__eq((*obj._v__ast__ConstField).mod, c->mod) || c->pref->is_test)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("constant `"), 0xfe10, {.d_s = (*obj._v__ast__ConstField).name}}, {_S("` is private"), 0, { .d_c = 0 }}})), node->pos); } v__ast__Type typ = (*obj._v__ast__ConstField).typ; if (typ == 0) { string old_c_mod = c->mod; c->mod = (*obj._v__ast__ConstField).mod; c->inside_const = true; typ = v__checker__Checker_expr(c, &(*obj._v__ast__ConstField).expr); c->inside_const = false; c->mod = old_c_mod; if (((*obj._v__ast__ConstField).expr)._typ == 344 /* v.ast.CallExpr */) { if ((*(*obj._v__ast__ConstField).expr._v__ast__CallExpr).or_block.kind != v__ast__OrKind__absent) { typ = v__ast__Type_clear_option_and_result(typ); } } } node->name = name; node->kind = v__ast__IdentKind__constant; node->info = v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentVar, (((v__ast__IdentVar){.typ = typ,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_option = 0,.share = 0,})))); (*obj._v__ast__ConstField).typ = typ; node->obj = obj; if (Array_v__ast__Attr_contains((*obj._v__ast__ConstField).attrs, _S("deprecated")) && !string__eq((*obj._v__ast__ConstField).mod, c->mod)) { v__checker__Checker_deprecate(c, _S("const"), (*obj._v__ast__ConstField).name, (*obj._v__ast__ConstField).attrs, node->pos); } if (node->or_expr.kind != v__ast__OrKind__absent) { v__ast__Type unwrapped_typ = v__ast__Type_clear_option_and_result(typ); c->expected_or_type = unwrapped_typ; v__checker__Checker_stmts_ending_with_expression(c, &node->or_expr.stmts, c->expected_or_type); v__checker__Checker_check_or_expr(c, node->or_expr, typ, c->expected_or_type, v__ast__Ident_to_sumtype_v__ast__Expr(node)); } return typ; } else { } } _option_v__ast__Fn _t24; if (_t24 = v__ast__Table_find_fn(c->table, name), _t24.state == 0) { v__ast__Fn func = *(v__ast__Fn*)_t24.data; if (func.generic_names.len > 0) { if (node->concrete_types.len == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = node->name}}, {_S("` is a generic fn, you should pass its concrete types, e.g. "), 0xfe10, {.d_s = node->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), node->pos); } bool has_generic = false; for (int _t25 = 0; _t25 < node->concrete_types.len; ++_t25) { v__ast__Type concrete_type = ((v__ast__Type*)node->concrete_types.data)[_t25]; if (v__ast__Type_has_flag(concrete_type, v__ast__TypeFlag__generic)) { has_generic = true; } } if (c->table->cur_fn != ((void*)0) && c->table->cur_concrete_types.len == 0 && has_generic && v__ast__Table_sym(c->table, c->expected_type)->kind != v__ast__Kind__function) { v__checker__Checker_error(c, _S("a generic fn with generic types, cannot be used outside of another generic fn"), node->pos); } } return v__checker__Checker_resolve_var_fn(c, (voidptr)&func, node, name); } } if (node->language == v__ast__Language__c) { if (fast_string_eq(node->name, _S("C.NULL"))) { return _const_v__ast__voidptr_type; } _option_v__ast__ConstField_ptr _t28; if (_t28 = v__ast__Scope_find_const(c->table->global_scope, node->name), _t28.state == 0) { v__ast__ConstField* x = *(v__ast__ConstField**)_t28.data; return x->typ; } return _const_v__ast__int_type; } if (c->inside_sql) { _result_v__ast__StructField _t31; if (_t31 = v__ast__Table_find_field(c->table, (voidptr)&c->cur_orm_ts, node->name), !_t31.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t31.data; return field.typ; } } if (node->kind == v__ast__IdentKind__unresolved && !fast_string_eq(node->mod, _S("builtin"))) { string saved_mod = node->mod; node->mod = _S("builtin"); v__ast__Type builtin_type = v__checker__Checker_ident(c, node); if ((node->obj)._typ == 420 /* v.ast.ConstField */) { v__ast__ConstField field = *(v__ast__ConstField*)__as_cast((node->obj)._v__ast__ConstField,(node->obj)._typ, 420); if (Array_v__ast__Attr_contains(field.attrs, _S("deprecated")) && !string__eq(field.mod, c->mod)) { v__checker__Checker_deprecate(c, _S("const"), field.name, field.attrs, node->pos); } } if (builtin_type != _const_v__ast__void_type) { return builtin_type; } node->mod = saved_mod; } if (node->tok_kind == v__token__Kind__assign) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("undefined ident: `"), 0xfe10, {.d_s = node->name}}, {_S("` (use `:=` to declare a variable)"), 0, { .d_c = 0 }}})), node->pos); } else if (fast_string_eq(node->name, _S("errcode"))) { v__checker__Checker_error(c, _S("undefined ident: `errcode`; did you mean `err.code`?"), node->pos); } else { if (c->inside_ct_attr) { v__checker__Checker_note(c, str_intp(3, _MOV((StrIntpData[]){{_S("`[if "), 0xfe10, {.d_s = node->name}}, {_S("]` is deprecated. Use `@[if "), 0xfe10, {.d_s = node->name}}, {_S("?]` instead"), 0, { .d_c = 0 }}})), node->pos); } else { string cname_mod = string_all_before(node->name, _S(".")); if (cname_mod.len != node->name.len) { Array_string const_names_in_mod = __new_array_with_default(0, 0, sizeof(string), 0); Map_string_v__ast__ScopeObject _t34 = c->table->global_scope->objects; int _t36 = _t34.key_values.len; for (int _t35 = 0; _t35 < _t36; ++_t35 ) { int _t37 = _t34.key_values.len - _t36; _t36 = _t34.key_values.len; if (_t37 < 0) { _t35 = -1; continue; } if (!DenseArray_has_index(&_t34.key_values, _t35)) {continue;} v__ast__ScopeObject so = (*(v__ast__ScopeObject*)DenseArray_value(&_t34.key_values, _t35)); if ((so)._typ == 420 /* v.ast.ConstField */) { if (string__eq((*so._v__ast__ConstField).mod, cname_mod)) { array_push((array*)&const_names_in_mod, _MOV((string[]){ string_clone((*so._v__ast__ConstField).name) })); } } } v__checker__Checker_error(c, v__util__Suggestion_say(v__util__new_suggestion(node->name, const_names_in_mod, ((v__util__SuggestionParams){.similarity_threshold = 0.5,.similarity_fn = strings__dice_coefficient,})), str_intp(2, _MOV((StrIntpData[]){{_S("undefined ident: `"), 0xfe10, {.d_s = node->name}}, {_S("`"), 0, { .d_c = 0 }}}))), node->pos); } else { if (c->inside_anon_fn) { _option_v__ast__Var_ptr found_var = v__ast__Scope_find_var(c->fn_scope, node->name); if ((found_var).state != 2) { if (c->inside_lambda) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("undefined variable `"), 0xfe10, {.d_s = node->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else { v__checker__Checker_add_error_detail(c, str_intp(2, _MOV((StrIntpData[]){{_S("use `fn ["), 0xfe10, {.d_s = node->name}}, {_S("] () {` instead of `fn () {`"), 0, { .d_c = 0 }}}))); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = node->name}}, {_S("` must be explicitly listed as inherited variable to be used inside a closure"), 0, { .d_c = 0 }}})), node->pos); } return _const_v__ast__void_type; } } v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("undefined ident: `"), 0xfe10, {.d_s = node->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } } return _const_v__ast__void_type; } VV_LOC v__ast__Type v__checker__Checker_concat_expr(v__checker__Checker* c, v__ast__ConcatExpr* node) { Array_v__ast__Type mr_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t1 = 0; _t1 < node->vals.len; ++_t1) { v__ast__Expr* expr = ((v__ast__Expr*)node->vals.data) + _t1; v__ast__Type typ = v__checker__Checker_expr(c, expr); if (typ == _const_v__ast__nil_type) { typ = _const_v__ast__voidptr_type; } array_push((array*)&mr_types, _MOV((v__ast__Type[]){ typ })); } if (node->vals.len == 1) { v__ast__Type typ = (*(v__ast__Type*)array_get(mr_types, 0)); node->return_type = typ; return typ; } else { for (int i = 0; i < mr_types.len; i++) { if ((*(v__ast__Type*)array_get(mr_types, i)) == _const_v__ast__void_type) { v__checker__Checker_error(c, _S("type `void` cannot be used in multi-return"), v__ast__Expr_pos((*(v__ast__Expr*)array_get(node->vals, i)))); return _const_v__ast__void_type; } } int typ = v__ast__Table_find_or_register_multi_return(c->table, mr_types); v__ast__new_type(typ); node->return_type = typ; return typ; } return 0; } VV_LOC void v__checker__Checker_smartcast(v__checker__Checker* c, v__ast__Expr* expr, v__ast__Type cur_type, v__ast__Type to_type_, v__ast__Scope* scope, bool is_comptime, bool is_option_unwrap) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, cur_type); v__ast__Type to_type = (sym->kind == v__ast__Kind__interface && v__ast__Table_sym(c->table, to_type_)->kind != v__ast__Kind__interface ? (v__ast__Type_ref(to_type_)) : (to_type_)); if (expr->_typ == 379 /* v.ast.SelectorExpr */) { bool is_mut = false; Array_v__ast__Type smartcasts = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); v__ast__TypeSymbol* expr_sym = v__ast__Table_sym(c->table, (*expr->_v__ast__SelectorExpr).expr_type); v__ast__Type orig_type = _const_v__ast__no_type; _result_v__ast__StructField _t1; if (_t1 = v__ast__Table_find_field(c->table, expr_sym, (*expr->_v__ast__SelectorExpr).field_name), !_t1.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t1.data; if (field.is_mut) { _option_v__ast__Ident _t2; if (_t2 = v__ast__SelectorExpr_root_ident(&(*expr->_v__ast__SelectorExpr)), _t2.state == 0) { v__ast__Ident root_ident = *(v__ast__Ident*)_t2.data; _option_v__ast__Var_ptr _t3; if (_t3 = v__ast__Scope_find_var(scope, root_ident.name), _t3.state == 0) { v__ast__Var* v = *(v__ast__Var**)_t3.data; is_mut = v->is_mut; } } } if (orig_type == 0) { orig_type = field.typ; } } string expr_str = v__ast__Expr_str(&(*expr->_v__ast__SelectorExpr).expr); if (((*expr->_v__ast__SelectorExpr).expr)._typ == 374 /* v.ast.ParExpr */ && ((*(v__ast__ParExpr*)__as_cast(((*expr->_v__ast__SelectorExpr).expr)._v__ast__ParExpr,((*expr->_v__ast__SelectorExpr).expr)._typ, 374)).expr)._typ == 339 /* v.ast.AsCast */) { expr_str = v__ast__Expr_str(&(*(*(*expr->_v__ast__SelectorExpr).expr._v__ast__ParExpr).expr._v__ast__AsCast).expr); } v__ast__ScopeStructField* field = v__ast__Scope_find_struct_field(scope, expr_str, (*expr->_v__ast__SelectorExpr).expr_type, (*expr->_v__ast__SelectorExpr).field_name); if (field != ((void*)0)) { _PUSH_MANY(&smartcasts, (field->smartcasts), _t4, Array_v__ast__Type); } if (!is_mut || (*expr->_v__ast__SelectorExpr).is_mut || is_option_unwrap || v__ast__Type_has_flag(orig_type, v__ast__TypeFlag__option)) { array_push((array*)&smartcasts, _MOV((v__ast__Type[]){ to_type })); v__ast__Scope_register_struct_field(scope, expr_str, ((v__ast__ScopeStructField){ .struct_type = (*expr->_v__ast__SelectorExpr).expr_type, .name = (*expr->_v__ast__SelectorExpr).field_name, .pos = (*expr->_v__ast__SelectorExpr).pos, .typ = cur_type, .orig_type = orig_type, .smartcasts = smartcasts, })); } else { c->smartcast_mut_pos = (*expr->_v__ast__SelectorExpr).pos; } } else if (expr->_typ == 358 /* v.ast.Ident */) { bool is_mut = false; Array_v__ast__Type smartcasts = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); bool is_already_casted = false; int orig_type = 0; bool is_inherited = false; v__ast__ComptimeVarKind ct_type_var = v__ast__ComptimeVarKind__no_comptime; bool is_ct_type_unwrapped = false; if (((*expr->_v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { is_ct_type_unwrapped = (*(*expr->_v__ast__Ident).obj._v__ast__Var).ct_type_var != v__ast__ComptimeVarKind__no_comptime; is_mut = (*(*expr->_v__ast__Ident).obj._v__ast__Var).is_mut; _PUSH_MANY(&smartcasts, ((*(*expr->_v__ast__Ident).obj._v__ast__Var).smartcasts), _t6, Array_v__ast__Type); is_already_casted = (*(*expr->_v__ast__Ident).obj._v__ast__Var).pos.pos == (*expr->_v__ast__Ident).pos.pos; if (orig_type == 0) { orig_type = (*(*expr->_v__ast__Ident).obj._v__ast__Var).typ; } is_inherited = (*(*expr->_v__ast__Ident).obj._v__ast__Var).is_inherited; ct_type_var = (is_comptime ? (v__ast__ComptimeVarKind__smartcast) : v__ast__Table_type_kind(c->table, to_type_) == v__ast__Kind__aggregate ? (v__ast__ComptimeVarKind__aggregate) : (v__ast__ComptimeVarKind__no_comptime)); } if ((!is_mut || (*expr->_v__ast__Ident).is_mut || is_option_unwrap) && !is_already_casted) { array_push((array*)&smartcasts, _MOV((v__ast__Type[]){ to_type })); _option_v__ast__Var_ptr _t8; if (_t8 = v__ast__Scope_find_var(scope, (*expr->_v__ast__Ident).name), _t8.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t8.data; if (is_comptime && var->ct_type_var == v__ast__ComptimeVarKind__smartcast) { if (v__ast__Type_has_flag(cur_type, v__ast__TypeFlag__option) && !v__ast__Type_has_flag(to_type, v__ast__TypeFlag__option)) { if (!var->is_unwrapped) { v__ast__Scope_register(scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){ .name = (*expr->_v__ast__Ident).name, .share = 0, .is_mut = (*expr->_v__ast__Ident).is_mut, .is_static = 0, .is_volatile = 0, .is_autofree_tmp = 0, .is_inherited = is_inherited, .has_inherited = 0, .is_arg = 0, .is_auto_deref = 0, .is_unwrapped = true, .is_index_var = 0, .expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .typ = cur_type, .orig_type = orig_type, .smartcasts = new_array_from_c_array(1, 1, sizeof(v__ast__Type), _MOV((v__ast__Type[1]){to_type})), .pos = (*expr->_v__ast__Ident).pos, .is_used = true, .is_changed = 0, .ct_type_var = ct_type_var, .ct_type_unwrapped = is_ct_type_unwrapped, .is_or = 0, .is_tmp = 0, .is_auto_heap = 0, .is_stack_obj = 0, }))))); } else { v__ast__Scope_update_smartcasts(scope, (*expr->_v__ast__Ident).name, to_type, true); } } else { v__ast__Scope_update_smartcasts(scope, (*expr->_v__ast__Ident).name, to_type, false); } return; } } v__ast__Scope_register(scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){ .name = (*expr->_v__ast__Ident).name, .share = 0, .is_mut = (*expr->_v__ast__Ident).is_mut, .is_static = 0, .is_volatile = 0, .is_autofree_tmp = 0, .is_inherited = is_inherited, .has_inherited = 0, .is_arg = 0, .is_auto_deref = 0, .is_unwrapped = is_option_unwrap, .is_index_var = 0, .expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .typ = cur_type, .orig_type = orig_type, .smartcasts = smartcasts, .pos = (*expr->_v__ast__Ident).pos, .is_used = true, .is_changed = 0, .ct_type_var = ct_type_var, .ct_type_unwrapped = is_ct_type_unwrapped, .is_or = 0, .is_tmp = 0, .is_auto_heap = 0, .is_stack_obj = 0, }))))); } else if (is_mut && !(*expr->_v__ast__Ident).is_mut) { c->smartcast_mut_pos = (*expr->_v__ast__Ident).pos; } } else { c->smartcast_cond_pos = v__ast__Expr_pos(*expr); } } VV_LOC v__ast__Type v__checker__Checker_select_expr(v__checker__Checker* c, v__ast__SelectExpr* node) { node->is_expr = c->expected_type != _const_v__ast__void_type; node->expected_type = c->expected_type; for (int _t1 = 0; _t1 < node->branches.len; ++_t1) { v__ast__SelectBranch* branch = ((v__ast__SelectBranch*)node->branches.data) + _t1; v__checker__Checker_stmt(c, &branch->stmt); if (branch->stmt._typ == 401 /* v.ast.ExprStmt */) { if (branch->is_timeout) { if (!v__ast__Type_is_int((*branch->stmt._v__ast__ExprStmt).typ)) { v__ast__TypeSymbol* tsym = v__ast__Table_sym(c->table, (*branch->stmt._v__ast__ExprStmt).typ); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid type `"), 0xfe10, {.d_s = tsym->name}}, {_S("` for timeout - expected integer number of nanoseconds aka `time.Duration`"), 0, { .d_c = 0 }}})), (*branch->stmt._v__ast__ExprStmt).pos); } } else { if (((*branch->stmt._v__ast__ExprStmt).expr)._typ == 362 /* v.ast.InfixExpr */) { if (!(((*(*branch->stmt._v__ast__ExprStmt).expr._v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ || ((*(*branch->stmt._v__ast__ExprStmt).expr._v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ || ((*(*branch->stmt._v__ast__ExprStmt).expr._v__ast__InfixExpr).left)._typ == 361 /* v.ast.IndexExpr */)) { v__checker__Checker_error(c, _S("channel in `select` key must be predefined"), v__ast__Expr_pos((*(*branch->stmt._v__ast__ExprStmt).expr._v__ast__InfixExpr).left)); } } else { v__checker__Checker_error(c, _S("invalid expression for `select` key"), v__ast__Expr_pos((*branch->stmt._v__ast__ExprStmt).expr)); } } } else if (branch->stmt._typ == 392 /* v.ast.AssignStmt */) { v__ast__Expr expr = (*(v__ast__Expr*)array_get((*branch->stmt._v__ast__AssignStmt).right, 0)); if (expr._typ == 376 /* v.ast.PrefixExpr */) { if (!(((*expr._v__ast__PrefixExpr).right)._typ == 358 /* v.ast.Ident */ || ((*expr._v__ast__PrefixExpr).right)._typ == 379 /* v.ast.SelectorExpr */ || ((*expr._v__ast__PrefixExpr).right)._typ == 361 /* v.ast.IndexExpr */)) { v__checker__Checker_error(c, _S("channel in `select` key must be predefined"), v__ast__Expr_pos((*expr._v__ast__PrefixExpr).right)); } if ((*expr._v__ast__PrefixExpr).or_block.kind != v__ast__OrKind__absent) { string err_prefix = ((*expr._v__ast__PrefixExpr).or_block.kind == v__ast__OrKind__block ? (_S("or block")) : (_S("error propagation"))); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = err_prefix}}, {_S(" not allowed in `select` key"), 0, { .d_c = 0 }}})), (*expr._v__ast__PrefixExpr).or_block.pos); } } else { v__checker__Checker_error(c, _S("`<-` receive expression expected"), v__ast__Expr_pos((*(v__ast__Expr*)array_get((*branch->stmt._v__ast__AssignStmt).right, 0)))); } if (((*(v__ast__Expr*)array_get((*branch->stmt._v__ast__AssignStmt).left, 0)))._typ == 358 /* v.ast.Ident */) { v__ast__Ident ident = *(v__ast__Ident*)__as_cast(((*(v__ast__Expr*)array_get((*branch->stmt._v__ast__AssignStmt).left, 0)))._v__ast__Ident,((*(v__ast__Expr*)array_get((*branch->stmt._v__ast__AssignStmt).left, 0)))._typ, 358); if (ident.kind == v__ast__IdentKind__blank_ident && (*branch->stmt._v__ast__AssignStmt).op != v__token__Kind__decl_assign) { v__checker__Checker_error(c, _S("cannot send on `_`, use `_ := <- quit` instead"), v__ast__Expr_pos((*(v__ast__Expr*)array_get((*branch->stmt._v__ast__AssignStmt).left, 0)))); } } } else { if (!branch->is_else) { v__checker__Checker_error(c, _S("receive or send statement expected as `select` key"), (*(branch->stmt.pos))); } } v__checker__Checker_stmts(c, &branch->stmts); } return _const_v__ast__bool_type; } VV_LOC v__ast__Type v__checker__Checker_lock_expr(v__checker__Checker* c, v__ast__LockExpr* node) { v__ast__Type expected_type = c->expected_type; if (c->rlocked_names.len > 0 || c->locked_names.len > 0) { v__checker__Checker_error(c, _S("nested `lock`/`rlock` not allowed"), node->pos); } for (int i = 0; i < node->lockeds.len; ++i) { v__ast__Expr expr_ = (*(v__ast__Expr*)array_get(node->lockeds, i)); v__ast__Type e_typ = v__checker__Checker_expr(c, &expr_); string id_name = v__ast__Expr_str(&(*(v__ast__Expr*)array_get(node->lockeds, i))); if (!v__ast__Type_has_flag(e_typ, v__ast__TypeFlag__shared_f)) { string obj_type = (((*(v__ast__Expr*)array_get(node->lockeds, i)))._typ == 358 /* v.ast.Ident */ ? (_S("variable")) : (_S("struct element"))); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = id_name}}, {_S("` must be declared as `shared` "), 0xfe10, {.d_s = obj_type}}, {_S(" to be locked"), 0, { .d_c = 0 }}})), v__ast__Expr_pos((*(v__ast__Expr*)array_get(node->lockeds, i)))); } if ((Array_string_contains(c->locked_names, id_name))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = id_name}}, {_S("` is already locked"), 0, { .d_c = 0 }}})), v__ast__Expr_pos((*(v__ast__Expr*)array_get(node->lockeds, i)))); } else if ((Array_string_contains(c->rlocked_names, id_name))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = id_name}}, {_S("` is already read-locked"), 0, { .d_c = 0 }}})), v__ast__Expr_pos((*(v__ast__Expr*)array_get(node->lockeds, i)))); } if ((*(bool*)array_get(node->is_rlock, i))) { array_push((array*)&c->rlocked_names, _MOV((string[]){ string_clone(id_name) })); } else { array_push((array*)&c->locked_names, _MOV((string[]){ string_clone(id_name) })); } } v__checker__Checker_stmts(c, &node->stmts); v__ast__Type ret_type = _const_v__ast__void_type; if (node->stmts.len > 0) { v__ast__Stmt last_stmt = (*(v__ast__Stmt*)array_last(node->stmts)); if ((last_stmt)._typ == 401 /* v.ast.ExprStmt */) { c->expected_type = expected_type; ret_type = v__checker__Checker_expr(c, &(*last_stmt._v__ast__ExprStmt).expr); } } c->rlocked_names = __new_array_with_default(0, 0, sizeof(string), 0); c->locked_names = __new_array_with_default(0, 0, sizeof(string), 0); if (ret_type != _const_v__ast__void_type) { node->is_expr = true; } node->typ = ret_type; return ret_type; } VV_LOC v__ast__Type v__checker__Checker_unsafe_expr(v__checker__Checker* c, v__ast__UnsafeExpr* node) { bool prev_unsafe = c->inside_unsafe; c->inside_unsafe = true; v__ast__Type t = v__checker__Checker_expr(c, &node->expr); c->inside_unsafe = prev_unsafe; return t; } VV_LOC _result_v__ast__Expr v__checker__Checker_find_definition(v__checker__Checker* c, v__ast__Ident ident) { if (ident.kind == (v__ast__IdentKind__unresolved) || ident.kind == (v__ast__IdentKind__blank_ident)) { return (_result_v__ast__Expr){ .is_error=true, .err=_v_error(_S("none")), .data={E_STRUCT} }; } else if (ident.kind == (v__ast__IdentKind__variable) || ident.kind == (v__ast__IdentKind__constant)) { return v__checker__Checker_find_obj_definition(c, ident.obj); } else if (ident.kind == (v__ast__IdentKind__global)) { return (_result_v__ast__Expr){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ident.name}}, {_S(" is a global variable"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } else if (ident.kind == (v__ast__IdentKind__function)) { return (_result_v__ast__Expr){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ident.name}}, {_S(" is a function"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } return (_result_v__ast__Expr){0}; } VV_LOC _result_v__ast__Expr v__checker__Checker_find_obj_definition(v__checker__Checker* c, v__ast__ScopeObject obj) { string name = _S(""); if (obj._typ == 418 /* v.ast.EmptyScopeObject */) { name = (*obj._v__ast__EmptyScopeObject).name; } else if (obj._typ == 422 /* v.ast.Var */) { name = (*obj._v__ast__Var).name; } else if (obj._typ == 420 /* v.ast.ConstField */) { name = (*obj._v__ast__ConstField).name; } else if (obj._typ == 421 /* v.ast.GlobalField */) { name = (*obj._v__ast__GlobalField).name; } else if (obj._typ == 419 /* v.ast.AsmRegister */) { name = (*obj._v__ast__AsmRegister).name; } v__ast__Expr expr = _const_v__ast__empty_expr; if ((obj)._typ == 422 /* v.ast.Var */) { if ((*obj._v__ast__Var).is_mut) { return (_result_v__ast__Expr){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = name}}, {_S("` is mut and may have changed since its definition"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } expr = (*obj._v__ast__Var).expr; } else if ((obj)._typ == 420 /* v.ast.ConstField */) { expr = (*obj._v__ast__ConstField).expr; } else { return (_result_v__ast__Expr){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = name}}, {_S("` is a global variable and is unknown at compile time"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } if ((expr)._typ == 358 /* v.ast.Ident */) { return v__checker__Checker_find_definition(c, (*expr._v__ast__Ident)); } if ((expr)._typ == 349 /* v.ast.ComptimeCall */ && (*(v__ast__ComptimeCall*)__as_cast((expr)._v__ast__ComptimeCall,(expr)._typ, 349)).kind == v__ast__ComptimeCallKind__d) { if ((*expr._v__ast__ComptimeCall).result_type == _const_v__ast__bool_type) { _result_v__ast__Expr _t4 = {0}; _result_ok(&(v__ast__Expr[]) { v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = string_bool((*expr._v__ast__ComptimeCall).compile_value),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))) }, (_result*)(&_t4), sizeof(v__ast__Expr)); return _t4; } } if (!v__ast__Expr_is_pure_literal(expr)) { return (_result_v__ast__Expr){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("definition of `"), 0xfe10, {.d_s = name}}, {_S("` is unknown at compile time"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } _result_v__ast__Expr _t6 = {0}; _result_ok(&(v__ast__Expr[]) { expr }, (_result*)(&_t6), sizeof(v__ast__Expr)); return _t6; } VV_LOC _option_bool v__checker__Checker_has_return(v__checker__Checker* c, Array_v__ast__Stmt stmts) { bool has_complexity = false; for (int _t1 = 0; _t1 < stmts.len; ++_t1) { v__ast__Stmt s = ((v__ast__Stmt*)stmts.data)[_t1]; if ((s)._typ == 401 /* v.ast.ExprStmt */) { if (((*s._v__ast__ExprStmt).expr)._typ == 359 /* v.ast.IfExpr */ || ((*s._v__ast__ExprStmt).expr)._typ == 369 /* v.ast.MatchExpr */) { has_complexity = true; break; } } } if (!has_complexity || !c->returns) { _option_bool _t2; _option_ok(&(bool[]) { v__checker__has_top_return(stmts) }, (_option*)(&_t2), sizeof(bool)); return _t2; } return (_option_bool){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } VV_LOC void v__checker__Checker_mark_as_referenced(v__checker__Checker* c, v__ast__Expr* node, bool as_interface) { if (node->_typ == 358 /* v.ast.Ident */) { if (((*node->_v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { v__ast__Var* obj = &(*(*node->_v__ast__Ident).obj._v__ast__Var); if (c->fn_scope != ((void*)0)) { _option_v__ast__Var_ptr _t1 = v__ast__Scope_find_var(c->fn_scope, (*(*node->_v__ast__Ident).obj._v__ast__Var).name); if (_t1.state != 0) { IError err = _t1.err; *(v__ast__Var**) _t1.data = obj; } obj = (*(v__ast__Var**)_t1.data); } if (obj->typ == 0) { return; } v__ast__TypeSymbol* type_sym = v__ast__Table_sym(c->table, v__ast__Type_set_nr_muls(obj->typ, 0)); if (obj->is_stack_obj && !v__ast__TypeSymbol_is_heap(type_sym) && !v__ast__TypeSymbol_is_int(type_sym) && !c->pref->translated && !c->file->is_translated) { string suggestion = (type_sym->kind == v__ast__Kind__struct ? (str_intp(2, _MOV((StrIntpData[]){{_S("declaring `"), 0xfe10, {.d_s = type_sym->name}}, {_S("` as `@[heap]`"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("wrapping the `"), 0xfe10, {.d_s = type_sym->name}}, {_S("` object in a `struct` declared as `@[heap]`"), 0, { .d_c = 0 }}})))); string mischief = (as_interface ? (_S("used as interface object")) : (_S("referenced"))); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = (*node->_v__ast__Ident).name}}, {_S("` cannot be "), 0xfe10, {.d_s = mischief}}, {_S(" outside `unsafe` blocks as it might be stored on stack. Consider "), 0xfe10, {.d_s = suggestion}}, {_S("."), 0, { .d_c = 0 }}})), (*node->_v__ast__Ident).pos); } else if (type_sym->kind == v__ast__Kind__array_fixed) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot reference fixed array `"), 0xfe10, {.d_s = (*node->_v__ast__Ident).name}}, {_S("` outside `unsafe` blocks as it is supposed to be stored on stack"), 0, { .d_c = 0 }}})), (*node->_v__ast__Ident).pos); } else { if (type_sym->kind == (v__ast__Kind__struct)) { v__ast__Struct info = *(v__ast__Struct*)__as_cast((type_sym->info)._v__ast__Struct,(type_sym->info)._typ, 518); if (!info.is_heap && !(*(*node->_v__ast__Ident).obj._v__ast__Var).is_inherited) { (*(*node->_v__ast__Ident).obj._v__ast__Var).is_auto_heap = true; } } else if (type_sym->kind == (v__ast__Kind__sum_type) || type_sym->kind == (v__ast__Kind__interface)) { } else if (type_sym->kind == (v__ast__Kind__function)) { if ((type_sym->info)._typ == 553 /* v.ast.FnType */) { if ((*type_sym->info._v__ast__FnType).is_anon) { (*(*node->_v__ast__Ident).obj._v__ast__Var).is_auto_heap = true; } } } else { (*(*node->_v__ast__Ident).obj._v__ast__Var).is_auto_heap = true; } } } } else if (node->_typ == 379 /* v.ast.SelectorExpr */) { if (!v__ast__Type_is_ptr((*node->_v__ast__SelectorExpr).expr_type)) { v__checker__Checker_mark_as_referenced(c, &(*node->_v__ast__SelectorExpr).expr, as_interface); } } else if (node->_typ == 361 /* v.ast.IndexExpr */) { v__checker__Checker_mark_as_referenced(c, &(*node->_v__ast__IndexExpr).left, as_interface); } else { } } VV_LOC string v__checker__Checker_get_base_name(v__checker__Checker* c, v__ast__Expr* node) { if (node->_typ == 358 /* v.ast.Ident */) { return (*node->_v__ast__Ident).name; } else if (node->_typ == 379 /* v.ast.SelectorExpr */) { return v__checker__Checker_get_base_name(c, &(*node->_v__ast__SelectorExpr).expr); } else if (node->_typ == 361 /* v.ast.IndexExpr */) { return v__checker__Checker_get_base_name(c, &(*node->_v__ast__IndexExpr).left); } else { return _S(""); } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC v__ast__Type v__checker__Checker_prefix_expr(v__checker__Checker* c, v__ast__PrefixExpr* node) { bool old_inside_ref_lit = c->inside_ref_lit; c->inside_ref_lit = c->inside_ref_lit || node->op == v__token__Kind__amp; v__ast__Type right_type = v__checker__Checker_expr(c, &node->right); c->inside_ref_lit = old_inside_ref_lit; node->right_type = right_type; v__ast__Expr expr = node->right; expr = v__ast__Expr_remove_par(&expr); if (node->op == v__token__Kind__amp) { if ((expr)._typ == 370 /* v.ast.Nil */) { v__checker__Checker_error(c, _S("invalid operation: cannot take address of nil"), v__ast__Expr_pos(expr)); } if ((node->right)._typ == 376 /* v.ast.PrefixExpr */) { if ((*node->right._v__ast__PrefixExpr).op == v__token__Kind__amp) { v__checker__Checker_error(c, _S("unexpected `&`, expecting expression"), (*node->right._v__ast__PrefixExpr).pos); } } else if ((expr)._typ == 376 /* v.ast.PrefixExpr */) { if ((*expr._v__ast__PrefixExpr).op == v__token__Kind__amp) { v__checker__Checker_error(c, _S("cannot take the address of this expression"), (*expr._v__ast__PrefixExpr).pos); } } else if ((expr)._typ == 379 /* v.ast.SelectorExpr */) { if (v__ast__Expr_is_literal((*expr._v__ast__SelectorExpr).expr)) { v__checker__Checker_error(c, _S("cannot take the address of a literal value"), v__token__Pos_extend(node->pos, (*expr._v__ast__SelectorExpr).pos)); } else if (((*expr._v__ast__SelectorExpr).expr)._typ == 385 /* v.ast.StructInit */) { v__checker__Checker_error(c, _S("should not create object instance on the heap to simply access a member"), v__token__Pos_extend(node->pos, (*expr._v__ast__SelectorExpr).pos)); } v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type); v__ast__TypeSymbol* expr_sym = v__ast__Table_sym(c->table, (*expr._v__ast__SelectorExpr).expr_type); if (expr_sym->kind == v__ast__Kind__struct && (*(v__ast__Struct*)__as_cast((expr_sym->info)._v__ast__Struct,(expr_sym->info)._typ, 518)).is_minify && ((*expr._v__ast__SelectorExpr).typ == 19 || (right_sym->kind == v__ast__Kind__enum && !(*(v__ast__Enum*)__as_cast((right_sym->info)._v__ast__Enum,(right_sym->info)._typ, 548)).is_flag && !(*(v__ast__Enum*)__as_cast((right_sym->info)._v__ast__Enum,(right_sym->info)._typ, 548)).uses_exprs))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot take the address of field in struct `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, (*expr._v__ast__SelectorExpr).expr_type)}}, {_S("`, which is tagged as `@[minify]`"), 0, { .d_c = 0 }}})), v__token__Pos_extend(node->pos, (*expr._v__ast__SelectorExpr).pos)); } if (v__ast__Type_has_flag((*expr._v__ast__SelectorExpr).typ, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("cannot take the address of an Option field"), v__token__Pos_extend(node->pos, (*expr._v__ast__SelectorExpr).pos)); } } } bool right_is_ptr = v__ast__Type_is_ptr(right_type); if (node->op == v__token__Kind__amp && (!right_is_ptr || (right_is_ptr && (expr)._typ == 344 /* v.ast.CallExpr */))) { if ((expr)._typ == 342 /* v.ast.BoolLiteral */ || (expr)._typ == 344 /* v.ast.CallExpr */ || (expr)._typ == 347 /* v.ast.CharLiteral */ || (expr)._typ == 356 /* v.ast.FloatLiteral */ || (expr)._typ == 363 /* v.ast.IntegerLiteral */ || (expr)._typ == 362 /* v.ast.InfixExpr */ || (expr)._typ == 384 /* v.ast.StringLiteral */ || (expr)._typ == 383 /* v.ast.StringInterLiteral */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot take the address of "), 0xfe10, {.d_s = v__ast__Expr_str(&expr)}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } if ((expr)._typ == 358 /* v.ast.Ident */) { if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__constant && !c->inside_unsafe && c->pref->experimental) { v__checker__Checker_warn(c, _S("cannot take the address of const outside `unsafe`"), (*expr._v__ast__Ident).pos); } } if ((expr)._typ == 379 /* v.ast.SelectorExpr */) { v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, right_type); if (typ_sym->kind == v__ast__Kind__map && !c->inside_unsafe) { v__checker__Checker_error(c, _S("cannot take the address of map values outside `unsafe`"), node->pos); } } if ((expr)._typ == 361 /* v.ast.IndexExpr */) { v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, (*expr._v__ast__IndexExpr).left_type); bool is_mut = false; if (((*expr._v__ast__IndexExpr).left)._typ == 358 /* v.ast.Ident */) { v__ast__Ident ident = (*(*expr._v__ast__IndexExpr).left._v__ast__Ident); v__ast__ScopeObject ident_obj = ident.obj; if ((ident_obj)._typ == 422 /* v.ast.Var */) { is_mut = (*ident_obj._v__ast__Var).is_mut; } } if (!c->inside_unsafe) { if (typ_sym->kind == v__ast__Kind__array && is_mut) { v__checker__Checker_error(c, _S("cannot take the address of mutable array elements outside unsafe blocks"), (*expr._v__ast__IndexExpr).pos); } if (typ_sym->kind == v__ast__Kind__map) { v__checker__Checker_error(c, _S("cannot take the address of map values outside `unsafe`"), (*expr._v__ast__IndexExpr).pos); } } } if (!c->inside_fn_arg && !c->inside_unsafe) { v__checker__Checker_mark_as_referenced(c, &expr, false); } return v__ast__Type_ref(right_type); } else if (node->op == v__token__Kind__amp && (expr)._typ != 345 /* v.ast.CastExpr */) { if (!c->inside_fn_arg && !c->inside_unsafe) { v__checker__Checker_mark_as_referenced(c, &expr, false); } if (v__ast__Expr_is_auto_deref_var(expr)) { return right_type; } else { return v__ast__Type_ref(right_type); } } v__ast__TypeSymbol* right_sym = v__ast__Table_final_sym(c->table, v__checker__Checker_unwrap_generic(c, right_type)); if (node->op == v__token__Kind__mul) { if (v__ast__Type_has_flag(right_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type `?"), 0xfe10, {.d_s = right_sym->name}}, {_S("` is an Option, it must be unwrapped first; use `*var?` to do it"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(expr)); } if (v__ast__Type_is_ptr(right_type)) { return v__ast__Type_deref(right_type); } if (!v__ast__Type_is_pointer(right_type) && !c->pref->translated && !c->file->is_translated) { string s = v__ast__Table_type_to_str(c->table, right_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("invalid indirect of `"), 0xfe10, {.d_s = s}}, {_S("`, the type `"), 0xfe10, {.d_s = right_sym->name}}, {_S("` is not a pointer"), 0, { .d_c = 0 }}})), node->pos); } if (v__ast__Type_is_voidptr(right_type)) { v__checker__Checker_error(c, _S("cannot dereference to void"), node->pos); } if ((expr)._typ == 358 /* v.ast.Ident */) { _option_v__ast__Var_ptr _t5; if (_t5 = v__ast__Scope_find_var((*expr._v__ast__Ident).scope, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*expr._v__ast__Ident).name}}, {_SLIT0, 0, { .d_c = 0 }}}))), _t5.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t5.data; if ((var->expr)._typ == 388 /* v.ast.UnsafeExpr */) { if (((*var->expr._v__ast__UnsafeExpr).expr)._typ == 370 /* v.ast.Nil */) { v__checker__Checker_error(c, _S("cannot deference a `nil` pointer"), (*expr._v__ast__Ident).pos); } } } } } if (node->op == v__token__Kind__bit_not && !c->pref->translated && !c->file->is_translated) { if ((right_sym->info)._typ == 548 /* v.ast.Enum */ && !(*(v__ast__Enum*)__as_cast((right_sym->info)._v__ast__Enum,(right_sym->info)._typ, 548)).is_flag) { v__checker__Checker_error(c, _S("operator `~` can only be used with `@[flag]` tagged enums"), node->pos); } if (!v__ast__TypeSymbol_is_int(right_sym) && (right_sym->info)._typ != 548 /* v.ast.Enum */) { v__checker__Checker_type_error_for_operator(c, _S("~"), _S("integer"), right_sym->name, node->pos); } } if (node->op == v__token__Kind__not && right_sym->kind != v__ast__Kind__bool && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_type_error_for_operator(c, _S("!"), _S("bool"), right_sym->name, node->pos); } if (node->op == v__token__Kind__minus && !v__ast__TypeSymbol_is_number(right_sym)) { v__checker__Checker_type_error_for_operator(c, _S("-"), _S("numeric"), right_sym->name, node->pos); } if (node->op == v__token__Kind__arrow) { v__ast__TypeSymbol* raw_right_sym = v__ast__Table_final_sym(c->table, right_type); if (raw_right_sym->kind == v__ast__Kind__chan) { v__checker__Checker_stmts_ending_with_expression(c, &node->or_block.stmts, c->expected_or_type); return v__ast__TypeSymbol_chan_info(raw_right_sym).elem_type; } v__checker__Checker_type_error_for_operator(c, _S("<-"), _S("`chan`"), raw_right_sym->name, node->pos); } return right_type; } VV_LOC void v__checker__Checker_type_error_for_operator(v__checker__Checker* c, string op_label, string types_label, string found_type_label, v__token__Pos pos) { v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("operator `"), 0xfe10, {.d_s = op_label}}, {_S("` can only be used with "), 0xfe10, {.d_s = types_label}}, {_S(" types, but the value after `"), 0xfe10, {.d_s = op_label}}, {_S("` is of type `"), 0xfe10, {.d_s = found_type_label}}, {_S("` instead"), 0, { .d_c = 0 }}})), pos); } VV_LOC void v__checker__Checker_check_index(v__checker__Checker* c, v__ast__TypeSymbol* typ_sym, v__ast__Expr index, v__ast__Type index_type, v__token__Pos pos, bool range_index, bool is_gated) { if (typ_sym->kind == v__ast__Kind__array || typ_sym->kind == v__ast__Kind__array_fixed || typ_sym->kind == v__ast__Kind__string) { v__ast__TypeSymbol* index_type_sym = v__ast__Table_sym(c->table, index_type); if (!(v__ast__Type_is_int(index_type) || index_type_sym->kind == v__ast__Kind__enum || (index_type_sym->kind == v__ast__Kind__alias && v__ast__Type_is_int((*(v__ast__Alias*)__as_cast((index_type_sym->info)._v__ast__Alias,(index_type_sym->info)._typ, 539)).parent_type)) || (c->pref->translated && v__ast__Type_is_any_kind_of_pointer(index_type)))) { string type_str = (typ_sym->kind == v__ast__Kind__string ? (str_intp(2, _MOV((StrIntpData[]){{_S("non-integer string index `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, index_type)}}, {_S("`"), 0, { .d_c = 0 }}}))) : (str_intp(3, _MOV((StrIntpData[]){{_S("non-integer index `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, index_type)}}, {_S("` (array type `"), 0xfe10, {.d_s = typ_sym->name}}, {_S("`)"), 0, { .d_c = 0 }}})))); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_str}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); } if ((index)._typ == 363 /* v.ast.IntegerLiteral */ && !is_gated) { if (string_at((*index._v__ast__IntegerLiteral).val, 0) == '-') { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("negative index `"), 0xfe10, {.d_s = (*index._v__ast__IntegerLiteral).val}}, {_S("`"), 0, { .d_c = 0 }}})), (*index._v__ast__IntegerLiteral).pos); } else if (typ_sym->kind == v__ast__Kind__array_fixed) { int i = string_int((*index._v__ast__IntegerLiteral).val); v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((typ_sym->info)._v__ast__ArrayFixed,(typ_sym->info)._typ, 549); if ((!range_index && i >= info.size) || (range_index && i > info.size)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("index out of range (index: "), 0xfe07, {.d_i32 = i}}, {_S(", len: "), 0xfe07, {.d_i32 = info.size}}, {_S(")"), 0, { .d_c = 0 }}})), (*index._v__ast__IntegerLiteral).pos); } } } if (v__ast__Type_has_option_or_result(index_type)) { string type_str = (typ_sym->kind == v__ast__Kind__string ? (str_intp(2, _MOV((StrIntpData[]){{_S("(type `"), 0xfe10, {.d_s = typ_sym->name}}, {_S("`)"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("(array type `"), 0xfe10, {.d_s = typ_sym->name}}, {_S("`)"), 0, { .d_c = 0 }}})))); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use Option or Result as index "), 0xfe10, {.d_s = type_str}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); } } } VV_LOC v__ast__Type v__checker__Checker_index_expr(v__checker__Checker* c, v__ast__IndexExpr* node) { v__ast__Type typ = v__checker__Checker_expr(c, &node->left); if (typ == 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type for expression `"), 0xfe10, {.d_s = v__ast__Expr_str(&node->left)}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); return typ; } v__ast__TypeSymbol* typ_sym = v__ast__Table_final_sym(c->table, typ); node->left_type = typ; switch (typ_sym->kind) { case v__ast__Kind__map: { node->is_map = true; break; } case v__ast__Kind__array: { node->is_array = true; if (node->or_expr.kind != v__ast__OrKind__absent && (node->index)._typ == 377 /* v.ast.RangeExpr */) { v__checker__Checker_error(c, _S("custom error handling on range expressions for arrays is not supported yet."), node->or_expr.pos); } break; } case v__ast__Kind__array_fixed: { node->is_farray = true; break; } case v__ast__Kind__any: { v__ast__Type unwrapped_typ = v__checker__Checker_unwrap_generic(c, typ); v__ast__TypeSymbol* unwrapped_sym = v__ast__Table_final_sym(c->table, unwrapped_typ); if (unwrapped_sym->kind == v__ast__Kind__map || unwrapped_sym->kind == v__ast__Kind__array || unwrapped_sym->kind == v__ast__Kind__array_fixed) { typ = unwrapped_typ; typ_sym = unwrapped_sym; } break; } case v__ast__Kind__string: { if (node->is_gated && !fast_string_eq(c->mod, _S("strings"))) { c->table->used_features->range_index = true; } break; } case v__ast__Kind__placeholder: case v__ast__Kind__void: case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__i32: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__isize: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__usize: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__bool: case v__ast__Kind__none: case v__ast__Kind__chan: case v__ast__Kind__struct: case v__ast__Kind__generic_inst: case v__ast__Kind__multi_return: case v__ast__Kind__sum_type: case v__ast__Kind__alias: case v__ast__Kind__enum: case v__ast__Kind__function: case v__ast__Kind__interface: case v__ast__Kind__float_literal: case v__ast__Kind__int_literal: case v__ast__Kind__aggregate: case v__ast__Kind__thread: default: { { break; } } } if (!c->is_builtin_mod && !(fast_string_eq(c->mod, _S("strings")) || fast_string_eq(c->mod, _S("math.bits")))) { if ((node->index)._typ == 377 /* v.ast.RangeExpr */) { c->table->used_features->range_index = true; } c->table->used_features->index = true; } bool _t2 = (typ_sym->kind == v__ast__Kind__aggregate); Array_v__ast__Type _t3 = {0}; if (_t2) { Array_v__ast__Type _t3_orig = (*(v__ast__Aggregate*)__as_cast((typ_sym->info)._v__ast__Aggregate,(typ_sym->info)._typ, 537)).types; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__Type)); for (int _t4 = 0; _t4 < _t3_len; ++_t4) { v__ast__Type it = ((v__ast__Type*) _t3_orig.data)[_t4]; if (!(Array_v__ast__Kind_contains(new_array_from_c_array(4, 4, sizeof(v__ast__Kind), _MOV((v__ast__Kind[4]){v__ast__Kind__array, v__ast__Kind__array_fixed, v__ast__Kind__string, v__ast__Kind__map})), v__ast__Table_type_kind(c->table, it)))) { array_push((array*)&_t3, &it); } } } bool is_aggregate_arr = _t2 &&_t3.len == 0; if (!(typ_sym->kind == v__ast__Kind__array || typ_sym->kind == v__ast__Kind__array_fixed || typ_sym->kind == v__ast__Kind__string || typ_sym->kind == v__ast__Kind__map) && (!v__ast__Type_is_ptr(typ) || (typ_sym->kind == v__ast__Kind__sum_type || typ_sym->kind == v__ast__Kind__interface)) && !(typ == _const_v__ast__byteptr_type || typ == _const_v__ast__charptr_type) && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__variadic) && !is_aggregate_arr) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type `"), 0xfe10, {.d_s = typ_sym->name}}, {_S("` does not support indexing"), 0, { .d_c = 0 }}})), node->pos); } if (is_aggregate_arr) { typ = (*(v__ast__Type*)array_get((*(v__ast__Aggregate*)__as_cast((typ_sym->info)._v__ast__Aggregate,(typ_sym->info)._typ, 537)).types, 0)); } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { if ((node->left)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node->left)._v__ast__Ident,(node->left)._typ, 358)).or_expr.kind == v__ast__OrKind__absent) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type `?"), 0xfe10, {.d_s = typ_sym->name}}, {_S("` is an Option, it must be unwrapped first; use `var?[]` to do it"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); } else if ((node->left)._typ == 344 /* v.ast.CallExpr */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type `?"), 0xfe10, {.d_s = typ_sym->name}}, {_S("` is an Option, it must be unwrapped with `func()?`, or use `func() or {default}`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); } else if ((node->left)._typ == 379 /* v.ast.SelectorExpr */ && (*(v__ast__SelectorExpr*)__as_cast((node->left)._v__ast__SelectorExpr,(node->left)._typ, 379)).or_block.kind == v__ast__OrKind__absent) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("type `?"), 0xfe10, {.d_s = typ_sym->name}}, {_S("` is an Option, it must be unwrapped first; use `"), 0xfe10, {.d_s = v__ast__Expr_str(&node->left)}}, {_S("?` to do it"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); } } else if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type `!"), 0xfe10, {.d_s = typ_sym->name}}, {_S("` is a Result, it does not support indexing"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); } if (typ_sym->kind == v__ast__Kind__string && !v__ast__Type_is_ptr(typ) && node->is_setter) { v__checker__Checker_error(c, _S("cannot assign to s[i] since V strings are immutable\n(note, that variables may be mutable but string values are always immutable, like in Go and Java)"), node->pos); } if (!c->inside_unsafe && !c->is_builtin_mod && !c->inside_if_guard && !c->is_index_assign && typ_sym->kind == v__ast__Kind__map && node->or_expr.stmts.len == 0) { v__ast__Type elem_type = v__ast__Table_value_type(c->table, typ); if (v__ast__Type_is_any_kind_of_pointer(elem_type)) { v__checker__Checker_warn(c, _S("accessing a pointer map value requires an `or {}` block outside `unsafe`"), node->pos); } Array_v__ast__Type checked_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); if (v__checker__Checker_is_contains_any_kind_of_pointer(c, elem_type, &checked_types)) { v__checker__Checker_warn(c, _S("accessing map value that contain pointers requires an `or {}` block outside `unsafe`"), node->pos); } } if ((v__ast__Type_is_ptr(typ) && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f) && (!v__ast__Expr_is_auto_deref_var(node->left) || (typ_sym->kind == v__ast__Kind__struct && !fast_string_eq(typ_sym->name, _S("array"))))) || v__ast__Type_is_pointer(typ)) { bool is_ok = false; bool is_mut_struct = false; if ((node->left)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((node->left)._v__ast__Ident,(node->left)._typ, 358)).obj)._typ == 422 /* v.ast.Var */) { is_ok = (*(*node->left._v__ast__Ident).obj._v__ast__Var).is_mut && (*(*node->left._v__ast__Ident).obj._v__ast__Var).is_arg && !v__ast__Type_is_ptr(v__ast__Type_deref(typ)) && typ_sym->kind != v__ast__Kind__struct; is_mut_struct = (*(*node->left._v__ast__Ident).obj._v__ast__Var).is_mut && (*(*node->left._v__ast__Ident).obj._v__ast__Var).is_arg && typ_sym->kind == v__ast__Kind__struct; } if (!is_ok && (node->index)._typ == 377 /* v.ast.RangeExpr */) { string s = v__ast__Table_type_to_str(c->table, typ); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type `"), 0xfe10, {.d_s = s}}, {_S("` does not support slicing"), 0, { .d_c = 0 }}})), node->pos); } else if (is_mut_struct) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type `mut "), 0xfe10, {.d_s = typ_sym->name}}, {_S("` does not support slicing"), 0, { .d_c = 0 }}})), node->pos); } else if (!c->inside_unsafe && !is_ok && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, _S("pointer indexing is only allowed in `unsafe` blocks"), node->pos); } } if ((node->index)._typ == 377 /* v.ast.RangeExpr */) { if ((*node->index._v__ast__RangeExpr).has_low) { v__ast__Type index_type = v__checker__Checker_expr(c, &(*node->index._v__ast__RangeExpr).low); v__checker__Checker_check_index(c, typ_sym, (*node->index._v__ast__RangeExpr).low, index_type, node->pos, true, node->is_gated); } if ((*node->index._v__ast__RangeExpr).has_high) { v__ast__Type index_type = v__checker__Checker_expr(c, &(*node->index._v__ast__RangeExpr).high); v__checker__Checker_check_index(c, typ_sym, (*node->index._v__ast__RangeExpr).high, index_type, node->pos, true, node->is_gated); } if (typ_sym->kind == v__ast__Kind__array_fixed) { v__ast__Type elem_type = v__ast__Table_value_type(c->table, typ); int idx = v__ast__Table_find_or_register_array(c->table, elem_type); typ = v__ast__new_type(idx); } else { typ = v__ast__Type_set_nr_muls(typ, 0); } } else { if (typ_sym->kind == v__ast__Kind__map) { v__ast__Map info = *(v__ast__Map*)__as_cast((typ_sym->info)._v__ast__Map,(typ_sym->info)._typ, 514); c->expected_type = info.key_type; v__ast__Type index_type = v__checker__Checker_expr(c, &node->index); v__ast__Type key_type = v__checker__Checker_unwrap_generic(c, info.key_type); if (!v__checker__Checker_check_types(c, index_type, key_type)) { string err = v__checker__Checker_expected_msg(c, index_type, key_type); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid key: "), 0xfe10, {.d_s = err}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } v__ast__TypeSymbol* value_sym = v__ast__Table_sym(c->table, info.value_type); if (!node->is_setter && value_sym->kind == v__ast__Kind__sum_type && node->or_expr.kind == v__ast__OrKind__absent && !c->inside_unsafe && !c->inside_if_guard) { v__checker__Checker_warn(c, _S("`or {}` block required when indexing a map with sum type value"), node->pos); } } else { v__ast__Type index_type = v__checker__Checker_expr(c, &node->index); if (node->is_gated == true) { v__checker__Checker_error(c, _S("`#[]` allowed only for ranges"), node->pos); } v__checker__Checker_check_index(c, typ_sym, node->index, index_type, node->pos, false, false); } v__ast__Type value_type = v__ast__Table_value_type(c->table, typ); if (value_type != _const_v__ast__void_type) { typ = value_type; } } bool _t5 = (node->or_expr.stmts.len > 0); if ( _t5 && ((*(v__ast__Stmt*)array_last(node->or_expr.stmts)))._typ == 401 /* v.ast.ExprStmt */) { c->expected_or_type = typ; } v__checker__Checker_stmts_ending_with_expression(c, &node->or_expr.stmts, c->expected_or_type); v__checker__Checker_check_expr_option_or_result_call(c, v__ast__IndexExpr_to_sumtype_v__ast__Expr(node), typ); node->typ = typ; return typ; } VV_LOC v__ast__Type v__checker__Checker_enum_val(v__checker__Checker* c, v__ast__EnumVal* node) { int typ_idx = ((node->enum_name).len == 0 ? ((c->expected_type == _const_v__ast__void_type && c->expected_expr_type != _const_v__ast__void_type ? (v__ast__Type_idx(c->expected_expr_type)) : (v__ast__Type_idx(c->expected_type)))) : (v__ast__Table_find_type_idx(c->table, node->enum_name))); if (typ_idx == 0) { if (string_starts_with(node->enum_name, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->mod}}, {_S("."), 0, { .d_c = 0 }}})))) { typ_idx = v__ast__Table_find_type(c->table, string_substr(node->enum_name, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->mod}}, {_S("."), 0, { .d_c = 0 }}})).len, 2147483647)); if (typ_idx == 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown enum `"), 0xfe10, {.d_s = node->enum_name}}, {_S("` (type_idx=0)"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__void_type; } } if (typ_idx == 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown enum `"), 0xfe10, {.d_s = node->enum_name}}, {_S("` (type_idx=0)"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__void_type; } } v__ast__Type typ = v__ast__new_type(typ_idx); if (c->pref->translated || c->file->is_translated) { node->typ = typ; return typ; } if (typ == _const_v__ast__void_type) { v__checker__Checker_error(c, _S("not an enum"), node->pos); return _const_v__ast__void_type; } v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, typ); if (typ_sym->kind == v__ast__Kind__array && node->enum_name.len == 0) { v__ast__Array array_info = *(v__ast__Array*)__as_cast((typ_sym->info)._v__ast__Array,(typ_sym->info)._typ, 513); typ = array_info.elem_type; typ_sym = v__ast__Table_sym(c->table, typ); } v__ast__TypeSymbol* fsym = v__ast__Table_final_sym(c->table, typ); if (fsym->kind != v__ast__Kind__enum && !c->pref->translated && !c->file->is_translated) { if (typ_sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = typ_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expected type is not an enum (`"), 0xfe10, {.d_s = typ_sym->name}}, {_S("`)"), 0, { .d_c = 0 }}})), node->pos); } return _const_v__ast__void_type; } if ((fsym->info)._typ != 548 /* v.ast.Enum */) { v__checker__Checker_error(c, _S("not an enum"), node->pos); return _const_v__ast__void_type; } if (!(typ_sym->is_pub || string__eq(typ_sym->mod, c->mod))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("enum `"), 0xfe10, {.d_s = typ_sym->name}}, {_S("` is private"), 0, { .d_c = 0 }}})), node->pos); } v__ast__Enum info = v__ast__TypeSymbol_enum_info(typ_sym); if (!(Array_string_contains(info.vals, node->val))) { v__util__Suggestion suggestion = v__util__new_suggestion(node->val, info.vals, ((v__util__SuggestionParams){.similarity_threshold = 0.5,.similarity_fn = strings__dice_coefficient,})); v__checker__Checker_error(c, v__util__Suggestion_say(suggestion, str_intp(3, _MOV((StrIntpData[]){{_S("enum `"), 0xfe10, {.d_s = typ_sym->name}}, {_S("` does not have a value `"), 0xfe10, {.d_s = node->val}}, {_S("`"), 0, { .d_c = 0 }}}))), node->pos); } node->typ = typ; return typ; } VV_LOC v__ast__Type v__checker__Checker_chan_init(v__checker__Checker* c, v__ast__ChanInit* node) { if (node->typ != 0) { v__ast__Chan info = v__ast__TypeSymbol_chan_info(v__ast__Table_sym(c->table, node->typ)); node->elem_type = info.elem_type; if (node->elem_type != 0) { v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(c->table, node->elem_type); if (elem_sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = elem_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->elem_type_pos); } } if (node->has_cap) { v__checker__Checker_check_array_init_para_type(c, _S("cap"), &node->cap_expr, node->pos); } if (c->pref->skip_unused && v__ast__Type_has_flag(node->typ, v__ast__TypeFlag__generic)) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__checker__Checker_unwrap_generic(c, node->typ)}, &(bool[]) { true }); } return node->typ; } else { v__checker__Checker_error(c, _S("`chan` of unknown type"), node->pos); return node->typ; } return 0; } VV_LOC v__ast__Type v__checker__Checker_offset_of(v__checker__Checker* c, v__ast__OffsetOf node) { v__ast__TypeSymbol* sym = v__ast__Table_final_sym(c->table, node.struct_type); if (sym->kind != v__ast__Kind__struct) { v__checker__Checker_error(c, _S("first argument of __offsetof must be struct"), node.pos); return _const_v__ast__u32_type; } if (!v__ast__Table_struct_has_field(c->table, sym, node.field)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("struct `"), 0xfe10, {.d_s = sym->name}}, {_S("` has no field called `"), 0xfe10, {.d_s = node.field}}, {_S("`"), 0, { .d_c = 0 }}})), node.pos); } return _const_v__ast__u32_type; } VV_LOC void v__checker__Checker_check_dup_keys(v__checker__Checker* c, v__ast__MapInit* node, int i) { v__ast__Expr key_i = (*(v__ast__Expr*)array_get(node->keys, i)); if ((key_i)._typ == 384 /* v.ast.StringLiteral */) { for (int j = 0; j < i; ++j) { v__ast__Expr key_j = (*(v__ast__Expr*)array_get(node->keys, j)); if ((key_j)._typ == 384 /* v.ast.StringLiteral */) { if (string__eq((*key_i._v__ast__StringLiteral).val, (*key_j._v__ast__StringLiteral).val)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate key \""), 0xfe10, {.d_s = (*key_i._v__ast__StringLiteral).val}}, {_S("\" in map literal"), 0, { .d_c = 0 }}})), (*key_i._v__ast__StringLiteral).pos); } } } } else if ((key_i)._typ == 363 /* v.ast.IntegerLiteral */) { for (int j = 0; j < i; ++j) { v__ast__Expr key_j = (*(v__ast__Expr*)array_get(node->keys, j)); if ((key_j)._typ == 363 /* v.ast.IntegerLiteral */) { if (string__eq((*key_i._v__ast__IntegerLiteral).val, (*key_j._v__ast__IntegerLiteral).val)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate key \""), 0xfe10, {.d_s = (*key_i._v__ast__IntegerLiteral).val}}, {_S("\" in map literal"), 0, { .d_c = 0 }}})), (*key_i._v__ast__IntegerLiteral).pos); } } } } } VV_LOC bool v__checker__Checker_check_struct_signature_init_fields(v__checker__Checker* c, v__ast__Struct from, v__ast__Struct to, v__ast__StructInit node) { if (node.init_fields.len == 0) { return from.fields.len == to.fields.len; } int count_not_in_from = 0; for (int _t2 = 0; _t2 < node.init_fields.len; ++_t2) { v__ast__StructInitField field = ((v__ast__StructInitField*)node.init_fields.data)[_t2]; Array_v__ast__StructField _t3 = {0}; Array_v__ast__StructField _t3_orig = from.fields; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__StructField)); for (int _t4 = 0; _t4 < _t3_len; ++_t4) { v__ast__StructField it = ((v__ast__StructField*) _t3_orig.data)[_t4]; if (string__eq(it.name, field.name)) { array_push((array*)&_t3, &it); } } Array_v__ast__StructField filtered =_t3; if (filtered.len != 1) { count_not_in_from++; } } return ((int)(from.fields.len + count_not_in_from)) == to.fields.len; } VV_LOC bool v__checker__Checker_check_struct_signature(v__checker__Checker* c, v__ast__Struct from, v__ast__Struct to) { if (from.fields.len == 0) { return false; } for (int _t2 = 0; _t2 < from.fields.len; ++_t2) { v__ast__StructField field = ((v__ast__StructField*)from.fields.data)[_t2]; Array_v__ast__StructField _t3 = {0}; Array_v__ast__StructField _t3_orig = to.fields; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__StructField)); for (int _t4 = 0; _t4 < _t3_len; ++_t4) { v__ast__StructField it = ((v__ast__StructField*) _t3_orig.data)[_t4]; if (string__eq(it.name, field.name)) { array_push((array*)&_t3, &it); } } Array_v__ast__StructField filtered =_t3; if (filtered.len != 1) { return false; } v__ast__StructField counterpart = (*(v__ast__StructField*)array_get(filtered, 0)); if (field.typ != counterpart.typ) { return false; } if (field.is_pub != counterpart.is_pub) { return false; } if (field.is_mut != counterpart.is_mut) { return false; } } return true; } VV_LOC string v__checker__Checker_fetch_field_name(v__checker__Checker* c, v__ast__StructField field) { string name = field.name; for (int _t1 = 0; _t1 < field.attrs.len; ++_t1) { v__ast__Attr attr = ((v__ast__Attr*)field.attrs.data)[_t1]; if (attr.kind == v__ast__AttrKind__string && (attr.arg).len != 0 && fast_string_eq(attr.name, _S("sql"))) { name = attr.arg; break; } } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, field.typ); if (sym->kind == v__ast__Kind__struct && !fast_string_eq(sym->name, _S("time.Time"))) { name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = name}}, {_S("_id"), 0, { .d_c = 0 }}})); } return name; } VV_LOC bool v__checker__Checker_ensure_generic_type_specify_type_names(v__checker__Checker* c, v__ast__Type typ, v__token__Pos pos, bool is_container_typ, bool is_generic_container) { bool v__checker__Checker_ensure_generic_type_specify_type_names_defer_0 = false; if (typ == 0) { v__checker__Checker_error(c, _S("unknown type"), pos); return false; } c->ensure_generic_type_level++; v__checker__Checker_ensure_generic_type_specify_type_names_defer_0 = true; if (c->ensure_generic_type_level > 40) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("checker: too many levels of Checker.ensure_generic_type_specify_type_names calls: "), 0xfe07, {.d_i32 = c->ensure_generic_type_level}}, {_S(" "), 0, { .d_c = 0 }}})), pos); bool _t2 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t2; } v__ast__TypeSymbol* sym = v__ast__Table_final_sym(c->table, typ); if (c->ensure_generic_type_level > 38) { eprintln(str_intp(6, _MOV((StrIntpData[]){{_S(">> c.ensure_generic_type_level: "), 0xfe07, {.d_i32 = c->ensure_generic_type_level}}, {_S(" > 38, in "), 0xfe10, {.d_s = _S("Checker.ensure_generic_type_specify_type_names")}}, {_S(", typ: "), 0xfe10, {.d_s = v__ast__Type_str(typ)}}, {_S(", sym.kind: "), 0xfe10, {.d_s = v__ast__Kind_str(sym->kind)}}, {_S(", pos: "), 0xfe10, {.d_s = v__token__Pos_str(pos)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } switch (sym->kind) { case v__ast__Kind__function: { v__ast__FnType fn_info = *(v__ast__FnType*)__as_cast((sym->info)._v__ast__FnType,(sym->info)._typ, 553); if (!v__checker__Checker_ensure_generic_type_specify_type_names(c, fn_info.func.return_type, fn_info.func.return_type_pos, is_container_typ, is_generic_container)) { bool _t3 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t3; } for (int _t4 = 0; _t4 < fn_info.func.params.len; ++_t4) { v__ast__Param param = ((v__ast__Param*)fn_info.func.params.data)[_t4]; if (!v__checker__Checker_ensure_generic_type_specify_type_names(c, param.typ, param.type_pos, is_container_typ, is_generic_container)) { bool _t5 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t5; } } if (fn_info.func.generic_names.len > 0 && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = sym->name}}, {_S("` type is generic fn type, must specify the generic type names, e.g. "), 0xfe10, {.d_s = sym->name}}, {_S("[T], "), 0xfe10, {.d_s = sym->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), pos); bool _t6 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t6; } break; } case v__ast__Kind__array: { if (!v__checker__Checker_ensure_generic_type_specify_type_names(c, (*(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513)).elem_type, pos, true, v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic))) { bool _t7 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t7; } break; } case v__ast__Kind__array_fixed: { if (!v__checker__Checker_ensure_generic_type_specify_type_names(c, (*(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549)).elem_type, pos, true, v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic))) { bool _t8 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t8; } break; } case v__ast__Kind__map: { v__ast__Map info = *(v__ast__Map*)__as_cast((sym->info)._v__ast__Map,(sym->info)._typ, 514); if (!v__checker__Checker_ensure_generic_type_specify_type_names(c, info.key_type, pos, true, v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic))) { bool _t9 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t9; } if (!v__checker__Checker_ensure_generic_type_specify_type_names(c, info.value_type, pos, true, v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic))) { bool _t10 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t10; } break; } case v__ast__Kind__sum_type: { v__ast__SumType info = *(v__ast__SumType*)__as_cast((sym->info)._v__ast__SumType,(sym->info)._typ, 544); if (info.generic_types.len > 0 && ((is_container_typ && !is_generic_container) || !v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) && info.concrete_types.len == 0) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = sym->name}}, {_S("` type is generic sumtype, must specify the generic type names, e.g. "), 0xfe10, {.d_s = sym->name}}, {_S("[T], "), 0xfe10, {.d_s = sym->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), pos); bool _t11 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t11; } break; } case v__ast__Kind__struct: { v__ast__Struct info = *(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518); if (info.generic_types.len > 0 && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic) && info.concrete_types.len == 0) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = sym->name}}, {_S("` type is generic struct, must specify the generic type names, e.g. "), 0xfe10, {.d_s = sym->name}}, {_S("[T], "), 0xfe10, {.d_s = sym->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), pos); bool _t12 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t12; } break; } case v__ast__Kind__interface: { v__ast__Interface info = *(v__ast__Interface*)__as_cast((sym->info)._v__ast__Interface,(sym->info)._typ, 542); if (info.generic_types.len > 0 && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic) && info.concrete_types.len == 0) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = sym->name}}, {_S("` type is generic interface, must specify the generic type names, e.g. "), 0xfe10, {.d_s = sym->name}}, {_S("[T], "), 0xfe10, {.d_s = sym->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), pos); bool _t13 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t13; } break; } case v__ast__Kind__alias: { v__ast__Alias info = *(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539); if (!v__checker__Checker_ensure_generic_type_specify_type_names(c, info.parent_type, pos, is_container_typ, is_generic_container)) { bool _t14 = false; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t14; } break; } case v__ast__Kind__placeholder: case v__ast__Kind__void: case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__i32: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__isize: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__usize: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__bool: case v__ast__Kind__none: case v__ast__Kind__string: case v__ast__Kind__chan: case v__ast__Kind__any: case v__ast__Kind__generic_inst: case v__ast__Kind__multi_return: case v__ast__Kind__enum: case v__ast__Kind__float_literal: case v__ast__Kind__int_literal: case v__ast__Kind__aggregate: case v__ast__Kind__thread: default: { { break; } } } bool _t15 = true; // Defer begin if (v__checker__Checker_ensure_generic_type_specify_type_names_defer_0) { c->ensure_generic_type_level--; } // Defer end return _t15; } VV_LOC bool v__checker__Checker_ensure_type_exists(v__checker__Checker* c, v__ast__Type typ, v__token__Pos pos) { bool v__checker__Checker_ensure_type_exists_defer_0 = false; if (typ == 0) { v__checker__Checker_error(c, _S("unknown type"), pos); return false; } c->type_level++; v__checker__Checker_ensure_type_exists_defer_0 = true; if (c->type_level > 40) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("checker: too many levels of Checker.ensure_type_exists calls: "), 0xfe07, {.d_i32 = c->type_level}}, {_S(", probably due to a self referencing type"), 0, { .d_c = 0 }}})), pos); bool _t2 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t2; } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); if (!c->is_builtin_mod && !sym->is_pub && !string__eq(sym->mod, c->mod) && !fast_string_eq(sym->mod, _S("main"))) { if (sym->kind == v__ast__Kind__function) { v__ast__FnType fn_info = *(v__ast__FnType*)__as_cast((sym->info)._v__ast__FnType,(sym->info)._typ, 553); string fn_mod = sym->mod; if ((fn_mod).len == 0) { fn_mod = string_all_before_last(fn_info.func.name, _S(".")); if (string__eq(fn_mod, fn_info.func.name)) { fn_mod = _S("builtin"); } } if ((fn_mod).len != 0 && !string__eq(fn_mod, c->mod) && (fn_info.func.name).len != 0 && !fn_info.is_anon) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("function type `"), 0xfe10, {.d_s = fn_info.func.name}}, {_S("` was declared as private to module `"), 0xfe10, {.d_s = fn_mod}}, {_S("`, so it can not be used inside module `"), 0xfe10, {.d_s = c->mod}}, {_S("`"), 0, { .d_c = 0 }}})), pos); bool _t3 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t3; } } else if ((sym->mod).len != 0) { v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Kind_str(sym->kind)}}, {_S(" `"), 0xfe10, {.d_s = sym->name}}, {_S("` was declared as private to module `"), 0xfe10, {.d_s = sym->mod}}, {_S("`, so it can not be used inside module `"), 0xfe10, {.d_s = c->mod}}, {_S("`"), 0, { .d_c = 0 }}})), pos); bool _t4 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t4; } } switch (sym->kind) { case v__ast__Kind__placeholder: { if (sym->language == v__ast__Language__v) { v__checker__Checker_error(c, v__util__Suggestion_say(v__util__new_suggestion(sym->name, v__ast__Table_known_type_names(c->table), ((v__util__SuggestionParams){.similarity_threshold = 0.5,.similarity_fn = strings__dice_coefficient,})), str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`"), 0, { .d_c = 0 }}}))), pos); bool _t5 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t5; } else if (sym->language == v__ast__Language__c) { if (!c->pref->translated && !c->file->is_translated) { v__checker__Checker_warn(c, v__util__Suggestion_say(v__util__new_suggestion(sym->name, v__ast__Table_known_type_names(c->table), ((v__util__SuggestionParams){.similarity_threshold = 0.5,.similarity_fn = strings__dice_coefficient,})), str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("` (all virtual C types must be defined, this will be an error soon)"), 0, { .d_c = 0 }}}))), pos); } } break; } case v__ast__Kind__int_literal: case v__ast__Kind__float_literal: { if (!c->is_builtin_mod) { string msg = (sym->kind == v__ast__Kind__int_literal ? (str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`.\nDid you mean `int`?"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`.\nDid you mean `f64`?"), 0, { .d_c = 0 }}})))); v__checker__Checker_error(c, msg, pos); bool _t6 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t6; } break; } case v__ast__Kind__function: { v__ast__FnType fn_info = *(v__ast__FnType*)__as_cast((sym->info)._v__ast__FnType,(sym->info)._typ, 553); if (!v__checker__Checker_ensure_type_exists(c, fn_info.func.return_type, fn_info.func.return_type_pos)) { bool _t7 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t7; } for (int _t8 = 0; _t8 < fn_info.func.params.len; ++_t8) { v__ast__Param param = ((v__ast__Param*)fn_info.func.params.data)[_t8]; if (!v__checker__Checker_ensure_type_exists(c, param.typ, param.type_pos)) { bool _t9 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t9; } } break; } case v__ast__Kind__array: { if (!v__checker__Checker_ensure_type_exists(c, (*(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513)).elem_type, pos)) { bool _t10 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t10; } break; } case v__ast__Kind__array_fixed: { if (!v__checker__Checker_ensure_type_exists(c, (*(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549)).elem_type, pos)) { bool _t11 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t11; } break; } case v__ast__Kind__map: { v__ast__Map info = *(v__ast__Map*)__as_cast((sym->info)._v__ast__Map,(sym->info)._typ, 514); if (!v__checker__Checker_ensure_type_exists(c, info.key_type, pos)) { bool _t12 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t12; } if (!v__checker__Checker_ensure_type_exists(c, info.value_type, pos)) { bool _t13 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t13; } break; } case v__ast__Kind__sum_type: { v__ast__SumType info = *(v__ast__SumType*)__as_cast((sym->info)._v__ast__SumType,(sym->info)._typ, 544); for (int _t14 = 0; _t14 < info.concrete_types.len; ++_t14) { v__ast__Type concrete_typ = ((v__ast__Type*)info.concrete_types.data)[_t14]; if (!v__checker__Checker_ensure_type_exists(c, concrete_typ, pos)) { bool _t15 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t15; } } break; } case v__ast__Kind__chan: { if ((sym->info)._typ == 550 /* v.ast.Chan */) { if (!v__checker__Checker_ensure_type_exists(c, ((*sym->info._v__ast__Chan)).elem_type, ((v__token__Pos){.len = (pos).len,.line_nr = (pos).line_nr,.pos = (pos).pos,.col = (int)(pos.col + 5),.last_line = (pos).last_line,}))) { bool _t16 = false; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t16; } } break; } case v__ast__Kind__void: case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__i32: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__isize: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__usize: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__bool: case v__ast__Kind__none: case v__ast__Kind__string: case v__ast__Kind__any: case v__ast__Kind__struct: case v__ast__Kind__generic_inst: case v__ast__Kind__multi_return: case v__ast__Kind__alias: case v__ast__Kind__enum: case v__ast__Kind__interface: case v__ast__Kind__aggregate: case v__ast__Kind__thread: default: { { break; } } } bool _t17 = true; // Defer begin if (v__checker__Checker_ensure_type_exists_defer_0) { c->type_level--; } // Defer end return _t17; } VV_LOC bool v__checker__Checker_fail_if_unreadable(v__checker__Checker* c, v__ast__Expr expr, v__ast__Type typ, string what) { v__token__Pos pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (expr._typ == 358 /* v.ast.Ident */) { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f)) { if (!(Array_string_contains(c->rlocked_names, (*expr._v__ast__Ident).name)) && !(Array_string_contains(c->locked_names, (*expr._v__ast__Ident).name))) { string action = (_SLIT_EQ(what.str, what.len, "argument") ? (_S("passed")) : (_S("used"))); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = (*expr._v__ast__Ident).name}}, {_S("` is `shared` and must be `rlock`ed or `lock`ed to be "), 0xfe10, {.d_s = action}}, {_S(" as non-mut "), 0xfe10, {.d_s = what}}, {_SLIT0, 0, { .d_c = 0 }}})), (*expr._v__ast__Ident).pos); return true; } } return false; } else if (expr._typ == 379 /* v.ast.SelectorExpr */) { pos = (*expr._v__ast__SelectorExpr).pos; if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f)) { string expr_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*expr._v__ast__SelectorExpr).expr)}}, {_S("."), 0xfe10, {.d_s = (*expr._v__ast__SelectorExpr).field_name}}, {_SLIT0, 0, { .d_c = 0 }}})); if (!(Array_string_contains(c->rlocked_names, expr_name)) && !(Array_string_contains(c->locked_names, expr_name))) { string action = (_SLIT_EQ(what.str, what.len, "argument") ? (_S("passed")) : (_S("used"))); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = expr_name}}, {_S("` is `shared` and must be `rlock`ed or `lock`ed to be "), 0xfe10, {.d_s = action}}, {_S(" as non-mut "), 0xfe10, {.d_s = what}}, {_SLIT0, 0, { .d_c = 0 }}})), (*expr._v__ast__SelectorExpr).pos); return true; } return false; } else { if (v__checker__Checker_fail_if_unreadable(c, (*expr._v__ast__SelectorExpr).expr, (*expr._v__ast__SelectorExpr).expr_type, what)) { return true; } } } else if (expr._typ == 344 /* v.ast.CallExpr */) { pos = (*expr._v__ast__CallExpr).pos; if ((*expr._v__ast__CallExpr).is_method) { if (v__checker__Checker_fail_if_unreadable(c, (*expr._v__ast__CallExpr).left, (*expr._v__ast__CallExpr).left_type, what)) { return true; } } return false; } else if (expr._typ == 367 /* v.ast.LockExpr */) { return false; } else if (expr._typ == 361 /* v.ast.IndexExpr */) { pos = v__token__Pos_extend(v__ast__Expr_pos((*expr._v__ast__IndexExpr).left), (*expr._v__ast__IndexExpr).pos); if (v__checker__Checker_fail_if_unreadable(c, (*expr._v__ast__IndexExpr).left, (*expr._v__ast__IndexExpr).left_type, what)) { return true; } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f) && ((*expr._v__ast__IndexExpr).left)._typ == 379 /* v.ast.SelectorExpr */) { return false; } } else if (expr._typ == 362 /* v.ast.InfixExpr */) { pos = v__token__Pos_extend(v__ast__Expr_pos((*expr._v__ast__InfixExpr).left), (*expr._v__ast__InfixExpr).pos); if (v__checker__Checker_fail_if_unreadable(c, (*expr._v__ast__InfixExpr).left, (*expr._v__ast__InfixExpr).left_type, what)) { return true; } if (v__checker__Checker_fail_if_unreadable(c, (*expr._v__ast__InfixExpr).right, (*expr._v__ast__InfixExpr).right_type, what)) { return true; } } else { pos = v__ast__Expr_pos(expr); } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("you have to create a handle and `rlock` it to use a `shared` element as non-mut "), 0xfe10, {.d_s = what}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); return true; } return false; } VV_LOC void v__checker__Checker_fail_if_stack_struct_action_outside_unsafe(v__checker__Checker* c, v__ast__Ident* ident, string failed_action) { if ((ident->obj)._typ == 422 /* v.ast.Var */) { v__ast__Var* obj = &(*ident->obj._v__ast__Var); if (c->fn_scope != ((void*)0)) { _option_v__ast__Var_ptr _t1 = v__ast__Scope_find_var(c->fn_scope, (*ident->obj._v__ast__Var).name); if (_t1.state != 0) { IError err = _t1.err; *(v__ast__Var**) _t1.data = obj; } obj = (*(v__ast__Var**)_t1.data); } if (obj->is_stack_obj && !c->inside_unsafe) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, v__ast__Type_set_nr_muls(obj->typ, 0)); bool is_heap = v__ast__TypeSymbol_is_heap(sym); if ((!is_heap || !v__ast__Type_is_ptr(obj->typ)) && !c->pref->translated && !c->file->is_translated) { bool _t2 = (c->table->cur_fn != ((void*)0)); Array_v__ast__Param _t3 = {0}; if (_t2) { Array_v__ast__Param _t3_orig = c->table->cur_fn->params; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__Param)); for (int _t4 = 0; _t4 < _t3_len; ++_t4) { v__ast__Param it = ((v__ast__Param*) _t3_orig.data)[_t4]; if (string__eq(it.name, ident->name) && it.is_mut) { array_push((array*)&_t3, &it); } } } bool is_mut_param = _t2 &&_t3.len > 0; if (is_mut_param) { return; } string suggestion = (!is_heap && sym->kind == v__ast__Kind__struct ? (str_intp(2, _MOV((StrIntpData[]){{_S("declaring `"), 0xfe10, {.d_s = sym->name}}, {_S("` as `@[heap]`"), 0, { .d_c = 0 }}}))) : !is_heap ? (str_intp(2, _MOV((StrIntpData[]){{_S("wrapping the `"), 0xfe10, {.d_s = sym->name}}, {_S("` object in a `struct` declared as `@[heap]`"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("declaring `"), 0xfe10, {.d_s = ident->name}}, {_S("` mutable"), 0, { .d_c = 0 }}})))); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = ident->name}}, {_S("` cannot be "), 0xfe10, {.d_s = failed_action}}, {_S(" outside `unsafe` blocks as it might refer to an object stored on stack. Consider "), 0xfe10, {.d_s = suggestion}}, {_S("."), 0, { .d_c = 0 }}})), ident->pos); } } } } VV_LOC void v__checker__Checker_goto_label(v__checker__Checker* c, v__ast__GotoLabel node) { if (!_IN_MAP(ADDR(string, node.name), ADDR(map, c->goto_labels))) { (*(v__ast__GotoLabel*)map_get_and_set((map*)&c->goto_labels, &(string[]){node.name}, &(v__ast__GotoLabel[]){ (v__ast__GotoLabel){.name = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_used = 0,} })) = node; (*(v__ast__GotoLabel*)map_get_and_set((map*)&c->goto_labels, &(string[]){node.name}, &(v__ast__GotoLabel[]){ (v__ast__GotoLabel){.name = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_used = 0,} })).is_used = false; } } VV_LOC void v__checker__Checker_goto_stmt(v__checker__Checker* c, v__ast__GotoStmt node) { if (c->inside_defer) { v__checker__Checker_error(c, _S("goto is not allowed in defer statements"), node.pos); } if (!c->inside_unsafe) { if (!c->pref->translated && !c->file->is_translated) { v__checker__Checker_warn(c, _S("`goto` requires `unsafe` (consider using labelled break/continue)"), node.pos); } } if (c->table->cur_fn != ((void*)0) && !(Array_string_contains(c->table->cur_fn->label_names, node.name))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown label `"), 0xfe10, {.d_s = node.name}}, {_S("`"), 0, { .d_c = 0 }}})), node.pos); } (*(v__ast__GotoLabel*)map_get_and_set((map*)&c->goto_labels, &(string[]){node.name}, &(v__ast__GotoLabel[]){ (v__ast__GotoLabel){.name = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_used = 0,} })).is_used = true; } VV_LOC void v__checker__Checker_check_unused_labels(v__checker__Checker* c) { Map_string_v__ast__GotoLabel _t1 = c->goto_labels; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string name = *(string*)DenseArray_key(&_t1.key_values, _t2); name = string_clone(name); v__ast__GotoLabel label = (*(v__ast__GotoLabel*)DenseArray_value(&_t1.key_values, _t2)); if (!label.is_used) { v__checker__Checker_warn(c, str_intp(2, _MOV((StrIntpData[]){{_S("label `"), 0xfe10, {.d_s = name}}, {_S("` defined and not used"), 0, { .d_c = 0 }}})), label.pos); (*(v__ast__GotoLabel*)map_get_and_set((map*)&c->goto_labels, &(string[]){name}, &(v__ast__GotoLabel[]){ (v__ast__GotoLabel){.name = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_used = 0,} })).is_used = true; } } } VV_LOC bool v__checker__Checker_check_import_sym_conflict(v__checker__Checker* c, string ident) { for (int _t1 = 0; _t1 < c->file->imports.len; ++_t1) { v__ast__Import import_sym = ((v__ast__Import*)c->file->imports.data)[_t1]; if (!string_is_blank(import_sym.alias)) { if (import_sym.alias.len == ident.len && string__eq(import_sym.alias, ident)) { return true; } } else if (import_sym.mod.len == ident.len && string__eq(import_sym.mod, ident)) { return true; } } return false; } void v__checker__Checker_update_unresolved_fixed_sizes(v__checker__Checker* c) { for (int _t1 = 0; _t1 < c->unresolved_fixed_sizes.len; ++_t1) { v__ast__Stmt** stmt = ((v__ast__Stmt**)c->unresolved_fixed_sizes.data) + _t1; if ((*stmt)->_typ == 237 /* v.ast.FnDecl */) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, (*(*stmt)->_v__ast__FnDecl).return_type); if ((ret_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && v__checker__Checker_array_fixed_has_unresolved_size(c, (v__ast__ArrayFixed*)__as_cast((ret_sym->info)._v__ast__ArrayFixed,(ret_sym->info)._typ, 549))) { v__ast__Expr size_expr = (*ret_sym->info._v__ast__ArrayFixed).size_expr; (*(*stmt)->_v__ast__FnDecl).return_type = v__checker__Checker_eval_array_fixed_sizes(c, &size_expr, 0, (*ret_sym->info._v__ast__ArrayFixed).elem_type); } } else if ((*stmt)->_typ == 334 /* v.ast.TypeDecl */) { v__ast__TypeDecl alias_decl = (*(*stmt)->_v__ast__TypeDecl); if ((alias_decl)._typ == 331 /* v.ast.AliasTypeDecl */) { v__ast__TypeSymbol* alias_sym = v__ast__Table_sym(c->table, (*alias_decl._v__ast__AliasTypeDecl).parent_type); if ((alias_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && v__checker__Checker_array_fixed_has_unresolved_size(c, (v__ast__ArrayFixed*)__as_cast((alias_sym->info)._v__ast__ArrayFixed,(alias_sym->info)._typ, 549))) { v__ast__Expr size_expr = (*alias_sym->info._v__ast__ArrayFixed).size_expr; (*alias_decl._v__ast__AliasTypeDecl).parent_type = v__checker__Checker_eval_array_fixed_sizes(c, &size_expr, 0, (*alias_sym->info._v__ast__ArrayFixed).elem_type); v__ast__TypeSymbol* typ_sym = (*(v__ast__TypeSymbol**)array_get(c->table->type_symbols, v__ast__Type_idx((*alias_decl._v__ast__AliasTypeDecl).typ))); typ_sym->parent_idx = v__ast__Type_idx((*alias_decl._v__ast__AliasTypeDecl).parent_type); if ((typ_sym->info)._typ == 539 /* v.ast.Alias */) { (*typ_sym->info._v__ast__Alias).parent_type = (*alias_decl._v__ast__AliasTypeDecl).parent_type; } } } } } } VV_LOC string v__checker__Checker_dir_path(v__checker__Checker* c) { return os__real_path(os__dir(c->file->path)); } VV_LOC v__ast__Type v__checker__Checker_comptime_call(v__checker__Checker* c, v__ast__ComptimeCall* node) { if ((node->left)._typ != 354 /* v.ast.EmptyExpr */) { node->left_type = v__checker__Checker_expr(c, &node->left); } if (node->kind == v__ast__ComptimeCallKind__compile_error) { v__checker__Checker_error(c, v__checker__Checker_comptime_call_msg(c, *node), node->pos); return _const_v__ast__void_type; } else if (node->kind == v__ast__ComptimeCallKind__compile_warn) { v__checker__Checker_warn(c, v__checker__Checker_comptime_call_msg(c, *node), node->pos); return _const_v__ast__void_type; } if (node->kind == v__ast__ComptimeCallKind__env) { _result_string _t3 = v__util__resolve_env_value(str_intp(2, _MOV((StrIntpData[]){{_S("$env('"), 0xfe10, {.d_s = node->args_var}}, {_S("')"), 0, { .d_c = 0 }}})), false); if (_t3.is_error) { IError err = _t3.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->env_pos); return _const_v__ast__string_type; } string env_value = (*(string*)_t3.data); node->env_value = env_value; return _const_v__ast__string_type; } if (node->kind == v__ast__ComptimeCallKind__d) { _result_void _t6 = v__ast__ComptimeCall_resolve_compile_value(node, c->pref->compile_values); if (_t6.is_error) { IError err = _t6.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), node->pos); return _const_v__ast__void_type; } ; return node->result_type; } if (node->kind == v__ast__ComptimeCallKind__embed_file) { if (node->args.len == 1) { v__ast__CallArg embed_arg = (*(v__ast__CallArg*)array_get(node->args, 0)); string raw_path = _S(""); if ((embed_arg.expr)._typ == 341 /* v.ast.AtExpr */) { v__ast__AtExpr expr = (*embed_arg.expr._v__ast__AtExpr); v__checker__Checker_at_expr(c, (voidptr)&expr); raw_path = expr.val; } if ((embed_arg.expr)._typ == 384 /* v.ast.StringLiteral */) { raw_path = (*embed_arg.expr._v__ast__StringLiteral).val; } else if ((embed_arg.expr)._typ == 358 /* v.ast.Ident */) { _option_v__ast__Var_ptr _t9; if (_t9 = v__ast__Scope_find_var(c->fn_scope, (*embed_arg.expr._v__ast__Ident).name), _t9.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t9.data; if ((var->expr)._typ == 384 /* v.ast.StringLiteral */) { raw_path = (*var->expr._v__ast__StringLiteral).val; } } } string escaped_path = string_replace(raw_path, _S("/"), _const_os__path_separator); if ((escaped_path).len == 0) { v__checker__Checker_error(c, _S("supply a valid relative or absolute file path to the file to embed, that is known at compile time"), node->pos); return _const_v__ast__string_type; } string abs_path = os__real_path(escaped_path); if (!os__exists(abs_path)) { escaped_path = os__real_path(os__join_path_single(os__dir(c->file->path), escaped_path)); if (!os__exists(escaped_path)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("\""), 0xfe10, {.d_s = escaped_path}}, {_S("\" does not exist so it cannot be embedded"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__string_type; } if (!os__is_file(escaped_path)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("\""), 0xfe10, {.d_s = escaped_path}}, {_S("\" is not a file so it cannot be embedded"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__string_type; } } else { escaped_path = abs_path; } node->embed_file.rpath = raw_path; node->embed_file.apath = escaped_path; } if (!(Array_string_contains(_const_v__ast__valid_comptime_compression_types, node->embed_file.compression_type))) { Array_string _t13 = {0}; Array_string _t13_orig = _const_v__ast__valid_comptime_compression_types; int _t13_len = _t13_orig.len; _t13 = __new_array(0, _t13_len, sizeof(string)); for (int _t15 = 0; _t15 < _t13_len; ++_t15) { string it = ((string*) _t13_orig.data)[_t15]; string _t14 = str_intp(2, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = it}}, {_SLIT0, 0, { .d_c = 0 }}})); array_push((array*)&_t13, &_t14); } string supported = Array_string_join(_t13, _S(", ")); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("not supported compression type: ."), 0xfe10, {.d_s = node->embed_file.compression_type}}, {_S(". supported: "), 0xfe10, {.d_s = supported}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } return v__ast__Table_find_type(c->table, _S("v.embed_file.EmbedFileData")); } if (node->is_vweb) { v__ast__FnDecl* save_cur_fn = c->table->cur_fn; v__pref__Preferences *pref_ = HEAP(v__pref__Preferences, (*c->pref)); v__pref__Preferences* pref2 = ((v__pref__Preferences*)memdup(&(v__pref__Preferences){.os = ((*(pref_))).os,.backend = ((*(pref_))).backend,.backend_set_by_flag = ((*(pref_))).backend_set_by_flag,.build_mode = ((*(pref_))).build_mode,.arch = ((*(pref_))).arch,.output_mode = ((*(pref_))).output_mode,.is_verbose = ((*(pref_))).is_verbose,.is_glibc = ((*(pref_))).is_glibc,.is_musl = ((*(pref_))).is_musl,.is_test = ((*(pref_))).is_test,.is_script = ((*(pref_))).is_script,.is_vsh = ((*(pref_))).is_vsh,.raw_vsh_tmp_prefix = ((*(pref_))).raw_vsh_tmp_prefix,.is_livemain = ((*(pref_))).is_livemain,.is_liveshared = ((*(pref_))).is_liveshared,.is_shared = ((*(pref_))).is_shared,.is_o = ((*(pref_))).is_o,.is_prof = ((*(pref_))).is_prof,.is_prod = ((*(pref_))).is_prod,.no_prod_options = ((*(pref_))).no_prod_options,.is_repl = ((*(pref_))).is_repl,.is_eval_argument = ((*(pref_))).is_eval_argument,.is_run = ((*(pref_))).is_run,.is_crun = ((*(pref_))).is_crun,.is_debug = ((*(pref_))).is_debug,.is_vlines = ((*(pref_))).is_vlines,.is_stats = ((*(pref_))).is_stats,.show_asserts = ((*(pref_))).show_asserts,.show_timings = ((*(pref_))).show_timings,.is_fmt = ((*(pref_))).is_fmt,.is_vet = ((*(pref_))).is_vet,.is_vweb = true,.is_ios_simulator = ((*(pref_))).is_ios_simulator,.is_apk = ((*(pref_))).is_apk,.is_help = ((*(pref_))).is_help,.is_quiet = ((*(pref_))).is_quiet,.is_cstrict = ((*(pref_))).is_cstrict,.is_callstack = ((*(pref_))).is_callstack,.is_trace = ((*(pref_))).is_trace,.is_coverage = ((*(pref_))).is_coverage,.is_check_return = ((*(pref_))).is_check_return,.eval_argument = ((*(pref_))).eval_argument,.test_runner = ((*(pref_))).test_runner,.profile_file = ((*(pref_))).profile_file,.coverage_dir = ((*(pref_))).coverage_dir,.profile_no_inline = ((*(pref_))).profile_no_inline,.profile_fns = ((*(pref_))).profile_fns,.translated = ((*(pref_))).translated,.translated_go = ((*(pref_))).translated_go,.obfuscate_removed = ((*(pref_))).obfuscate_removed,.hide_auto_str = ((*(pref_))).hide_auto_str,.sanitize = ((*(pref_))).sanitize,.sourcemap = ((*(pref_))).sourcemap,.sourcemap_inline = ((*(pref_))).sourcemap_inline,.sourcemap_src_included = ((*(pref_))).sourcemap_src_included,.show_cc = ((*(pref_))).show_cc,.show_c_output = ((*(pref_))).show_c_output,.show_callgraph = ((*(pref_))).show_callgraph,.show_depgraph = ((*(pref_))).show_depgraph,.show_unused_params = ((*(pref_))).show_unused_params,.dump_c_flags = ((*(pref_))).dump_c_flags,.dump_modules = ((*(pref_))).dump_modules,.dump_files = ((*(pref_))).dump_files,.dump_defines = ((*(pref_))).dump_defines,.use_cache = ((*(pref_))).use_cache,.retry_compilation = ((*(pref_))).retry_compilation,.use_os_system_to_run = ((*(pref_))).use_os_system_to_run,.macosx_version_min = ((*(pref_))).macosx_version_min,.cflags = ((*(pref_))).cflags,.ldflags = ((*(pref_))).ldflags,.m64 = ((*(pref_))).m64,.ccompiler = ((*(pref_))).ccompiler,.ccompiler_type = ((*(pref_))).ccompiler_type,.cppcompiler = ((*(pref_))).cppcompiler,.third_party_option = ((*(pref_))).third_party_option,.building_v = ((*(pref_))).building_v,.no_bounds_checking = ((*(pref_))).no_bounds_checking,.force_bounds_checking = ((*(pref_))).force_bounds_checking,.autofree = ((*(pref_))).autofree,.print_autofree_vars = ((*(pref_))).print_autofree_vars,.print_autofree_vars_in_fn = ((*(pref_))).print_autofree_vars_in_fn,.trace_calls = ((*(pref_))).trace_calls,.trace_fns = ((*(pref_))).trace_fns,.compress = ((*(pref_))).compress,.no_builtin = ((*(pref_))).no_builtin,.enable_globals = ((*(pref_))).enable_globals,.is_bare = ((*(pref_))).is_bare,.bare_builtin_dir = ((*(pref_))).bare_builtin_dir,.no_preludes = ((*(pref_))).no_preludes,.custom_prelude = ((*(pref_))).custom_prelude,.cmain = ((*(pref_))).cmain,.lookup_path = ((*(pref_))).lookup_path,.output_cross_c = ((*(pref_))).output_cross_c,.output_es5 = ((*(pref_))).output_es5,.prealloc = ((*(pref_))).prealloc,.vroot = ((*(pref_))).vroot,.vlib = ((*(pref_))).vlib,.vmodules_paths = ((*(pref_))).vmodules_paths,.out_name_c = ((*(pref_))).out_name_c,.out_name = ((*(pref_))).out_name,.path = ((*(pref_))).path,.line_info = ((*(pref_))).line_info,.linfo = ((*(pref_))).linfo,.run_only = ((*(pref_))).run_only,.exclude = ((*(pref_))).exclude,.compile_defines = ((*(pref_))).compile_defines,.compile_defines_all = ((*(pref_))).compile_defines_all,.compile_values = ((*(pref_))).compile_values,.run_args = ((*(pref_))).run_args,.printfn_list = ((*(pref_))).printfn_list,.print_v_files = ((*(pref_))).print_v_files,.print_watched_files = ((*(pref_))).print_watched_files,.skip_running = ((*(pref_))).skip_running,.skip_warnings = ((*(pref_))).skip_warnings,.skip_notes = ((*(pref_))).skip_notes,.warn_impure_v = ((*(pref_))).warn_impure_v,.warns_are_errors = ((*(pref_))).warns_are_errors,.notes_are_errors = ((*(pref_))).notes_are_errors,.fatal_errors = ((*(pref_))).fatal_errors,.reuse_tmpc = ((*(pref_))).reuse_tmpc,.no_rsp = ((*(pref_))).no_rsp,.no_std = ((*(pref_))).no_std,.no_parallel = ((*(pref_))).no_parallel,.parallel_cc = ((*(pref_))).parallel_cc,.only_check_syntax = ((*(pref_))).only_check_syntax,.check_only = ((*(pref_))).check_only,.experimental = ((*(pref_))).experimental,.skip_unused = ((*(pref_))).skip_unused,.use_color = ((*(pref_))).use_color,.cleanup_files = ((*(pref_))).cleanup_files,.build_options = ((*(pref_))).build_options,.cache_manager = ((*(pref_))).cache_manager,.gc_mode = ((*(pref_))).gc_mode,.assert_failure_mode = ((*(pref_))).assert_failure_mode,.message_limit = ((*(pref_))).message_limit,.nofloat = ((*(pref_))).nofloat,.use_coroutines = ((*(pref_))).use_coroutines,.fast_math = ((*(pref_))).fast_math,.checker_match_exhaustive_cutoff_limit = ((*(pref_))).checker_match_exhaustive_cutoff_limit,.thread_stack_size = ((*(pref_))).thread_stack_size,.wasm_stack_top = ((*(pref_))).wasm_stack_top,.wasm_validate = ((*(pref_))).wasm_validate,.warn_about_allocs = ((*(pref_))).warn_about_allocs,.div_by_zero_is_zero = ((*(pref_))).div_by_zero_is_zero,.relaxed_gcc14 = ((*(pref_))).relaxed_gcc14,.subsystem = ((*(pref_))).subsystem,.is_vls = ((*(pref_))).is_vls,}, sizeof(v__pref__Preferences))); v__checker__Checker* c2 = v__checker__new_checker(c->table, pref2); c2->comptime_call_pos = node->pos.pos; v__checker__Checker_check(c2, (voidptr)&node->veb_tmpl); _PUSH_MANY(&c->warnings, (c2->warnings), _t17, Array_v__errors__Warning); _PUSH_MANY(&c->errors, (c2->errors), _t18, Array_v__errors__Error); _PUSH_MANY(&c->notices, (c2->notices), _t19, Array_v__errors__Notice); c->nr_warnings += c2->nr_warnings; c->nr_errors += c2->nr_errors; c->nr_notices += c2->nr_notices; c->table->cur_fn = save_cur_fn; } if (node->kind == v__ast__ComptimeCallKind__html) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, c->table->cur_fn->return_type); if (!(fast_string_eq(ret_sym->cname, _S("veb__Result")) || fast_string_eq(ret_sym->cname, _S("vweb__Result")) || fast_string_eq(ret_sym->cname, _S("x__vweb__Result")))) { string ct_call = (node->is_veb ? (_S("veb")) : (_S("vweb"))); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("`$"), 0xfe10, {.d_s = ct_call}}, {_S(".html()` must be called inside a web method, e.g. `fn (mut app App) foo(mut ctx Context) "), 0xfe10, {.d_s = ct_call}}, {_S(".Result { return $"), 0xfe10, {.d_s = ct_call}}, {_S(".html(\'index.html\') }`"), 0, { .d_c = 0 }}})), node->pos); } v__ast__Type rtyp = (node->is_veb ? (v__ast__Table_find_type(c->table, _S("veb.Result"))) : (v__ast__Table_find_type(c->table, _S("vweb.Result")))); node->result_type = rtyp; return rtyp; } if (fast_string_eq(node->method_name, _S("method"))) { bool _t21 = (c->inside_anon_fn); Array_string _t22 = {0}; if (_t21) { Array_v__ast__Param _t22_orig = c->cur_anon_fn->inherited_vars; int _t22_len = _t22_orig.len; _t22 = __new_array(0, _t22_len, sizeof(string)); for (int _t24 = 0; _t24 < _t22_len; ++_t24) { v__ast__Param it = ((v__ast__Param*) _t22_orig.data)[_t24]; string _t23 = it.name; array_push((array*)&_t22, &_t23); } } if ( _t21 && !(Array_string_contains(_t22, _S("method")))) { v__checker__Checker_error(c, _S("undefined ident `method` in the anonymous function"), node->pos); } for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + i; (*(v__ast__CallArg*)array_get(node->args, i)).typ = v__checker__Checker_expr(c, &arg->expr); } v__checker__Checker_markused_comptimecall(c, node); v__checker__Checker_stmts_ending_with_expression(c, &node->or_block.stmts, c->expected_or_type); return v__type_resolver__TypeResolver_get_type(&c->type_resolver, v__ast__ComptimeCall_to_sumtype_v__ast__Expr(node)); } if (node->kind == v__ast__ComptimeCallKind__res) { if (!c->inside_defer) { v__checker__Checker_error(c, _S("`res` can only be used in defer blocks"), node->pos); return _const_v__ast__void_type; } if (c->fn_return_type == _const_v__ast__void_type) { v__checker__Checker_error(c, _S("`res` can only be used in functions that returns something"), node->pos); return _const_v__ast__void_type; } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, c->fn_return_type); if (v__ast__Type_has_flag(c->fn_return_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("`res` cannot be used in functions that returns a Result"), node->pos); return _const_v__ast__void_type; } if ((sym->info)._typ == 552 /* v.ast.MultiReturn */) { if ((node->args_var).len == 0) { v__checker__Checker_error(c, _S("`res` requires an index of the returned value"), node->pos); return _const_v__ast__void_type; } int idx = string_int(node->args_var); if (idx < 0 || idx >= (*sym->info._v__ast__MultiReturn).types.len) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("index "), 0xfe07, {.d_i32 = idx}}, {_S(" out of range of "), 0xfe07, {.d_i32 = (*sym->info._v__ast__MultiReturn).types.len}}, {_S(" return types"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__void_type; } return (*(v__ast__Type*)array_get((*sym->info._v__ast__MultiReturn).types, idx)); } return c->fn_return_type; } if (node->is_vweb) { return _const_v__ast__string_type; } _option_v__ast__Var_ptr _t34 = v__ast__Scope_find_var(node->scope, node->method_name); if (_t34.state != 0) { IError err = _t34.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown identifier `"), 0xfe10, {.d_s = node->method_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->method_pos); return _const_v__ast__void_type; } v__ast__Var* v = (*(v__ast__Var**)_t34.data); if (v->typ != _const_v__ast__string_type) { string s = v__checker__Checker_expected_msg(c, v->typ, _const_v__ast__string_type); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid string method call: "), 0xfe10, {.d_s = s}}, {_SLIT0, 0, { .d_c = 0 }}})), node->method_pos); return _const_v__ast__void_type; } string method_name = _S(""); if ((v->expr)._typ == 384 /* v.ast.StringLiteral */) { method_name = (*v->expr._v__ast__StringLiteral).val; } else { v__checker__Checker_error(c, _S("todo: not a string literal"), node->method_pos); } v__ast__Type left_type = v__checker__Checker_unwrap_generic(c, node->left_type); v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, left_type); _option_v__ast__Fn _t37 = v__ast__TypeSymbol_find_method(left_sym, method_name); if (_t37.state != 0) { IError err = _t37.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("could not find method `"), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->method_pos); return _const_v__ast__void_type; } v__ast__Fn f = (*(v__ast__Fn*)_t37.data); v__checker__Checker_markused_comptime_call(c, true, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(left_type))}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); node->result_type = f.return_type; return f.return_type; } VV_LOC string v__checker__Checker_comptime_call_msg(v__checker__Checker* c, v__ast__ComptimeCall _v_toheap_node) { v__ast__ComptimeCall* node = HEAP(v__ast__ComptimeCall, _v_toheap_node); string _t2; /* if prepend */ _option_v__ast__ComptTimeConstValue _t3; if ((*(node)).args_var.len > 0) { _t2 = (*(node)).args_var; } else if (_t3 = v__checker__Checker_eval_comptime_const_expr(c, (*(v__ast__CallArg*)array_get((*(node)).args, 0)).expr, -1), _t3.state == 0) { v__ast__ComptTimeConstValue value = *(v__ast__ComptTimeConstValue*)_t3.data; _option_string _t4 = v__ast__ComptTimeConstValue_string(value); if (_t4.state != 0) { IError err = _t4.err; *(string*) _t4.data = _S(""); } _t2 = (*(string*)_t4.data); } else { IError err = _t3.err; _t2 = _S(""); } return _t2; } VV_LOC v__ast__Type v__checker__Checker_comptime_selector(v__checker__Checker* c, v__ast__ComptimeSelector* node) { node->left_type = v__checker__Checker_expr(c, &node->left); v__ast__Type expr_type = v__checker__Checker_unwrap_generic(c, v__checker__Checker_expr(c, &node->field_expr)); v__ast__TypeSymbol* expr_sym = v__ast__Table_sym(c->table, expr_type); if (expr_type != _const_v__ast__string_type) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expected `string` instead of `"), 0xfe10, {.d_s = expr_sym->name}}, {_S("` (e.g. `field.name`)"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->field_expr)); } if ((node->field_expr)._typ == 379 /* v.ast.SelectorExpr */) { v__token__Pos left_pos = v__ast__Expr_pos((*node->field_expr._v__ast__SelectorExpr).expr); if (c->type_resolver.type_map.len == 0) { v__checker__Checker_error(c, _S("compile time field access can only be used when iterating over `T.fields`"), left_pos); } node->is_name = fast_string_eq((*node->field_expr._v__ast__SelectorExpr).field_name, _S("name")); if (((*node->field_expr._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */) { node->typ_key = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*(*node->field_expr._v__ast__SelectorExpr).expr._v__ast__Ident).name}}, {_S(".typ"), 0, { .d_c = 0 }}})); } expr_type = v__type_resolver__TypeResolver_get_comptime_selector_type(&c->type_resolver, *node, _const_v__ast__void_type); if (expr_type != _const_v__ast__void_type) { if (node->or_block.kind == v__ast__OrKind__propagate_option) { return v__ast__Type_clear_flag(expr_type, v__ast__TypeFlag__option); } return expr_type; } string expr_name = v__ast__Expr_str(&(*node->field_expr._v__ast__SelectorExpr).expr); if (_IN_MAP(ADDR(string, expr_name), ADDR(map, c->type_resolver.type_map))) { return v__type_resolver__TypeResolver_get_ct_type_or_default(&c->type_resolver, expr_name, _const_v__ast__void_type); } v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown `$for` variable `"), 0xfe10, {.d_s = expr_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_pos); } else { v__checker__Checker_error(c, _S("expected selector expression e.g. `$(field.name)`"), v__ast__Expr_pos(node->field_expr)); } return _const_v__ast__void_type; } VV_LOC void v__checker__Checker_comptime_for(v__checker__Checker* c, v__ast__ComptimeFor* node) { v__ast__Type _t1; /* if prepend */ if (node->typ != _const_v__ast__void_type) { _t1 = v__checker__Checker_unwrap_generic(c, node->typ); } else { node->typ = v__checker__Checker_expr(c, &node->expr); _t1 = v__checker__Checker_unwrap_generic(c, node->typ); } v__ast__Type typ = _t1; v__ast__TypeSymbol* sym = v__ast__Table_final_sym(c->table, typ); if (sym->kind == v__ast__Kind__placeholder || v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("$for expects a type name or variable name to be used here, but "), 0xfe10, {.d_s = sym->name}}, {_S(" is not a type or variable name"), 0, { .d_c = 0 }}})), node->typ_pos); return; } else if (sym->kind == v__ast__Kind__void) { v__checker__Checker_error(c, _S("only known compile-time variables can be used"), node->typ_pos); return; } if (node->kind == v__ast__ComptimeForKind__fields) { if (sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__interface) { Array_v__ast__StructField fields = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); if (sym->info._typ == 518 /* v.ast.Struct */) { fields = array_clone_to_depth(&(*sym->info._v__ast__Struct).fields, 0); } else if (sym->info._typ == 542 /* v.ast.Interface */) { fields = array_clone_to_depth(&(*sym->info._v__ast__Interface).fields, 0); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("iterating over .fields is supported only for structs and interfaces, and "), 0xfe10, {.d_s = sym->name}}, {_S(" is neither"), 0, { .d_c = 0 }}})), node->typ_pos); return; } bool _t2 = (fields.len > 1); bool _t3 = true; if (_t2) { Array_v__ast__StructField _t3_orig = fields; int _t3_len = _t3_orig.len; for (int _t4 = 0; _t4 < _t3_len; ++_t4) { v__ast__StructField it = ((v__ast__StructField*) _t3_orig.data)[_t4]; if (!(v__checker__Checker_check_basic(c, it.typ, (*(v__ast__StructField*)array_get(fields, 0)).typ))) { _t3 = false; break; } } } bool has_different_types = _t2 && !_t3; for (int _t5 = 0; _t5 < fields.len; ++_t5) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t5]; bool prev_inside_x_matches_type = c->inside_x_matches_type; v__checker__Checker_push_new_comptime_info(c); c->comptime->inside_comptime_for = true; if (c->field_data_type == 0) { c->field_data_type = v__ast__Table_find_type(c->table, _S("FieldData")); } c->comptime->comptime_for_field_value = field; c->comptime->comptime_for_field_var = node->val_var; v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, node->val_var, c->field_data_type); v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->val_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), node->typ); c->comptime->comptime_for_field_type = field.typ; c->comptime->has_different_types = has_different_types; v__checker__Checker_stmts(c, &node->stmts); v__ast__Type unwrapped_expr_type = v__checker__Checker_unwrap_generic(c, field.typ); v__ast__TypeSymbol* tsym = v__ast__Table_sym(c->table, unwrapped_expr_type); v__checker__Checker_markused_comptimefor(c, node, unwrapped_expr_type); if (tsym->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((tsym->info)._v__ast__ArrayFixed,(tsym->info)._typ, 549); if (!info.is_fn_ret) { v__ast__Table_find_or_register_array_fixed(c->table, info.elem_type, info.size, info.size_expr, true); } } v__checker__Checker_pop_comptime_info(c); c->inside_x_matches_type = prev_inside_x_matches_type; } } else if (node->typ != _const_v__ast__void_type && v__ast__Table_generic_type_names(c->table, node->typ).len == 0 && sym->kind != v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("iterating over .fields is supported only for structs and interfaces, and "), 0xfe10, {.d_s = sym->name}}, {_S(" is neither"), 0, { .d_c = 0 }}})), node->typ_pos); return; } } else if (node->kind == v__ast__ComptimeForKind__values) { if (sym->kind == v__ast__Kind__enum) { v__checker__Checker_push_new_comptime_info(c); c->comptime->inside_comptime_for = true; if (c->enum_data_type == 0) { c->enum_data_type = v__ast__Table_find_type(c->table, _S("EnumData")); } c->comptime->comptime_for_enum_var = node->val_var; v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, node->val_var, c->enum_data_type); v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->val_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), node->typ); v__checker__Checker_stmts(c, &node->stmts); v__checker__Checker_pop_comptime_info(c); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("iterating over .values is supported only for enums, and "), 0xfe10, {.d_s = sym->name}}, {_S(" is not an enum"), 0, { .d_c = 0 }}})), node->typ_pos); return; } } else if (node->kind == v__ast__ComptimeForKind__methods) { Array_v__ast__Fn methods = v__ast__TypeSymbol_get_methods(sym); for (int _t6 = 0; _t6 < methods.len; ++_t6) { v__ast__Fn method = ((v__ast__Fn*)methods.data)[_t6]; v__checker__Checker_push_new_comptime_info(c); c->comptime->inside_comptime_for = true; c->comptime->comptime_for_method = &method; c->comptime->comptime_for_method_var = node->val_var; c->comptime->comptime_for_method_ret_type = method.return_type; v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->val_var}}, {_S(".return_type"), 0, { .d_c = 0 }}})), method.return_type); v__checker__Checker_stmts(c, &node->stmts); v__checker__Checker_pop_comptime_info(c); } } else if (node->kind == v__ast__ComptimeForKind__params) { if (!(sym->kind == v__ast__Kind__function || fast_string_eq(sym->name, _S("FunctionData")))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("iterating over `.params` is supported only for functions, and `"), 0xfe10, {.d_s = sym->name}}, {_S("` is not a function"), 0, { .d_c = 0 }}})), node->typ_pos); return; } v__checker__Checker_push_new_comptime_info(c); c->comptime->inside_comptime_for = true; c->comptime->comptime_for_method_param_var = node->val_var; v__checker__Checker_stmts(c, &node->stmts); v__checker__Checker_pop_comptime_info(c); } else if (node->kind == v__ast__ComptimeForKind__variants) { if (c->variant_data_type == 0) { c->variant_data_type = v__ast__Table_find_type(c->table, _S("VariantData")); } Array_v__ast__Type variants = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); if ((c->comptime->comptime_for_field_var).len != 0 && typ == c->field_data_type) { v__ast__TypeSymbol* sumtype_sym = v__ast__Table_sym(c->table, c->comptime->comptime_for_field_type); if (sumtype_sym->kind == v__ast__Kind__sum_type) { variants = array_clone_to_depth(ADDR(Array_v__ast__Type, (*(v__ast__SumType*)__as_cast((sumtype_sym->info)._v__ast__SumType,(sumtype_sym->info)._typ, 544)).variants), 0); } } else if (sym->kind != v__ast__Kind__sum_type) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sym->name}}, {_S(" is not Sum type to use with .variants"), 0, { .d_c = 0 }}})), node->typ_pos); } else { variants = array_clone_to_depth(ADDR(Array_v__ast__Type, (*(v__ast__SumType*)__as_cast((sym->info)._v__ast__SumType,(sym->info)._typ, 544)).variants), 0); } for (int _t7 = 0; _t7 < variants.len; ++_t7) { v__ast__Type variant = ((v__ast__Type*)variants.data)[_t7]; v__checker__Checker_push_new_comptime_info(c); c->comptime->inside_comptime_for = true; c->comptime->comptime_for_variant_var = node->val_var; v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, node->val_var, c->variant_data_type); v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->val_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), variant); v__checker__Checker_stmts(c, &node->stmts); v__checker__Checker_pop_comptime_info(c); } } else { v__checker__Checker_stmts(c, &node->stmts); } } VV_LOC _option_v__ast__ComptTimeConstValue v__checker__Checker_eval_comptime_const_expr(v__checker__Checker* c, v__ast__Expr expr, int nlevel) { if (nlevel > 100) { return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } if (expr._typ == 374 /* v.ast.ParExpr */) { return v__checker__Checker_eval_comptime_const_expr(c, (*expr._v__ast__ParExpr).expr, (int)(nlevel + 1)); } else if (expr._typ == 355 /* v.ast.EnumVal */) { string enum_name = (((*expr._v__ast__EnumVal).enum_name).len == 0 ? (v__ast__Table_type_to_str(c->table, c->expected_type)) : ((*expr._v__ast__EnumVal).enum_name)); _option_i64 _t3; if (_t3 = v__ast__Table_find_enum_field_val(c->table, enum_name, (*expr._v__ast__EnumVal).val), _t3.state == 0) { i64 val = *(i64*)_t3.data; _option_v__ast__ComptTimeConstValue _t4; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(&val) }, (_option*)(&_t4), sizeof(v__ast__ComptTimeConstValue)); return _t4; } } else if (expr._typ == 380 /* v.ast.SizeOf */) { multi_return_int_int mr_13478 = v__ast__Table_type_size(c->table, v__checker__Checker_unwrap_generic(c, (*expr._v__ast__SizeOf).typ)); int s = mr_13478.arg0; _option_v__ast__ComptTimeConstValue _t5; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((i64)(s))))) }, (_option*)(&_t5), sizeof(v__ast__ComptTimeConstValue)); return _t5; } else if (expr._typ == 356 /* v.ast.FloatLiteral */) { f64 x = string_f64((*expr._v__ast__FloatLiteral).val); _option_v__ast__ComptTimeConstValue _t6; _option_ok(&(v__ast__ComptTimeConstValue[]) { f64_to_sumtype_v__ast__ComptTimeConstValue(&x) }, (_option*)(&_t6), sizeof(v__ast__ComptTimeConstValue)); return _t6; } else if (expr._typ == 363 /* v.ast.IntegerLiteral */) { u64 x = string_u64((*expr._v__ast__IntegerLiteral).val); if (x > 9223372036854775807U) { _option_v__ast__ComptTimeConstValue _t7; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(&x) }, (_option*)(&_t7), sizeof(v__ast__ComptTimeConstValue)); return _t7; } _option_v__ast__ComptTimeConstValue _t8; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (string_i64((*expr._v__ast__IntegerLiteral).val)))) }, (_option*)(&_t8), sizeof(v__ast__ComptTimeConstValue)); return _t8; } else if (expr._typ == 384 /* v.ast.StringLiteral */) { _option_v__ast__ComptTimeConstValue _t9; _option_ok(&(v__ast__ComptTimeConstValue[]) { string_to_sumtype_v__ast__ComptTimeConstValue(ADDR(string, (v__util__smart_quote((*expr._v__ast__StringLiteral).val, (*expr._v__ast__StringLiteral).is_raw)))) }, (_option*)(&_t9), sizeof(v__ast__ComptTimeConstValue)); return _t9; } else if (expr._typ == 383 /* v.ast.StringInterLiteral */) { if (nlevel < 0) { strings__Builder sb = strings__new_builder(20); for (int i = 0; i < (*expr._v__ast__StringInterLiteral).vals.len; ++i) { string val = ((string*)(*expr._v__ast__StringInterLiteral).vals.data)[i]; strings__Builder_write_string(&sb, val); v__ast__Expr* _t11 = (v__ast__Expr*)(array_get_with_check((*expr._v__ast__StringInterLiteral).exprs, i)); _option_v__ast__Expr _t10 = {0}; if (_t11) { *((v__ast__Expr*)&_t10.data) = *((v__ast__Expr*)_t11); } else { _t10.state = 2; _t10.err = _v_error(_S("array index out of range")); } if (_t10.state == 0) { v__ast__Expr e = (*(v__ast__Expr*)_t10.data); _option_v__ast__ComptTimeConstValue _t12; if (_t12 = v__checker__Checker_eval_comptime_const_expr(c, e, (int)(nlevel + 1)), _t12.state == 0) { v__ast__ComptTimeConstValue value = *(v__ast__ComptTimeConstValue*)_t12.data; _option_string _t13 = v__ast__ComptTimeConstValue_string(value); if (_t13.state != 0) { IError err = _t13.err; *(string*) _t13.data = _S(""); } strings__Builder_write_string(&sb, (*(string*)_t13.data)); } else { IError err = _t12.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unsupport expr `"), 0xfe10, {.d_s = v__ast__Expr_str(&e)}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(e)); } } } _option_v__ast__ComptTimeConstValue _t14; _option_ok(&(v__ast__ComptTimeConstValue[]) { string_to_sumtype_v__ast__ComptTimeConstValue(ADDR(string, (strings__Builder_str(&sb)))) }, (_option*)(&_t14), sizeof(v__ast__ComptTimeConstValue)); return _t14; } } else if (expr._typ == 347 /* v.ast.CharLiteral */) { Array_rune runes = string_runes((*expr._v__ast__CharLiteral).val); if (runes.len > 0) { _option_v__ast__ComptTimeConstValue _t15; _option_ok(&(v__ast__ComptTimeConstValue[]) { rune_to_sumtype_v__ast__ComptTimeConstValue(&(*(rune*)array_get(runes, 0))) }, (_option*)(&_t15), sizeof(v__ast__ComptTimeConstValue)); return _t15; } return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } else if (expr._typ == 358 /* v.ast.Ident */) { if (((*expr._v__ast__Ident).obj)._typ == 420 /* v.ast.ConstField */) { return v__checker__Checker_eval_comptime_const_expr(c, (*(*expr._v__ast__Ident).obj._v__ast__ConstField).expr, (int)(nlevel + 1)); } int idx = Array_string_index(c->table->cur_fn->generic_names, (*expr._v__ast__Ident).name); v__ast__Type* _t19 = (v__ast__Type*)(array_get_with_check(c->table->cur_concrete_types, idx)); _option_v__ast__Type _t18 = {0}; if (_t19) { *((v__ast__Type*)&_t18.data) = *((v__ast__Type*)_t19); } else { _t18.state = 2; _t18.err = _v_error(_S("array index out of range")); } if (_t18.state == 0) { v__ast__Type typ = (*(v__ast__Type*)_t18.data); v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); _option_v__ast__ComptTimeConstValue _t20; _option_ok(&(v__ast__ComptTimeConstValue[]) { string_to_sumtype_v__ast__ComptTimeConstValue(ADDR(string, (v__ast__TypeSymbol_str(sym)))) }, (_option*)(&_t20), sizeof(v__ast__ComptTimeConstValue)); return _t20; } } else if (expr._typ == 379 /* v.ast.SelectorExpr */) { if (((*expr._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */) { int idx = Array_string_index(c->table->cur_fn->generic_names, (*(*expr._v__ast__SelectorExpr).expr._v__ast__Ident).name); v__ast__Type* _t22 = (v__ast__Type*)(array_get_with_check(c->table->cur_concrete_types, idx)); _option_v__ast__Type _t21 = {0}; if (_t22) { *((v__ast__Type*)&_t21.data) = *((v__ast__Type*)_t22); } else { _t21.state = 2; _t21.err = _v_error(_S("array index out of range")); } if (_t21.state == 0) { v__ast__Type typ = (*(v__ast__Type*)_t21.data); v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); if (_SLIT_EQ((*expr._v__ast__SelectorExpr).field_name.str, (*expr._v__ast__SelectorExpr).field_name.len, "name")) { _option_v__ast__ComptTimeConstValue _t23; _option_ok(&(v__ast__ComptTimeConstValue[]) { string_to_sumtype_v__ast__ComptTimeConstValue(&sym->name) }, (_option*)(&_t23), sizeof(v__ast__ComptTimeConstValue)); return _t23; } else if (_SLIT_EQ((*expr._v__ast__SelectorExpr).field_name.str, (*expr._v__ast__SelectorExpr).field_name.len, "idx")) { _option_v__ast__ComptTimeConstValue _t24; _option_ok(&(v__ast__ComptTimeConstValue[]) { i32_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i32, (((i32)(sym->idx))))) }, (_option*)(&_t24), sizeof(v__ast__ComptTimeConstValue)); return _t24; } else { } } } } else if (expr._typ == 345 /* v.ast.CastExpr */) { _option_v__ast__ComptTimeConstValue _t25 = v__checker__Checker_eval_comptime_const_expr(c, (*expr._v__ast__CastExpr).expr, (int)(nlevel + 1)); if (_t25.state != 0) { IError err = _t25.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } v__ast__ComptTimeConstValue cast_expr_value = (*(v__ast__ComptTimeConstValue*)_t25.data); if ((*expr._v__ast__CastExpr).typ == _const_v__ast__i8_type) { _option_i8 _t28 = v__ast__ComptTimeConstValue_i8(cast_expr_value); if (_t28.state != 0) { IError err = _t28.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue _t27; _option_ok(&(v__ast__ComptTimeConstValue[]) { i8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i8, ((*(i8*)_t28.data)))) }, (_option*)(&_t27), sizeof(v__ast__ComptTimeConstValue)); return _t27; } if ((*expr._v__ast__CastExpr).typ == _const_v__ast__i16_type) { _option_i16 _t31 = v__ast__ComptTimeConstValue_i16(cast_expr_value); if (_t31.state != 0) { IError err = _t31.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue _t30; _option_ok(&(v__ast__ComptTimeConstValue[]) { i16_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i16, ((*(i16*)_t31.data)))) }, (_option*)(&_t30), sizeof(v__ast__ComptTimeConstValue)); return _t30; } if ((*expr._v__ast__CastExpr).typ == _const_v__ast__i32_type) { _option_i32 _t34 = v__ast__ComptTimeConstValue_i32(cast_expr_value); if (_t34.state != 0) { IError err = _t34.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue _t33; _option_ok(&(v__ast__ComptTimeConstValue[]) { i32_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i32, ((*(i32*)_t34.data)))) }, (_option*)(&_t33), sizeof(v__ast__ComptTimeConstValue)); return _t33; } if ((*expr._v__ast__CastExpr).typ == _const_v__ast__i64_type) { _option_i64 _t37 = v__ast__ComptTimeConstValue_i64(cast_expr_value); if (_t37.state != 0) { IError err = _t37.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue _t36; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((*(i64*)_t37.data)))) }, (_option*)(&_t36), sizeof(v__ast__ComptTimeConstValue)); return _t36; } if ((*expr._v__ast__CastExpr).typ == _const_v__ast__int_type) { _option_i64 _t40 = v__ast__ComptTimeConstValue_i64(cast_expr_value); if (_t40.state != 0) { IError err = _t40.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue _t39; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((*(i64*)_t40.data)))) }, (_option*)(&_t39), sizeof(v__ast__ComptTimeConstValue)); return _t39; } if ((*expr._v__ast__CastExpr).typ == _const_v__ast__u8_type) { _option_u8 _t43 = v__ast__ComptTimeConstValue_u8(cast_expr_value); if (_t43.state != 0) { IError err = _t43.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue _t42; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, ((*(u8*)_t43.data)))) }, (_option*)(&_t42), sizeof(v__ast__ComptTimeConstValue)); return _t42; } if ((*expr._v__ast__CastExpr).typ == _const_v__ast__u16_type) { _option_u16 _t46 = v__ast__ComptTimeConstValue_u16(cast_expr_value); if (_t46.state != 0) { IError err = _t46.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue _t45; _option_ok(&(v__ast__ComptTimeConstValue[]) { u16_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u16, ((*(u16*)_t46.data)))) }, (_option*)(&_t45), sizeof(v__ast__ComptTimeConstValue)); return _t45; } if ((*expr._v__ast__CastExpr).typ == _const_v__ast__u32_type) { _option_u32 _t49 = v__ast__ComptTimeConstValue_u32(cast_expr_value); if (_t49.state != 0) { IError err = _t49.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue _t48; _option_ok(&(v__ast__ComptTimeConstValue[]) { u32_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u32, ((*(u32*)_t49.data)))) }, (_option*)(&_t48), sizeof(v__ast__ComptTimeConstValue)); return _t48; } if ((*expr._v__ast__CastExpr).typ == _const_v__ast__u64_type) { _option_u64 _t52 = v__ast__ComptTimeConstValue_u64(cast_expr_value); if (_t52.state != 0) { IError err = _t52.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue _t51; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, ((*(u64*)_t52.data)))) }, (_option*)(&_t51), sizeof(v__ast__ComptTimeConstValue)); return _t51; } if ((*expr._v__ast__CastExpr).typ == _const_v__ast__f32_type) { _option_f32 _t55 = v__ast__ComptTimeConstValue_f32(cast_expr_value); if (_t55.state != 0) { IError err = _t55.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue _t54; _option_ok(&(v__ast__ComptTimeConstValue[]) { f32_to_sumtype_v__ast__ComptTimeConstValue(ADDR(f32, ((*(f32*)_t55.data)))) }, (_option*)(&_t54), sizeof(v__ast__ComptTimeConstValue)); return _t54; } if ((*expr._v__ast__CastExpr).typ == _const_v__ast__f64_type) { _option_f64 _t58 = v__ast__ComptTimeConstValue_f64(cast_expr_value); if (_t58.state != 0) { IError err = _t58.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_v__ast__ComptTimeConstValue _t57; _option_ok(&(v__ast__ComptTimeConstValue[]) { f64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(f64, ((*(f64*)_t58.data)))) }, (_option*)(&_t57), sizeof(v__ast__ComptTimeConstValue)); return _t57; } if ((*expr._v__ast__CastExpr).typ == _const_v__ast__voidptr_type || (*expr._v__ast__CastExpr).typ == _const_v__ast__nil_type) { _option_voidptr _t60 = v__ast__ComptTimeConstValue_voidptr(cast_expr_value); if (_t60.state != 0) { IError err = _t60.err; return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } voidptr ptrvalue = (*(voidptr*)_t60.data); _option_v__ast__ComptTimeConstValue _t62; _option_ok(&(v__ast__ComptTimeConstValue[]) { voidptr_to_sumtype_v__ast__ComptTimeConstValue(&ptrvalue) }, (_option*)(&_t62), sizeof(v__ast__ComptTimeConstValue)); return _t62; } } else if (expr._typ == 362 /* v.ast.InfixExpr */) { _option_v__ast__ComptTimeConstValue _t63 = v__checker__Checker_eval_comptime_const_expr(c, (*expr._v__ast__InfixExpr).left, (int)(nlevel + 1)); if (_t63.state != 0) { _option_v__ast__ComptTimeConstValue _t64; memcpy(&_t64, &_t63, sizeof(_option)); return _t64; } v__ast__ComptTimeConstValue left = (*(v__ast__ComptTimeConstValue*)_t63.data); v__ast__Type saved_expected_type = c->expected_type; if (((*expr._v__ast__InfixExpr).left)._typ == 355 /* v.ast.EnumVal */) { c->expected_type = (*(*expr._v__ast__InfixExpr).left._v__ast__EnumVal).typ; } else if (((*expr._v__ast__InfixExpr).left)._typ == 362 /* v.ast.InfixExpr */) { v__ast__InfixExpr infixexpr = (*expr._v__ast__InfixExpr); for (;;) { if ((infixexpr.left)._typ == 362 /* v.ast.InfixExpr */) { infixexpr = *(v__ast__InfixExpr*)__as_cast((infixexpr.left)._v__ast__InfixExpr,(infixexpr.left)._typ, 362); } else { break; } } if ((infixexpr.left)._typ == 355 /* v.ast.EnumVal */) { c->expected_type = (*infixexpr.left._v__ast__EnumVal).typ; } } _option_v__ast__ComptTimeConstValue _t65 = v__checker__Checker_eval_comptime_const_expr(c, (*expr._v__ast__InfixExpr).right, (int)(nlevel + 1)); if (_t65.state != 0) { _option_v__ast__ComptTimeConstValue _t66; memcpy(&_t66, &_t65, sizeof(_option)); return _t66; } v__ast__ComptTimeConstValue right = (*(v__ast__ComptTimeConstValue*)_t65.data); c->expected_type = saved_expected_type; if ((left)._typ == 21 /* string */ && (right)._typ == 21 /* string */) { if ((*expr._v__ast__InfixExpr).op == (v__token__Kind__plus)) { _option_v__ast__ComptTimeConstValue _t67; _option_ok(&(v__ast__ComptTimeConstValue[]) { string_to_sumtype_v__ast__ComptTimeConstValue(ADDR(string, (string__plus((*left._string), (*right._string))))) }, (_option*)(&_t67), sizeof(v__ast__ComptTimeConstValue)); return _t67; } else { return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } } else if ((left)._typ == 14 /* u64 */ && (right)._typ == 9 /* i64 */) { switch ((*expr._v__ast__InfixExpr).op) { case v__token__Kind__plus: { _option_v__ast__ComptTimeConstValue _t69; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)(((i64)((*left._u64))) + ((i64)((*right._i64))))))) }, (_option*)(&_t69), sizeof(v__ast__ComptTimeConstValue)); return _t69; } case v__token__Kind__minus: { _option_v__ast__ComptTimeConstValue _t70; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)(((i64)((*left._u64))) - ((i64)((*right._i64))))))) }, (_option*)(&_t70), sizeof(v__ast__ComptTimeConstValue)); return _t70; } case v__token__Kind__mul: { _option_v__ast__ComptTimeConstValue _t71; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)(((i64)((*left._u64))) * ((i64)((*right._i64))))))) }, (_option*)(&_t71), sizeof(v__ast__ComptTimeConstValue)); return _t71; } case v__token__Kind__div: { _option_v__ast__ComptTimeConstValue _t72; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)(((i64)((*left._u64))) / ((i64)((*right._i64))))))) }, (_option*)(&_t72), sizeof(v__ast__ComptTimeConstValue)); return _t72; } case v__token__Kind__mod: { _option_v__ast__ComptTimeConstValue _t73; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)(((i64)((*left._u64))) % ((i64)((*right._i64))))))) }, (_option*)(&_t73), sizeof(v__ast__ComptTimeConstValue)); return _t73; } case v__token__Kind__xor: { _option_v__ast__ComptTimeConstValue _t74; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((((i64)((*left._u64))) ^ ((i64)((*right._i64))))))) }, (_option*)(&_t74), sizeof(v__ast__ComptTimeConstValue)); return _t74; } case v__token__Kind__pipe: { _option_v__ast__ComptTimeConstValue _t75; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((((i64)((*left._u64))) | ((i64)((*right._i64))))))) }, (_option*)(&_t75), sizeof(v__ast__ComptTimeConstValue)); return _t75; } case v__token__Kind__amp: { _option_v__ast__ComptTimeConstValue _t76; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((((i64)((*left._u64))) & ((i64)((*right._i64))))))) }, (_option*)(&_t76), sizeof(v__ast__ComptTimeConstValue)); return _t76; } case v__token__Kind__left_shift: { _option_v__ast__ComptTimeConstValue _t77; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((i64)((((u64)((*left._u64))) << ((i64)((*right._i64))))))))) }, (_option*)(&_t77), sizeof(v__ast__ComptTimeConstValue)); return _t77; } case v__token__Kind__right_shift: { _option_v__ast__ComptTimeConstValue _t78; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((i64)((((u64)((*left._u64))) >> ((i64)((*right._i64))))))))) }, (_option*)(&_t78), sizeof(v__ast__ComptTimeConstValue)); return _t78; } case v__token__Kind__unsigned_right_shift: { _option_v__ast__ComptTimeConstValue _t79; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((i64)((((u64)(((u64)((*left._u64))))) >> ((i64)((*right._i64))))))))) }, (_option*)(&_t79), sizeof(v__ast__ComptTimeConstValue)); return _t79; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__and: case v__token__Kind__logical_or: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__not_in: case v__token__Kind__not_is: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__eq: case v__token__Kind__ne: case v__token__Kind__gt: case v__token__Kind__lt: case v__token__Kind__ge: case v__token__Kind__le: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_in: case v__token__Kind__key_interface: case v__token__Kind__key_is: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } } } } else if ((left)._typ == 9 /* i64 */ && (right)._typ == 14 /* u64 */) { switch ((*expr._v__ast__InfixExpr).op) { case v__token__Kind__plus: { _option_v__ast__ComptTimeConstValue _t81; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)(((i64)((*left._i64))) + ((i64)((*right._u64))))))) }, (_option*)(&_t81), sizeof(v__ast__ComptTimeConstValue)); return _t81; } case v__token__Kind__minus: { _option_v__ast__ComptTimeConstValue _t82; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)(((i64)((*left._i64))) - ((i64)((*right._u64))))))) }, (_option*)(&_t82), sizeof(v__ast__ComptTimeConstValue)); return _t82; } case v__token__Kind__mul: { _option_v__ast__ComptTimeConstValue _t83; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)(((i64)((*left._i64))) * ((i64)((*right._u64))))))) }, (_option*)(&_t83), sizeof(v__ast__ComptTimeConstValue)); return _t83; } case v__token__Kind__div: { _option_v__ast__ComptTimeConstValue _t84; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)(((i64)((*left._i64))) / ((i64)((*right._u64))))))) }, (_option*)(&_t84), sizeof(v__ast__ComptTimeConstValue)); return _t84; } case v__token__Kind__mod: { _option_v__ast__ComptTimeConstValue _t85; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)(((i64)((*left._i64))) % ((i64)((*right._u64))))))) }, (_option*)(&_t85), sizeof(v__ast__ComptTimeConstValue)); return _t85; } case v__token__Kind__xor: { _option_v__ast__ComptTimeConstValue _t86; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((((i64)((*left._i64))) ^ ((i64)((*right._u64))))))) }, (_option*)(&_t86), sizeof(v__ast__ComptTimeConstValue)); return _t86; } case v__token__Kind__pipe: { _option_v__ast__ComptTimeConstValue _t87; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((((i64)((*left._i64))) | ((i64)((*right._u64))))))) }, (_option*)(&_t87), sizeof(v__ast__ComptTimeConstValue)); return _t87; } case v__token__Kind__amp: { _option_v__ast__ComptTimeConstValue _t88; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((((i64)((*left._i64))) & ((i64)((*right._u64))))))) }, (_option*)(&_t88), sizeof(v__ast__ComptTimeConstValue)); return _t88; } case v__token__Kind__left_shift: { _option_v__ast__ComptTimeConstValue _t89; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((i64)((((u64)((*left._i64))) << ((i64)((*right._u64))))))))) }, (_option*)(&_t89), sizeof(v__ast__ComptTimeConstValue)); return _t89; } case v__token__Kind__right_shift: { _option_v__ast__ComptTimeConstValue _t90; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((i64)((((u64)((*left._i64))) >> ((i64)((*right._u64))))))))) }, (_option*)(&_t90), sizeof(v__ast__ComptTimeConstValue)); return _t90; } case v__token__Kind__unsigned_right_shift: { _option_v__ast__ComptTimeConstValue _t91; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((i64)((((u64)(((u64)((*left._i64))))) >> ((i64)((*right._u64))))))))) }, (_option*)(&_t91), sizeof(v__ast__ComptTimeConstValue)); return _t91; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__and: case v__token__Kind__logical_or: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__not_in: case v__token__Kind__not_is: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__eq: case v__token__Kind__ne: case v__token__Kind__gt: case v__token__Kind__lt: case v__token__Kind__ge: case v__token__Kind__le: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_in: case v__token__Kind__key_interface: case v__token__Kind__key_is: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } } } } else if ((left)._typ == 14 /* u64 */ && (right)._typ == 14 /* u64 */) { switch ((*expr._v__ast__InfixExpr).op) { case v__token__Kind__plus: { _option_v__ast__ComptTimeConstValue _t93; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, ((u64)((*left._u64) + (*right._u64))))) }, (_option*)(&_t93), sizeof(v__ast__ComptTimeConstValue)); return _t93; } case v__token__Kind__minus: { _option_v__ast__ComptTimeConstValue _t94; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, ((u64)((*left._u64) - (*right._u64))))) }, (_option*)(&_t94), sizeof(v__ast__ComptTimeConstValue)); return _t94; } case v__token__Kind__mul: { _option_v__ast__ComptTimeConstValue _t95; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, ((u64)((*left._u64) * (*right._u64))))) }, (_option*)(&_t95), sizeof(v__ast__ComptTimeConstValue)); return _t95; } case v__token__Kind__div: { _option_v__ast__ComptTimeConstValue _t96; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, ((u64)((*left._u64) / (*right._u64))))) }, (_option*)(&_t96), sizeof(v__ast__ComptTimeConstValue)); return _t96; } case v__token__Kind__mod: { _option_v__ast__ComptTimeConstValue _t97; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, ((u64)((*left._u64) % (*right._u64))))) }, (_option*)(&_t97), sizeof(v__ast__ComptTimeConstValue)); return _t97; } case v__token__Kind__xor: { _option_v__ast__ComptTimeConstValue _t98; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, (((*left._u64) ^ (*right._u64))))) }, (_option*)(&_t98), sizeof(v__ast__ComptTimeConstValue)); return _t98; } case v__token__Kind__pipe: { _option_v__ast__ComptTimeConstValue _t99; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, (((*left._u64) | (*right._u64))))) }, (_option*)(&_t99), sizeof(v__ast__ComptTimeConstValue)); return _t99; } case v__token__Kind__amp: { _option_v__ast__ComptTimeConstValue _t100; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, (((*left._u64) & (*right._u64))))) }, (_option*)(&_t100), sizeof(v__ast__ComptTimeConstValue)); return _t100; } case v__token__Kind__left_shift: { _option_v__ast__ComptTimeConstValue _t101; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, (((*left._u64) << (*right._u64))))) }, (_option*)(&_t101), sizeof(v__ast__ComptTimeConstValue)); return _t101; } case v__token__Kind__right_shift: { _option_v__ast__ComptTimeConstValue _t102; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, (((*left._u64) >> (*right._u64))))) }, (_option*)(&_t102), sizeof(v__ast__ComptTimeConstValue)); return _t102; } case v__token__Kind__unsigned_right_shift: { _option_v__ast__ComptTimeConstValue _t103; _option_ok(&(v__ast__ComptTimeConstValue[]) { u64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u64, ((((u64)((*left._u64))) >> (*right._u64))))) }, (_option*)(&_t103), sizeof(v__ast__ComptTimeConstValue)); return _t103; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__and: case v__token__Kind__logical_or: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__not_in: case v__token__Kind__not_is: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__eq: case v__token__Kind__ne: case v__token__Kind__gt: case v__token__Kind__lt: case v__token__Kind__ge: case v__token__Kind__le: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_in: case v__token__Kind__key_interface: case v__token__Kind__key_is: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } } } } else if ((left)._typ == 9 /* i64 */ && (right)._typ == 9 /* i64 */) { switch ((*expr._v__ast__InfixExpr).op) { case v__token__Kind__plus: { _option_v__ast__ComptTimeConstValue _t105; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)((*left._i64) + (*right._i64))))) }, (_option*)(&_t105), sizeof(v__ast__ComptTimeConstValue)); return _t105; } case v__token__Kind__minus: { _option_v__ast__ComptTimeConstValue _t106; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)((*left._i64) - (*right._i64))))) }, (_option*)(&_t106), sizeof(v__ast__ComptTimeConstValue)); return _t106; } case v__token__Kind__mul: { _option_v__ast__ComptTimeConstValue _t107; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)((*left._i64) * (*right._i64))))) }, (_option*)(&_t107), sizeof(v__ast__ComptTimeConstValue)); return _t107; } case v__token__Kind__div: { _option_v__ast__ComptTimeConstValue _t108; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)((*left._i64) / (*right._i64))))) }, (_option*)(&_t108), sizeof(v__ast__ComptTimeConstValue)); return _t108; } case v__token__Kind__mod: { _option_v__ast__ComptTimeConstValue _t109; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, ((i64)((*left._i64) % (*right._i64))))) }, (_option*)(&_t109), sizeof(v__ast__ComptTimeConstValue)); return _t109; } case v__token__Kind__xor: { _option_v__ast__ComptTimeConstValue _t110; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((*left._i64) ^ (*right._i64))))) }, (_option*)(&_t110), sizeof(v__ast__ComptTimeConstValue)); return _t110; } case v__token__Kind__pipe: { _option_v__ast__ComptTimeConstValue _t111; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((*left._i64) | (*right._i64))))) }, (_option*)(&_t111), sizeof(v__ast__ComptTimeConstValue)); return _t111; } case v__token__Kind__amp: { _option_v__ast__ComptTimeConstValue _t112; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((*left._i64) & (*right._i64))))) }, (_option*)(&_t112), sizeof(v__ast__ComptTimeConstValue)); return _t112; } case v__token__Kind__left_shift: { _option_v__ast__ComptTimeConstValue _t113; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((i64)((((u64)((*left._i64))) << (*right._i64))))))) }, (_option*)(&_t113), sizeof(v__ast__ComptTimeConstValue)); return _t113; } case v__token__Kind__right_shift: { _option_v__ast__ComptTimeConstValue _t114; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((i64)((((u64)((*left._i64))) >> (*right._i64))))))) }, (_option*)(&_t114), sizeof(v__ast__ComptTimeConstValue)); return _t114; } case v__token__Kind__unsigned_right_shift: { _option_v__ast__ComptTimeConstValue _t115; _option_ok(&(v__ast__ComptTimeConstValue[]) { i64_to_sumtype_v__ast__ComptTimeConstValue(ADDR(i64, (((i64)((((u64)(((u64)((*left._i64))))) >> (*right._i64))))))) }, (_option*)(&_t115), sizeof(v__ast__ComptTimeConstValue)); return _t115; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__and: case v__token__Kind__logical_or: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__not_in: case v__token__Kind__not_is: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__eq: case v__token__Kind__ne: case v__token__Kind__gt: case v__token__Kind__lt: case v__token__Kind__ge: case v__token__Kind__le: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_in: case v__token__Kind__key_interface: case v__token__Kind__key_is: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } } } } else if ((left)._typ == 11 /* u8 */ && (right)._typ == 11 /* u8 */) { switch ((*expr._v__ast__InfixExpr).op) { case v__token__Kind__plus: { _option_v__ast__ComptTimeConstValue _t117; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, ((u8)((*left._u8) + (*right._u8))))) }, (_option*)(&_t117), sizeof(v__ast__ComptTimeConstValue)); return _t117; } case v__token__Kind__minus: { _option_v__ast__ComptTimeConstValue _t118; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, ((u8)((*left._u8) - (*right._u8))))) }, (_option*)(&_t118), sizeof(v__ast__ComptTimeConstValue)); return _t118; } case v__token__Kind__mul: { _option_v__ast__ComptTimeConstValue _t119; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, ((u8)((*left._u8) * (*right._u8))))) }, (_option*)(&_t119), sizeof(v__ast__ComptTimeConstValue)); return _t119; } case v__token__Kind__div: { _option_v__ast__ComptTimeConstValue _t120; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, ((u8)((*left._u8) / (*right._u8))))) }, (_option*)(&_t120), sizeof(v__ast__ComptTimeConstValue)); return _t120; } case v__token__Kind__mod: { _option_v__ast__ComptTimeConstValue _t121; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, ((u8)((*left._u8) % (*right._u8))))) }, (_option*)(&_t121), sizeof(v__ast__ComptTimeConstValue)); return _t121; } case v__token__Kind__xor: { _option_v__ast__ComptTimeConstValue _t122; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, (((*left._u8) ^ (*right._u8))))) }, (_option*)(&_t122), sizeof(v__ast__ComptTimeConstValue)); return _t122; } case v__token__Kind__pipe: { _option_v__ast__ComptTimeConstValue _t123; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, (((*left._u8) | (*right._u8))))) }, (_option*)(&_t123), sizeof(v__ast__ComptTimeConstValue)); return _t123; } case v__token__Kind__amp: { _option_v__ast__ComptTimeConstValue _t124; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, (((*left._u8) & (*right._u8))))) }, (_option*)(&_t124), sizeof(v__ast__ComptTimeConstValue)); return _t124; } case v__token__Kind__left_shift: { _option_v__ast__ComptTimeConstValue _t125; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, (((*left._u8) << (*right._u8))))) }, (_option*)(&_t125), sizeof(v__ast__ComptTimeConstValue)); return _t125; } case v__token__Kind__right_shift: { _option_v__ast__ComptTimeConstValue _t126; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, (((*left._u8) >> (*right._u8))))) }, (_option*)(&_t126), sizeof(v__ast__ComptTimeConstValue)); return _t126; } case v__token__Kind__unsigned_right_shift: { _option_v__ast__ComptTimeConstValue _t127; _option_ok(&(v__ast__ComptTimeConstValue[]) { u8_to_sumtype_v__ast__ComptTimeConstValue(ADDR(u8, ((((u8)((*left._u8))) >> (*right._u8))))) }, (_option*)(&_t127), sizeof(v__ast__ComptTimeConstValue)); return _t127; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__and: case v__token__Kind__logical_or: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__not_in: case v__token__Kind__not_is: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__eq: case v__token__Kind__ne: case v__token__Kind__gt: case v__token__Kind__lt: case v__token__Kind__ge: case v__token__Kind__le: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_in: case v__token__Kind__key_interface: case v__token__Kind__key_is: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } } } } } else if (expr._typ == 359 /* v.ast.IfExpr */) { if (!(*expr._v__ast__IfExpr).is_comptime) { return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } for (int i = 0; i < (*expr._v__ast__IfExpr).branches.len; ++i) { v__ast__IfBranch branch = (*(v__ast__IfBranch*)array_get((*expr._v__ast__IfExpr).branches, i)); if (!(*expr._v__ast__IfExpr).has_else || i < (int)((*expr._v__ast__IfExpr).branches.len - 1)) { if (v__checker__Checker_comptime_if_cond(c, &branch.cond, branch.pos) == v__checker__ComptimeBranchSkipState__eval) { v__ast__Stmt last_stmt = (*(v__ast__Stmt*)array_last(branch.stmts)); if ((last_stmt)._typ == 401 /* v.ast.ExprStmt */) { return v__checker__Checker_eval_comptime_const_expr(c, (*last_stmt._v__ast__ExprStmt).expr, (int)(nlevel + 1)); } } } else { v__ast__Stmt last_stmt = (*(v__ast__Stmt*)array_last(branch.stmts)); if ((last_stmt)._typ == 401 /* v.ast.ExprStmt */) { return v__checker__Checker_eval_comptime_const_expr(c, (*last_stmt._v__ast__ExprStmt).expr, (int)(nlevel + 1)); } } } } else { return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } return (_option_v__ast__ComptTimeConstValue){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } VV_LOC multi_return_bool_int_int v__checker__Checker_verify_vweb_params_for_method(v__checker__Checker* c, v__ast__Fn* node) { int margs = (int)(node->params.len - 1); if (node->attrs.len == 0) { return (multi_return_bool_int_int){.arg0=true, .arg1=-1, .arg2=margs}; } if (node->params.len > 1) { Array_v__ast__Param _t2 = array_slice(node->params, 1, 2147483647); for (int _t3 = 0; _t3 < _t2.len; ++_t3) { v__ast__Param param = ((v__ast__Param*)_t2.data)[_t3]; v__ast__TypeSymbol* param_sym = v__ast__Table_final_sym(c->table, param.typ); if (!(v__ast__TypeSymbol_is_string(param_sym) || v__ast__TypeSymbol_is_number(param_sym) || v__ast__TypeSymbol_is_float(param_sym) || param_sym->kind == v__ast__Kind__bool)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("invalid type `"), 0xfe10, {.d_s = param_sym->name}}, {_S("` for parameter `"), 0xfe10, {.d_s = param.name}}, {_S("` in vweb app method `"), 0xfe10, {.d_s = node->name}}, {_S("` (only strings, numbers, and bools are allowed)"), 0, { .d_c = 0 }}})), param.pos); } } } int route_attributes = 0; for (int _t4 = 0; _t4 < node->attrs.len; ++_t4) { v__ast__Attr a = ((v__ast__Attr*)node->attrs.data)[_t4]; if (string_starts_with(a.name, _S("/"))) { route_attributes += string_count(a.name, _S(":")); } } return (multi_return_bool_int_int){.arg0=route_attributes == margs, .arg1=route_attributes, .arg2=margs}; } VV_LOC void v__checker__Checker_verify_all_vweb_routes(v__checker__Checker* c) { if (c->vweb_gen_types.len == 0) { return; } c->table->used_features->used_veb_types = c->vweb_gen_types; v__ast__Type typ_vweb_result = v__ast__Table_find_type(c->table, _S("vweb.Result")); v__ast__File* old_file = c->file; for (int _t1 = 0; _t1 < c->vweb_gen_types.len; ++_t1) { v__ast__Type vgt = ((v__ast__Type*)c->vweb_gen_types.data)[_t1]; v__ast__TypeSymbol* sym_app = v__ast__Table_sym(c->table, vgt); for (int _t2 = 0; _t2 < sym_app->methods.len; ++_t2) { v__ast__Fn m = ((v__ast__Fn*)sym_app->methods.data)[_t2]; if (m.return_type == typ_vweb_result) { multi_return_bool_int_int mr_21985 = v__checker__Checker_verify_vweb_params_for_method(c, (voidptr)&m); bool is_ok = mr_21985.arg0; int nroute_attributes = mr_21985.arg1; int nargs = mr_21985.arg2; if (!is_ok) { v__ast__FnDecl* f = ((v__ast__FnDecl*)(m.source_fn)); if (f == ((void*)0)) { continue; } bool _t3 = (f->return_type == typ_vweb_result && f->receiver.typ == (*(v__ast__Param*)array_get(m.params, 0)).typ && string__eq(f->name, m.name)); if ( _t3 && !Array_v__ast__Attr_contains(f->attrs, _S("post"))) { v__checker__Checker_change_current_file(c, f->source_file); v__checker__Checker_warn(c, str_intp(6, _MOV((StrIntpData[]){{_S("mismatched parameters count between vweb method `"), 0xfe10, {.d_s = sym_app->name}}, {_S("."), 0xfe10, {.d_s = m.name}}, {_S("` ("), 0xfe07, {.d_i32 = nargs}}, {_S(") and route attribute "), 0xfe10, {.d_s = Array_v__ast__Attr_str(m.attrs)}}, {_S(" ("), 0xfe07, {.d_i32 = nroute_attributes}}, {_S(")"), 0, { .d_c = 0 }}})), f->pos); } } } } } v__checker__Checker_change_current_file(c, old_file); } VV_LOC bool v__checker__Checker_evaluate_once_comptime_if_attribute(v__checker__Checker* c, v__ast__Attr* node) { if (node->ct_evaled) { return node->ct_skip; } if ((node->ct_expr)._typ == 358 /* v.ast.Ident */) { if (node->ct_opt) { if ((Array_string_contains(_const_v__ast__valid_comptime_not_user_defined, (*node->ct_expr._v__ast__Ident).name))) { v__checker__Checker_error(c, _S("option `@[if expression ?]` tags, can be used only for user defined identifiers"), node->pos); node->ct_skip = true; } else { node->ct_skip = !(Array_string_contains(c->pref->compile_defines, (*node->ct_expr._v__ast__Ident).name)); } node->ct_evaled = true; return node->ct_skip; } else { if (!(Array_string_contains(_const_v__ast__valid_comptime_not_user_defined, (*node->ct_expr._v__ast__Ident).name))) { v__checker__Checker_note(c, str_intp(3, _MOV((StrIntpData[]){{_S("`@[if "), 0xfe10, {.d_s = (*node->ct_expr._v__ast__Ident).name}}, {_S("]` is deprecated. Use `@[if "), 0xfe10, {.d_s = (*node->ct_expr._v__ast__Ident).name}}, {_S(" ?]` instead"), 0, { .d_c = 0 }}})), node->pos); node->ct_skip = !(Array_string_contains(c->pref->compile_defines, (*node->ct_expr._v__ast__Ident).name)); node->ct_evaled = true; return node->ct_skip; } else { if ((Array_string_contains(c->pref->compile_defines, (*node->ct_expr._v__ast__Ident).name))) { node->ct_skip = false; node->ct_evaled = true; return node->ct_skip; } } } } c->inside_ct_attr = true; node->ct_skip = (v__checker__Checker_comptime_if_cond(c, &node->ct_expr, node->pos) == v__checker__ComptimeBranchSkipState__skip ? (true) : (false)); c->inside_ct_attr = false; node->ct_evaled = true; return node->ct_skip; } VV_LOC v__checker__ComptimeBranchSkipState v__checker__Checker_comptime_if_cond(v__checker__Checker* c, v__ast__Expr* cond, v__token__Pos pos) { bool v__checker__Checker_comptime_if_cond_defer_0 = false; bool should_record_ident; bool is_user_ident; string ident_name; should_record_ident = false; is_user_ident = false; ident_name = _S(""); v__checker__Checker_comptime_if_cond_defer_0 = true; if (cond->_typ == 342 /* v.ast.BoolLiteral */) { v__checker__ComptimeBranchSkipState _t1 = ((*cond->_v__ast__BoolLiteral).val ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t1 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t1 }); } } } // Defer end return _t1; } else if (cond->_typ == 374 /* v.ast.ParExpr */) { v__checker__ComptimeBranchSkipState _t2 = v__checker__Checker_comptime_if_cond(c, &(*cond->_v__ast__ParExpr).expr, pos); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t2 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t2 }); } } } // Defer end return _t2; } else if (cond->_typ == 376 /* v.ast.PrefixExpr */) { if ((*cond->_v__ast__PrefixExpr).op != v__token__Kind__not) { v__checker__Checker_error(c, _S("invalid `$if` condition"), (*cond->_v__ast__PrefixExpr).pos); } v__checker__ComptimeBranchSkipState reversed = v__checker__Checker_comptime_if_cond(c, &(*cond->_v__ast__PrefixExpr).right, (*cond->_v__ast__PrefixExpr).pos); v__checker__ComptimeBranchSkipState _t3 = (reversed == v__checker__ComptimeBranchSkipState__eval ? (v__checker__ComptimeBranchSkipState__skip) : reversed == v__checker__ComptimeBranchSkipState__skip ? (v__checker__ComptimeBranchSkipState__eval) : (reversed)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t3 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t3 }); } } } // Defer end return _t3; } else if (cond->_typ == 375 /* v.ast.PostfixExpr */) { if ((*cond->_v__ast__PostfixExpr).op != v__token__Kind__question) { v__checker__Checker_error(c, _S("invalid $if postfix operator"), (*cond->_v__ast__PostfixExpr).pos); } else if (((*cond->_v__ast__PostfixExpr).expr)._typ == 358 /* v.ast.Ident */) { should_record_ident = true; is_user_ident = true; ident_name = (*(*cond->_v__ast__PostfixExpr).expr._v__ast__Ident).name; v__checker__ComptimeBranchSkipState _t4 = ((Array_string_contains(c->pref->compile_defines, (*(*cond->_v__ast__PostfixExpr).expr._v__ast__Ident).name)) ? (v__checker__ComptimeBranchSkipState__eval) : (((Array_string_contains(c->pref->compile_defines_all, (*(*cond->_v__ast__PostfixExpr).expr._v__ast__Ident).name)) ? (v__checker__ComptimeBranchSkipState__unknown) : (v__checker__ComptimeBranchSkipState__skip)))); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t4 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t4 }); } } } // Defer end return _t4; } else { v__checker__Checker_error(c, _S("invalid `$if` condition"), (*cond->_v__ast__PostfixExpr).pos); } } else if (cond->_typ == 362 /* v.ast.InfixExpr */) { switch ((*cond->_v__ast__InfixExpr).op) { case v__token__Kind__and: { v__checker__ComptimeBranchSkipState l = v__checker__Checker_comptime_if_cond(c, &(*cond->_v__ast__InfixExpr).left, (*cond->_v__ast__InfixExpr).pos); v__checker__ComptimeBranchSkipState r = v__checker__Checker_comptime_if_cond(c, &(*cond->_v__ast__InfixExpr).right, (*cond->_v__ast__InfixExpr).pos); if (l == v__checker__ComptimeBranchSkipState__unknown || r == v__checker__ComptimeBranchSkipState__unknown) { v__checker__ComptimeBranchSkipState _t5 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t5 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t5 }); } } } // Defer end return _t5; } v__checker__ComptimeBranchSkipState _t6 = (l == v__checker__ComptimeBranchSkipState__eval && r == v__checker__ComptimeBranchSkipState__eval ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t6 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t6 }); } } } // Defer end return _t6; } case v__token__Kind__logical_or: { v__checker__ComptimeBranchSkipState l = v__checker__Checker_comptime_if_cond(c, &(*cond->_v__ast__InfixExpr).left, (*cond->_v__ast__InfixExpr).pos); v__checker__ComptimeBranchSkipState r = v__checker__Checker_comptime_if_cond(c, &(*cond->_v__ast__InfixExpr).right, (*cond->_v__ast__InfixExpr).pos); if (l == v__checker__ComptimeBranchSkipState__unknown || r == v__checker__ComptimeBranchSkipState__unknown) { v__checker__ComptimeBranchSkipState _t7 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t7 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t7 }); } } } // Defer end return _t7; } v__checker__ComptimeBranchSkipState _t8 = (l == v__checker__ComptimeBranchSkipState__eval || r == v__checker__ComptimeBranchSkipState__eval ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t8 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t8 }); } } } // Defer end return _t8; } case v__token__Kind__key_is: case v__token__Kind__not_is: { if (((*cond->_v__ast__InfixExpr).left)._typ == 386 /* v.ast.TypeNode */ && ((*cond->_v__ast__InfixExpr).right)._typ == 386 /* v.ast.TypeNode */) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, (*(*cond->_v__ast__InfixExpr).right._v__ast__TypeNode).typ); if (sym->kind != v__ast__Kind__interface) { v__checker__Checker_expr(c, &(*cond->_v__ast__InfixExpr).left); } else { v__checker__ComptimeBranchSkipState _t9 = v__checker__Checker_check_compatible_types(c, (*(v__ast__TypeNode*)__as_cast(((*cond->_v__ast__InfixExpr).left)._v__ast__TypeNode,((*cond->_v__ast__InfixExpr).left)._typ, 386)).typ, (*(*cond->_v__ast__InfixExpr).right._v__ast__TypeNode)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t9 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t9 }); } } } // Defer end return _t9; } v__checker__ComptimeBranchSkipState _t10 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t10 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t10 }); } } } // Defer end return _t10; } else if (((*cond->_v__ast__InfixExpr).left)._typ == 386 /* v.ast.TypeNode */ && ((*cond->_v__ast__InfixExpr).right)._typ == 351 /* v.ast.ComptimeType */) { v__ast__TypeNode left = *(v__ast__TypeNode*)__as_cast(((*cond->_v__ast__InfixExpr).left)._v__ast__TypeNode,((*cond->_v__ast__InfixExpr).left)._typ, 386); v__ast__Type checked_type = v__checker__Checker_unwrap_generic(c, left.typ); v__checker__ComptimeBranchSkipState _t11 = (v__type_resolver__TypeResolver_is_comptime_type(&c->type_resolver, checked_type, (*(*cond->_v__ast__InfixExpr).right._v__ast__ComptimeType)) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t11 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t11 }); } } } // Defer end return _t11; } else if (((*cond->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ || ((*cond->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ || ((*cond->_v__ast__InfixExpr).left)._typ == 386 /* v.ast.TypeNode */) { v__checker__Checker_expr(c, &(*cond->_v__ast__InfixExpr).left); c->comptime->inside_comptime_if = true; if (((*cond->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ && ((*cond->_v__ast__InfixExpr).right)._typ == 351 /* v.ast.ComptimeType */) { v__ast__ComptimeType comptime_type = *(v__ast__ComptimeType*)__as_cast(((*cond->_v__ast__InfixExpr).right)._v__ast__ComptimeType,((*cond->_v__ast__InfixExpr).right)._typ, 351); if (v__type_resolver__ResolverInfo_is_comptime_selector_type(c->comptime, (*(*cond->_v__ast__InfixExpr).left._v__ast__SelectorExpr))) { v__ast__Type checked_type = v__type_resolver__TypeResolver_get_type(&c->type_resolver, (*cond->_v__ast__InfixExpr).left); v__checker__ComptimeBranchSkipState _t12 = (v__type_resolver__TypeResolver_is_comptime_type(&c->type_resolver, checked_type, comptime_type) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t12 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t12 }); } } } // Defer end return _t12; } else if ((*(*cond->_v__ast__InfixExpr).left._v__ast__SelectorExpr).gkind_field == v__ast__GenericKindField__unaliased_typ && (*(*cond->_v__ast__InfixExpr).left._v__ast__SelectorExpr).name_type != 0) { v__ast__Type checked_type = v__checker__Checker_unwrap_generic(c, (*(*cond->_v__ast__InfixExpr).left._v__ast__SelectorExpr).name_type); v__checker__ComptimeBranchSkipState _t13 = (v__type_resolver__TypeResolver_is_comptime_type(&c->type_resolver, v__ast__Table_unaliased_type(c->table, checked_type), comptime_type) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t13 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t13 }); } } } // Defer end return _t13; } } v__checker__ComptimeBranchSkipState _t14 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t14 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t14 }); } } } // Defer end return _t14; } else { v__checker__Checker_error(c, _S("invalid `$if` condition: expected a type or a selector expression or an interface check"), v__ast__Expr_pos((*cond->_v__ast__InfixExpr).left)); } break; } case v__token__Kind__eq: case v__token__Kind__ne: { if (((*cond->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ && (((*cond->_v__ast__InfixExpr).right)._typ == 363 /* v.ast.IntegerLiteral */ || ((*cond->_v__ast__InfixExpr).right)._typ == 384 /* v.ast.StringLiteral */)) { if ((*(*cond->_v__ast__InfixExpr).left._v__ast__SelectorExpr).typ == 0 && (*(*cond->_v__ast__InfixExpr).left._v__ast__SelectorExpr).name_type == 0 && (((*(*cond->_v__ast__InfixExpr).left._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*(*cond->_v__ast__InfixExpr).left._v__ast__SelectorExpr).expr)._v__ast__Ident,((*(*cond->_v__ast__InfixExpr).left._v__ast__SelectorExpr).expr)._typ, 358)).name.len == 1)) { v__checker__Checker_expr(c, HEAP(v__ast__Expr, v__ast__SelectorExpr_to_sumtype_v__ast__Expr(&(*(*cond->_v__ast__InfixExpr).left._v__ast__SelectorExpr)))); } v__checker__ComptimeBranchSkipState _t15 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t15 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t15 }); } } } // Defer end return _t15; } else if (((*cond->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ && v__type_resolver__ResolverInfo_check_comptime_is_field_selector_bool(c->comptime, *(v__ast__SelectorExpr*)__as_cast(((*cond->_v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*cond->_v__ast__InfixExpr).left)._typ, 379))) { } else if (((*cond->_v__ast__InfixExpr).right)._typ == 379 /* v.ast.SelectorExpr */ && v__type_resolver__ResolverInfo_check_comptime_is_field_selector_bool(c->comptime, *(v__ast__SelectorExpr*)__as_cast(((*cond->_v__ast__InfixExpr).right)._v__ast__SelectorExpr,((*cond->_v__ast__InfixExpr).right)._typ, 379))) { } else if (((*cond->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */) { v__ast__Type left_type = v__checker__Checker_expr(c, &(*cond->_v__ast__InfixExpr).left); v__ast__Type right_type = v__checker__Checker_expr(c, &(*cond->_v__ast__InfixExpr).right); _result_v__ast__Expr _t16 = v__checker__Checker_find_definition(c, *(v__ast__Ident*)__as_cast(((*cond->_v__ast__InfixExpr).left)._v__ast__Ident,((*cond->_v__ast__InfixExpr).left)._typ, 358)); if (_t16.is_error) { IError err = _t16.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), v__ast__Expr_pos((*cond->_v__ast__InfixExpr).left)); v__checker__ComptimeBranchSkipState _t17 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t17 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t17 }); } } } // Defer end return _t17; } v__ast__Expr expr = (*(v__ast__Expr*)_t16.data); if (!v__checker__Checker_check_types(c, right_type, left_type)) { string left_name = v__ast__Table_type_to_str(c->table, left_type); string right_name = v__ast__Table_type_to_str(c->table, right_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), (*cond->_v__ast__InfixExpr).pos); } bool different = !string__eq(v__ast__Expr_str(&expr), v__ast__Expr_str(&(*cond->_v__ast__InfixExpr).right)); v__checker__ComptimeBranchSkipState _t18 = ((*cond->_v__ast__InfixExpr).op == v__token__Kind__eq ? ((different ? (v__checker__ComptimeBranchSkipState__skip) : (v__checker__ComptimeBranchSkipState__eval))) : ((different ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)))); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t18 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t18 }); } } } // Defer end return _t18; } else if (((*cond->_v__ast__InfixExpr).left)._typ == 380 /* v.ast.SizeOf */) { } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid `$if` condition: "), 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_sumtype_v__ast__Expr( ((*cond->_v__ast__InfixExpr).left)._typ ))}}, {_SLIT0, 0, { .d_c = 0 }}})), (*cond->_v__ast__InfixExpr).pos); } break; } case v__token__Kind__key_in: case v__token__Kind__not_in: { if (((*cond->_v__ast__InfixExpr).right)._typ == 338 /* v.ast.ArrayInit */ && (((*cond->_v__ast__InfixExpr).left)._typ == 386 /* v.ast.TypeNode */ || ((*cond->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ || ((*cond->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */)) { v__checker__Checker_expr(c, &(*cond->_v__ast__InfixExpr).left); for (int _t19 = 0; _t19 < (*(*cond->_v__ast__InfixExpr).right._v__ast__ArrayInit).exprs.len; ++_t19) { v__ast__Expr expr = ((v__ast__Expr*)(*(*cond->_v__ast__InfixExpr).right._v__ast__ArrayInit).exprs.data)[_t19]; if (!((expr)._typ == 351 /* v.ast.ComptimeType */ || (expr)._typ == 386 /* v.ast.TypeNode */)) { v__checker__Checker_error(c, _S("invalid `$if` condition, only types are allowed"), v__ast__Expr_pos(expr)); } } v__checker__ComptimeBranchSkipState _t20 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t20 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t20 }); } } } // Defer end return _t20; } else { v__checker__Checker_error(c, _S("invalid `$if` condition"), (*cond->_v__ast__InfixExpr).pos); } break; } case v__token__Kind__gt: case v__token__Kind__lt: case v__token__Kind__ge: case v__token__Kind__le: { if (((*cond->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ && (*(v__ast__SelectorExpr*)__as_cast(((*cond->_v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*cond->_v__ast__InfixExpr).left)._typ, 379)).typ == 0 && (*(v__ast__SelectorExpr*)__as_cast(((*cond->_v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*cond->_v__ast__InfixExpr).left)._typ, 379)).name_type == 0 && (((*(v__ast__SelectorExpr*)__as_cast(((*cond->_v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*cond->_v__ast__InfixExpr).left)._typ, 379)).expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*(v__ast__SelectorExpr*)__as_cast(((*cond->_v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*cond->_v__ast__InfixExpr).left)._typ, 379)).expr)._v__ast__Ident,((*(v__ast__SelectorExpr*)__as_cast(((*cond->_v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*cond->_v__ast__InfixExpr).left)._typ, 379)).expr)._typ, 358)).name.len == 1)) { v__checker__Checker_expr(c, &(*cond->_v__ast__InfixExpr).left); } if (((*cond->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ && ((*cond->_v__ast__InfixExpr).right)._typ == 363 /* v.ast.IntegerLiteral */ && v__type_resolver__ResolverInfo_is_comptime_selector_field_name(c->comptime, *(v__ast__SelectorExpr*)__as_cast(((*cond->_v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*cond->_v__ast__InfixExpr).left)._typ, 379), _S("indirections"))) { v__checker__ComptimeBranchSkipState _t21 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t21 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t21 }); } } } // Defer end return _t21; } else if (((*cond->_v__ast__InfixExpr).left)._typ == 380 /* v.ast.SizeOf */) { v__checker__ComptimeBranchSkipState _t22 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t22 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t22 }); } } } // Defer end return _t22; } v__checker__Checker_error(c, _S("invalid `$if` condition"), (*cond->_v__ast__InfixExpr).pos); break; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__plus: case v__token__Kind__minus: case v__token__Kind__mul: case v__token__Kind__div: case v__token__Kind__mod: case v__token__Kind__xor: case v__token__Kind__pipe: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__amp: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__left_shift: case v__token__Kind__right_shift: case v__token__Kind__unsigned_right_shift: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_interface: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { v__checker__Checker_error(c, _S("invalid `$if` condition"), (*cond->_v__ast__InfixExpr).pos); break; } } } } else if (cond->_typ == 358 /* v.ast.Ident */) { string cname = (*cond->_v__ast__Ident).name; should_record_ident = true; is_user_ident = false; ident_name = cname; if ((Array_string_contains(_const_v__ast__valid_comptime_if_os, cname))) { v__checker__ComptimeBranchSkipState ident_result = v__checker__ComptimeBranchSkipState__skip; if (!c->pref->output_cross_c) { _result_v__pref__OS _t23; if (_t23 = v__pref__os_from_string(cname), !_t23.is_error) { v__pref__OS cname_enum_val = *(v__pref__OS*)_t23.data; if (cname_enum_val == c->pref->os) { ident_result = v__checker__ComptimeBranchSkipState__eval; } } } #if defined(CUSTOM_DEFINE_trace_comptime_os_checks) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S(">>> ident_name: "), 0xfe10, {.d_s = ident_name}}, {_S(" | c.pref.os: "), 0xfe10, {.d_s = v__pref__OS_str(c->pref->os)}}, {_S(" | ident_result: "), 0xfe10, {.d_s = v__checker__ComptimeBranchSkipState_str(ident_result)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__checker__ComptimeBranchSkipState _t25 = ident_result; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t25 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t25 }); } } } // Defer end return _t25; } else if ((Array_string_contains(_const_v__ast__valid_comptime_if_compilers, cname))) { v__checker__ComptimeBranchSkipState _t26 = (v__pref__cc_from_string(cname) == c->pref->ccompiler_type ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t26 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t26 }); } } } // Defer end return _t26; } else if ((Array_string_contains(_const_v__ast__valid_comptime_if_platforms, cname))) { if (_SLIT_EQ(cname.str, cname.len, "aarch64")) { v__checker__Checker_note(c, _S("use `arm64` instead of `aarch64`"), pos); } if (_SLIT_EQ(cname.str, cname.len, "amd64")) { v__checker__ComptimeBranchSkipState _t27 = (c->pref->arch == v__pref__Arch__amd64 ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t27 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t27 }); } } } // Defer end return _t27; } else if (_SLIT_EQ(cname.str, cname.len, "i386")) { v__checker__ComptimeBranchSkipState _t28 = (c->pref->arch == v__pref__Arch__i386 ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t28 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t28 }); } } } // Defer end return _t28; } else if (_SLIT_EQ(cname.str, cname.len, "aarch64")) { v__checker__ComptimeBranchSkipState _t29 = (c->pref->arch == v__pref__Arch__arm64 ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t29 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t29 }); } } } // Defer end return _t29; } else if (_SLIT_EQ(cname.str, cname.len, "arm64")) { v__checker__ComptimeBranchSkipState _t30 = (c->pref->arch == v__pref__Arch__arm64 ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t30 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t30 }); } } } // Defer end return _t30; } else if (_SLIT_EQ(cname.str, cname.len, "arm32")) { v__checker__ComptimeBranchSkipState _t31 = (c->pref->arch == v__pref__Arch__arm32 ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t31 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t31 }); } } } // Defer end return _t31; } else if (_SLIT_EQ(cname.str, cname.len, "rv64")) { v__checker__ComptimeBranchSkipState _t32 = (c->pref->arch == v__pref__Arch__rv64 ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t32 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t32 }); } } } // Defer end return _t32; } else if (_SLIT_EQ(cname.str, cname.len, "rv32")) { v__checker__ComptimeBranchSkipState _t33 = (c->pref->arch == v__pref__Arch__rv32 ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t33 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t33 }); } } } // Defer end return _t33; } else { v__checker__ComptimeBranchSkipState _t34 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t34 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t34 }); } } } // Defer end return _t34; } } else if ((Array_string_contains(_const_v__ast__valid_comptime_if_cpu_features, cname))) { if (_SLIT_EQ(cname.str, cname.len, "x64")) { v__checker__ComptimeBranchSkipState _t35 = (c->pref->m64 ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t35 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t35 }); } } } // Defer end return _t35; } else if (_SLIT_EQ(cname.str, cname.len, "x32")) { v__checker__ComptimeBranchSkipState _t36 = (!c->pref->m64 ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t36 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t36 }); } } } // Defer end return _t36; } else { v__checker__ComptimeBranchSkipState _t37 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t37 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t37 }); } } } // Defer end return _t37; } } else if ((Array_string_contains(_const_v__ast__valid_comptime_if_other, cname))) { if (_SLIT_EQ(cname.str, cname.len, "apk")) { v__checker__ComptimeBranchSkipState _t38 = (c->pref->is_apk ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t38 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t38 }); } } } // Defer end return _t38; } else if (_SLIT_EQ(cname.str, cname.len, "js")) { v__checker__ComptimeBranchSkipState _t39 = (v__pref__Backend_is_js(c->pref->backend) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t39 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t39 }); } } } // Defer end return _t39; } else if (_SLIT_EQ(cname.str, cname.len, "debug")) { v__checker__ComptimeBranchSkipState _t40 = (c->pref->is_debug ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t40 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t40 }); } } } // Defer end return _t40; } else if (_SLIT_EQ(cname.str, cname.len, "prod")) { v__checker__ComptimeBranchSkipState _t41 = (c->pref->is_prod ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t41 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t41 }); } } } // Defer end return _t41; } else if (_SLIT_EQ(cname.str, cname.len, "profile")) { v__checker__ComptimeBranchSkipState _t42 = (c->pref->is_prof ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t42 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t42 }); } } } // Defer end return _t42; } else if (_SLIT_EQ(cname.str, cname.len, "test")) { v__checker__ComptimeBranchSkipState _t43 = (c->pref->is_test ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t43 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t43 }); } } } // Defer end return _t43; } else if (_SLIT_EQ(cname.str, cname.len, "musl")) { v__checker__ComptimeBranchSkipState _t44 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t44 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t44 }); } } } // Defer end return _t44; } else if (_SLIT_EQ(cname.str, cname.len, "glibc")) { v__checker__ComptimeBranchSkipState _t45 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t45 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t45 }); } } } // Defer end return _t45; } else if (_SLIT_EQ(cname.str, cname.len, "threads")) { v__checker__ComptimeBranchSkipState _t46 = (c->table->gostmts > 0 ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t46 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t46 }); } } } // Defer end return _t46; } else if (_SLIT_EQ(cname.str, cname.len, "prealloc")) { v__checker__ComptimeBranchSkipState _t47 = (c->pref->prealloc ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t47 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t47 }); } } } // Defer end return _t47; } else if (_SLIT_EQ(cname.str, cname.len, "no_bounds_checking")) { v__checker__ComptimeBranchSkipState _t48 = ((Array_string_contains(c->pref->compile_defines_all, cname)) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t48 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t48 }); } } } // Defer end return _t48; } else if (_SLIT_EQ(cname.str, cname.len, "autofree")) { v__checker__ComptimeBranchSkipState _t49 = (c->pref->autofree ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t49 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t49 }); } } } // Defer end return _t49; } else if (_SLIT_EQ(cname.str, cname.len, "freestanding")) { v__checker__ComptimeBranchSkipState _t50 = (c->pref->is_bare && !c->pref->output_cross_c ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t50 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t50 }); } } } // Defer end return _t50; } else if (_SLIT_EQ(cname.str, cname.len, "interpreter")) { v__checker__ComptimeBranchSkipState _t51 = (c->pref->backend == v__pref__Backend__interpret ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t51 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t51 }); } } } // Defer end return _t51; } else { v__checker__ComptimeBranchSkipState _t52 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t52 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t52 }); } } } // Defer end return _t52; } } else if (!(Array_string_contains(c->pref->compile_defines_all, cname))) { if (_SLIT_EQ(cname.str, cname.len, "linux_or_macos")) { v__checker__Checker_error(c, _S("linux_or_macos is deprecated, use `$if linux || macos {` instead"), (*cond->_v__ast__Ident).pos); v__checker__ComptimeBranchSkipState _t53 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t53 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t53 }); } } } // Defer end return _t53; } v__ast__Type typ = v__checker__Checker_unwrap_generic(c, v__checker__Checker_expr(c, cond)); if (!(((*cond->_v__ast__Ident).obj)._typ == 422 /* v.ast.Var */ || ((*cond->_v__ast__Ident).obj)._typ == 420 /* v.ast.ConstField */ || ((*cond->_v__ast__Ident).obj)._typ == 421 /* v.ast.GlobalField */)) { if (!c->inside_ct_attr) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown var: `"), 0xfe10, {.d_s = cname}}, {_S("`"), 0, { .d_c = 0 }}})), pos); } v__checker__ComptimeBranchSkipState _t54 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t54 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t54 }); } } } // Defer end return _t54; } _result_v__ast__Expr _t55 = v__checker__Checker_find_obj_definition(c, (*cond->_v__ast__Ident).obj); if (_t55.is_error) { IError err = _t55.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), (*cond->_v__ast__Ident).pos); v__checker__ComptimeBranchSkipState _t56 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t56 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t56 }); } } } // Defer end return _t56; } v__ast__Expr expr = (*(v__ast__Expr*)_t55.data); if (!v__checker__Checker_check_types(c, typ, _const_v__ast__bool_type)) { string type_name = v__ast__Table_type_to_str(c->table, typ); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("non-bool type `"), 0xfe10, {.d_s = type_name}}, {_S("` used as $if condition"), 0, { .d_c = 0 }}})), (*cond->_v__ast__Ident).pos); } v__checker__ComptimeBranchSkipState _t57 = ((*(v__ast__BoolLiteral*)__as_cast((expr)._v__ast__BoolLiteral,(expr)._typ, 342)).val ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t57 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t57 }); } } } // Defer end return _t57; } } else if (cond->_typ == 349 /* v.ast.ComptimeCall */) { if ((*cond->_v__ast__ComptimeCall).kind == v__ast__ComptimeCallKind__pkgconfig) { _result_v__pkgconfig__Main_ptr _t58 = v__pkgconfig__main(new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){string_clone((*cond->_v__ast__ComptimeCall).args_var)}))); if (_t58.is_error) { IError err = _t58.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), (*cond->_v__ast__ComptimeCall).pos); v__checker__ComptimeBranchSkipState _t59 = v__checker__ComptimeBranchSkipState__skip; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t59 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t59 }); } } } // Defer end return _t59; } v__pkgconfig__Main* m = (*(v__pkgconfig__Main**)_t58.data); _result_string _t60 = v__pkgconfig__Main_run(m); if (_t60.is_error) { IError err = _t60.err; v__checker__ComptimeBranchSkipState _t61 = v__checker__ComptimeBranchSkipState__skip; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t61 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t61 }); } } } // Defer end return _t61; } ; v__checker__ComptimeBranchSkipState _t62 = v__checker__ComptimeBranchSkipState__eval; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t62 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t62 }); } } } // Defer end return _t62; } if ((*cond->_v__ast__ComptimeCall).kind == v__ast__ComptimeCallKind__d) { v__ast__Type t = v__checker__Checker_expr(c, cond); if (t != _const_v__ast__bool_type) { v__checker__Checker_error(c, _S("inside $if, only $d() expressions that return bool are allowed"), (*cond->_v__ast__ComptimeCall).pos); v__checker__ComptimeBranchSkipState _t63 = v__checker__ComptimeBranchSkipState__skip; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t63 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t63 }); } } } // Defer end return _t63; } v__checker__ComptimeBranchSkipState _t64 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t64 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t64 }); } } } // Defer end return _t64; } v__checker__ComptimeBranchSkipState _t65 = v__checker__ComptimeBranchSkipState__eval; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t65 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t65 }); } } } // Defer end return _t65; } else if (cond->_typ == 379 /* v.ast.SelectorExpr */) { if (v__type_resolver__ResolverInfo_check_comptime_is_field_selector(c->comptime, (*cond->_v__ast__SelectorExpr))) { if (v__type_resolver__ResolverInfo_check_comptime_is_field_selector_bool(c->comptime, (*cond->_v__ast__SelectorExpr))) { bool ret_bool = v__type_resolver__TypeResolver_get_comptime_selector_bool_field(&c->type_resolver, (*cond->_v__ast__SelectorExpr).field_name); v__checker__ComptimeBranchSkipState _t66 = (ret_bool ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t66 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t66 }); } } } // Defer end return _t66; } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("unknown field `"), 0xfe10, {.d_s = (*cond->_v__ast__SelectorExpr).field_name}}, {_S("` from "), 0xfe10, {.d_s = c->comptime->comptime_for_field_var}}, {_SLIT0, 0, { .d_c = 0 }}})), (*cond->_v__ast__SelectorExpr).pos); } v__checker__ComptimeBranchSkipState _t67 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t67 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t67 }); } } } // Defer end return _t67; } else { v__checker__Checker_error(c, _S("invalid `$if` condition"), pos); } v__checker__ComptimeBranchSkipState _t68 = v__checker__ComptimeBranchSkipState__unknown; // Defer begin if (v__checker__Checker_comptime_if_cond_defer_0) { if (should_record_ident) { if (is_user_ident) { map_set(&c->ct_user_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t68 }); } else { map_set(&c->ct_system_defines, &(string[]){ident_name}, &(v__checker__ComptimeBranchSkipState[]) { _t68 }); } } } // Defer end return _t68; } VV_LOC void v__checker__Checker_push_new_comptime_info(v__checker__Checker* c) { array_push((array*)&c->type_resolver.info_stack, _MOV((v__type_resolver__ResolverInfo[]){ ((v__type_resolver__ResolverInfo){ .saved_type_map = map_clone(&c->type_resolver.type_map), .comptime_loop_id = 0, .inside_comptime_for = c->comptime->inside_comptime_for, .inside_comptime_if = c->comptime->inside_comptime_if, .has_different_types = c->comptime->has_different_types, .comptime_for_variant_var = c->comptime->comptime_for_variant_var, .comptime_for_field_var = c->comptime->comptime_for_field_var, .comptime_for_field_type = c->comptime->comptime_for_field_type, .comptime_for_field_value = c->comptime->comptime_for_field_value, .comptime_for_enum_var = c->comptime->comptime_for_enum_var, .comptime_for_attr_var = (string){.str=(byteptr)"", .is_lit=1}, .comptime_for_method_var = c->comptime->comptime_for_method_var, .comptime_for_method = c->comptime->comptime_for_method, .comptime_for_method_ret_type = c->comptime->comptime_for_method_ret_type, .comptime_for_method_param_var = (string){.str=(byteptr)"", .is_lit=1}, }) })); } VV_LOC void v__checker__Checker_pop_comptime_info(v__checker__Checker* c) { v__type_resolver__ResolverInfo old = (*(v__type_resolver__ResolverInfo*)array_pop(&c->type_resolver.info_stack)); c->type_resolver.type_map = map_clone(&old.saved_type_map); c->comptime->inside_comptime_for = old.inside_comptime_for; c->comptime->inside_comptime_if = old.inside_comptime_if; c->comptime->has_different_types = old.has_different_types; c->comptime->comptime_for_variant_var = old.comptime_for_variant_var; c->comptime->comptime_for_field_var = old.comptime_for_field_var; c->comptime->comptime_for_field_type = old.comptime_for_field_type; c->comptime->comptime_for_field_value = old.comptime_for_field_value; c->comptime->comptime_for_enum_var = old.comptime_for_enum_var; c->comptime->comptime_for_method_var = old.comptime_for_method_var; c->comptime->comptime_for_method = old.comptime_for_method; c->comptime->comptime_for_method_ret_type = old.comptime_for_method_ret_type; } VV_LOC bool v__checker__overflows_i32(i64 val) { return val > _const_max_i32 || val < _const_min_i32; } VV_LOC v__ast__Type v__checker__Checker_array_init(v__checker__Checker* c, v__ast__ArrayInit* node) { v__ast__Type elem_type = _const_v__ast__void_type; v__ast__Type unwrap_elem_type = v__checker__Checker_unwrap_generic(c, node->elem_type); if (v__ast__Type_has_flag(node->typ, v__ast__TypeFlag__generic)) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__checker__Checker_unwrap_generic(c, node->typ)}, &(bool[]) { true }); } if (c->pref->warn_about_allocs) { v__checker__Checker_warn_alloc(c, _S("array initialization"), node->pos); } if (node->typ != _const_v__ast__void_type) { if (node->elem_type != 0) { v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(c->table, node->elem_type); v__checker__Checker_check_any_type(c, node->elem_type, elem_sym, node->pos); if (v__ast__Type_has_flag(node->typ, v__ast__TypeFlag__option) && (node->has_cap || node->has_len)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("Option array `"), 0xfe10, {.d_s = elem_sym->name}}, {_S("` cannot have initializers"), 0, { .d_c = 0 }}})), node->pos); } if (elem_sym->info._typ == 518 /* v.ast.Struct */) { if ((*elem_sym->info._v__ast__Struct).generic_types.len > 0 && (*elem_sym->info._v__ast__Struct).concrete_types.len == 0 && !v__ast__Type_has_flag(node->elem_type, v__ast__TypeFlag__generic)) { if (c->table->cur_concrete_types.len == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic struct `"), 0xfe10, {.d_s = elem_sym->name}}, {_S("` must specify type parameter, e.g. "), 0xfe10, {.d_s = elem_sym->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), node->elem_type_pos); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic struct `"), 0xfe10, {.d_s = elem_sym->name}}, {_S("` must specify type parameter, e.g. "), 0xfe10, {.d_s = elem_sym->name}}, {_S("[T]"), 0, { .d_c = 0 }}})), node->elem_type_pos); } } } else if (elem_sym->info._typ == 542 /* v.ast.Interface */) { if ((*elem_sym->info._v__ast__Interface).generic_types.len > 0 && (*elem_sym->info._v__ast__Interface).concrete_types.len == 0 && !v__ast__Type_has_flag(node->elem_type, v__ast__TypeFlag__generic)) { if (c->table->cur_concrete_types.len == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic interface `"), 0xfe10, {.d_s = elem_sym->name}}, {_S("` must specify type parameter, e.g. "), 0xfe10, {.d_s = elem_sym->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), node->elem_type_pos); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic interface `"), 0xfe10, {.d_s = elem_sym->name}}, {_S("` must specify type parameter, e.g. "), 0xfe10, {.d_s = elem_sym->name}}, {_S("[T]"), 0, { .d_c = 0 }}})), node->elem_type_pos); } } } else if (elem_sym->info._typ == 544 /* v.ast.SumType */) { if ((*elem_sym->info._v__ast__SumType).generic_types.len > 0 && (*elem_sym->info._v__ast__SumType).concrete_types.len == 0 && !v__ast__Type_has_flag(node->elem_type, v__ast__TypeFlag__generic)) { if (c->table->cur_concrete_types.len == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic sumtype `"), 0xfe10, {.d_s = elem_sym->name}}, {_S("` must specify type parameter, e.g. "), 0xfe10, {.d_s = elem_sym->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), node->elem_type_pos); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic sumtype `"), 0xfe10, {.d_s = elem_sym->name}}, {_S("` must specify type parameter, e.g. "), 0xfe10, {.d_s = elem_sym->name}}, {_S("[T]"), 0, { .d_c = 0 }}})), node->elem_type_pos); } } } else if (elem_sym->info._typ == 539 /* v.ast.Alias */) { if (fast_string_eq(elem_sym->name, _S("byte"))) { v__checker__Checker_error(c, _S("byte is deprecated, use u8 instead"), node->elem_type_pos); } } else if (elem_sym->info._typ == 514 /* v.ast.Map */) { v__checker__Checker_markused_array_method(c, !c->is_builtin_mod, _S("map")); } else { } } if (node->exprs.len == 0) { if (node->has_cap) { v__checker__Checker_check_array_init_para_type(c, _S("cap"), &node->cap_expr, node->pos); } if (node->has_len) { v__checker__Checker_check_array_init_para_type(c, _S("len"), &node->len_expr, node->pos); } } if (node->has_init) { v__checker__Checker_check_array_init_default_expr(c, node); } if (node->has_len) { v__ast__Type len_typ = v__checker__Checker_check_expr_option_or_result_call(c, node->len_expr, v__checker__Checker_expr(c, &node->len_expr)); if (v__ast__Type_has_flag(len_typ, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("cannot use unwrapped Option as length"), v__ast__Expr_pos(node->len_expr)); } if (!node->has_init) { _result_void _t1 = v__checker__Checker_check_elements_initialized(c, unwrap_elem_type); if (_t1.is_error) { IError err = _t1.err; v__checker__Checker_warn(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(", therefore `len:` cannot be used (unless inside `unsafe`, or if you also use `init:`)"), 0, { .d_c = 0 }}})), node->pos); ; } ; } } if (node->has_cap) { v__ast__Type cap_typ = v__checker__Checker_check_expr_option_or_result_call(c, node->cap_expr, v__checker__Checker_expr(c, &node->cap_expr)); if (v__ast__Type_has_flag(cap_typ, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("cannot use unwrapped Option as capacity"), v__ast__Expr_pos(node->cap_expr)); } } v__checker__Checker_ensure_type_exists(c, node->elem_type, node->elem_type_pos); if (v__ast__Type_has_flag(node->typ, v__ast__TypeFlag__generic) && c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len == 0) { v__checker__Checker_error(c, _S("generic struct cannot be used in non-generic function"), node->pos); } if (node->has_len) { v__checker__Checker_check_elements_ref_fields_initialized(c, unwrap_elem_type, (voidptr)&node->pos); } if (!node->is_fixed && node->expr_types.len == 0) { for (int _t2 = 0; _t2 < node->exprs.len; ++_t2) { v__ast__Expr* expr = ((v__ast__Expr*)node->exprs.data) + _t2; v__ast__Type typ = v__checker__Checker_expr(c, expr); _result_void _t3 = v__checker__Checker_check_expected(c, typ, node->elem_type); if (_t3.is_error) { IError err = _t3.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid array element: "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_pos(*expr)); ; } ; array_push((array*)&node->expr_types, _MOV((v__ast__Type[]){ typ })); } } return node->typ; } if (node->is_fixed) { v__checker__Checker_ensure_type_exists(c, node->elem_type, node->elem_type_pos); if (!c->is_builtin_mod) { _result_void _t6 = v__checker__Checker_check_elements_initialized(c, unwrap_elem_type); if (_t6.is_error) { IError err = _t6.err; v__checker__Checker_warn(c, str_intp(2, _MOV((StrIntpData[]){{_S("fixed "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" (unless inside `unsafe`)"), 0, { .d_c = 0 }}})), node->pos); ; } ; } v__checker__Checker_check_elements_ref_fields_initialized(c, unwrap_elem_type, (voidptr)&node->pos); } if (node->exprs.len == 0) { if (c->expected_type == _const_v__ast__void_type) { if (c->expected_or_type != _const_v__ast__void_type) { c->expected_type = c->expected_or_type; } else if (c->expected_expr_type != _const_v__ast__void_type) { c->expected_type = c->expected_expr_type; } } v__ast__TypeSymbol* type_sym = v__ast__Table_sym(c->table, c->expected_type); if (type_sym->kind != v__ast__Kind__array || v__ast__TypeSymbol_array_info(type_sym).elem_type == _const_v__ast__void_type) { v__checker__Checker_error(c, _S("array_init: no type specified (maybe: `[]Type{}` instead of `[]`)"), node->pos); return _const_v__ast__void_type; } v__ast__Array array_info = v__ast__TypeSymbol_array_info(type_sym); node->elem_type = array_info.elem_type; return v__ast__Type_clear_option_and_result((v__ast__Type_has_flag(c->expected_type, v__ast__TypeFlag__shared_f) ? (v__ast__Type_deref(v__ast__Type_clear_flag(c->expected_type, v__ast__TypeFlag__shared_f))) : (c->expected_type))); } if (node->exprs.len > 0 && node->elem_type == _const_v__ast__void_type) { v__ast__Type expected_value_type = _const_v__ast__void_type; bool expecting_interface_array = false; bool expecting_sumtype_array = false; bool is_first_elem_ptr = false; if (c->expected_type != 0) { expected_value_type = v__ast__Table_value_type(c->table, c->expected_type); v__ast__TypeSymbol* expected_value_sym = v__ast__Table_sym(c->table, expected_value_type); if (expected_value_sym->kind == v__ast__Kind__interface) { expecting_interface_array = true; } else if (expected_value_sym->kind == v__ast__Kind__sum_type) { expecting_sumtype_array = true; } } for (int i = 0; i < node->exprs.len; ++i) { v__ast__Expr* expr = ((v__ast__Expr*)node->exprs.data) + i; v__ast__Type typ = _const_v__ast__void_type; if ((expr)->_typ == 338 /* v.ast.ArrayInit */) { v__ast__Type old_expected_type = c->expected_type; c->expected_type = v__ast__Table_value_type(c->table, c->expected_type); typ = v__checker__Checker_check_expr_option_or_result_call(c, *expr, v__checker__Checker_expr(c, expr)); c->expected_type = old_expected_type; } else { if (c->expected_type == _const_v__ast__none_type && (expr)->_typ == 371 /* v.ast.None */) { v__checker__Checker_error(c, _S("invalid expression `none`, it is not an array of Option type"), v__ast__Expr_pos(*expr)); continue; } typ = v__checker__Checker_check_expr_option_or_result_call(c, *expr, v__checker__Checker_expr(c, expr)); } if ((expr)->_typ == 344 /* v.ast.CallExpr */) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, typ); if (ret_sym->kind == v__ast__Kind__array_fixed) { typ = v__checker__Checker_cast_fixed_array_ret(c, typ, *ret_sym); } node->has_callexpr = true; } if (typ == _const_v__ast__void_type) { v__checker__Checker_error(c, _S("invalid void array element type"), v__ast__Expr_pos(*expr)); } array_push((array*)&node->expr_types, _MOV((v__ast__Type[]){ typ })); if (expecting_interface_array) { if (i == 0) { elem_type = expected_value_type; c->expected_type = elem_type; v__checker__Checker_type_implements(c, typ, elem_type, v__ast__Expr_pos(*expr)); } if (!v__ast__Type_is_any_kind_of_pointer(typ) && !c->inside_unsafe) { v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, typ); if (typ_sym->kind != v__ast__Kind__interface) { v__checker__Checker_mark_as_referenced(c, expr, true); } } continue; } else if (expecting_sumtype_array) { if (i == 0) { if (v__ast__Table_is_sumtype_or_in_variant(c->table, expected_value_type, v__ast__mktyp(typ))) { elem_type = expected_value_type; } else { if (v__ast__Expr_is_auto_deref_var(*expr)) { elem_type = v__ast__mktyp(v__ast__Type_deref(typ)); } else { elem_type = v__ast__mktyp(typ); } } c->expected_type = elem_type; } continue; } if (i == 0) { if (v__ast__Expr_is_auto_deref_var(*expr)) { elem_type = v__ast__mktyp(v__ast__Type_deref(typ)); } else { elem_type = v__ast__mktyp(typ); } if (v__ast__Type_is_ptr(typ) && c->in_for_count == 0) { is_first_elem_ptr = true; } c->expected_type = elem_type; continue; } else { if (!v__ast__Type_is_any_kind_of_pointer(typ) && !v__ast__Type_is_int(typ) && is_first_elem_ptr) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot have non-pointer of type `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, typ)}}, {_S("` in a pointer array of type `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, elem_type)}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*expr)); } } if ((expr)->_typ != 386 /* v.ast.TypeNode */) { if (v__ast__Table_type_kind(c->table, elem_type) == v__ast__Kind__interface) { if (v__checker__Checker_type_implements(c, typ, elem_type, v__ast__Expr_pos(*expr))) { continue; } } _result_void _t10 = v__checker__Checker_check_expected(c, typ, elem_type); if (_t10.is_error) { IError err = _t10.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid array element: "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_pos(*expr)); ; } ; if (!v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__option) && (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option) || v__ast__Type_idx(typ) == 20)) { multi_return_string_string mr_8884 = v__checker__Checker_get_string_names_of(c, typ, elem_type); string typ_str = mr_8884.arg0; string elem_type_str = mr_8884.arg1; if (v__ast__Type_idx(typ) == 20) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = typ_str}}, {_S("` as `"), 0xfe10, {.d_s = elem_type_str}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*expr)); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = typ_str}}, {_S("` as `"), 0xfe10, {.d_s = elem_type_str}}, {_S("`, it must be unwrapped first"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*expr)); } } else if (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__option) && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__option) && v__ast__Type_idx(typ) != 20 && !v__ast__Expr_is_pure_literal(*expr)) { multi_return_string_string mr_9336 = v__checker__Checker_get_string_names_of(c, typ, elem_type); string typ_str = mr_9336.arg0; string elem_type_str = mr_9336.arg1; v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = typ_str}}, {_S("` as `"), 0xfe10, {.d_s = elem_type_str}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*expr)); } } } if (node->is_fixed) { int idx = v__ast__Table_find_or_register_array_fixed(c->table, elem_type, node->exprs.len, _const_v__ast__empty_expr, false); if (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__generic)) { node->typ = v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); } else { node->typ = v__ast__new_type(idx); } } else { int idx = v__ast__Table_find_or_register_array(c->table, elem_type); if (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__generic)) { node->typ = v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); } else { node->typ = v__ast__new_type(idx); } } node->elem_type = elem_type; } else if (node->is_fixed && node->exprs.len == 1 && node->elem_type != _const_v__ast__void_type) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, node->typ); if ((sym->info)._typ != 549 /* v.ast.ArrayFixed */ || v__checker__Checker_array_fixed_has_unresolved_size(c, (v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549))) { v__ast__Expr size_expr = (*(v__ast__Expr*)array_get(node->exprs, 0)); node->typ = v__checker__Checker_eval_array_fixed_sizes(c, &size_expr, 0, node->elem_type); if (node->is_option) { node->typ = v__ast__Type_set_flag(node->typ, v__ast__TypeFlag__option); } node->elem_type = (({ v__ast__TypeInfo _t11 = v__ast__Table_sym(c->table, node->typ)->info; *(v__ast__ArrayFixed*)__as_cast(_t11._v__ast__ArrayFixed,_t11._typ, 549); })).elem_type; } if (node->has_init) { v__checker__Checker_check_array_init_default_expr(c, node); } } return node->typ; } VV_LOC void v__checker__Checker_check_array_init_default_expr(v__checker__Checker* c, v__ast__ArrayInit* node) { v__ast__Expr init_expr = node->init_expr; c->expected_type = node->elem_type; v__ast__Type init_typ = v__checker__Checker_check_expr_option_or_result_call(c, init_expr, v__checker__Checker_expr(c, &init_expr)); node->init_type = init_typ; if (!v__ast__Type_has_flag(node->elem_type, v__ast__TypeFlag__option) && v__ast__Type_has_flag(init_typ, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("cannot use unwrapped Option as initializer"), v__ast__Expr_pos(init_expr)); } if (v__ast__Type_is_number(node->elem_type) && v__ast__Type_is_number(init_typ)) { return; } _result_void _t1 = v__checker__Checker_check_expected(c, init_typ, node->elem_type); if (_t1.is_error) { IError err = _t1.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), v__ast__Expr_pos(init_expr)); ; } ; } VV_LOC void v__checker__Checker_check_array_init_para_type(v__checker__Checker* c, string para, v__ast__Expr* expr, v__token__Pos pos) { v__ast__TypeSymbol* sym = v__ast__Table_final_sym(c->table, v__checker__Checker_unwrap_generic(c, v__checker__Checker_expr(c, expr))); if (!(sym->kind == v__ast__Kind__int || sym->kind == v__ast__Kind__int_literal)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("array "), 0xfe10, {.d_s = para}}, {_S(" needs to be an int"), 0, { .d_c = 0 }}})), pos); } if ((expr)->_typ == 363 /* v.ast.IntegerLiteral */) { v__ast__IntegerLiteral lit = *(v__ast__IntegerLiteral*)__as_cast((expr)->_v__ast__IntegerLiteral,(expr)->_typ, 363); if (string_int(lit.val) < 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("array "), 0xfe10, {.d_s = para}}, {_S(" can not be negative"), 0, { .d_c = 0 }}})), lit.pos); } } } VV_LOC v__ast__Type v__checker__Checker_eval_array_fixed_sizes(v__checker__Checker* c, v__ast__Expr* size_expr, int size, v__ast__Type elem_type) { v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(c->table, elem_type); v__ast__TypeInfo elem_info = elem_sym->info; v__ast__Type _t1; /* if prepend */ if (elem_sym->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((elem_info)._v__ast__ArrayFixed,(elem_info)._typ, 549); v__ast__Expr elem_size_expr = info.size_expr; _t1 = v__checker__Checker_eval_array_fixed_sizes(c, &elem_size_expr, info.size, info.elem_type); } else { _t1 = elem_type; } v__ast__Type new_elem_typ = _t1; i64 fixed_size = ((i64)(size)); if (fixed_size <= 0) { v__checker__Checker_expr(c, size_expr); if (size_expr->_typ == 363 /* v.ast.IntegerLiteral */) { fixed_size = string_int((*size_expr->_v__ast__IntegerLiteral).val); } else if (size_expr->_typ == 349 /* v.ast.ComptimeCall */) { if ((*size_expr->_v__ast__ComptimeCall).kind == v__ast__ComptimeCallKind__d) { _result_void _t2 = v__ast__ComptimeCall_resolve_compile_value(&(*size_expr->_v__ast__ComptimeCall), c->pref->compile_values); if (_t2.is_error) { IError err = _t2.err; v__checker__Checker_error(c, IError_name_table[err._typ]._method_msg(err._object), (*size_expr->_v__ast__ComptimeCall).pos); ; } ; if ((*size_expr->_v__ast__ComptimeCall).result_type != _const_v__ast__i64_type) { v__checker__Checker_error(c, _S("value from $d() can only be positive integers when used as fixed size"), (*size_expr->_v__ast__ComptimeCall).pos); } fixed_size = string_int((*size_expr->_v__ast__ComptimeCall).compile_value); } else { v__checker__Checker_error(c, _S("only $d() can be used for fixed size arrays"), (*size_expr->_v__ast__ComptimeCall).pos); } } else if (size_expr->_typ == 345 /* v.ast.CastExpr */) { if (!v__ast__Type_is_pure_int((*size_expr->_v__ast__CastExpr).typ)) { v__checker__Checker_error(c, _S("only integer types are allowed"), (*size_expr->_v__ast__CastExpr).pos); } if ((*size_expr->_v__ast__CastExpr).expr._typ == 363 /* v.ast.IntegerLiteral */) { fixed_size = string_int((*(*size_expr->_v__ast__CastExpr).expr._v__ast__IntegerLiteral).val); } else if ((*size_expr->_v__ast__CastExpr).expr._typ == 355 /* v.ast.EnumVal */) { _option_i64 _t3; if (_t3 = v__ast__Table_find_enum_field_val(c->table, (*(*size_expr->_v__ast__CastExpr).expr._v__ast__EnumVal).enum_name, (*(*size_expr->_v__ast__CastExpr).expr._v__ast__EnumVal).val), _t3.state == 0) { i64 val = *(i64*)_t3.data; fixed_size = val; } } else { } } else if (size_expr->_typ == 355 /* v.ast.EnumVal */) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*size_expr->_v__ast__EnumVal).enum_name}}, {_S("."), 0xfe10, {.d_s = (*size_expr->_v__ast__EnumVal).val}}, {_S(" has to be casted to integer to be used as size"), 0, { .d_c = 0 }}})), (*size_expr->_v__ast__EnumVal).pos); } else if (size_expr->_typ == 358 /* v.ast.Ident */) { if (((*size_expr->_v__ast__Ident).obj)._typ == 420 /* v.ast.ConstField */) { if (((*(*size_expr->_v__ast__Ident).obj._v__ast__ConstField).expr)._typ == 355 /* v.ast.EnumVal */) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*(*(*size_expr->_v__ast__Ident).obj._v__ast__ConstField).expr._v__ast__EnumVal).enum_name}}, {_S("."), 0xfe10, {.d_s = (*(*(*size_expr->_v__ast__Ident).obj._v__ast__ConstField).expr._v__ast__EnumVal).val}}, {_S(" has to be casted to integer to be used as size"), 0, { .d_c = 0 }}})), (*size_expr->_v__ast__Ident).pos); } if (((*(*size_expr->_v__ast__Ident).obj._v__ast__ConstField).expr)._typ == 345 /* v.ast.CastExpr */) { if (!v__ast__Type_is_pure_int((*(*(*size_expr->_v__ast__Ident).obj._v__ast__ConstField).expr._v__ast__CastExpr).typ)) { v__checker__Checker_error(c, _S("only integer types are allowed"), (*size_expr->_v__ast__Ident).pos); } if (((*(*(*size_expr->_v__ast__Ident).obj._v__ast__ConstField).expr._v__ast__CastExpr).expr)._typ == 363 /* v.ast.IntegerLiteral */) { _option_v__ast__ComptTimeConstValue _t4; if (_t4 = v__checker__Checker_eval_comptime_const_expr(c, (*(*(*size_expr->_v__ast__Ident).obj._v__ast__ConstField).expr._v__ast__CastExpr).expr, 0), _t4.state == 0) { v__ast__ComptTimeConstValue comptime_value = *(v__ast__ComptTimeConstValue*)_t4.data; _option_i64 _t5 = v__ast__ComptTimeConstValue_i64(comptime_value); if (_t5.state != 0) { IError err = _t5.err; *(i64*) _t5.data = fixed_size; } fixed_size = (*(i64*)_t5.data); } } if (((*(*(*size_expr->_v__ast__Ident).obj._v__ast__ConstField).expr._v__ast__CastExpr).expr)._typ == 362 /* v.ast.InfixExpr */) { _option_v__ast__ComptTimeConstValue _t6; if (_t6 = v__checker__Checker_eval_comptime_const_expr(c, (*(*(*size_expr->_v__ast__Ident).obj._v__ast__ConstField).expr._v__ast__CastExpr).expr, 0), _t6.state == 0) { v__ast__ComptTimeConstValue comptime_value = *(v__ast__ComptTimeConstValue*)_t6.data; _option_i64 _t7 = v__ast__ComptTimeConstValue_i64(comptime_value); if (_t7.state != 0) { IError err = _t7.err; *(i64*) _t7.data = fixed_size; } fixed_size = (*(i64*)_t7.data); } } } _option_v__ast__ComptTimeConstValue _t8; if (_t8 = v__checker__Checker_eval_comptime_const_expr(c, (*(*size_expr->_v__ast__Ident).obj._v__ast__ConstField).expr, 0), _t8.state == 0) { v__ast__ComptTimeConstValue comptime_value = *(v__ast__ComptTimeConstValue*)_t8.data; _option_i64 _t9 = v__ast__ComptTimeConstValue_i64(comptime_value); if (_t9.state != 0) { IError err = _t9.err; *(i64*) _t9.data = fixed_size; } fixed_size = (*(i64*)_t9.data); } } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("non-constant array bound `"), 0xfe10, {.d_s = (*size_expr->_v__ast__Ident).name}}, {_S("`"), 0, { .d_c = 0 }}})), (*size_expr->_v__ast__Ident).pos); } } else if (size_expr->_typ == 362 /* v.ast.InfixExpr */) { _option_v__ast__ComptTimeConstValue _t10; if (_t10 = v__checker__Checker_eval_comptime_const_expr(c, v__ast__InfixExpr_to_sumtype_v__ast__Expr(&(*size_expr->_v__ast__InfixExpr)), 0), _t10.state == 0) { v__ast__ComptTimeConstValue comptime_value = *(v__ast__ComptTimeConstValue*)_t10.data; _option_i64 _t11 = v__ast__ComptTimeConstValue_i64(comptime_value); if (_t11.state != 0) { IError err = _t11.err; *(i64*) _t11.data = fixed_size; } fixed_size = (*(i64*)_t11.data); } } else { v__checker__Checker_error(c, _S("fixed array size cannot use non-constant value"), v__ast__Expr_pos(*size_expr)); } if (fixed_size <= 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("fixed size cannot be zero or negative (fixed_size: "), 0xfe09, {.d_i64 = fixed_size}}, {_S(")"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*size_expr)); } } int idx = v__ast__Table_find_or_register_array_fixed(c->table, new_elem_typ, ((int)(fixed_size)), *size_expr, false); return (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__generic) ? (v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic)) : (v__ast__new_type(idx))); } VV_LOC bool v__checker__Checker_array_fixed_has_unresolved_size(v__checker__Checker* c, v__ast__ArrayFixed* info) { if (info->size <= 0) { return true; } v__ast__Type elem_type = info->elem_type; v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(c->table, elem_type); for (;;) { if ((elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { if ((*elem_sym->info._v__ast__ArrayFixed).size <= 0) { return true; } elem_type = (*elem_sym->info._v__ast__ArrayFixed).elem_type; elem_sym = v__ast__Table_sym(c->table, elem_type); } else { break; } } return false; } VV_LOC v__ast__Type v__checker__Checker_map_init(v__checker__Checker* c, v__ast__MapInit* node) { if (node->keys.len == 0 && node->vals.len == 0 && !node->has_update_expr && node->typ == 0) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, c->expected_type); if (sym->kind == v__ast__Kind__map) { v__ast__Map info = v__ast__TypeSymbol_map_info(sym); node->typ = v__ast__Type_clear_option_and_result(c->expected_type); node->key_type = info.key_type; node->value_type = info.value_type; return node->typ; } else if ((sym->info)._typ == 518 /* v.ast.Struct */) { string msg = ((*sym->info._v__ast__Struct).is_anon ? (_S("`{}` cannot be used to initialize anonymous structs. Use `struct{}` instead.")) : (str_intp(2, _MOV((StrIntpData[]){{_S("`{}` can not be used for initialising empty structs any more. Use `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, c->expected_type)}}, {_S("{}` instead."), 0, { .d_c = 0 }}})))); v__checker__Checker_error(c, msg, node->pos); if ((*sym->info._v__ast__Struct).is_anon) { return c->expected_type; } } else { v__checker__Checker_error(c, _S("invalid empty map initialisation syntax, use e.g. map[string]int{} instead"), node->pos); } return _const_v__ast__void_type; } if (node->typ != 0) { v__ast__Map info = v__ast__TypeSymbol_map_info(v__ast__Table_sym(c->table, node->typ)); if (v__ast__Type_has_flag(node->typ, v__ast__TypeFlag__generic)) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__checker__Checker_unwrap_generic(c, node->typ)}, &(bool[]) { true }); } if (info.value_type != 0) { if (v__ast__Type_has_flag(info.value_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("cannot use Result type as map value type"), node->pos); } v__ast__TypeSymbol* val_sym = v__ast__Table_sym(c->table, info.value_type); if (val_sym->kind == v__ast__Kind__struct) { v__ast__Struct val_info = *(v__ast__Struct*)__as_cast((val_sym->info)._v__ast__Struct,(val_sym->info)._typ, 518); if (val_info.generic_types.len > 0 && val_info.concrete_types.len == 0 && !v__ast__Type_has_flag(info.value_type, v__ast__TypeFlag__generic)) { if (c->table->cur_concrete_types.len == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic struct `"), 0xfe10, {.d_s = val_sym->name}}, {_S("` must specify type parameter, e.g. "), 0xfe10, {.d_s = val_sym->name}}, {_S("[int]"), 0, { .d_c = 0 }}})), node->pos); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic struct `"), 0xfe10, {.d_s = val_sym->name}}, {_S("` must specify type parameter, e.g. "), 0xfe10, {.d_s = val_sym->name}}, {_S("[T]"), 0, { .d_c = 0 }}})), node->pos); } } } else if ((val_sym->info)._typ == 553 /* v.ast.FnType */) { for (int _t4 = 0; _t4 < (*val_sym->info._v__ast__FnType).func.params.len; ++_t4) { v__ast__Param param = ((v__ast__Param*)(*val_sym->info._v__ast__FnType).func.params.data)[_t4]; if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("result type arguments are not supported"), node->pos); } } } } v__checker__Checker_ensure_type_exists(c, info.key_type, node->pos); v__checker__Checker_ensure_type_exists(c, info.value_type, node->pos); node->key_type = info.key_type; node->value_type = info.value_type; if ((v__ast__Table_sym(c->table, info.key_type)->language == v__ast__Language__v && info.key_type == _const_v__ast__any_type) || (v__ast__Table_sym(c->table, info.value_type)->language == v__ast__Language__v && info.value_type == _const_v__ast__any_type)) { v__checker__Checker_note(c, _S("the `any` type is deprecated and will be removed soon - either use an empty interface, or a sum type"), node->pos); v__checker__Checker_error(c, _S("cannot use type `any` here"), node->pos); } return node->typ; } if ((node->keys.len > 0 && node->vals.len > 0) || node->has_update_expr) { v__ast__Type map_type = _const_v__ast__void_type; bool use_expected_type = c->expected_type != _const_v__ast__void_type && !c->inside_const && v__ast__Table_sym(c->table, c->expected_type)->kind == v__ast__Kind__map && !(c->inside_fn_arg && v__ast__Type_has_flag(c->expected_type, v__ast__TypeFlag__generic)); if (use_expected_type) { map_type = c->expected_type; } if (node->has_update_expr) { v__ast__Type update_type = v__checker__Checker_expr(c, &node->update_expr); if (map_type != _const_v__ast__void_type) { if (update_type != map_type) { string msg = v__checker__Checker_expected_msg(c, update_type, map_type); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid map update: "), 0xfe10, {.d_s = msg}}, {_SLIT0, 0, { .d_c = 0 }}})), node->update_expr_pos); } } else if (v__ast__Table_sym(c->table, update_type)->kind != v__ast__Kind__map) { v__checker__Checker_error(c, _S("invalid map update: non-map type"), node->update_expr_pos); } else { map_type = update_type; } } v__ast__Type map_key_type = _const_v__ast__void_type; v__ast__Type map_val_type = _const_v__ast__void_type; if (map_type != _const_v__ast__void_type) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, map_type); v__ast__Map info = v__ast__TypeSymbol_map_info(sym); map_key_type = info.key_type; map_val_type = info.value_type; } else if (node->keys.len > 0) { v__ast__Expr key_ = (*(v__ast__Expr*)array_get(node->keys, 0)); map_key_type = v__ast__mktyp(v__checker__Checker_expr(c, &key_)); if (v__ast__Expr_is_auto_deref_var((*(v__ast__Expr*)array_get(node->keys, 0)))) { map_key_type = v__ast__Type_deref(map_key_type); } v__ast__Expr val_ = (*(v__ast__Expr*)array_get(node->vals, 0)); map_val_type = v__ast__mktyp(v__checker__Checker_expr(c, &val_)); if (v__ast__Expr_is_auto_deref_var((*(v__ast__Expr*)array_get(node->vals, 0)))) { map_val_type = v__ast__Type_deref(map_val_type); } array_push((array*)&node->val_types, _MOV((v__ast__Type[]){ map_val_type })); if (node->keys.len == 1 && map_val_type == _const_v__ast__none_type) { v__checker__Checker_error(c, _S("map value cannot be only `none`"), v__ast__Expr_pos((*(v__ast__Expr*)array_get(node->vals, 0)))); } v__checker__Checker_check_expr_option_or_result_call(c, key_, map_key_type); v__checker__Checker_check_expr_option_or_result_call(c, val_, map_val_type); } map_key_type = v__checker__Checker_unwrap_generic(c, map_key_type); map_val_type = v__checker__Checker_unwrap_generic(c, map_val_type); node->typ = v__ast__new_type(v__ast__Table_find_or_register_map(c->table, map_key_type, map_val_type)); node->key_type = map_key_type; node->value_type = map_val_type; v__ast__TypeSymbol* map_value_sym = v__ast__Table_sym(c->table, map_val_type); bool expecting_interface_map = map_value_sym->kind == v__ast__Kind__interface; bool same_key_type = true; for (int i = 0; i < node->keys.len; ++i) { v__ast__Expr* key = ((v__ast__Expr*)node->keys.data) + i; if (i == 0 && map_type == _const_v__ast__void_type) { continue; } v__ast__Expr val = (*(v__ast__Expr*)array_get(node->vals, i)); c->expected_type = map_key_type; v__ast__Type key_type = v__checker__Checker_expr(c, key); c->expected_type = map_val_type; v__ast__Type val_type = v__checker__Checker_expr(c, &val); array_push((array*)&node->val_types, _MOV((v__ast__Type[]){ val_type })); v__ast__TypeSymbol* val_type_sym = v__ast__Table_sym(c->table, val_type); v__checker__Checker_check_expr_option_or_result_call(c, *key, key_type); v__checker__Checker_check_expr_option_or_result_call(c, val, val_type); if (!v__checker__Checker_check_types(c, key_type, map_key_type) || (i == 0 && v__ast__Type_is_number(key_type) && v__ast__Type_is_number(map_key_type) && map_key_type != v__ast__mktyp(key_type))) { string msg = v__checker__Checker_expected_msg(c, key_type, map_key_type); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid map key: "), 0xfe10, {.d_s = msg}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_pos(*key)); same_key_type = false; } if (expecting_interface_map) { if (val_type == map_val_type) { continue; } if (val_type_sym->kind == v__ast__Kind__struct && v__checker__Checker_type_implements(c, val_type, map_val_type, v__ast__Expr_pos(val))) { array_set(&node->vals, i, &(v__ast__Expr[]) { v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = map_val_type,.expr = val,.typname = v__ast__Table_get_type_name(c->table, map_val_type),.expr_type = val_type,.has_arg = 0,.pos = v__ast__Expr_pos(val),})))) }); continue; } else { string msg = v__checker__Checker_expected_msg(c, val_type, map_val_type); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid map value: "), 0xfe10, {.d_s = msg}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_pos(val)); } } if (val_type == _const_v__ast__none_type && v__ast__Type_has_flag(map_val_type, v__ast__TypeFlag__option)) { continue; } if (!v__checker__Checker_check_types(c, val_type, map_val_type) || v__ast__Type_has_flag(map_val_type, v__ast__TypeFlag__option) != v__ast__Type_has_flag(val_type, v__ast__TypeFlag__option) || (i == 0 && v__ast__Type_is_number(val_type) && v__ast__Type_is_number(map_val_type) && map_val_type != v__ast__mktyp(val_type))) { string msg = v__checker__Checker_expected_msg(c, val_type, map_val_type); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid map value: "), 0xfe10, {.d_s = msg}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_pos(val)); } } if (same_key_type) { for (int i = 1; i < node->keys.len; ++i) { v__checker__Checker_check_dup_keys(c, node, i); } } } return node->typ; } VV_LOC void v__checker__Checker_check_elements_ref_fields_initialized(v__checker__Checker* c, v__ast__Type typ, v__token__Pos* pos) { if (typ == 0 || c->inside_const) { return; } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); Array_v__ast__Type checked_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); v__checker__Checker_do_check_elements_ref_fields_initialized(c, sym, &checked_types, pos); } VV_LOC void v__checker__Checker_do_check_elements_ref_fields_initialized(v__checker__Checker* c, v__ast__TypeSymbol* sym, Array_v__ast__Type* checked_types, v__token__Pos* pos) { if ((sym->info)._typ == 518 /* v.ast.Struct */) { string linked_name = sym->name; v__checker__Checker_check_ref_fields_initialized_note(c, sym, checked_types, linked_name, pos); return; } if (sym->info._typ == 513 /* v.ast.Array */) { v__ast__Type elem_type = (*sym->info._v__ast__Array).elem_type; if ((Array_v__ast__Type_contains(*checked_types, elem_type))) { return; } array_push((array*)checked_types, _MOV((v__ast__Type[]){ elem_type })); v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(c->table, elem_type); v__checker__Checker_do_check_elements_ref_fields_initialized(c, elem_sym, checked_types, pos); } else if (sym->info._typ == 549 /* v.ast.ArrayFixed */) { v__ast__Type elem_type = (*sym->info._v__ast__ArrayFixed).elem_type; if ((Array_v__ast__Type_contains(*checked_types, elem_type))) { return; } array_push((array*)checked_types, _MOV((v__ast__Type[]){ elem_type })); v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(c->table, elem_type); v__checker__Checker_do_check_elements_ref_fields_initialized(c, elem_sym, checked_types, pos); } else if (sym->info._typ == 514 /* v.ast.Map */) { v__ast__Type key_type = (*sym->info._v__ast__Map).key_type; if ((Array_v__ast__Type_contains(*checked_types, key_type))) { return; } array_push((array*)checked_types, _MOV((v__ast__Type[]){ key_type })); v__ast__TypeSymbol* key_sym = v__ast__Table_sym(c->table, key_type); v__checker__Checker_do_check_elements_ref_fields_initialized(c, key_sym, checked_types, pos); v__ast__Type value_type = (*sym->info._v__ast__Map).value_type; if ((Array_v__ast__Type_contains(*checked_types, value_type))) { return; } array_push((array*)checked_types, _MOV((v__ast__Type[]){ value_type })); v__ast__TypeSymbol* value_sym = v__ast__Table_sym(c->table, value_type); v__checker__Checker_do_check_elements_ref_fields_initialized(c, value_sym, checked_types, pos); } else if (sym->info._typ == 539 /* v.ast.Alias */) { v__ast__Type parent_type = (*sym->info._v__ast__Alias).parent_type; if ((Array_v__ast__Type_contains(*checked_types, parent_type))) { return; } array_push((array*)checked_types, _MOV((v__ast__Type[]){ parent_type })); v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(c->table, parent_type); v__checker__Checker_do_check_elements_ref_fields_initialized(c, parent_sym, checked_types, pos); } else { } } VV_LOC _result_void v__checker__Checker_check_elements_initialized(v__checker__Checker* c, v__ast__Type typ) { if (typ == 0 || c->inside_unsafe) { return (_result_void){0}; } if (v__ast__Type_is_any_kind_of_pointer(typ)) { if (!c->pref->translated && !c->file->is_translated) { return (_result_void){ .is_error=true, .err=_const_v__checker__err_ref_uninitialized, .data={E_STRUCT} }; } else { return (_result_void){0}; } } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); if (sym->kind == v__ast__Kind__interface) { return (_result_void){ .is_error=true, .err=_const_v__checker__err_interface_uninitialized, .data={E_STRUCT} }; } else if (sym->kind == v__ast__Kind__sum_type) { return (_result_void){ .is_error=true, .err=_const_v__checker__err_sumtype_uninitialized, .data={E_STRUCT} }; } if (sym->info._typ == 513 /* v.ast.Array */) { v__ast__Type elem_type = (*sym->info._v__ast__Array).elem_type; return v__checker__Checker_check_elements_initialized(c, elem_type); } else if (sym->info._typ == 549 /* v.ast.ArrayFixed */) { v__ast__Type elem_type = (*sym->info._v__ast__ArrayFixed).elem_type; if (!c->is_builtin_mod) { return v__checker__Checker_check_elements_initialized(c, elem_type); } } else if (sym->info._typ == 514 /* v.ast.Map */) { v__ast__Type value_type = (*sym->info._v__ast__Map).value_type; if (!c->is_builtin_mod) { return v__checker__Checker_check_elements_initialized(c, value_type); } } else if (sym->info._typ == 539 /* v.ast.Alias */) { v__ast__Type parent_type = (*sym->info._v__ast__Alias).parent_type; return v__checker__Checker_check_elements_initialized(c, parent_type); } else { } return (_result_void){0}; } VV_LOC v__ast__Type v__checker__Checker_check_append(v__checker__Checker* c, v__ast__InfixExpr* node, v__ast__Type left_type, v__ast__Type right_type, v__ast__TypeSymbol right_final_sym) { if (!node->is_stmt) { v__checker__Checker_error(c, _S("array append cannot be used in an expression"), node->pos); } if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option) && (node->left)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node->left)._v__ast__Ident,(node->left)._typ, 358)).or_expr.kind == v__ast__OrKind__absent) { v__checker__Checker_error(c, _S("unwrapped Option cannot be used in an infix expression"), node->pos); } v__token__Pos right_pos = v__ast__Expr_pos(node->right); v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type); v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, left_type); v__checker__Checker_check_expr_option_or_result_call(c, node->right, right_type); multi_return_string_v__token__Pos mr_26075 = v__checker__Checker_fail_if_immutable(c, &node->left); node->auto_locked = mr_26075.arg0; v__ast__Type left_value_type = v__ast__Table_value_type(c->table, v__checker__Checker_unwrap_generic(c, left_type)); v__ast__TypeSymbol* left_value_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, left_value_type)); if (!v__ast__Type_has_flag(left_value_type, v__ast__TypeFlag__option) && v__ast__Type_has_flag(right_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("unwrapped Option cannot be used in an infix expression"), node->pos); } v__ast__Expr right = node->right; if ((right)._typ == 376 /* v.ast.PrefixExpr */ && (*(v__ast__PrefixExpr*)__as_cast((right)._v__ast__PrefixExpr,(right)._typ, 376)).op == v__token__Kind__amp) { v__ast__Expr expr2 = (*right._v__ast__PrefixExpr).right; if ((expr2)._typ == 358 /* v.ast.Ident */ && !v__ast__Expr_is_blank_ident(node->left) && ((*(v__ast__Ident*)__as_cast((expr2)._v__ast__Ident,(expr2)._typ, 358)).obj)._typ == 420 /* v.ast.ConstField */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot have mutable reference to const `"), 0xfe10, {.d_s = (*expr2._v__ast__Ident).name}}, {_S("`"), 0, { .d_c = 0 }}})), (*expr2._v__ast__Ident).pos); } } if (left_value_sym->kind == v__ast__Kind__interface) { if (right_final_sym.kind != v__ast__Kind__array) { if (v__checker__Checker_type_implements(c, right_type, left_value_type, right_pos)) { if (!v__ast__Type_is_any_kind_of_pointer(right_type) && !c->inside_unsafe && right_sym->kind != v__ast__Kind__interface) { v__checker__Checker_mark_as_referenced(c, &node->right, true); } } } else { v__checker__Checker_type_implements(c, v__ast__Table_value_type(c->table, right_type), left_value_type, right_pos); } return _const_v__ast__void_type; } else if (left_value_sym->kind == v__ast__Kind__sum_type) { if (right_sym->kind != v__ast__Kind__array) { if (!v__ast__Table_is_sumtype_or_in_variant(c->table, left_value_type, v__ast__mktyp(v__checker__Checker_unwrap_generic(c, right_type)))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot append `"), 0xfe10, {.d_s = right_sym->name}}, {_S("` to `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), right_pos); } } else { v__ast__Type right_value_type = v__ast__Table_value_type(c->table, v__checker__Checker_unwrap_generic(c, right_type)); if (!v__ast__Table_is_sumtype_or_in_variant(c->table, left_value_type, v__ast__mktyp(right_value_type))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot append `"), 0xfe10, {.d_s = right_sym->name}}, {_S("` to `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), right_pos); } } return _const_v__ast__void_type; } v__ast__Type unwrapped_right_type = v__checker__Checker_unwrap_generic(c, right_type); if (v__checker__Checker_check_types(c, unwrapped_right_type, left_value_type)) { if (!(!v__ast__Type_is_ptr(unwrapped_right_type) && v__ast__Type_is_ptr(left_value_type) && v__ast__Type_share(left_value_type) == v__ast__ShareType__mut_t)) { return _const_v__ast__void_type; } } else if (v__checker__Checker_check_types(c, unwrapped_right_type, v__checker__Checker_unwrap_generic(c, left_type))) { return _const_v__ast__void_type; } if (v__ast__Type_has_flag(left_value_type, v__ast__TypeFlag__option) && right_type == _const_v__ast__none_type) { return _const_v__ast__void_type; } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot append `"), 0xfe10, {.d_s = right_sym->name}}, {_S("` to `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), right_pos); return _const_v__ast__void_type; } VV_LOC void v__checker__Checker_add_error_detail(v__checker__Checker* c, string s) { array_push((array*)&c->error_details, _MOV((string[]){ string_clone(s) })); } VV_LOC void v__checker__Checker_add_error_detail_with_pos(v__checker__Checker* c, string msg, v__token__Pos pos) { v__checker__Checker_add_error_detail(c, v__util__formatted_error(_S("details:"), msg, c->file->path, pos)); } VV_LOC void v__checker__Checker_add_instruction_for_option_type(v__checker__Checker* c) { v__checker__Checker_add_error_detail_with_pos(c, str_intp(2, _MOV((StrIntpData[]){{_S("prepend ? before the declaration of the return type of `"), 0xfe10, {.d_s = c->table->cur_fn->name}}, {_S("`"), 0, { .d_c = 0 }}})), c->table->cur_fn->return_type_pos); } VV_LOC void v__checker__Checker_add_instruction_for_result_type(v__checker__Checker* c) { v__checker__Checker_add_error_detail_with_pos(c, str_intp(2, _MOV((StrIntpData[]){{_S("prepend ! before the declaration of the return type of `"), 0xfe10, {.d_s = c->table->cur_fn->name}}, {_S("`"), 0, { .d_c = 0 }}})), c->table->cur_fn->return_type_pos); } VV_LOC void v__checker__Checker_warn(v__checker__Checker* c, string s, v__token__Pos pos) { bool allow_warnings = !(c->pref->is_prod || c->pref->warns_are_errors); v__checker__Checker_warn_or_error(c, s, pos, allow_warnings); } VV_LOC void v__checker__Checker_warn_alloc(v__checker__Checker* c, string s, v__token__Pos pos) { if (fast_string_eq(c->assign_stmt_attr, _S("freed"))) { return; } if (!c->is_builtin_mod && !(fast_string_eq(c->mod, _S("strings")) || fast_string_eq(c->mod, _S("math")) || fast_string_eq(c->mod, _S("math.bits")) || fast_string_eq(c->mod, _S("builtin")) || fast_string_eq(c->mod, _S("strconv")))) { v__checker__Checker_warn(c, str_intp(2, _MOV((StrIntpData[]){{_S("allocation ("), 0xfe10, {.d_s = s}}, {_S(")"), 0, { .d_c = 0 }}})), pos); } } VV_LOC void v__checker__Checker_error(v__checker__Checker* c, string message, v__token__Pos pos) { if ((c->pref->translated || c->file->is_translated) && string_starts_with(message, _S("mismatched types"))) { return; } string msg = string_replace(message, _S("`Array_"), _S("`[]")); if (c->pref->is_vweb) { string veb_action = string_replace(c->table->cur_fn->name, _S("veb_tmpl_"), _S("")); int j = 0; for (int _t1 = 0; _t1 < veb_action.len; ++_t1) { u8 ch = veb_action.str[_t1]; if (u8_is_digit(ch)) { break; } j++; } msg = string__plus(msg, str_intp(2, _MOV((StrIntpData[]){{_S(" (veb action: "), 0xfe10, {.d_s = string_substr(veb_action, 0, j)}}, {_S(")"), 0, { .d_c = 0 }}}))); } v__checker__Checker_warn_or_error(c, msg, pos, false); } VV_LOC void v__checker__Checker_fatal(v__checker__Checker* c, string message, v__token__Pos pos) { if ((c->pref->translated || c->file->is_translated) && string_starts_with(message, _S("mismatched types"))) { return; } string msg = string_replace(message, _S("`Array_"), _S("`[]")); c->pref->fatal_errors = true; v__checker__Checker_warn_or_error(c, msg, pos, false); } VV_LOC void v__checker__Checker_note(v__checker__Checker* c, string message, v__token__Pos pos) { if (c->pref->message_limit >= 0 && c->nr_notices >= c->pref->message_limit) { c->should_abort = true; return; } if (c->is_generated) { return; } if (c->pref->notes_are_errors) { v__checker__Checker_error(c, message, pos); } string details = _S(""); if (c->error_details.len > 0) { details = Array_string_join(c->error_details, _S("\n")); c->error_details = __new_array_with_default(0, 0, sizeof(string), 0); } string kpos = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->file->path}}, {_S(":"), 0xfe07, {.d_i32 = pos.line_nr}}, {_S(":"), 0xfe10, {.d_s = message}}, {_SLIT0, 0, { .d_c = 0 }}})); if (!_IN_MAP(ADDR(string, kpos), ADDR(map, c->notice_lines))) { map_set(&c->notice_lines, &(string[]){kpos}, &(bool[]) { true }); v__errors__Notice note = ((v__errors__Notice){.CompilerMessage = ((v__errors__CompilerMessage){.message = message,.details = details,.file_path = c->file->path,.pos = pos,.reporter = v__errors__Reporter__checker,}),}); array_push((array*)&c->file->notices, _MOV((v__errors__Notice[]){ note })); array_push((array*)&c->notices, _MOV((v__errors__Notice[]){ note })); c->nr_notices++; } } VV_LOC void v__checker__Checker_warn_or_error(v__checker__Checker* c, string message, v__token__Pos pos, bool warn) { if (!warn) { #if defined(CUSTOM_DEFINE_checker_exit_on_first_error) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("\n\n>> checker error: "), 0xfe10, {.d_s = message}}, {_S(", pos: "), 0xfe10, {.d_s = v__token__Pos_str(pos)}}, {_SLIT0, 0, { .d_c = 0 }}}))); print_backtrace(); _v_exit(1); VUNREACHABLE(); } #endif if (c->pref->is_verbose) { print_backtrace(); } } string details = _S(""); if (c->error_details.len > 0) { details = Array_string_join(c->error_details, _S("\n")); c->error_details = __new_array_with_default(0, 0, sizeof(string), 0); } if (warn && !c->pref->skip_warnings) { c->nr_warnings++; if (c->pref->message_limit >= 0 && c->nr_warnings >= c->pref->message_limit) { c->should_abort = true; return; } string kpos = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->file->path}}, {_S(":"), 0xfe07, {.d_i32 = pos.line_nr}}, {_S(":"), 0xfe10, {.d_s = message}}, {_SLIT0, 0, { .d_c = 0 }}})); if (!_IN_MAP(ADDR(string, kpos), ADDR(map, c->warning_lines))) { map_set(&c->warning_lines, &(string[]){kpos}, &(bool[]) { true }); v__errors__Warning wrn = ((v__errors__Warning){.CompilerMessage = ((v__errors__CompilerMessage){.message = message,.details = details,.file_path = c->file->path,.pos = pos,.reporter = v__errors__Reporter__checker,}),}); array_push((array*)&c->file->warnings, _MOV((v__errors__Warning[]){ wrn })); array_push((array*)&c->warnings, _MOV((v__errors__Warning[]){ wrn })); } return; } if (!warn) { if (c->pref->fatal_errors) { v__util__show_compiler_message(_S("error:"), ((v__errors__CompilerMessage){.message = message,.details = details,.file_path = c->file->path,.pos = pos,.reporter = 0,})); _v_exit(1); VUNREACHABLE(); } c->nr_errors++; if (c->pref->message_limit >= 0 && c->errors.len >= c->pref->message_limit) { c->should_abort = true; return; } string kpos = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->file->path}}, {_S(":"), 0xfe07, {.d_i32 = pos.line_nr}}, {_S(":"), 0xfe10, {.d_s = message}}, {_SLIT0, 0, { .d_c = 0 }}})); if (!_IN_MAP(ADDR(string, kpos), ADDR(map, c->error_lines))) { map_set(&c->error_lines, &(string[]){kpos}, &(bool[]) { true }); v__errors__Error err = ((v__errors__Error){.CompilerMessage = ((v__errors__CompilerMessage){.message = message,.details = details,.file_path = c->file->path,.pos = pos,.reporter = v__errors__Reporter__checker,}),}); array_push((array*)&c->file->errors, _MOV((v__errors__Error[]){ err })); array_push((array*)&c->errors, _MOV((v__errors__Error[]){ err })); } } } VV_LOC void v__checker__Checker_deprecate(v__checker__Checker* c, string kind, string name, Array_v__ast__Attr attrs, v__token__Pos pos) { string deprecation_message = _S(""); time__Time now = time__now(); time__Time after_time = now; for (int _t1 = 0; _t1 < attrs.len; ++_t1) { v__ast__Attr attr = ((v__ast__Attr*)attrs.data)[_t1]; if ((attr.arg).len == 0) { continue; } if (fast_string_eq(attr.name, _S("deprecated"))) { deprecation_message = attr.arg; } else if (fast_string_eq(attr.name, _S("deprecated_after"))) { _result_time__Time _t2 = time__parse_iso8601(attr.arg); if (_t2.is_error) { IError err = _t2.err; v__checker__Checker_error(c, _S("invalid time format"), attr.pos); *(time__Time*) _t2.data = now; } after_time = (*(time__Time*)_t2.data); } } string start_message = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = kind}}, {_S(" `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}})); time__Time error_time = time__Time_add_days(after_time, 180); if (time__Time__lt(error_time, now)) { v__checker__Checker_error(c, v__checker__semicolonize(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = start_message}}, {_S(" has been deprecated since "), 0xfe10, {.d_s = time__Time_ymmdd(after_time)}}, {_SLIT0, 0, { .d_c = 0 }}})), deprecation_message), pos); } else if (time__Time__lt(after_time, now)) { v__checker__Checker_warn(c, v__checker__semicolonize(str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = start_message}}, {_S(" has been deprecated since "), 0xfe10, {.d_s = time__Time_ymmdd(after_time)}}, {_S(", it will be an error after "), 0xfe10, {.d_s = time__Time_ymmdd(error_time)}}, {_SLIT0, 0, { .d_c = 0 }}})), deprecation_message), pos); } else if (time__Time__eq(after_time, now)) { v__checker__Checker_warn(c, v__checker__semicolonize(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = start_message}}, {_S(" has been deprecated"), 0, { .d_c = 0 }}})), deprecation_message), pos); } else { v__checker__Checker_note(c, v__checker__semicolonize(str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = start_message}}, {_S(" will be deprecated after "), 0xfe10, {.d_s = time__Time_ymmdd(after_time)}}, {_S(", and will become an error after "), 0xfe10, {.d_s = time__Time_ymmdd(error_time)}}, {_SLIT0, 0, { .d_c = 0 }}})), deprecation_message), pos); } } VV_LOC string v__checker__semicolonize(string main, string details) { if ((details).len == 0) { return main; } return str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = main}}, {_S("; "), 0xfe10, {.d_s = details}}, {_SLIT0, 0, { .d_c = 0 }}})); } VV_LOC void v__checker__Checker_fn_decl(v__checker__Checker* c, v__ast__FnDecl* node) { bool v__checker__Checker_fn_decl_defer_0 = false; int prev_stmt_level; bool prev_returns; bool prev_inside_anon_fn; bool prev_inside_unsafe; bool prev_inside_defer; int prev_in_for_count; v__ast__Scope* prev_fn_scope; #if defined(CUSTOM_DEFINE_trace_post_process_generic_fns_types) { if (node->generic_names.len > 0) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S(">>> post processing node.name: "), 0x3cfe10, {.d_s = node->name}}, {_S(" | "), 0xfe10, {.d_s = Array_string_str(node->generic_names)}}, {_S(" <=> "), 0xfe10, {.d_s = Array_v__ast__Type_str(c->table->cur_concrete_types)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } #endif if ((node->language == v__ast__Language__c || node->language == v__ast__Language__js) && node->generic_names.len > 0) { string lang = (node->language == v__ast__Language__c ? (_S("C")) : (_S("JS"))); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = lang}}, {_S(" functions cannot be declared as generic"), 0, { .d_c = 0 }}})), node->pos); } if (node->generic_names.len > 0 && node->is_pub) { v__ast__Type typ_vweb_result = v__ast__Table_find_type(c->table, _S("veb.Result")); if (node->return_type == typ_vweb_result) { v__ast__TypeSymbol* rec_sym = v__ast__Table_sym(c->table, node->receiver.typ); if (rec_sym->kind == v__ast__Kind__struct) { _result_v__ast__StructField _t2; if (_t2 = v__ast__Table_find_field_with_embeds(c->table, rec_sym, _S("Context")), !_t2.is_error) { v__checker__Checker_note(c, _S("generic method routes of veb will be skipped"), node->pos); } } } } if (node->generic_names.len > 0 && c->table->cur_concrete_types.len == 0) { string fkey = v__ast__FnDecl_fkey(node); if (!(*(bool*)map_get(ADDR(map, c->generic_fns), &(string[]){fkey}, &(bool[]){ 0 }))) { c->need_recheck_generic_fns = true; map_set(&c->generic_fns, &(string[]){fkey}, &(bool[]) { true }); array_push((array*)&c->file->generic_fns, _MOV((v__ast__FnDecl*[]){ node })); } return; } node->ninstances++; prev_fn_scope = c->fn_scope; prev_in_for_count = c->in_for_count; prev_inside_defer = c->inside_defer; prev_inside_unsafe = c->inside_unsafe; prev_inside_anon_fn = c->inside_anon_fn; prev_returns = c->returns; prev_stmt_level = c->stmt_level; c->fn_level++; c->in_for_count = 0; c->inside_defer = false; c->inside_unsafe = node->is_unsafe; c->returns = false; v__checker__Checker_fn_decl_defer_0 = true; bool need_generic_names = false; if (node->generic_names.len == 0) { if (v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__generic)) { need_generic_names = true; } else { for (int _t4 = 0; _t4 < node->params.len; ++_t4) { v__ast__Param param = ((v__ast__Param*)node->params.data)[_t4]; if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { need_generic_names = true; break; } } } if (need_generic_names) { if (node->is_method) { v__checker__Checker_add_error_detail(c, _S("use `fn (r SomeType[T]) foo[T]() {`, not just `fn (r SomeType[T]) foo() {`")); v__checker__Checker_error(c, _S("generic method declaration must specify generic type names"), node->pos); } else { v__checker__Checker_add_error_detail(c, _S("use `fn foo[T](x T) {`, not just `fn foo(x T) {`")); v__checker__Checker_error(c, _S("generic function declaration must specify generic type names"), node->pos); } } } if (node->language == v__ast__Language__v && !c->is_builtin_mod && !node->is_anon) { v__checker__Checker_check_valid_snake_case(c, v__ast__FnDecl_get_name(node), _S("function name"), node->pos); if (!node->is_method && fast_string_eq(node->mod, _S("main")) && _IN_MAP(ADDR(string, node->short_name), ADDR(map, c->table->builtin_pub_fns))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot redefine builtin public function `"), 0xfe10, {.d_s = node->short_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } if (fast_string_eq(node->name, _S("main.main"))) { c->main_fn_decl_node = *node; } if (node->language == v__ast__Language__v && node->attrs.len > 0) { Array_string required_args_attr = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("export"), _S("_linker_section")})); for (int _t5 = 0; _t5 < required_args_attr.len; ++_t5) { string attr_name = ((string*)required_args_attr.data)[_t5]; _option_v__ast__Attr _t6; if (_t6 = Array_v__ast__Attr_find_first(node->attrs, attr_name), _t6.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t6.data; if ((attr.arg).len == 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("missing argument for @["), 0xfe10, {.d_s = attr_name}}, {_S("] attribute"), 0, { .d_c = 0 }}})), attr.pos); } } } } if (node->return_type == _const_v__ast__no_type) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid return type in fn `"), 0xfe10, {.d_s = node->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); // Defer begin if (v__checker__Checker_fn_decl_defer_0) { c->stmt_level = prev_stmt_level; c->fn_level--; c->returns = prev_returns; c->inside_anon_fn = prev_inside_anon_fn; c->inside_unsafe = prev_inside_unsafe; c->inside_defer = prev_inside_defer; c->in_for_count = prev_in_for_count; c->fn_scope = prev_fn_scope; } // Defer end return; } c->fn_return_type = node->return_type; v__ast__Type return_type_unaliased = v__ast__Table_unaliased_type(c->table, node->return_type); if (v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__option) && v__ast__Type_has_flag(return_type_unaliased, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("the fn returns "), 0xfe10, {.d_s = v__checker__Checker_error_type_name(c, node->return_type)}}, {_S(", but "), 0xfe10, {.d_s = v__checker__Checker_error_type_name(c, v__ast__Type_clear_flag(node->return_type, v__ast__TypeFlag__option))}}, {_S(" is a Result alias, you can not mix them"), 0, { .d_c = 0 }}})), node->return_type_pos); } if (v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__result) && v__ast__Type_has_flag(return_type_unaliased, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("the fn returns "), 0xfe10, {.d_s = v__checker__Checker_error_type_name(c, node->return_type)}}, {_S(", but "), 0xfe10, {.d_s = v__checker__Checker_error_type_name(c, v__ast__Type_clear_flag(node->return_type, v__ast__TypeFlag__result))}}, {_S(" is an Option alias, you can not mix them"), 0, { .d_c = 0 }}})), node->return_type_pos); } if (node->return_type != _const_v__ast__void_type) { if (node->language == v__ast__Language__v && v__ast__Type_clear_option_and_result(node->return_type) == _const_v__ast__any_type) { v__checker__Checker_error(c, _S("cannot use type `any` here"), node->return_type_pos); } _option_int _t7; if (_t7 = Array_v__ast__Attr_find_comptime_define(node->attrs), _t7.state == 0) { int ct_attr_idx = *(int*)_t7.data; string sexpr = v__ast__Expr_str(&(*(v__ast__Attr*)array_get(node->attrs, ct_attr_idx)).ct_expr); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("only functions that do NOT return values can have `@[if "), 0xfe10, {.d_s = sexpr}}, {_S("]` tags"), 0, { .d_c = 0 }}})), node->pos); } if (node->generic_names.len > 0) { v__ast__TypeSymbol* gs = v__ast__Table_sym(c->table, node->return_type); if ((gs->info)._typ == 518 /* v.ast.Struct */) { if ((*gs->info._v__ast__Struct).is_generic && !v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__generic)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("return generic struct `"), 0xfe10, {.d_s = gs->name}}, {_S("` in fn declaration must specify the generic type names, e.g. "), 0xfe10, {.d_s = gs->name}}, {_S("[T]"), 0, { .d_c = 0 }}})), node->return_type_pos); } } if (gs->kind == v__ast__Kind__struct && v__checker__Checker_needs_unwrap_generic_type(c, node->return_type)) { if (v__checker__Checker_ensure_generic_type_specify_type_names(c, node->return_type, node->return_type_pos, false, false)) { v__ast__Table_unwrap_generic_type_ex(c->table, node->return_type, c->table->cur_fn->generic_names, c->table->cur_concrete_types, true); } } } v__ast__TypeSymbol* return_sym = v__ast__Table_sym(c->table, node->return_type); if ((return_sym->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(c->table, (*return_sym->info._v__ast__Alias).parent_type); if ((parent_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { v__ast__Table_find_or_register_array_fixed(c->table, (*parent_sym->info._v__ast__ArrayFixed).elem_type, (*parent_sym->info._v__ast__ArrayFixed).size, (*parent_sym->info._v__ast__ArrayFixed).size_expr, true); } if (fast_string_eq(return_sym->name, _S("byte"))) { v__checker__Checker_error(c, _S("byte is deprecated, use u8 instead"), node->return_type_pos); } } if ((return_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && v__checker__Checker_array_fixed_has_unresolved_size(c, (v__ast__ArrayFixed*)__as_cast((return_sym->info)._v__ast__ArrayFixed,(return_sym->info)._typ, 549))) { array_push((array*)&c->unresolved_fixed_sizes, _MOV((v__ast__Stmt*[]){ HEAP(v__ast__Stmt, v__ast__FnDecl_to_sumtype_v__ast__Stmt(node)) })); } v__ast__TypeSymbol* final_return_sym = v__ast__Table_final_sym(c->table, node->return_type); if ((final_return_sym->info)._typ == 552 /* v.ast.MultiReturn */) { for (int _t9 = 0; _t9 < (*final_return_sym->info._v__ast__MultiReturn).types.len; ++_t9) { v__ast__Type multi_type = ((v__ast__Type*)(*final_return_sym->info._v__ast__MultiReturn).types.data)[_t9]; if (multi_type == _const_v__ast__error_type) { v__checker__Checker_error(c, _S("type `IError` cannot be used in multi-return, return an Option instead"), node->return_type_pos); } else if (v__ast__Type_has_flag(multi_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("result cannot be used in multi-return, return a Result instead"), node->return_type_pos); } } } if (v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__generic)) { Array_string generic_names = v__ast__Table_generic_type_names(c->table, node->return_type); for (int _t10 = 0; _t10 < generic_names.len; ++_t10) { string name = ((string*)generic_names.data)[_t10]; if (!(Array_string_contains(node->generic_names, name))) { string fn_generic_names = Array_string_join(node->generic_names, _S(", ")); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("generic type name `"), 0xfe10, {.d_s = name}}, {_S("` is not mentioned in fn `"), 0xfe10, {.d_s = node->name}}, {_S("["), 0xfe10, {.d_s = fn_generic_names}}, {_S("]`"), 0, { .d_c = 0 }}})), node->return_type_pos); } } } } else { for (int _t11 = 0; _t11 < node->attrs.len; ++_t11) { v__ast__Attr* a = ((v__ast__Attr*)node->attrs.data) + _t11; if (a->kind == v__ast__AttrKind__comptime_define) { node->should_be_skipped = v__checker__Checker_evaluate_once_comptime_if_attribute(c, a); } } } if (node->is_method) { if ((Array_string_contains(c->global_names, node->receiver.name))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use global variable name `"), 0xfe10, {.d_s = node->receiver.name}}, {_S("` as receiver"), 0, { .d_c = 0 }}})), node->receiver_pos); } if (v__ast__Type_has_flag(node->receiver.typ, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("option types cannot have methods"), node->receiver_pos); } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, node->receiver.typ); if (sym->kind == v__ast__Kind__array && !c->is_builtin_mod && fast_string_eq(node->name, _S("map"))) { v__checker__Checker_error(c, _S("method overrides built-in array method"), node->pos); } else if (sym->kind == v__ast__Kind__sum_type && fast_string_eq(node->name, _S("type_name"))) { v__checker__Checker_error(c, _S("method overrides built-in sum type method"), node->pos); } else if (sym->kind == v__ast__Kind__sum_type && fast_string_eq(node->name, _S("type_idx"))) { v__checker__Checker_error(c, _S("method overrides built-in sum type method"), node->pos); } else if (sym->kind == v__ast__Kind__multi_return) { v__checker__Checker_error(c, _S("cannot define method on multi-value"), node->method_type_pos); } if (sym->name.len == 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->receiver_pos); // Defer begin if (v__checker__Checker_fn_decl_defer_0) { c->stmt_level = prev_stmt_level; c->fn_level--; c->returns = prev_returns; c->inside_anon_fn = prev_inside_anon_fn; c->inside_unsafe = prev_inside_unsafe; c->inside_defer = prev_inside_defer; c->in_for_count = prev_in_for_count; c->fn_scope = prev_fn_scope; } // Defer end return; } if ((sym->info)._typ == 542 /* v.ast.Interface */ && v__ast__TypeSymbol_has_method(sym, node->name)) { if (v__ast__Interface_has_method(&(*sym->info._v__ast__Interface), node->name)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("interface `"), 0xfe10, {.d_s = sym->name}}, {_S("` cannot implement its own interface method `"), 0xfe10, {.d_s = node->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } if ((sym->info)._typ == 518 /* v.ast.Struct */) { _result_v__ast__StructField _t12; if (_t12 = v__ast__Table_find_field(c->table, sym, node->name), !_t12.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t12.data; v__ast__TypeSymbol* field_sym = v__ast__Table_sym(c->table, field.typ); if (field_sym->kind == v__ast__Kind__function) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("type `"), 0xfe10, {.d_s = sym->name}}, {_S("` has both field and method named `"), 0xfe10, {.d_s = node->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } if (fast_string_eq(node->name, _S("free"))) { if (node->return_type != _const_v__ast__void_type) { v__checker__Checker_error(c, _S("`.free()` methods should not have a return type"), node->return_type_pos); } if (!v__ast__Type_is_ptr(node->receiver.typ)) { string tname = string_after_char(sym->name, '.'); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`.free()` methods should be defined on either a `(mut x &"), 0xfe10, {.d_s = tname}}, {_S(")`, or a `(x &"), 0xfe10, {.d_s = tname}}, {_S(")` receiver"), 0, { .d_c = 0 }}})), node->receiver_pos); } if (node->params.len != 1) { v__checker__Checker_error(c, _S("`.free()` methods should have 0 arguments"), node->pos); } } } if (node->method_idx < sym->methods.len) { (*(v__ast__Fn*)array_get(sym->methods, node->method_idx)).source_fn = ((voidptr)(node)); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("method index: "), 0xfe07, {.d_i32 = node->method_idx}}, {_S(" >= sym.methods.len: "), 0xfe07, {.d_i32 = sym->methods.len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } } if (node->language == v__ast__Language__v) { for (int _t13 = 0; _t13 < node->params.len; ++_t13) { v__ast__Param* param = ((v__ast__Param*)node->params.data) + _t13; if (!v__checker__Checker_ensure_type_exists(c, param->typ, param->type_pos)) { // Defer begin if (v__checker__Checker_fn_decl_defer_0) { c->stmt_level = prev_stmt_level; c->fn_level--; c->returns = prev_returns; c->inside_anon_fn = prev_inside_anon_fn; c->inside_unsafe = prev_inside_unsafe; c->inside_defer = prev_inside_defer; c->in_for_count = prev_in_for_count; c->fn_scope = prev_fn_scope; } // Defer end return; } if (v__token__KeywordsMatcherTrie_matches(&_const_v__checker__reserved_type_names_chk, param->name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid use of reserved type `"), 0xfe10, {.d_s = param->name}}, {_S("` as a parameter name"), 0, { .d_c = 0 }}})), param->pos); } if (v__ast__Type_has_flag(param->typ, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("result type arguments are not supported"), param->type_pos); } v__ast__TypeSymbol* arg_typ_sym = v__ast__Table_sym(c->table, param->typ); if (arg_typ_sym->language == v__ast__Language__v && param->typ == _const_v__ast__any_type && !fast_string_eq(c->file->mod.name, _S("builtin"))) { v__checker__Checker_note(c, _S("the `any` type is deprecated and will be removed soon - either use an empty interface, or a sum type"), param->pos); } if ((arg_typ_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && v__checker__Checker_array_fixed_has_unresolved_size(c, (v__ast__ArrayFixed*)__as_cast((arg_typ_sym->info)._v__ast__ArrayFixed,(arg_typ_sym->info)._typ, 549))) { v__ast__Expr size_expr = (*arg_typ_sym->info._v__ast__ArrayFixed).size_expr; param->typ = v__checker__Checker_eval_array_fixed_sizes(c, &size_expr, 0, (*arg_typ_sym->info._v__ast__ArrayFixed).elem_type); _option_v__ast__Var_ptr _t14 = v__ast__Scope_find_var(node->scope, param->name); if (_t14.state != 0) { IError err = _t14.err; continue; } v__ast__Var* v = (*(v__ast__Var**)_t14.data); v->typ = param->typ; } else if ((arg_typ_sym->info)._typ == 518 /* v.ast.Struct */) { if (!v__ast__Type_is_ptr(param->typ) && (*arg_typ_sym->info._v__ast__Struct).is_heap) { _option_v__ast__Var_ptr _t15 = v__ast__Scope_find_var(node->scope, param->name); if (_t15.state != 0) { IError err = _t15.err; continue; } v__ast__Var* v = (*(v__ast__Var**)_t15.data); v->is_auto_heap = true; } if ((*arg_typ_sym->info._v__ast__Struct).generic_types.len > 0 && !v__ast__Type_has_flag(param->typ, v__ast__TypeFlag__generic) && (*arg_typ_sym->info._v__ast__Struct).concrete_types.len == 0) { string pure_sym_name = v__ast__TypeSymbol_embed_name(arg_typ_sym); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic struct `"), 0xfe10, {.d_s = pure_sym_name}}, {_S("` in fn declaration must specify the generic type names, e.g. "), 0xfe10, {.d_s = pure_sym_name}}, {_S("[T]"), 0, { .d_c = 0 }}})), param->type_pos); } bool _t16 = (param->is_mut); bool _t17 = false; if (_t16) { Array_v__ast__Attr _t17_orig = (*arg_typ_sym->info._v__ast__Struct).attrs; int _t17_len = _t17_orig.len; for (int _t18 = 0; _t18 < _t17_len; ++_t18) { v__ast__Attr it = ((v__ast__Attr*) _t17_orig.data)[_t18]; if (fast_string_eq(it.name, _S("params"))) { _t17 = true; break; } } } if ( _t16 &&_t17) { v__checker__Checker_error(c, _S("declaring a mutable parameter that accepts a struct with the `@[params]` attribute is not allowed"), param->type_pos); } } else if ((arg_typ_sym->info)._typ == 542 /* v.ast.Interface */) { if ((*arg_typ_sym->info._v__ast__Interface).generic_types.len > 0 && !v__ast__Type_has_flag(param->typ, v__ast__TypeFlag__generic) && (*arg_typ_sym->info._v__ast__Interface).concrete_types.len == 0) { string pure_sym_name = v__ast__TypeSymbol_embed_name(arg_typ_sym); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic interface `"), 0xfe10, {.d_s = pure_sym_name}}, {_S("` in fn declaration must specify the generic type names, e.g. "), 0xfe10, {.d_s = pure_sym_name}}, {_S("[T]"), 0, { .d_c = 0 }}})), param->type_pos); } } else if ((arg_typ_sym->info)._typ == 544 /* v.ast.SumType */) { if ((*arg_typ_sym->info._v__ast__SumType).generic_types.len > 0 && !v__ast__Type_has_flag(param->typ, v__ast__TypeFlag__generic) && (*arg_typ_sym->info._v__ast__SumType).concrete_types.len == 0) { string pure_sym_name = v__ast__TypeSymbol_embed_name(arg_typ_sym); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic sumtype `"), 0xfe10, {.d_s = pure_sym_name}}, {_S("` in fn declaration must specify the generic type names, e.g. "), 0xfe10, {.d_s = pure_sym_name}}, {_S("[T]"), 0, { .d_c = 0 }}})), param->type_pos); } } else if ((arg_typ_sym->info)._typ == 553 /* v.ast.FnType */) { if ((*arg_typ_sym->info._v__ast__FnType).func.generic_names.len > 0 && !v__ast__Type_has_flag(param->typ, v__ast__TypeFlag__generic)) { string pure_sym_name = v__ast__TypeSymbol_embed_name(arg_typ_sym); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic function `"), 0xfe10, {.d_s = pure_sym_name}}, {_S("` in fn declaration must specify the generic type names, e.g. "), 0xfe10, {.d_s = pure_sym_name}}, {_S("[T]"), 0, { .d_c = 0 }}})), param->type_pos); } } if (v__ast__Type_has_flag(param->typ, v__ast__TypeFlag__generic)) { Array_string generic_names = v__ast__Table_generic_type_names(c->table, param->typ); for (int _t19 = 0; _t19 < generic_names.len; ++_t19) { string name = ((string*)generic_names.data)[_t19]; if (!(Array_string_contains(node->generic_names, name))) { string fn_generic_names = Array_string_join(node->generic_names, _S(", ")); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("generic type name `"), 0xfe10, {.d_s = name}}, {_S("` is not mentioned in fn `"), 0xfe10, {.d_s = node->name}}, {_S("["), 0xfe10, {.d_s = fn_generic_names}}, {_S("]`"), 0, { .d_c = 0 }}})), param->type_pos); } } } if (c->pref->skip_unused) { if (v__ast__Type_has_flag(param->typ, v__ast__TypeFlag__generic)) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__checker__Checker_unwrap_generic(c, param->typ)}, &(bool[]) { true }); map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){param->typ}, &(bool[]) { true }); } if (v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__generic)) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__checker__Checker_unwrap_generic(c, node->return_type)}, &(bool[]) { true }); map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){node->return_type}, &(bool[]) { true }); } if (v__ast__Type_has_flag(node->receiver.typ, v__ast__TypeFlag__generic)) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){node->receiver.typ}, &(bool[]) { true }); map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__checker__Checker_unwrap_generic(c, node->receiver.typ)}, &(bool[]) { true }); } } if (string__eq(param->name, node->mod) && !fast_string_eq(param->name, _S("main"))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate of a module name `"), 0xfe10, {.d_s = param->name}}, {_S("`"), 0, { .d_c = 0 }}})), param->pos); } if (v__checker__Checker_check_import_sym_conflict(c, param->name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate of an import symbol `"), 0xfe10, {.d_s = param->name}}, {_S("`"), 0, { .d_c = 0 }}})), param->pos); } if (arg_typ_sym->kind == v__ast__Kind__alias && fast_string_eq(arg_typ_sym->name, _S("byte"))) { v__checker__Checker_error(c, _S("byte is deprecated, use u8 instead"), param->type_pos); } } if (!node->is_method) { if (v__checker__Checker_check_import_sym_conflict(c, node->short_name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate of an import symbol `"), 0xfe10, {.d_s = node->short_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } if (node->params.len == 0 && string__eq(string_after_char(node->name, '.'), _S("init"))) { if (node->is_pub) { v__checker__Checker_error(c, _S("fn `init` must not be public"), node->pos); } if (node->return_type != _const_v__ast__void_type) { v__checker__Checker_error(c, _S("fn `init` cannot have a return type"), node->pos); } } if (!c->is_builtin_mod && fast_string_eq(node->mod, _S("main")) && (Array_string_contains(_const_v__checker__reserved_type_names, string_after_char(node->name, '.')))) { v__checker__Checker_error(c, _S("top level declaration cannot shadow builtin type"), node->pos); } if (node->is_static_type_method) { _option_v__ast__TypeSymbol_ptr _t20; if (_t20 = v__ast__Table_find_sym(c->table, string_all_before(node->name, _S("__static__"))), _t20.state == 0) { v__ast__TypeSymbol* sym = *(v__ast__TypeSymbol**)_t20.data; if (sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->static_type_pos); } } } } } if (node->return_type != _const_v__ast__no_type) { if (!v__checker__Checker_ensure_type_exists(c, node->return_type, node->return_type_pos)) { // Defer begin if (v__checker__Checker_fn_decl_defer_0) { c->stmt_level = prev_stmt_level; c->fn_level--; c->returns = prev_returns; c->inside_anon_fn = prev_inside_anon_fn; c->inside_unsafe = prev_inside_unsafe; c->inside_defer = prev_inside_defer; c->in_for_count = prev_in_for_count; c->fn_scope = prev_fn_scope; } // Defer end return; } if (node->language == v__ast__Language__v && node->is_method && fast_string_eq(node->name, _S("str"))) { if (node->return_type != _const_v__ast__string_type) { v__checker__Checker_error(c, _S(".str() methods should return `string`"), node->pos); } if (node->params.len != 1) { v__checker__Checker_error(c, _S(".str() methods should have 0 arguments"), node->pos); } } if (node->language == v__ast__Language__v && node->is_method && (fast_string_eq(node->name, _S("+")) || fast_string_eq(node->name, _S("-")) || fast_string_eq(node->name, _S("*")) || fast_string_eq(node->name, _S("%")) || fast_string_eq(node->name, _S("/")) || fast_string_eq(node->name, _S("<")) || fast_string_eq(node->name, _S("==")))) { if (node->params.len != 2) { v__checker__Checker_error(c, _S("operator methods should have exactly 1 argument"), node->pos); } else { v__ast__Type receiver_type = node->receiver.typ; v__ast__TypeSymbol* receiver_sym = v__ast__Table_sym(c->table, receiver_type); v__ast__Type param_type = (*(v__ast__Param*)array_get(node->params, 1)).typ; v__ast__TypeSymbol* param_sym = v__ast__Table_sym(c->table, param_type); if (param_sym->kind == v__ast__Kind__string && receiver_sym->kind == v__ast__Kind__string) { } else if (!(param_sym->kind == v__ast__Kind__struct || param_sym->kind == v__ast__Kind__alias) || !(receiver_sym->kind == v__ast__Kind__struct || receiver_sym->kind == v__ast__Kind__alias)) { v__checker__Checker_error(c, _S("operator methods are only allowed for struct and type alias"), node->pos); } else { v__ast__TypeSymbol* parent_sym = v__ast__Table_final_sym(c->table, node->receiver.typ); if (node->rec_mut) { v__checker__Checker_error(c, _S("receiver cannot be `mut` for operator overloading"), node->receiver_pos); } else if ((*(v__ast__Param*)array_get(node->params, 1)).is_mut) { v__checker__Checker_error(c, _S("argument cannot be `mut` for operator overloading"), node->pos); } else if (!v__checker__Checker_check_same_type_ignoring_pointers(c, node->receiver.typ, (*(v__ast__Param*)array_get(node->params, 1)).typ)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("expected `"), 0xfe10, {.d_s = receiver_sym->name}}, {_S("` not `"), 0xfe10, {.d_s = param_sym->name}}, {_S("` - both operands must be the same type for operator overloading"), 0, { .d_c = 0 }}})), (*(v__ast__Param*)array_get(node->params, 1)).type_pos); } else if (node->return_type != _const_v__ast__bool_type && (fast_string_eq(node->name, _S("<")) || fast_string_eq(node->name, _S("==")))) { v__checker__Checker_error(c, _S("operator comparison methods should return `bool`"), node->pos); } else if (v__ast__TypeSymbol_is_primitive(parent_sym)) { } else if (receiver_type != param_type) { string srtype = v__ast__Table_type_to_str(c->table, receiver_type); string sptype = v__ast__Table_type_to_str(c->table, param_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("the receiver type `"), 0xfe10, {.d_s = srtype}}, {_S("` should be the same type as the operand `"), 0xfe10, {.d_s = sptype}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else if (v__ast__Type_has_option_or_result(node->return_type)) { v__checker__Checker_error(c, _S("return type cannot be Option or Result"), node->return_type_pos); } } } } } if (c->file->is_test && (!node->is_method && (string_starts_with(node->short_name, _S("test_")) || string_starts_with(node->short_name, _S("testsuite_"))))) { if (!c->pref->is_test) { for (int _t21 = 0; _t21 < node->stmts.len; ++_t21) { v__ast__Stmt st = ((v__ast__Stmt*)node->stmts.data)[_t21]; if ((st)._typ == 391 /* v.ast.AssertStmt */) { v__checker__Checker_warn(c, _S("tests will not be run, because filename does not end with `_test.v`"), node->pos); break; } } } if (node->params.len != 0) { v__checker__Checker_error(c, _S("test functions should take 0 parameters"), node->pos); } if (node->return_type != 1 && v__ast__Type_clear_flag(node->return_type, v__ast__TypeFlag__option) != 1 && v__ast__Type_clear_flag(node->return_type, v__ast__TypeFlag__result) != 1) { v__checker__Checker_error(c, _S("test functions should either return nothing at all, or be marked to return `?` or `!`"), node->pos); } } c->expected_type = _const_v__ast__void_type; c->table->cur_fn = node; bool _t22 = (node->return_type != _const_v__ast__void_type && v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__option)); bool _t23 = (node->stmts.len == 0); if ( _t22 && ( _t23 || ((*(v__ast__Stmt*)array_last(node->stmts)))._typ != 412 /* v.ast.Return */)) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, node->return_type); if (sym->kind == v__ast__Kind__void) { v__token__Pos _t24; /* if prepend */ if (node->stmts.len == 0) { _t24 = node->pos; } else { _t24 = (*((*(v__ast__Stmt*)array_last(node->stmts)).pos)); } v__token__Pos return_pos = _t24; array_push((array*)&node->stmts, _MOV((v__ast__Stmt[]){ v__ast__Return_to_sumtype_v__ast__Stmt(ADDR(v__ast__Return, (((v__ast__Return){.pos = return_pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.types = __new_array(0, 0, sizeof(v__ast__Type)),})))) })); } } bool _t26 = (node->return_type != _const_v__ast__void_type && v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__result)); bool _t27 = (node->stmts.len == 0); if ( _t26 && ( _t27 || ((*(v__ast__Stmt*)array_last(node->stmts)))._typ != 412 /* v.ast.Return */)) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, node->return_type); if (sym->kind == v__ast__Kind__void) { array_push((array*)&node->stmts, _MOV((v__ast__Stmt[]){ v__ast__Return_to_sumtype_v__ast__Stmt(ADDR(v__ast__Return, (((v__ast__Return){.pos = node->pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.types = __new_array(0, 0, sizeof(v__ast__Type)),})))) })); } } c->fn_scope = node->scope; int typ_veb_result = v__ast__Table_get_veb_result_type_idx(c->table); if (node->is_method && _us32_eq(node->return_type,typ_veb_result)) { v__ast__Type ctx_idx = v__ast__Table_find_type(c->table, _S("main.Context")); if (ctx_idx < 1) { ctx_idx = v__ast__Table_find_type(c->table, _S("veb.Context")); } v__ast__Type typ_veb_context = v__ast__Type_set_nr_muls(ctx_idx, 1); bool _t29 = false; Array_v__ast__Param _t29_orig = node->params; int _t29_len = _t29_orig.len; for (int _t30 = 0; _t30 < _t29_len; ++_t30) { v__ast__Param it = ((v__ast__Param*) _t29_orig.data)[_t30]; if (v__checker__Checker_has_veb_context(c, it.typ)) { _t29 = true; break; } } if (!_t29 && node->params.len >= 1) { Array_v__ast__Param params = array_clone_to_depth(&node->params, 0); v__ast__Param ctx_param = ((v__ast__Param){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = _S("ctx"),.is_mut = true,.is_shared = 0,.is_atomic = 0,.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_hidden = 0,.on_newline = 0,.typ = typ_veb_context,}); node->params = new_array_from_c_array(2, 2, sizeof(v__ast__Param), _MOV((v__ast__Param[2]){(*(v__ast__Param*)array_get(node->params, 0)), ctx_param})); _PUSH_MANY(&node->params, (array_slice(params, 1, 2147483647)), _t31, Array_v__ast__Param); v__ast__TypeSymbol* rec_sym = v__ast__Table_sym(c->table, node->receiver.typ); _result_v__ast__Fn _t32; if (_t32 = v__ast__Table_find_method(c->table, rec_sym, node->name), !_t32.is_error) { v__ast__Fn m = *(v__ast__Fn*)_t32.data; Array_v__ast__Param p = array_clone_to_depth(&m.params, 0); m.params = new_array_from_c_array(2, 2, sizeof(v__ast__Param), _MOV((v__ast__Param[2]){(*(v__ast__Param*)array_get(m.params, 0)), ctx_param})); _PUSH_MANY(&m.params, (array_slice(p, 1, 2147483647)), _t33, Array_v__ast__Param); v__ast__TypeSymbol_update_method(rec_sym, m); } } v__ast__Scope_register(c->fn_scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){ .name = _S("ctx"), .share = 0, .is_mut = true, .is_static = 0, .is_volatile = 0, .is_autofree_tmp = 0, .is_inherited = 0, .has_inherited = 0, .is_arg = 0, .is_auto_deref = 0, .is_unwrapped = 0, .is_index_var = 0, .expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .typ = typ_veb_context, .orig_type = 0, .smartcasts = __new_array(0, 0, sizeof(v__ast__Type)), .pos = node->pos, .is_used = true, .is_changed = 0, .ct_type_var = 0, .ct_type_unwrapped = 0, .is_or = 0, .is_tmp = 0, .is_auto_heap = 0, .is_stack_obj = false, }))))); } v__checker__Checker_stmts(c, &node->stmts); bool node_has_top_return = v__checker__has_top_return(node->stmts); node->has_return = c->returns || node_has_top_return; v__checker__Checker_check_noreturn_fn_decl(c, node); if (node->language == v__ast__Language__v && !node->no_body && node->return_type != _const_v__ast__void_type && !node->has_return && !node->is_noreturn) { bool _t34 = c->inside_anon_fn; bool _t35; if (!(_t34)) { _t35 = !Array_v__ast__Attr_contains(node->attrs, _S("_naked")); } if (_t34) { v__checker__Checker_error(c, _S("missing return at the end of an anonymous function"), node->pos); } else if (_t35) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("missing return at end of function `"), 0xfe10, {.d_s = node->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } node->source_file = c->file; if (_IN_MAP(ADDR(string, node->name), ADDR(map, c->table->fns))) { if (!fast_string_eq(node->name, _S("main.main"))) { Array_string dep_names = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t36 = 0; _t36 < node->stmts.len; ++_t36) { v__ast__Stmt stmt = ((v__ast__Stmt*)node->stmts.data)[_t36]; Array_string dnames = v__ast__Table_dependent_names_in_stmt(c->table, stmt); for (int _t37 = 0; _t37 < dnames.len; ++_t37) { string dname = ((string*)dnames.data)[_t37]; if ((Array_string_contains(dep_names, dname))) { continue; } array_push((array*)&dep_names, _MOV((string[]){ string_clone(dname) })); } } if (dep_names.len > 0) { { // Unsafe block (*(v__ast__Fn*)map_get_and_set((map*)&c->table->fns, &(string[]){node->name}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })).dep_names = dep_names; } } } { // Unsafe block (*(v__ast__Fn*)map_get_and_set((map*)&c->table->fns, &(string[]){node->name}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })).source_fn = ((voidptr)(node)); } } bool _t39 = (node->attrs.len > 0); bool _t40 = false; if (_t39) { Array_v__ast__Import _t40_orig = c->file->imports; int _t40_len = _t40_orig.len; for (int _t41 = 0; _t41 < _t40_len; ++_t41) { v__ast__Import it = ((v__ast__Import*) _t40_orig.data)[_t41]; if (fast_string_eq(it.mod, _S("vweb"))) { _t40 = true; break; } } } if ( _t39 &&_t40) { for (int _t42 = 0; _t42 < node->attrs.len; ++_t42) { v__ast__Attr attr = ((v__ast__Attr*)node->attrs.data)[_t42]; if (string_starts_with(attr.name, _S("/"))) { if (!fast_string_eq(v__ast__Table_sym(c->table, node->return_type)->name, _S("vweb.Result"))) { v__checker__Checker_error(c, _S("vweb actions must return `vweb.Result`"), node->pos); } break; } } } if (node->is_expand_simple_interpolation) { bool _t43 = true; if (_t43 == (!node->is_method)) { v__checker__Checker_error(c, _S("@[expand_simple_interpolation] is supported only on methods"), node->pos); } else if (_t43 == (node->params.len != 2)) { v__checker__Checker_error(c, _S("methods tagged with @[expand_simple_interpolation], should have exactly 1 argument"), node->pos); } else if (_t43 == (!v__ast__Type_is_string((*(v__ast__Param*)array_get(node->params, 1)).typ))) { v__checker__Checker_error(c, _S("methods tagged with @[expand_simple_interpolation], should accept a single string"), node->pos); } else { } } // Defer begin if (v__checker__Checker_fn_decl_defer_0) { c->stmt_level = prev_stmt_level; c->fn_level--; c->returns = prev_returns; c->inside_anon_fn = prev_inside_anon_fn; c->inside_unsafe = prev_inside_unsafe; c->inside_defer = prev_inside_defer; c->in_for_count = prev_in_for_count; c->fn_scope = prev_fn_scope; } // Defer end } VV_LOC bool v__checker__Checker_check_same_type_ignoring_pointers(v__checker__Checker* c, v__ast__Type type_a, v__ast__Type type_b) { if (type_a != type_b) { v__ast__Type clean_type_a = v__ast__Type_set_nr_muls(type_a, 0); v__ast__Type clean_type_b = v__ast__Type_set_nr_muls(type_b, 0); return clean_type_a == clean_type_b; } return true; } VV_LOC v__ast__Type v__checker__Checker_anon_fn(v__checker__Checker* c, v__ast__AnonFn* node) { bool v__checker__Checker_anon_fn_defer_0 = false; v__ast__FnDecl* keep_fn; bool keep_inside_anon; v__ast__AnonFn* keep_anon_fn; keep_fn = c->table->cur_fn; keep_inside_anon = c->inside_anon_fn; keep_anon_fn = c->cur_anon_fn; c->table->used_features->anon_fn = true; v__checker__Checker_anon_fn_defer_0 = true; if (node->decl.no_body) { v__checker__Checker_error(c, _S("anonymous function must declare a body"), node->decl.pos); } for (int _t1 = 0; _t1 < node->decl.params.len; ++_t1) { v__ast__Param param = ((v__ast__Param*)node->decl.params.data)[_t1]; if ((param.name).len == 0) { v__checker__Checker_error(c, _S("use `_` to name an unused parameter"), param.pos); } } c->table->cur_fn = &node->decl; c->inside_anon_fn = true; c->cur_anon_fn = node; bool has_generic = false; for (int _t2 = 0; _t2 < node->inherited_vars.len; ++_t2) { v__ast__Param* var = ((v__ast__Param*)node->inherited_vars.data) + _t2; _option_v__ast__Var_ptr _t3 = v__ast__Scope_find_var(node->decl.scope->parent, var->name); if (_t3.state != 0) { IError err = _t3.err; _v_panic(str_intp(2, _MOV((StrIntpData[]){{_S("unexpected checker error: cannot find parent of inherited variable `"), 0xfe10, {.d_s = var->name}}, {_S("`"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } v__ast__Var* parent_var = (*(v__ast__Var**)_t3.data); if (var->is_mut && !parent_var->is_mut) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("original `"), 0xfe10, {.d_s = parent_var->name}}, {_S("` is immutable, declare it with `mut` to make it mutable"), 0, { .d_c = 0 }}})), var->pos); } v__ast__Type _t4; /* if prepend */ if (parent_var->smartcasts.len > 0) { _t4 = (*(v__ast__Type*)array_last(parent_var->smartcasts)); } else { _t4 = parent_var->typ; } v__ast__Type ptyp = _t4; if (parent_var->typ != _const_v__ast__no_type) { v__ast__TypeSymbol* parent_var_sym = v__ast__Table_final_sym(c->table, ptyp); if ((parent_var_sym->info)._typ == 553 /* v.ast.FnType */) { v__ast__Type ret_typ = v__checker__Checker_unwrap_generic(c, (*parent_var_sym->info._v__ast__FnType).func.return_type); if (v__ast__Type_has_flag(ret_typ, v__ast__TypeFlag__generic)) { Array_string generic_names = v__ast__Table_generic_type_names(c->table, ret_typ); string curr_list = Array_string_join(c->table->cur_fn->generic_names, _S(", ")); for (int _t5 = 0; _t5 < generic_names.len; ++_t5) { string name = ((string*)generic_names.data)[_t5]; if (!(Array_string_contains(c->table->cur_fn->generic_names, name))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("Add the generic type `"), 0xfe10, {.d_s = name}}, {_S("` to the anon fn generic list type, that is currently `["), 0xfe10, {.d_s = curr_list}}, {_S("]`"), 0, { .d_c = 0 }}})), var->pos); } } } } } if ((parent_var->expr)._typ == 360 /* v.ast.IfGuardExpr */) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, (*parent_var->expr._v__ast__IfGuardExpr).expr_type); if ((sym->info)._typ == 552 /* v.ast.MultiReturn */) { for (int i = 0; i < (*parent_var->expr._v__ast__IfGuardExpr).vars.len; ++i) { v__ast__IfGuardVar v = ((v__ast__IfGuardVar*)(*parent_var->expr._v__ast__IfGuardExpr).vars.data)[i]; if (string__eq(v.name, var->name)) { var->typ = (*(v__ast__Type*)array_get((*sym->info._v__ast__MultiReturn).types, i)); break; } } } else { var->typ = v__ast__Type_clear_option_and_result((*parent_var->expr._v__ast__IfGuardExpr).expr_type); } } else { var->typ = ptyp; } if (v__ast__Type_has_flag(var->typ, v__ast__TypeFlag__generic)) { has_generic = true; } v__ast__Scope_update_var_type(node->decl.scope, var->name, var->typ); } if (has_generic && node->decl.generic_names.len == 0) { v__checker__Checker_error(c, _S("generic closure fn must specify type parameter, e.g. fn [foo] [T]()"), node->decl.pos); } v__checker__Checker_stmts(c, &node->decl.stmts); v__checker__Checker_fn_decl(c, (voidptr)&node->decl); v__ast__Type _t6 = node->typ; // Defer begin if (v__checker__Checker_anon_fn_defer_0) { c->table->cur_fn = keep_fn; c->inside_anon_fn = keep_inside_anon; c->cur_anon_fn = keep_anon_fn; } // Defer end return _t6; } VV_LOC v__ast__Type v__checker__Checker_call_expr(v__checker__Checker* c, v__ast__CallExpr* node) { _option_v__ast__Var_ptr _t1; if (_t1 = v__ast__Scope_find_var(node->scope, node->name), _t1.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t1.data; if ((var->expr)._typ == 336 /* v.ast.AnonFn */ && var->pos.pos > node->pos.pos) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown function: "), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } } v__ast__Type left_type = v__checker__Checker_expr(c, &node->left); v__checker__Checker_check_expr_option_or_result_call(c, node->left, left_type); bool old_inside_fn_arg = c->inside_fn_arg; c->inside_fn_arg = true; bool continue_check = true; node->left_type = left_type; v__ast__Type typ = (node->is_method ? (v__checker__Checker_method_call(c, node, (voidptr)&continue_check)) : (v__checker__Checker_fn_call(c, node, (voidptr)&continue_check))); if (!continue_check) { return _const_v__ast__void_type; } c->inside_fn_arg = old_inside_fn_arg; v__ast__CallArg arg0 = (node->args.len > 0 ? ((*(v__ast__CallArg*)array_get(node->args, 0))) : (((v__ast__CallArg){.is_mut = 0,.share = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = 0,.is_tmp_autofree = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.should_be_ptr = 0,.ct_expr = 0,}))); bool free_tmp_arg_vars = c->pref->autofree && !c->is_builtin_mod && node->args.len > 0 && !c->inside_const && !v__ast__Type_has_flag(arg0.typ, v__ast__TypeFlag__option) && !v__ast__Type_has_flag(arg0.typ, v__ast__TypeFlag__result) && !((arg0.expr)._typ == 344 /* v.ast.CallExpr */ && (v__ast__Type_has_flag((*(v__ast__CallExpr*)__as_cast((arg0.expr)._v__ast__CallExpr,(arg0.expr)._typ, 344)).return_type, v__ast__TypeFlag__option) || v__ast__Type_has_flag((*(v__ast__CallExpr*)__as_cast((arg0.expr)._v__ast__CallExpr,(arg0.expr)._typ, 344)).return_type, v__ast__TypeFlag__result))); if (free_tmp_arg_vars) { for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg arg = ((v__ast__CallArg*)node->args.data)[i]; if (arg.typ != _const_v__ast__string_type) { continue; } if (((arg.expr)._typ == 358 /* v.ast.Ident */ || (arg.expr)._typ == 384 /* v.ast.StringLiteral */ || (arg.expr)._typ == 379 /* v.ast.SelectorExpr */ || (arg.expr)._typ == 350 /* v.ast.ComptimeSelector */) || ((arg.expr)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast((arg.expr)._v__ast__CallExpr,(arg.expr)._typ, 344)).or_block.kind != v__ast__OrKind__absent)) { continue; } if ((arg.expr)._typ == 344 /* v.ast.CallExpr */ && (fast_string_eq((*(v__ast__CallExpr*)__as_cast((arg.expr)._v__ast__CallExpr,(arg.expr)._typ, 344)).name, _S("json.encode")) || fast_string_eq((*(v__ast__CallExpr*)__as_cast((arg.expr)._v__ast__CallExpr,(arg.expr)._typ, 344)).name, _S("json.encode_pretty")))) { continue; } (*(v__ast__CallArg*)array_get(node->args, i)).is_tmp_autofree = true; } if (node->receiver_type == _const_v__ast__string_type && !((node->left)._typ == 358 /* v.ast.Ident */ || (node->left)._typ == 384 /* v.ast.StringLiteral */ || (node->left)._typ == 379 /* v.ast.SelectorExpr */)) { node->free_receiver = true; } } if (node->nr_ret_values == -1 && node->return_type != 0) { if (node->return_type == _const_v__ast__void_type) { node->nr_ret_values = 0; } else { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, node->return_type); if ((ret_sym->info)._typ == 552 /* v.ast.MultiReturn */) { node->nr_ret_values = (*ret_sym->info._v__ast__MultiReturn).types.len; } else { node->nr_ret_values = 1; } } } v__ast__Type old_expected_or_type = c->expected_or_type; c->expected_or_type = v__ast__Type_clear_flag(node->return_type, v__ast__TypeFlag__result); v__checker__Checker_stmts_ending_with_expression(c, &node->or_block.stmts, c->expected_or_type); if (node->or_block.kind == v__ast__OrKind__block) { bool old_inside_or_block_value = c->inside_or_block_value; c->inside_or_block_value = true; v__checker__Checker_check_or_expr(c, node->or_block, typ, c->expected_or_type, v__ast__CallExpr_to_sumtype_v__ast__Expr(node)); c->inside_or_block_value = old_inside_or_block_value; } c->expected_or_type = old_expected_or_type; v__checker__Checker_markused_call_expr(c, left_type, node); if (!c->inside_const && c->table->cur_fn != ((void*)0) && !c->table->cur_fn->is_main && !c->table->cur_fn->is_test) { if (node->or_block.kind == v__ast__OrKind__propagate_result && !v__ast__Type_has_flag(c->table->cur_fn->return_type, v__ast__TypeFlag__result) && !v__ast__Type_has_flag(c->table->cur_fn->return_type, v__ast__TypeFlag__option)) { v__checker__Checker_add_instruction_for_result_type(c); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("to propagate the Result call, `"), 0xfe10, {.d_s = c->table->cur_fn->name}}, {_S("` must return a Result"), 0, { .d_c = 0 }}})), node->or_block.pos); } if (node->or_block.kind == v__ast__OrKind__propagate_option && !v__ast__Type_has_flag(c->table->cur_fn->return_type, v__ast__TypeFlag__option)) { v__checker__Checker_add_instruction_for_option_type(c); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("to propagate the Option call, `"), 0xfe10, {.d_s = c->table->cur_fn->name}}, {_S("` must return an Option"), 0, { .d_c = 0 }}})), node->or_block.pos); } } return typ; } VV_LOC void v__checker__Checker_builtin_args(v__checker__Checker* c, v__ast__CallExpr* node, string fn_name, v__ast__Fn* func) { c->inside_interface_deref = true; c->expected_type = _const_v__ast__string_type; if (!(node->language != v__ast__Language__js && ((*(v__ast__CallArg*)array_get(node->args, 0)).expr)._typ == 344 /* v.ast.CallExpr */)) { (*(v__ast__CallArg*)array_get(node->args, 0)).typ = v__checker__Checker_expr(c, &(*(v__ast__CallArg*)array_get(node->args, 0)).expr); } v__ast__CallArg arg = (*(v__ast__CallArg*)array_get(node->args, 0)); v__checker__Checker_check_expr_option_or_result_call(c, arg.expr, arg.typ); if (v__ast__Type_is_void(arg.typ)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = fn_name}}, {_S("` can not print void expressions"), 0, { .d_c = 0 }}})), node->pos); } else if (arg.typ == _const_v__ast__char_type && v__ast__Type_nr_muls(arg.typ) == 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = fn_name}}, {_S("` cannot print type `char` directly, print its address or cast it to an integer instead"), 0, { .d_c = 0 }}})), node->pos); } else if ((arg.expr)._typ == 337 /* v.ast.ArrayDecompose */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = fn_name}}, {_S("` cannot print variadic values"), 0, { .d_c = 0 }}})), node->pos); } v__checker__Checker_fail_if_unreadable(c, arg.expr, arg.typ, _S("argument to print")); c->inside_interface_deref = false; node->return_type = _const_v__ast__void_type; v__checker__Checker_set_node_expected_arg_types(c, node, func); } VV_LOC bool v__checker__Checker_needs_unwrap_generic_type(v__checker__Checker* c, v__ast__Type typ) { if (typ == 0 || !v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { return false; } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); if (sym->info._typ == 518 /* v.ast.Struct */) { return true; } else if (sym->info._typ == 542 /* v.ast.Interface */) { return true; } else if (sym->info._typ == 544 /* v.ast.SumType */) { return true; } else if (sym->info._typ == 513 /* v.ast.Array */) { return v__checker__Checker_needs_unwrap_generic_type(c, (*sym->info._v__ast__Array).elem_type); } else if (sym->info._typ == 549 /* v.ast.ArrayFixed */) { return v__checker__Checker_needs_unwrap_generic_type(c, (*sym->info._v__ast__ArrayFixed).elem_type); } else if (sym->info._typ == 514 /* v.ast.Map */) { if (v__checker__Checker_needs_unwrap_generic_type(c, (*sym->info._v__ast__Map).key_type)) { return true; } if (v__checker__Checker_needs_unwrap_generic_type(c, (*sym->info._v__ast__Map).value_type)) { return true; } } else if (sym->info._typ == 550 /* v.ast.Chan */) { return v__checker__Checker_needs_unwrap_generic_type(c, (*sym->info._v__ast__Chan).elem_type); } else if (sym->info._typ == 551 /* v.ast.Thread */) { return v__checker__Checker_needs_unwrap_generic_type(c, (*sym->info._v__ast__Thread).return_type); } else { return false; } return false; } VV_LOC v__ast__Type v__checker__Checker_fn_call(v__checker__Checker* c, v__ast__CallExpr* node, bool* continue_check) { bool v__checker__Checker_fn_call_defer_0 = false; bool found; v__ast__Fn func; bool is_va_arg = fast_string_eq(node->name, _S("C.va_arg")); bool is_json_decode = fast_string_eq(node->name, _S("json.decode")); bool is_json_encode = fast_string_eq(node->name, _S("json.encode")); string fn_name = node->name; if (node->is_static_method) { if (c->table->cur_fn != ((void*)0)) { multi_return_v__ast__Type_string mr_32737 = v__ast__Table_convert_generic_static_type_name(c->table, fn_name, c->table->cur_fn->generic_names, c->table->cur_concrete_types); node->left_type = mr_32737.arg0; fn_name = mr_32737.arg1; map_set(&c->table->used_features->comptime_calls, &(string[]){fn_name}, &(bool[]) { true }); } } if (!c->file->is_test && _SLIT_EQ(fn_name.str, fn_name.len, "main")) { v__checker__Checker_error(c, _S("the `main` function cannot be called in the program"), node->pos); } bool has_generic = false; Array_v__ast__Type concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); node->concrete_types = node->raw_concrete_types; for (int _t1 = 0; _t1 < node->concrete_types.len; ++_t1) { v__ast__Type concrete_type = ((v__ast__Type*)node->concrete_types.data)[_t1]; if (v__ast__Type_has_flag(concrete_type, v__ast__TypeFlag__generic)) { has_generic = true; array_push((array*)&concrete_types, _MOV((v__ast__Type[]){ v__checker__Checker_unwrap_generic(c, concrete_type) })); } else { array_push((array*)&concrete_types, _MOV((v__ast__Type[]){ concrete_type })); } } if (c->table->cur_fn != ((void*)0) && c->table->cur_concrete_types.len == 0 && has_generic) { v__checker__Checker_error(c, _S("generic fn using generic types cannot be called outside of generic fn"), node->pos); } string fkey = v__ast__CallExpr_fkey(node); bool fn_name_has_dot = string_contains(fn_name, _S(".")); if (concrete_types.len > 0) { bool no_exists = true; if (fn_name_has_dot) { no_exists = v__ast__Table_register_fn_concrete_types(c->table, fkey, concrete_types); } else { no_exists = v__ast__Table_register_fn_concrete_types(c->table, string__plus(string__plus(c->mod, _S(".")), fkey), concrete_types); if (!no_exists) { no_exists = v__ast__Table_register_fn_concrete_types(c->table, fkey, concrete_types); } } if (no_exists) { c->need_recheck_generic_fns = true; } } int args_len = node->args.len; if (_SLIT_EQ(fn_name.str, fn_name.len, "JS.await")) { if (node->args.len > 1) { v__checker__Checker_error(c, _S("JS.await expects 1 argument, a promise value (e.g `JS.await(fs.read())`"), node->pos); return _const_v__ast__void_type; } v__ast__Type typ = v__checker__Checker_expr(c, &(*(v__ast__CallArg*)array_get(node->args, 0)).expr); v__ast__TypeSymbol* tsym = v__ast__Table_sym(c->table, typ); if (!string_starts_with(tsym->name, _S("Promise["))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("JS.await: first argument must be a promise, got `"), 0xfe10, {.d_s = tsym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__void_type; } if (c->table->cur_fn != ((void*)0)) { c->table->cur_fn->has_await = true; } if (tsym->info._typ == 518 /* v.ast.Struct */) { v__ast__Type ret_type = (*(v__ast__Type*)array_get((*tsym->info._v__ast__Struct).concrete_types, 0)); ret_type = v__ast__Type_set_flag(ret_type, v__ast__TypeFlag__option); node->return_type = ret_type; return ret_type; } else { v__checker__Checker_error(c, _S("JS.await: Promise must be a struct type"), node->pos); return _const_v__ast__void_type; } _v_panic(_S("unreachable")); VUNREACHABLE(); } else if (args_len > 0 && v__ast__Type_has_flag((*(v__ast__CallArg*)array_get(node->args, 0)).typ, v__ast__TypeFlag__shared_f) && _SLIT_EQ(fn_name.str, fn_name.len, "json.encode")) { v__checker__Checker_error(c, _S("json.encode cannot handle shared data"), node->pos); return _const_v__ast__void_type; } else if (args_len > 0 && (is_va_arg || is_json_decode)) { if (args_len != 2) { if (is_json_decode) { v__checker__Checker_error(c, _S("json.decode expects 2 arguments, a type and a string (e.g `json.decode(T, '')`)"), node->pos); } else { v__checker__Checker_error(c, _S("C.va_arg expects 2 arguments, a type and va_list (e.g `C.va_arg(int, va)`)"), node->pos); } return _const_v__ast__void_type; } v__ast__Expr expr = (*(v__ast__CallArg*)array_get(node->args, 0)).expr; if ((expr)._typ == 386 /* v.ast.TypeNode */) { (*expr._v__ast__TypeNode).typ = v__checker__Checker_expr(c, HEAP(v__ast__Expr, v__ast__TypeNode_to_sumtype_v__ast__Expr(&(*expr._v__ast__TypeNode)))); v__ast__Type unwrapped_typ = v__checker__Checker_unwrap_generic(c, (*expr._v__ast__TypeNode).typ); if (v__checker__Checker_needs_unwrap_generic_type(c, (*expr._v__ast__TypeNode).typ)) { unwrapped_typ = v__ast__Table_unwrap_generic_type(c->table, (*expr._v__ast__TypeNode).typ, c->table->cur_fn->generic_names, c->table->cur_concrete_types); } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, unwrapped_typ); if (v__ast__Table_known_type(c->table, sym->name) && sym->kind != v__ast__Kind__placeholder) { v__ast__Kind kind = sym->kind; if ((sym->info)._typ == 539 /* v.ast.Alias */) { kind = v__ast__Table_sym(c->table, (*sym->info._v__ast__Alias).parent_type)->kind; } if (is_json_decode && !(kind == v__ast__Kind__struct || kind == v__ast__Kind__sum_type || kind == v__ast__Kind__map || kind == v__ast__Kind__array)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_name}}, {_S(": expected sum type, struct, map or array, found "), 0xfe10, {.d_s = v__ast__Kind_str(kind)}}, {_SLIT0, 0, { .d_c = 0 }}})), (*expr._v__ast__TypeNode).pos); } } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_name}}, {_S(": unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } else { string typ = charptr_vstring_literal(v_typeof_sumtype_v__ast__Expr( (expr)._typ )); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_name}}, {_S(": first argument needs to be a type, got `"), 0xfe10, {.d_s = typ}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__void_type; } c->expected_type = _const_v__ast__string_type; (*(v__ast__CallArg*)array_get(node->args, 1)).typ = v__checker__Checker_expr(c, &(*(v__ast__CallArg*)array_get(node->args, 1)).expr); if (is_json_decode && (*(v__ast__CallArg*)array_get(node->args, 1)).typ != _const_v__ast__string_type) { v__checker__Checker_error(c, _S("json.decode: second argument needs to be a string"), node->pos); } v__ast__TypeNode typ = *(v__ast__TypeNode*)__as_cast((expr)._v__ast__TypeNode,(expr)._typ, 386); node->return_type = (is_json_decode ? (v__ast__Type_set_flag(typ.typ, v__ast__TypeFlag__result)) : (typ.typ)); if (v__ast__Type_has_flag(typ.typ, v__ast__TypeFlag__generic)) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__checker__Checker_unwrap_generic(c, typ.typ)}, &(bool[]) { true }); } return node->return_type; } else if (_SLIT_EQ(fn_name.str, fn_name.len, "__addr")) { if (!c->inside_unsafe) { v__checker__Checker_error(c, _S("`__addr` must be called from an unsafe block"), node->pos); } if (args_len != 1) { v__checker__Checker_error(c, _S("`__addr` requires 1 argument"), node->pos); return _const_v__ast__void_type; } v__ast__Type typ = v__checker__Checker_expr(c, &(*(v__ast__CallArg*)array_get(node->args, 0)).expr); (*(v__ast__CallArg*)array_get(node->args, 0)).typ = typ; node->return_type = v__ast__Type_ref(typ); return node->return_type; } func = ((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); found = false; bool found_in_args = false; v__checker__Checker_fn_call_defer_0 = true; if ((node->left)._typ == 336 /* v.ast.AnonFn */) { node->name = _S(""); v__ast__AnonFn left = *(v__ast__AnonFn*)__as_cast((node->left)._v__ast__AnonFn,(node->left)._typ, 336); if (left.typ != _const_v__ast__no_type) { v__ast__TypeSymbol* anon_fn_sym = v__ast__Table_sym(c->table, left.typ); func = (*(v__ast__FnType*)__as_cast((anon_fn_sym->info)._v__ast__FnType,(anon_fn_sym->info)._typ, 553)).func; found = true; } } if (!found && !fast_string_eq(node->mod, _S("builtin")) && !fn_name_has_dot) { string name_prefixed = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node->mod}}, {_S("."), 0xfe10, {.d_s = fn_name}}, {_SLIT0, 0, { .d_c = 0 }}})); _option_v__ast__Fn _t14; if (_t14 = v__ast__Table_find_fn(c->table, name_prefixed), _t14.state == 0) { v__ast__Fn f = *(v__ast__Fn*)_t14.data; node->name = name_prefixed; found = true; func = f; (*(v__ast__Fn*)map_get((map*)&c->table->fns, &(string[]){name_prefixed}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })).usages++; } } if (!found && (node->left)._typ == 361 /* v.ast.IndexExpr */) { v__ast__IndexExpr left = *(v__ast__IndexExpr*)__as_cast((node->left)._v__ast__IndexExpr,(node->left)._typ, 361); v__ast__TypeSymbol* sym = v__ast__Table_final_sym(c->table, left.left_type); if ((sym->info)._typ == 513 /* v.ast.Array */) { v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(c->table, (*sym->info._v__ast__Array).elem_type); if ((elem_sym->info)._typ == 553 /* v.ast.FnType */) { func = (*elem_sym->info._v__ast__FnType).func; found = true; node->is_fn_var = true; node->fn_var_type = (*sym->info._v__ast__Array).elem_type; } else { v__checker__Checker_error(c, _S("cannot call the element of the array, it is not a function"), node->pos); } } else if ((sym->info)._typ == 514 /* v.ast.Map */) { v__ast__TypeSymbol* value_sym = v__ast__Table_sym(c->table, (*sym->info._v__ast__Map).value_type); if ((value_sym->info)._typ == 553 /* v.ast.FnType */) { func = (*value_sym->info._v__ast__FnType).func; found = true; node->is_fn_var = true; node->fn_var_type = (*sym->info._v__ast__Map).value_type; } else { v__checker__Checker_error(c, _S("cannot call the value of the map, it is not a function"), node->pos); } } else if ((sym->info)._typ == 549 /* v.ast.ArrayFixed */) { v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(c->table, (*sym->info._v__ast__ArrayFixed).elem_type); if ((elem_sym->info)._typ == 553 /* v.ast.FnType */) { func = (*elem_sym->info._v__ast__FnType).func; found = true; node->is_fn_var = true; node->fn_var_type = (*sym->info._v__ast__ArrayFixed).elem_type; } else { v__checker__Checker_error(c, _S("cannot call the element of the array, it is not a function"), node->pos); } } } if (!found && (node->left)._typ == 344 /* v.ast.CallExpr */) { v__ast__CallExpr left = *(v__ast__CallExpr*)__as_cast((node->left)._v__ast__CallExpr,(node->left)._typ, 344); if (left.return_type != 0) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, left.return_type); if ((sym->info)._typ == 553 /* v.ast.FnType */) { node->return_type = (*sym->info._v__ast__FnType).func.return_type; found = true; func = (*sym->info._v__ast__FnType).func; } } } if (!found) { _option_v__ast__Fn _t15; if (_t15 = v__ast__Table_find_fn(c->table, fn_name), _t15.state == 0) { v__ast__Fn f = *(v__ast__Fn*)_t15.data; found = true; func = f; (*(v__ast__Fn*)map_get((map*)&c->table->fns, &(string[]){fn_name}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })).usages++; } } if (!found && node->is_static_method) { _option_int _t16; if (_t16 = string_index(fn_name, _S("__static__")), _t16.state == 0) { int index = *(int*)_t16.data; string owner_name = string_substr_ni(fn_name, 0, index); Array_v__ast__Import _t18 = {0}; Array_v__ast__Import _t18_orig = c->file->imports; int _t18_len = _t18_orig.len; _t18 = __new_array(0, _t18_len, sizeof(v__ast__Import)); for (int _t19 = 0; _t19 < _t18_len; ++_t19) { v__ast__Import it = ((v__ast__Import*) _t18_orig.data)[_t19]; bool _t20 = false; Array_v__ast__ImportSymbol _t20_orig = it.syms; int _t20_len = _t20_orig.len; for (int _t21 = 0; _t21 < _t20_len; ++_t21) { v__ast__ImportSymbol it = ((v__ast__ImportSymbol*) _t20_orig.data)[_t21]; if (string__eq(it.name, owner_name)) { _t20 = true; break; } } if (_t20) { array_push((array*)&_t18, &it); } } Array_v__ast__Import _t17 =_t18; for (int _t22 = 0; _t22 < _t17.len; ++_t22) { v__ast__Import import_sym = ((v__ast__Import*)_t17.data)[_t22]; string qualified_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = import_sym.mod}}, {_S("."), 0xfe10, {.d_s = fn_name}}, {_SLIT0, 0, { .d_c = 0 }}})); _option_v__ast__Fn _t23; if (_t23 = v__ast__Table_find_fn(c->table, qualified_name), _t23.state == 0) { v__ast__Fn f = *(v__ast__Fn*)_t23.data; found = true; func = f; node->name = qualified_name; (*(v__ast__Fn*)map_get((map*)&c->table->fns, &(string[]){qualified_name}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })).usages++; break; } } if (!found) { string full_type_name = (!fn_name_has_dot ? (string__plus(string__plus(c->mod, _S(".")), owner_name)) : (owner_name)); v__ast__Type typ = v__ast__Table_find_type(c->table, full_type_name); if (typ != 0) { v__ast__TypeSymbol* final_sym = v__ast__Table_final_sym(c->table, typ); string orig_name = string__plus(final_sym->name, string_substr_ni(fn_name, index, 2147483647)); _option_v__ast__Fn _t24; if (_t24 = v__ast__Table_find_fn(c->table, orig_name), _t24.state == 0) { v__ast__Fn f = *(v__ast__Fn*)_t24.data; found = true; func = f; (*(v__ast__Fn*)map_get((map*)&c->table->fns, &(string[]){orig_name}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })).usages++; node->name = orig_name; node->left_type = typ; } } } } if (!found && string_ends_with(fn_name, _S("__static__from_string"))) { string enum_name = string_all_before(fn_name, _S("__static__")); string full_enum_name = (!string_contains(enum_name, _S(".")) ? (string__plus(string__plus(c->mod, _S(".")), enum_name)) : (enum_name)); int idx = (*(int*)map_get(ADDR(map, c->table->type_idxs), &(string[]){full_enum_name}, &(int[]){ 0 })); if (idx > 0) { if (string_contains(enum_name, _S("."))) { if (!v__checker__Checker_check_type_and_visibility(c, full_enum_name, idx, ADDR(v__ast__Kind, v__ast__Kind__enum), (voidptr)&node->pos)) { v__ast__Type _t25 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t25; } } else { if (!v__checker__Checker_check_type_sym_kind(c, full_enum_name, idx, ADDR(v__ast__Kind, v__ast__Kind__enum), (voidptr)&node->pos)) { v__ast__Type _t26 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t26; } } } else if (!string_contains(enum_name, _S("."))) { for (int _t27 = 0; _t27 < c->file->imports.len; ++_t27) { v__ast__Import import_sym = ((v__ast__Import*)c->file->imports.data)[_t27]; full_enum_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = import_sym.mod}}, {_S("."), 0xfe10, {.d_s = enum_name}}, {_SLIT0, 0, { .d_c = 0 }}})); idx = (*(int*)map_get(ADDR(map, c->table->type_idxs), &(string[]){full_enum_name}, &(int[]){ 0 })); if (idx < 1) { continue; } if (!v__checker__Checker_check_type_and_visibility(c, full_enum_name, idx, ADDR(v__ast__Kind, v__ast__Kind__enum), (voidptr)&node->pos)) { v__ast__Type _t28 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t28; } break; } } if (idx == 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown enum `"), 0xfe10, {.d_s = enum_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); *continue_check = false; v__ast__Type _t29 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t29; } v__ast__Type ret_typ = v__ast__Type_set_flag(v__ast__idx_to_type(idx), v__ast__TypeFlag__option); if (args_len != 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expected 1 argument, but got "), 0xfe07, {.d_i32 = args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else { (*(v__ast__CallArg*)array_get(node->args, 0)).typ = v__checker__Checker_expr(c, &(*(v__ast__CallArg*)array_get(node->args, 0)).expr); if ((*(v__ast__CallArg*)array_get(node->args, 0)).typ != _const_v__ast__string_type) { string styp = v__ast__Table_type_to_str(c->table, (*(v__ast__CallArg*)array_get(node->args, 0)).typ); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expected `string` argument, but got `"), 0xfe10, {.d_s = styp}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } node->return_type = ret_typ; v__ast__Type _t30 = ret_typ; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t30; } } bool is_native_builtin = false; if (!found && c->pref->backend == v__pref__Backend__native) { if ((Array_string_contains(_const_v__ast__native_builtins, fn_name))) { (*(v__ast__Fn*)map_get((map*)&c->table->fns, &(string[]){fn_name}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })).usages++; found = true; func = (*(v__ast__Fn*)map_get(ADDR(map, c->table->fns), &(string[]){fn_name}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })); is_native_builtin = true; } } if (!found && c->pref->is_vsh) { string os_name = str_intp(2, _MOV((StrIntpData[]){{_S("os."), 0xfe10, {.d_s = fn_name}}, {_SLIT0, 0, { .d_c = 0 }}})); _option_v__ast__Fn _t31; if (_t31 = v__ast__Table_find_fn(c->table, os_name), _t31.state == 0) { v__ast__Fn f = *(v__ast__Fn*)_t31.data; if (f.generic_names.len == node->concrete_types.len) { string node_alias_name = fkey; Array_Array_v__ast__Type* _t33 = (Array_Array_v__ast__Type*)(map_get_check(ADDR(map, c->table->fn_generic_types), &(string[]){os_name})); _option_Array_Array_v__ast__Type _t32 = {0}; if (_t33) { *((Array_Array_v__ast__Type*)&_t32.data) = *((Array_Array_v__ast__Type*)_t33); } else { _t32.state = 2; _t32.err = _v_error(_S("map key does not exist")); } ; if (_t32.state != 0) { IError err = _t32.err; *(Array_Array_v__ast__Type*) _t32.data = __new_array_with_default(0, 0, sizeof(Array_v__ast__Type), 0); } Array_Array_v__ast__Type existing = (*(Array_Array_v__ast__Type*)_t32.data); _PUSH_MANY(&existing, ((*(Array_Array_v__ast__Type*)map_get((map*)&c->table->fn_generic_types, &(string[]){node_alias_name}, &(Array_Array_v__ast__Type[]){ __new_array(0, 0, sizeof(Array_v__ast__Type)) }))), _t34, Array_Array_v__ast__Type); array_push((array*)&existing, _MOV((Array_v__ast__Type[]){ node->concrete_types })); (*(Array_Array_v__ast__Type*)map_get_and_set((map*)&c->table->fn_generic_types, &(string[]){os_name}, &(Array_Array_v__ast__Type[]){ __new_array(0, 0, sizeof(Array_v__ast__Type)) })) = existing; } node->name = os_name; found = true; func = f; (*(v__ast__Fn*)map_get((map*)&c->table->fns, &(string[]){os_name}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })).usages++; } } if (is_native_builtin) { if (args_len > 0 && (Array_string_contains(_const_v__checker__print_everything_fns, fn_name))) { v__checker__Checker_builtin_args(c, node, fn_name, (voidptr)&func); v__ast__Type _t36 = func.return_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t36; } v__ast__Type _t37 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t37; } if (!found) { int typ = 0; _option_v__ast__ScopeObject _t38; if (_t38 = v__ast__Scope_find(node->scope, node->name), _t38.state == 0) { v__ast__ScopeObject obj = *(v__ast__ScopeObject*)_t38.data; if (obj._typ == 421 /* v.ast.GlobalField */) { typ = (*obj._v__ast__GlobalField).typ; node->is_fn_var = true; node->fn_var_type = typ; } else if (obj._typ == 422 /* v.ast.Var */) { if ((*obj._v__ast__Var).smartcasts.len != 0) { typ = (*(v__ast__Type*)array_last((*obj._v__ast__Var).smartcasts)); } else { if ((*obj._v__ast__Var).typ == 0) { if (((*obj._v__ast__Var).expr)._typ == 360 /* v.ast.IfGuardExpr */) { typ = v__ast__Type_clear_option_and_result(v__checker__Checker_expr(c, &(*(*obj._v__ast__Var).expr._v__ast__IfGuardExpr).expr)); } else { typ = v__checker__Checker_expr(c, &(*obj._v__ast__Var).expr); } } else { typ = (*obj._v__ast__Var).typ; } } node->is_fn_var = true; node->fn_var_type = typ; } else { } } if (typ != 0) { v__ast__TypeSymbol* generic_vts = v__ast__Table_final_sym(c->table, typ); if ((generic_vts->info)._typ == 553 /* v.ast.FnType */) { func = (*generic_vts->info._v__ast__FnType).func; found = true; found_in_args = true; } else { v__ast__TypeSymbol* vts = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, typ)); if ((vts->info)._typ == 553 /* v.ast.FnType */) { func = (*vts->info._v__ast__FnType).func; found = true; found_in_args = true; } } } } if (!found) { _option_v__ast__ScopeObject _t39; if (_t39 = v__ast__Scope_find(c->file->global_scope, fn_name), _t39.state == 0) { v__ast__ScopeObject obj = *(v__ast__ScopeObject*)_t39.data; if ((*(obj.typ)) != 0) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, (*(obj.typ))); if ((sym->info)._typ == 553 /* v.ast.FnType */) { func = (*sym->info._v__ast__FnType).func; found = true; } } } } if (!found) { string qualified_const_name = (fn_name_has_dot ? (fn_name) : (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->mod}}, {_S("."), 0xfe10, {.d_s = fn_name}}, {_SLIT0, 0, { .d_c = 0 }}})))); _option_v__ast__ConstField_ptr _t40; if (_t40 = v__ast__Scope_find_const(c->table->global_scope, qualified_const_name), _t40.state == 0) { v__ast__ConstField* obj = *(v__ast__ConstField**)_t40.data; if (obj->typ == 0) { obj->typ = v__checker__Checker_expr(c, &obj->expr); } if (obj->typ != 0) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, obj->typ); if ((sym->info)._typ == 553 /* v.ast.FnType */) { (*(v__ast__Fn*)map_get((map*)&c->table->fns, &(string[]){qualified_const_name}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })).usages++; (*(v__ast__Fn*)map_get((map*)&c->table->fns, &(string[]){func.name}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })).usages++; found = true; func = (*sym->info._v__ast__FnType).func; node->is_fn_a_const = true; node->fn_var_type = obj->typ; node->const_name = qualified_const_name; } } } } if (!found) { *continue_check = false; _option_int _t41; if (_t41 = string_index(fn_name, _S(".")), _t41.state == 0) { int dot_index = *(int*)_t41.data; if (!u8_is_capital(string_at(fn_name, 0))) { string mod_name = string_substr_ni(fn_name, 0, dot_index); Array_string mod_func_names = __new_array_with_default(0, 0, sizeof(string), 0); Map_string_v__ast__Fn _t42 = c->table->fns; int _t44 = _t42.key_values.len; for (int _t43 = 0; _t43 < _t44; ++_t43 ) { int _t45 = _t42.key_values.len - _t44; _t44 = _t42.key_values.len; if (_t45 < 0) { _t43 = -1; continue; } if (!DenseArray_has_index(&_t42.key_values, _t43)) {continue;} string ctfnk = *(string*)DenseArray_key(&_t42.key_values, _t43); ctfnk = string_clone(ctfnk); v__ast__Fn ctfnv = (*(v__ast__Fn*)DenseArray_value(&_t42.key_values, _t43)); if (ctfnv.is_pub && string_starts_with(ctfnk, mod_name)) { array_push((array*)&mod_func_names, _MOV((string[]){ string_clone(ctfnk) })); } } v__util__Suggestion suggestion = v__util__new_suggestion(fn_name, mod_func_names, ((v__util__SuggestionParams){.similarity_threshold = 0.5,.similarity_fn = strings__dice_coefficient,})); v__checker__Checker_error(c, v__util__Suggestion_say(suggestion, str_intp(2, _MOV((StrIntpData[]){{_S("unknown function: "), 0xfe10, {.d_s = fn_name}}, {_S(" "), 0, { .d_c = 0 }}}))), node->pos); v__ast__Type _t47 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t47; } } string name = v__ast__CallExpr_get_name(node); if (c->pref->experimental && string_starts_with(name, _S("C."))) { println(string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("unknown function "), 0xfe10, {.d_s = name}}, {_S(", "), 0, { .d_c = 0 }}})), _S("searching for the C definition in one of the #includes"))); Array_string includes = __new_array_with_default(0, 5, sizeof(string), 0); for (int _t48 = 0; _t48 < c->file->stmts.len; ++_t48) { v__ast__Stmt stmt = ((v__ast__Stmt*)c->file->stmts.data)[_t48]; if ((stmt)._typ == 408 /* v.ast.HashStmt */) { if (fast_string_eq((*stmt._v__ast__HashStmt).kind, _S("include"))) { array_push((array*)&includes, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("#include "), 0xfe10, {.d_s = (*stmt._v__ast__HashStmt).main}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } } _result_os__File _t50 = os__create(_S("tmp.c")); if (_t50.is_error) { IError err = _t50.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } os__File tmp_c_file_with_includes = (*(os__File*)_t50.data); _result_int _t51 = os__File_write_string(&tmp_c_file_with_includes, Array_string_join(includes, _S("\n"))); if (_t51.is_error) { IError err = _t51.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; os__File_close(&tmp_c_file_with_includes); os__execute(str_intp(2, _MOV((StrIntpData[]){{_S("v translate fndef "), 0xfe10, {.d_s = string_substr(name, 2, 2147483647)}}, {_S(" tmp.c"), 0, { .d_c = 0 }}}))); _result_string _t52 = os__read_file(_S("__cdefs_autogen.v")); if (_t52.is_error) { IError err = _t52.err; for (int _t53 = 0; _t53 < node->args.len; ++_t53) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + _t53; v__checker__Checker_expr(c, &arg->expr); } v__ast__Type _t54 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t54; } string x = (*(string*)_t52.data); if (string_contains(x, str_intp(2, _MOV((StrIntpData[]){{_S("fn "), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})))) { println(string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("function definition for "), 0xfe10, {.d_s = name}}, {_S(" has been generated in __cdefs_autogen.v. "), 0, { .d_c = 0 }}})), _S("Please re-run the compilation with `v .` or `v run .`"))); _result_void _t55 = os__rm(_S("tmp.c")); (void)_t55; ; _v_exit(0); VUNREACHABLE(); } else { println(_S("Failed to generate function definition. Please report it via github.com/vlang/v/issues")); } _result_void _t56 = os__rm(_S("tmp.c")); (void)_t56; ; } for (int _t57 = 0; _t57 < node->args.len; ++_t57) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + _t57; v__checker__Checker_expr(c, &arg->expr); } v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown function: "), 0xfe10, {.d_s = v__ast__CallExpr_get_name(node)}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); v__ast__Type _t58 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t58; } node->is_file_translated = func.is_file_translated; node->is_noreturn = func.is_noreturn; node->is_expand_simple_interpolation = func.is_expand_simple_interpolation; node->is_ctor_new = func.is_ctor_new; if (!found_in_args) { if (v__ast__Scope_known_var(node->scope, fn_name)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("ambiguous call to: `"), 0xfe10, {.d_s = fn_name}}, {_S("`, may refer to fn `"), 0xfe10, {.d_s = fn_name}}, {_S("` or variable `"), 0xfe10, {.d_s = fn_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } if (!func.is_pub && func.language == v__ast__Language__v && (func.name).len != 0 && func.mod.len > 0 && !string__eq(func.mod, c->mod) && !c->pref->is_test) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("function `"), 0xfe10, {.d_s = func.name}}, {_S("` is private"), 0, { .d_c = 0 }}})), node->pos); } if (c->table->cur_fn != ((void*)0) && !c->table->cur_fn->is_deprecated && func.is_deprecated) { v__checker__Checker_deprecate(c, _S("function"), func.name, func.attrs, node->pos); } if (func.is_unsafe && !c->inside_unsafe && (func.language != v__ast__Language__c || ((string_at(func.name, 2) == 'm' || string_at(func.name, 2) == 's') && fast_string_eq(func.mod, _S("builtin"))))) { if (!c->pref->translated && !c->file->is_translated) { v__checker__Checker_warn(c, str_intp(2, _MOV((StrIntpData[]){{_S("function `"), 0xfe10, {.d_s = func.name}}, {_S("` must be called from an `unsafe` block"), 0, { .d_c = 0 }}})), node->pos); } } node->is_keep_alive = func.is_keep_alive; if (func.language == v__ast__Language__v && func.no_body && !c->pref->translated && !c->file->is_translated && !func.is_unsafe && !func.is_file_translated && !fast_string_eq(func.mod, _S("builtin"))) { v__checker__Checker_error(c, _S("cannot call a function that does not have a body"), node->pos); } if (node->concrete_types.len > 0 && func.generic_names.len > 0 && node->concrete_types.len != func.generic_names.len) { string plural = (func.generic_names.len == 1 ? (_S("")) : (_S("s"))); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("expected "), 0xfe07, {.d_i32 = func.generic_names.len}}, {_S(" generic parameter"), 0xfe10, {.d_s = plural}}, {_S(", got "), 0xfe07, {.d_i32 = node->concrete_types.len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->concrete_list_pos); } for (int _t59 = 0; _t59 < node->concrete_types.len; ++_t59) { v__ast__Type concrete_type = ((v__ast__Type*)node->concrete_types.data)[_t59]; v__checker__Checker_ensure_type_exists(c, concrete_type, node->concrete_list_pos); } if (func.generic_names.len > 0 && args_len == 0 && node->concrete_types.len == 0) { v__checker__Checker_error(c, _S("no argument generic function must add concrete types, e.g. foo[int]()"), node->pos); v__ast__Type _t60 = func.return_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t60; } if (func.return_type == _const_v__ast__void_type && func.is_conditional && func.ctdefine_idx != -1) { node->should_be_skipped = v__checker__Checker_evaluate_once_comptime_if_attribute(c, (voidptr)&(*(v__ast__Attr*)array_get(func.attrs, func.ctdefine_idx))); } if (node->language != v__ast__Language__js) { for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* call_arg = ((v__ast__CallArg*)node->args.data) + i; if ((call_arg->expr)._typ == 344 /* v.ast.CallExpr */) { (*(v__ast__CallArg*)array_get(node->args, i)).typ = v__checker__Checker_expr(c, &call_arg->expr); } else if ((call_arg->expr)._typ == 365 /* v.ast.LambdaExpr */) { if (node->concrete_types.len > 0) { (*call_arg->expr._v__ast__LambdaExpr).call_ctx = node; } } } _result_void _t61 = v__checker__Checker_check_expected_arg_count(c, node, (voidptr)&func); if (_t61.is_error) { IError err = _t61.err; v__ast__Type _t62 = func.return_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t62; } ; } if (args_len > 0 && (Array_string_contains(_const_v__checker__print_everything_fns, fn_name))) { (*(v__ast__CallArg*)array_get(node->args, 0)).ct_expr = v__type_resolver__ResolverInfo_is_comptime(c->comptime, (*(v__ast__CallArg*)array_get(node->args, 0)).expr); v__checker__Checker_builtin_args(c, node, fn_name, (voidptr)&func); v__checker__Checker_markused_fn_call(c, node); v__ast__Type _t63 = func.return_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t63; } if (args_len == 1 && _SLIT_EQ(fn_name.str, fn_name.len, "error")) { v__ast__CallArg arg = (*(v__ast__CallArg*)array_get(node->args, 0)); (*(v__ast__CallArg*)array_get(node->args, 0)).typ = v__checker__Checker_expr(c, &arg.expr); (*(v__ast__CallArg*)array_get(node->args, 0)).ct_expr = v__type_resolver__ResolverInfo_is_comptime(c->comptime, (*(v__ast__CallArg*)array_get(node->args, 0)).expr); if ((*(v__ast__CallArg*)array_get(node->args, 0)).typ == _const_v__ast__error_type) { v__checker__Checker_warn(c, str_intp(3, _MOV((StrIntpData[]){{_S("`error("), 0xfe10, {.d_s = v__ast__CallArg_str(arg)}}, {_S(")` can be shortened to just `"), 0xfe10, {.d_s = v__ast__CallArg_str(arg)}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } v__checker__Checker_set_node_expected_arg_types(c, node, (voidptr)&func); if (!v__pref__Backend_is_js(c->pref->backend) && args_len > 0 && func.params.len == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("too many arguments in call to `"), 0xfe10, {.d_s = func.name}}, {_S("` (non-js backend: "), 0xfe10, {.d_s = v__pref__Backend_str(c->pref->backend)}}, {_S(")"), 0, { .d_c = 0 }}})), node->pos); } bool has_decompose = false; for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* call_arg = ((v__ast__CallArg*)node->args.data) + i; if (func.params.len == 0) { continue; } if (!c->inside_recheck) { call_arg->ct_expr = v__type_resolver__ResolverInfo_is_comptime(c->comptime, call_arg->expr); } if (!func.is_variadic && has_decompose) { v__checker__Checker_error(c, _S("cannot have parameter after array decompose"), node->pos); } v__ast__Param _t64; /* if prepend */ if (func.is_variadic && i >= (int)(func.params.len - 1)) { _t64 = (*(v__ast__Param*)array_last(func.params)); } else { _t64 = (*(v__ast__Param*)array_get(func.params, i)); } v__ast__Param param = _t64; call_arg->should_be_ptr = v__ast__Type_is_ptr(param.typ) && !param.is_mut; if (func.is_variadic && (call_arg->expr)._typ == 337 /* v.ast.ArrayDecompose */) { if (i > (int)(func.params.len - 1)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("too many arguments in call to `"), 0xfe10, {.d_s = func.name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } has_decompose = (call_arg->expr)._typ == 337 /* v.ast.ArrayDecompose */; bool already_checked = node->language != v__ast__Language__js && (call_arg->expr)._typ == 344 /* v.ast.CallExpr */; if (func.is_variadic && i >= (int)(func.params.len - 1)) { v__ast__TypeSymbol* param_sym = v__ast__Table_sym(c->table, param.typ); v__ast__Type expected_type = param.typ; if ((param_sym->info)._typ == 513 /* v.ast.Array */) { expected_type = (*param_sym->info._v__ast__Array).elem_type; c->expected_type = expected_type; } v__ast__Type typ = (already_checked && (call_arg->expr)._typ == 344 /* v.ast.CallExpr */ ? ((*(v__ast__CallArg*)array_get(node->args, i)).typ) : (v__checker__Checker_expr(c, &call_arg->expr))); if (i == (int)(args_len - 1)) { if (v__ast__Table_sym(c->table, typ)->kind == v__ast__Kind__array && (call_arg->expr)._typ != 337 /* v.ast.ArrayDecompose */ && !(v__ast__Table_sym(c->table, expected_type)->kind == v__ast__Kind__sum_type || v__ast__Table_sym(c->table, expected_type)->kind == v__ast__Kind__interface) && !v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic) && expected_type != typ) { string styp = v__ast__Table_type_to_str(c->table, typ); string elem_styp = v__ast__Table_type_to_str(c->table, expected_type); v__checker__Checker_error(c, str_intp(6, _MOV((StrIntpData[]){{_S("to pass `"), 0xfe10, {.d_s = v__ast__Expr_str(&call_arg->expr)}}, {_S("` ("), 0xfe10, {.d_s = styp}}, {_S(") to `"), 0xfe10, {.d_s = func.name}}, {_S("` (which accepts type `..."), 0xfe10, {.d_s = elem_styp}}, {_S("`), use `..."), 0xfe10, {.d_s = v__ast__Expr_str(&call_arg->expr)}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else if ((call_arg->expr)._typ == 337 /* v.ast.ArrayDecompose */ && v__ast__Table_sym(c->table, expected_type)->kind == v__ast__Kind__sum_type && v__ast__Type_idx(expected_type) != v__ast__Type_idx(typ)) { string expected_type_str = v__ast__Table_type_to_str(c->table, expected_type); string got_type_str = v__ast__Table_type_to_str(c->table, typ); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("cannot use `..."), 0xfe10, {.d_s = got_type_str}}, {_S("` as `..."), 0xfe10, {.d_s = expected_type_str}}, {_S("` in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = fn_name}}, {_S("`"), 0, { .d_c = 0 }}})), call_arg->pos); } } } else { c->expected_type = param.typ; } v__ast__TypeSymbol* e_sym = v__ast__Table_sym(c->table, c->expected_type); if ((call_arg->expr)._typ == 368 /* v.ast.MapInit */ && e_sym->kind == v__ast__Kind__struct) { v__checker__Checker_error(c, _S("cannot initialize a struct with a map"), call_arg->pos); continue; } else if ((call_arg->expr)._typ == 385 /* v.ast.StructInit */ && e_sym->kind == v__ast__Kind__map && !v__ast__Type_has_flag((*(v__ast__StructInit*)__as_cast((call_arg->expr)._v__ast__StructInit,(call_arg->expr)._typ, 385)).typ, v__ast__TypeFlag__generic)) { v__checker__Checker_error(c, _S("cannot initialize a map with a struct"), call_arg->pos); continue; } v__ast__Type arg_typ = v__checker__Checker_check_expr_option_or_result_call(c, call_arg->expr, (already_checked ? ((*(v__ast__CallArg*)array_get(node->args, i)).typ) : (v__checker__Checker_expr(c, &call_arg->expr)))); if ((call_arg->expr)._typ == 385 /* v.ast.StructInit */) { arg_typ = v__checker__Checker_expr(c, &call_arg->expr); } (*(v__ast__CallArg*)array_get(node->args, i)).typ = arg_typ; if ((c->comptime->comptime_for_field_var).len != 0) { if ((call_arg->expr)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((call_arg->expr)._v__ast__Ident,(call_arg->expr)._typ, 358)).obj)._typ == 422 /* v.ast.Var */) { (*(v__ast__CallArg*)array_get(node->args, i)).typ = (*(*call_arg->expr._v__ast__Ident).obj._v__ast__Var).typ; } } v__ast__TypeSymbol* arg_typ_sym = v__ast__Table_sym(c->table, arg_typ); if (arg_typ_sym->kind == v__ast__Kind__none && v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic) && !v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("cannot use `none` as generic argument"), call_arg->pos); } v__ast__TypeSymbol* param_typ_sym = v__ast__Table_sym(c->table, param.typ); if (func.is_variadic && v__ast__Type_has_flag(arg_typ, v__ast__TypeFlag__variadic) && (int)(args_len - 1) > i) { v__checker__Checker_error(c, _S("when forwarding a variadic variable, it must be the final argument"), call_arg->pos); } v__ast__ShareType arg_share = v__ast__Type_share(param.typ); if (arg_share == v__ast__ShareType__shared_t && (c->locked_names.len > 0 || c->rlocked_names.len > 0)) { v__checker__Checker_error(c, _S("function with `shared` arguments cannot be called inside `lock`/`rlock` block"), call_arg->pos); } if (call_arg->is_mut) { multi_return_string_v__token__Pos mr_54398 = v__checker__Checker_fail_if_immutable(c, &call_arg->expr); string to_lock = mr_54398.arg0; v__token__Pos pos = mr_54398.arg1; if (!v__ast__Expr_is_lvalue(call_arg->expr)) { if ((call_arg->expr)._typ == 385 /* v.ast.StructInit */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot pass a struct initialization as `mut`, you may want to use a variable `mut var := "), 0xfe10, {.d_s = v__ast__Expr_str(&call_arg->expr)}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(call_arg->expr)); } else { v__checker__Checker_error(c, _S("cannot pass expression as `mut`"), v__ast__Expr_pos(call_arg->expr)); } } if (!param.is_mut) { string tok = v__ast__ShareType_str(call_arg->share); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = node->name}}, {_S("` parameter `"), 0xfe10, {.d_s = param.name}}, {_S("` is not `"), 0xfe10, {.d_s = tok}}, {_S("`, `"), 0xfe10, {.d_s = tok}}, {_S("` is not needed`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(call_arg->expr)); } else { if (v__ast__Type_share(param.typ) != call_arg->share) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("wrong shared type `"), 0xfe10, {.d_s = v__ast__ShareType_str(call_arg->share)}}, {_S("`, expected: `"), 0xfe10, {.d_s = v__ast__ShareType_str(v__ast__Type_share(param.typ))}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(call_arg->expr)); } if ((to_lock).len != 0 && !v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__shared_f)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = to_lock}}, {_S(" is `shared` and must be `lock`ed to be passed as `mut`"), 0, { .d_c = 0 }}})), pos); } } } else { if (param.is_mut) { string tok = v__ast__Param_specifier(¶m); v__ast__TypeSymbol* param_sym = v__ast__Table_sym(c->table, param.typ); bool _t65 = ((param_sym->info)._typ == 518 /* v.ast.Struct */); bool _t66 = false; if (_t65) { Array_v__ast__Attr _t66_orig = (*(v__ast__Struct*)__as_cast((param_sym->info)._v__ast__Struct,(param_sym->info)._typ, 518)).attrs; int _t66_len = _t66_orig.len; for (int _t67 = 0; _t67 < _t66_len; ++_t67) { v__ast__Attr it = ((v__ast__Attr*) _t66_orig.data)[_t67]; if (fast_string_eq(it.name, _S("params"))) { _t66 = true; break; } } } if (!( _t65 &&_t66)) { v__checker__Checker_error(c, str_intp(6, _MOV((StrIntpData[]){{_S("function `"), 0xfe10, {.d_s = node->name}}, {_S("` parameter `"), 0xfe10, {.d_s = param.name}}, {_S("` is `"), 0xfe10, {.d_s = tok}}, {_S("`, so use `"), 0xfe10, {.d_s = tok}}, {_S(" "), 0xfe10, {.d_s = v__ast__Expr_str(&call_arg->expr)}}, {_S("` instead"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(call_arg->expr)); } } else { v__checker__Checker_fail_if_unreadable(c, call_arg->expr, arg_typ, _S("argument")); } } v__ast__TypeSymbol* final_param_sym = param_typ_sym; v__ast__Type final_param_typ = param.typ; if (func.is_variadic && (param_typ_sym->info)._typ == 513 /* v.ast.Array */) { final_param_typ = (*param_typ_sym->info._v__ast__Array).elem_type; final_param_sym = v__ast__Table_sym(c->table, final_param_typ); } if (call_arg->typ != param.typ && (param.typ == _const_v__ast__voidptr_type || final_param_sym->idx == 2 || param.typ == _const_v__ast__nil_type || final_param_sym->idx == 31) && !v__ast__Type_is_any_kind_of_pointer(call_arg->typ) && func.language == v__ast__Language__v && !v__ast__Expr_is_lvalue(call_arg->expr) && !c->pref->translated && !c->file->is_translated && !func.is_c_variadic && !(fast_string_eq(func.name, _S("json.encode")) || fast_string_eq(func.name, _S("json.encode_pretty")))) { v__checker__Checker_error(c, _S("expression cannot be passed as `voidptr`"), v__ast__Expr_pos(call_arg->expr)); } if (final_param_sym->kind == v__ast__Kind__interface) { if (v__checker__Checker_type_implements(c, arg_typ, final_param_typ, v__ast__Expr_pos(call_arg->expr))) { if (!v__ast__Type_is_any_kind_of_pointer(arg_typ) && !c->inside_unsafe && arg_typ_sym->kind != v__ast__Kind__interface) { v__checker__Checker_mark_as_referenced(c, &call_arg->expr, true); } } if (!(arg_typ == _const_v__ast__voidptr_type || arg_typ == _const_v__ast__nil_type) && !v__checker__Checker_check_multiple_ptr_match(c, arg_typ, param.typ, param, *call_arg)) { multi_return_string_string mr_57459 = v__checker__Checker_get_string_names_of(c, arg_typ, param.typ); string got_typ_str = mr_57459.arg0; string expected_typ_str = mr_57459.arg1; v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("` in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = fn_name}}, {_S("`"), 0, { .d_c = 0 }}})), call_arg->pos); } if ((call_arg->expr)._typ == 337 /* v.ast.ArrayDecompose */ && v__ast__Type_idx(arg_typ) != v__ast__Type_idx(final_param_typ)) { string expected_type_str = v__ast__Table_type_to_str(c->table, param.typ); string got_type_str = v__ast__Table_type_to_str(c->table, arg_typ); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_type_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_type_str}}, {_S("` in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = fn_name}}, {_S("`"), 0, { .d_c = 0 }}})), call_arg->pos); } continue; } if (v__ast__Type_is_ptr(param.typ) && !param.is_mut && !v__ast__Type_is_any_kind_of_pointer(call_arg->typ) && v__ast__Expr_is_literal(call_arg->expr) && func.language == v__ast__Language__v && !c->pref->translated) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("literal argument cannot be passed as reference parameter `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, param.typ)}}, {_S("`"), 0, { .d_c = 0 }}})), call_arg->pos); } _result_void _t68 = v__checker__Checker_check_expected_call_arg(c, arg_typ, v__checker__Checker_unwrap_generic(c, param.typ), node->language, *call_arg); if (_t68.is_error) { IError err = _t68.err; if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { continue; } if ((param_typ_sym->info)._typ == 513 /* v.ast.Array */ && (arg_typ_sym->info)._typ == 513 /* v.ast.Array */) { v__ast__Type param_elem_type = v__ast__Table_unaliased_type(c->table, (*param_typ_sym->info._v__ast__Array).elem_type); v__ast__Type arg_elem_type = v__ast__Table_unaliased_type(c->table, (*arg_typ_sym->info._v__ast__Array).elem_type); int param_nr_muls = v__ast__Type_nr_muls(param.typ); int arg_nr_muls = (call_arg->is_mut ? ((int)(v__ast__Type_nr_muls(arg_typ) + 1)) : (v__ast__Type_nr_muls(arg_typ))); if (param_nr_muls == arg_nr_muls && (*param_typ_sym->info._v__ast__Array).nr_dims == (*arg_typ_sym->info._v__ast__Array).nr_dims && param_elem_type == arg_elem_type) { continue; } } else if ((arg_typ_sym->info)._typ == 552 /* v.ast.MultiReturn */) { Array_v__ast__Type arg_typs = (*arg_typ_sym->info._v__ast__MultiReturn).types; if (!(func.is_variadic && i >= (int)(func.params.len - 1))) { if ((*arg_typ_sym->info._v__ast__MultiReturn).types.len > func.params.len) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("trying to pass "), 0xfe07, {.d_i32 = (*arg_typ_sym->info._v__ast__MultiReturn).types.len}}, {_S(" argument(s), but function expects "), 0xfe07, {.d_i32 = func.params.len}}, {_S(" argument(s)"), 0, { .d_c = 0 }}})), node->pos); *continue_check = false; v__ast__Type _t69 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t69; } } out: {} for (int n = 0; n < (*arg_typ_sym->info._v__ast__MultiReturn).types.len; ++n) { v__ast__Type curr_arg = (*(v__ast__Type*)array_get(arg_typs, n)); v__ast__Param _t70; /* if prepend */ if (func.is_variadic && i >= (int)(func.params.len - 1)) { _t70 = (*(v__ast__Param*)array_last(func.params)); } else { _t70 = (*(v__ast__Param*)array_get(func.params, (int)(n + i))); } v__ast__Param multi_param = _t70; _result_void _t71 = v__checker__Checker_check_expected_call_arg(c, curr_arg, v__checker__Checker_unwrap_generic(c, multi_param.typ), node->language, *call_arg); if (_t71.is_error) { IError err = _t71.err; v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument "), 0xfe07, {.d_i32 = (int)((int)(i + n) + 1)}}, {_S(" to `"), 0xfe10, {.d_s = fn_name}}, {_S("` from "), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, arg_typ)}}, {_SLIT0, 0, { .d_c = 0 }}})), call_arg->pos); goto out__continue; } ; out__continue: {} } out__break: {} continue; } else if ((param_typ_sym->info)._typ == 518 /* v.ast.Struct */ && (arg_typ_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((param_typ_sym->info)._v__ast__Struct,(param_typ_sym->info)._typ, 518)).is_anon) { if (v__checker__Checker_is_anon_struct_compatible(c, (*param_typ_sym->info._v__ast__Struct), (*arg_typ_sym->info._v__ast__Struct))) { continue; } } if (c->pref->translated || c->file->is_translated) { v__ast__Type param_type = (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__variadic) ? (v__ast__TypeSymbol_array_info(param_typ_sym).elem_type) : (param.typ)); if ((Array_int_contains(_const_v__ast__integer_type_idxs, v__ast__Type_idx(param_type))) && arg_typ_sym->kind == v__ast__Kind__enum) { continue; } if ((Array_int_contains(_const_v__ast__integer_type_idxs, v__ast__Type_idx(arg_typ))) && param_typ_sym->kind == v__ast__Kind__enum) { continue; } if ((arg_typ == _const_v__ast__bool_type && v__ast__Type_is_int(param_type)) || (v__ast__Type_is_int(arg_typ) && param_type == _const_v__ast__bool_type)) { continue; } bool param_is_number = v__ast__Type_is_number(v__ast__Table_unaliased_type(c->table, param_type)); if (v__ast__Type_is_ptr(param_type)) { param_is_number = v__ast__Type_is_number(v__ast__Type_deref(param_type)); } bool typ_is_number = v__ast__Type_is_number(v__ast__Table_unaliased_type(c->table, arg_typ)); if (v__ast__Type_is_ptr(arg_typ)) { typ_is_number = v__ast__Type_is_number(v__ast__Type_deref(arg_typ)); } if (param_is_number && typ_is_number) { continue; } if (param_type == 2 || param_type == 31 || arg_typ == 2 || arg_typ == 31) { continue; } if (v__ast__Type_is_any_kind_of_pointer(param_type) && v__ast__Type_is_any_kind_of_pointer(arg_typ)) { continue; } v__ast__TypeSymbol* unaliased_param_sym = v__ast__Table_sym(c->table, v__ast__Table_unaliased_type(c->table, param_type)); v__ast__TypeSymbol* unaliased_arg_sym = v__ast__Table_sym(c->table, v__ast__Table_unaliased_type(c->table, arg_typ)); if (((unaliased_arg_sym->kind == v__ast__Kind__array_fixed || unaliased_arg_sym->kind == v__ast__Kind__array) && (param_is_number || v__ast__Type_is_any_kind_of_pointer(v__ast__Table_unaliased_type(c->table, param_type)))) || ((unaliased_param_sym->kind == v__ast__Kind__array_fixed || unaliased_param_sym->kind == v__ast__Kind__array) && (typ_is_number || v__ast__Type_is_any_kind_of_pointer(v__ast__Table_unaliased_type(c->table, arg_typ))))) { continue; } if ((unaliased_arg_sym->info)._typ == 513 /* v.ast.Array */ && (unaliased_param_sym->info)._typ == 513 /* v.ast.Array */) { if (v__ast__Type_is_any_kind_of_pointer((*unaliased_arg_sym->info._v__ast__Array).elem_type) && v__ast__Type_is_any_kind_of_pointer((*unaliased_param_sym->info._v__ast__Array).elem_type)) { continue; } } else if ((unaliased_arg_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && (unaliased_param_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { if (v__ast__Type_is_any_kind_of_pointer((*unaliased_arg_sym->info._v__ast__ArrayFixed).elem_type) && v__ast__Type_is_any_kind_of_pointer((*unaliased_param_sym->info._v__ast__ArrayFixed).elem_type)) { continue; } } if (v__ast__Type_is_any_kind_of_pointer(param_type) && typ_is_number) { continue; } if (v__ast__Type_is_any_kind_of_pointer(arg_typ) && param_is_number) { continue; } } v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = fn_name}}, {_S("`"), 0, { .d_c = 0 }}})), call_arg->pos); ; } ; if (final_param_sym->kind == v__ast__Kind__struct && !(arg_typ == _const_v__ast__voidptr_type || arg_typ == _const_v__ast__nil_type) && !v__checker__Checker_check_multiple_ptr_match(c, arg_typ, param.typ, param, *call_arg)) { multi_return_string_string mr_63560 = v__checker__Checker_get_string_names_of(c, arg_typ, param.typ); string got_typ_str = mr_63560.arg0; string expected_typ_str = mr_63560.arg1; v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("` in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = fn_name}}, {_S("`"), 0, { .d_c = 0 }}})), call_arg->pos); } if (func.language != v__ast__Language__c && !c->inside_unsafe && !(call_arg->is_mut && param.is_mut)) { if (v__ast__Type_nr_muls(arg_typ) != v__ast__Type_nr_muls(param.typ) && !(param.typ == _const_v__ast__byteptr_type || param.typ == _const_v__ast__charptr_type || param.typ == _const_v__ast__voidptr_type || param.typ == _const_v__ast__nil_type) && arg_typ != _const_v__ast__voidptr_type && !(!call_arg->is_mut && !param.is_mut)) { v__checker__Checker_warn(c, str_intp(3, _MOV((StrIntpData[]){{_S("automatic referencing/dereferencing is deprecated and will be removed soon (got: "), 0xfe07, {.d_i32 = v__ast__Type_nr_muls(arg_typ)}}, {_S(" references, expected: "), 0xfe07, {.d_i32 = v__ast__Type_nr_muls(param.typ)}}, {_S(" references)"), 0, { .d_c = 0 }}})), call_arg->pos); } else if (param.typ == _const_v__ast__voidptr_type && func.language == v__ast__Language__v && !(arg_typ == _const_v__ast__voidptr_type || arg_typ == _const_v__ast__nil_type) && v__ast__Type_nr_muls(arg_typ) == 0 && !(fast_string_eq(func.name, _S("isnil")) || fast_string_eq(func.name, _S("ptr_str"))) && !string_starts_with(func.name, _S("json.")) && !(arg_typ_sym->kind == v__ast__Kind__float_literal || arg_typ_sym->kind == v__ast__Kind__int_literal || arg_typ_sym->kind == v__ast__Kind__charptr || arg_typ_sym->kind == v__ast__Kind__function) && !v__pref__Backend_is_js(c->pref->backend)) { v__checker__Checker_warn(c, str_intp(2, _MOV((StrIntpData[]){{_S("automatic "), 0xfe10, {.d_s = arg_typ_sym->name}}, {_S(" referencing/dereferencing into voidptr is deprecated and will be removed soon; use `foo(&x)` instead of `foo(x)`"), 0, { .d_c = 0 }}})), call_arg->pos); } } } if (is_json_encode) { node->expected_arg_types = new_array_from_c_array(1, 1, sizeof(v__ast__Type), _MOV((v__ast__Type[1]){(*(v__ast__CallArg*)array_get(node->args, 0)).typ})); } if (func.generic_names.len != node->concrete_types.len) { v__checker__Checker_infer_fn_generic_types(c, (voidptr)&func, node); Array_v__ast__Type _t72 = {0}; Array_v__ast__Type _t72_orig = node->concrete_types; int _t72_len = _t72_orig.len; _t72 = __new_array(0, _t72_len, sizeof(v__ast__Type)); for (int _t74 = 0; _t74 < _t72_len; ++_t74) { v__ast__Type it = ((v__ast__Type*) _t72_orig.data)[_t74]; v__ast__Type _t73 = v__checker__Checker_unwrap_generic(c, it); array_push((array*)&_t72, &_t73); } concrete_types =_t72; multi_return_bool_Array_v__ast__Type mr_65475 = v__type_resolver__TypeResolver_resolve_fn_generic_args(&c->type_resolver, c->table->cur_fn, (voidptr)&func, node); bool need_recheck = mr_65475.arg0; if (need_recheck) { c->need_recheck_generic_fns = true; } } if (func.generic_names.len > 0) { for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* call_arg = ((v__ast__CallArg*)node->args.data) + i; v__ast__Param _t75; /* if prepend */ if (func.is_variadic && i >= (int)(func.params.len - 1)) { _t75 = (*(v__ast__Param*)array_last(func.params)); } else { _t75 = (*(v__ast__Param*)array_get(func.params, i)); } v__ast__Param param = _t75; if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t76; if (_t76 = v__ast__Table_convert_generic_type(c->table, param.typ, func.generic_names, concrete_types), _t76.state == 0) { v__ast__Type unwrap_typ = *(v__ast__Type*)_t76.data; c->expected_type = unwrap_typ; } } else { c->expected_type = param.typ; } bool already_checked = node->language != v__ast__Language__js && (call_arg->expr)._typ == 344 /* v.ast.CallExpr */; v__ast__Type typ = v__checker__Checker_check_expr_option_or_result_call(c, call_arg->expr, (already_checked && (call_arg->expr)._typ == 344 /* v.ast.CallExpr */ ? ((*call_arg->expr._v__ast__CallExpr).return_type) : (v__checker__Checker_expr(c, &call_arg->expr)))); if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic) && func.generic_names.len == node->concrete_types.len) { _option_v__ast__Type _t77; if (_t77 = v__ast__Table_convert_generic_type(c->table, param.typ, func.generic_names, concrete_types), _t77.state == 0) { v__ast__Type unwrap_typ = *(v__ast__Type*)_t77.data; v__ast__Type utyp = v__checker__Checker_unwrap_generic(c, typ); v__ast__TypeSymbol* unwrap_sym = v__ast__Table_sym(c->table, unwrap_typ); if (unwrap_sym->kind == v__ast__Kind__interface) { if (v__checker__Checker_type_implements(c, utyp, unwrap_typ, v__ast__Expr_pos(call_arg->expr))) { if (!v__ast__Type_is_any_kind_of_pointer(utyp) && !c->inside_unsafe && v__ast__Table_sym(c->table, utyp)->kind != v__ast__Kind__interface) { v__checker__Checker_mark_as_referenced(c, &call_arg->expr, true); } } continue; } _result_void _t78 = v__checker__Checker_check_expected_call_arg(c, utyp, unwrap_typ, node->language, *call_arg); if (_t78.is_error) { IError err = _t78.err; if (c->type_resolver.type_map.len > 0) { continue; } if ((call_arg->expr)._typ == 365 /* v.ast.LambdaExpr */) { v__checker__Checker_handle_generic_lambda_arg(c, node, (voidptr)&(*call_arg->expr._v__ast__LambdaExpr)); continue; } if (!v__ast__Type_has_flag(unwrap_typ, v__ast__TypeFlag__variadic) && unwrap_sym->kind == v__ast__Kind__array && v__ast__Table_final_sym(c->table, utyp)->kind == v__ast__Kind__array && v__checker__Checker_check_basic(c, v__ast__Type_clear_flag(v__ast__Table_value_type(c->table, utyp), v__ast__TypeFlag__option), v__ast__Table_value_type(c->table, unwrap_typ))) { continue; } v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = fn_name}}, {_S("`"), 0, { .d_c = 0 }}})), call_arg->pos); ; } ; } } } if (c->pref->skip_unused && node->concrete_types.len > 0) { for (int _t79 = 0; _t79 < node->concrete_types.len; ++_t79) { v__ast__Type concrete_type = ((v__ast__Type*)node->concrete_types.data)[_t79]; map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__checker__Checker_unwrap_generic(c, concrete_type)}, &(bool[]) { true }); } } } if (func.generic_names.len > 0 && v__ast__Type_has_flag(func.return_type, v__ast__TypeFlag__generic) && c->table->cur_fn != ((void*)0) && v__checker__Checker_needs_unwrap_generic_type(c, func.return_type)) { node->return_type = v__ast__Table_unwrap_generic_type(c->table, func.return_type, func.generic_names, concrete_types); } else { node->return_type = func.return_type; } if (v__ast__Type_has_flag(func.return_type, v__ast__TypeFlag__generic)) { node->return_type_generic = func.return_type; } if (node->concrete_types.len > 0 && func.return_type != 0 && c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len == 0) { _option_v__ast__Type _t80; if (_t80 = v__ast__Table_convert_generic_type(c->table, func.return_type, func.generic_names, concrete_types), _t80.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t80.data; node->return_type = typ; v__checker__Checker_register_trace_call(c, node, (voidptr)&func); if (v__ast__Type_has_flag(func.return_type, v__ast__TypeFlag__generic)) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__ast__Type_clear_option_and_result(typ)}, &(bool[]) { true }); map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){func.return_type}, &(bool[]) { true }); } v__ast__Type _t81 = typ; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t81; } } if (node->concrete_types.len > 0 && func.generic_names.len == 0) { v__checker__Checker_error(c, _S("a non generic function called like a generic one"), node->concrete_list_pos); } if (func.generic_names.len > 0 && node->return_type != _const_v__ast__void_type) { v__ast__Type ret_type = v__checker__Checker_resolve_fn_return_type(c, (voidptr)&func, *node, concrete_types); v__checker__Checker_register_trace_call(c, node, (voidptr)&func); node->return_type = ret_type; if (v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__generic)) { v__ast__Type unwrapped_ret = v__checker__Checker_unwrap_generic(c, ret_type); if (v__ast__Table_sym(c->table, unwrapped_ret)->kind == v__ast__Kind__multi_return) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){unwrapped_ret}, &(bool[]) { true }); } } v__ast__Type _t82 = ret_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t82; } v__checker__Checker_register_trace_call(c, node, (voidptr)&func); v__ast__Type _t83 = func.return_type; // Defer begin if (v__checker__Checker_fn_call_defer_0) { if (found) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&func, _S("function")); } } // Defer end return _t83; } VV_LOC void v__checker__Checker_register_trace_call(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Fn* func) { if (!(c->pref->is_callstack || c->pref->is_trace) || c->table->cur_fn == ((void*)0) || node->language != v__ast__Language__v) { return; } if (fast_string_eq(node->name, _S("v.debug.callstack")) || fast_string_eq(node->name, _S("v.debug.add_after_call")) || fast_string_eq(node->name, _S("v.debug.add_before_call")) || fast_string_eq(node->name, _S("v.debug.remove_after_call")) || fast_string_eq(node->name, _S("v.debug.remove_before_call"))) { return; } bool _t1 = false; Array_v__ast__Import _t1_orig = c->file->imports; int _t1_len = _t1_orig.len; for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__Import it = ((v__ast__Import*) _t1_orig.data)[_t2]; if (fast_string_eq(it.mod, _S("v.debug"))) { _t1 = true; break; } } if (!_t1) { return; } multi_return_string_string mr_70012 = v__ast__Table_get_trace_fn_name(c->table, *c->table->cur_fn, *node); string hash_fn = mr_70012.arg0; string fn_name = mr_70012.arg1; string calling_fn = (func->is_method ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, v__checker__Checker_unwrap_generic(c, node->left_type))}}, {_S("_"), 0xfe10, {.d_s = fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (fn_name)); (*(v__ast__FnTrace*)map_get_and_set((map*)&c->table->cur_fn->trace_fns, &(string[]){hash_fn}, &(v__ast__FnTrace[]){ (v__ast__FnTrace){.name = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.line = 0,.return_type = 0,.func = ((void*)0),.is_fn_var = 0,} })) = ((v__ast__FnTrace){ .name = calling_fn, .file = c->file->path, .line = (int)(node->pos.line_nr + 1), .return_type = node->return_type, .func = ((v__ast__Fn*)memdup(&(v__ast__Fn){.is_variadic = (func)->is_variadic,.is_c_variadic = (func)->is_c_variadic,.language = (func)->language,.is_pub = (func)->is_pub,.is_ctor_new = (func)->is_ctor_new,.is_deprecated = (func)->is_deprecated,.is_noreturn = (func)->is_noreturn,.is_unsafe = (func)->is_unsafe,.is_must_use = (func)->is_must_use,.is_placeholder = (func)->is_placeholder,.is_main = (func)->is_main,.is_test = (func)->is_test,.is_keep_alive = (func)->is_keep_alive,.is_method = (func)->is_method,.is_static_type_method = (func)->is_static_type_method,.no_body = (func)->no_body,.is_file_translated = (func)->is_file_translated,.mod = (func)->mod,.file = (func)->file,.file_mode = (func)->file_mode,.pos = (func)->pos,.name_pos = (func)->name_pos,.return_type_pos = (func)->return_type_pos,.return_type = (func)->return_type,.receiver_type = (func)->receiver_type,.name = (func)->name,.params = (func)->params,.source_fn = (func)->source_fn,.usages = (func)->usages,.generic_names = (func)->generic_names,.dep_names = (func)->dep_names,.attrs = (func)->attrs,.is_conditional = (func)->is_conditional,.ctdefine_idx = (func)->ctdefine_idx,.from_embedded_type = (func)->from_embedded_type,.is_expand_simple_interpolation = (func)->is_expand_simple_interpolation,}, sizeof(v__ast__Fn))), .is_fn_var = node->is_fn_var, }); } VV_LOC v__ast__Type v__checker__Checker_cast_fixed_array_ret(v__checker__Checker* c, v__ast__Type typ, v__ast__TypeSymbol sym) { if ((sym.info)._typ == 549 /* v.ast.ArrayFixed */ && (*(v__ast__ArrayFixed*)__as_cast((sym.info)._v__ast__ArrayFixed,(sym.info)._typ, 549)).is_fn_ret) { return v__ast__Table_find_or_register_array_fixed(c->table, (*sym.info._v__ast__ArrayFixed).elem_type, (*sym.info._v__ast__ArrayFixed).size, (*sym.info._v__ast__ArrayFixed).size_expr, false); } return typ; } VV_LOC v__ast__Type v__checker__Checker_cast_to_fixed_array_ret(v__checker__Checker* c, v__ast__Type typ, v__ast__TypeSymbol sym) { if ((sym.info)._typ == 549 /* v.ast.ArrayFixed */ && !(*(v__ast__ArrayFixed*)__as_cast((sym.info)._v__ast__ArrayFixed,(sym.info)._typ, 549)).is_fn_ret) { return v__ast__Table_find_or_register_array_fixed(c->table, (*sym.info._v__ast__ArrayFixed).elem_type, (*sym.info._v__ast__ArrayFixed).size, (*sym.info._v__ast__ArrayFixed).size_expr, true); } return typ; } VV_LOC bool v__checker__Checker_check_type_sym_kind(v__checker__Checker* c, string name, int type_idx, v__ast__Kind* expected_kind, v__token__Pos* pos) { v__ast__TypeSymbol* sym = v__ast__Table_sym_by_idx(c->table, type_idx); if (sym->kind == v__ast__Kind__alias) { v__ast__Type parent_type = (*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type; sym = v__ast__Table_sym(c->table, parent_type); } if (sym->kind != *expected_kind) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("expected "), 0xfe10, {.d_s = v__ast__Kind_str(*expected_kind)}}, {_S(", but `"), 0xfe10, {.d_s = name}}, {_S("` is "), 0xfe10, {.d_s = v__ast__Kind_str(sym->kind)}}, {_SLIT0, 0, { .d_c = 0 }}})), *pos); return false; } return true; } VV_LOC bool v__checker__Checker_check_type_and_visibility(v__checker__Checker* c, string name, int type_idx, v__ast__Kind* expected_kind, v__token__Pos* pos) { v__ast__TypeSymbol* sym = v__ast__Table_sym_by_idx(c->table, type_idx); if (sym->kind == v__ast__Kind__alias) { v__ast__Type parent_type = (*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type; sym = v__ast__Table_sym(c->table, parent_type); } if (sym->kind != *expected_kind) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("expected "), 0xfe10, {.d_s = v__ast__Kind_str(*expected_kind)}}, {_S(", but `"), 0xfe10, {.d_s = name}}, {_S("` is "), 0xfe10, {.d_s = v__ast__Kind_str(sym->kind)}}, {_SLIT0, 0, { .d_c = 0 }}})), *pos); return false; } if (!sym->is_pub) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("module `"), 0xfe10, {.d_s = sym->mod}}, {_S("` type `"), 0xfe10, {.d_s = sym->name}}, {_S("` is private"), 0, { .d_c = 0 }}})), *pos); return false; } return true; } VV_LOC v__ast__Type v__checker__Checker_method_call(v__checker__Checker* c, v__ast__CallExpr* node, bool* continue_check) { bool v__checker__Checker_method_call_defer_0 = false; bool has_method; v__ast__Fn method; v__ast__Expr left_expr = node->left; left_expr = v__ast__Expr_remove_par(&left_expr); if ((left_expr)._typ == 359 /* v.ast.IfExpr */) { if ((*left_expr._v__ast__IfExpr).branches.len > 0 && (*left_expr._v__ast__IfExpr).has_else) { v__ast__Stmt last_stmt = (*(v__ast__Stmt*)array_last((*(v__ast__IfBranch*)array_get((*left_expr._v__ast__IfExpr).branches, 0)).stmts)); if ((last_stmt)._typ == 401 /* v.ast.ExprStmt */) { c->expected_type = v__checker__Checker_expr(c, &(*last_stmt._v__ast__ExprStmt).expr); } } } v__ast__Type left_type = node->left_type; if (left_type == _const_v__ast__void_type) { *continue_check = false; return _const_v__ast__void_type; } v__checker__Checker_markused_method_call(c, node, &left_expr, left_type); c->expected_type = left_type; bool is_generic = v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic); node->left_type = left_type; node->return_type = left_type; node->receiver_type = left_type; if (is_generic) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__checker__Checker_unwrap_generic(c, left_type)}, &(bool[]) { true }); } if (c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len > 0) { v__ast__Table_unwrap_generic_type(c->table, left_type, c->table->cur_fn->generic_names, c->table->cur_concrete_types); } v__ast__Type unwrapped_left_type = v__checker__Checker_unwrap_generic(c, left_type); v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, unwrapped_left_type); v__ast__TypeSymbol* final_left_sym = v__ast__Table_final_sym(c->table, unwrapped_left_type); string method_name = node->name; if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("Option type cannot be called directly, you should unwrap it first"), v__ast__Expr_pos(node->left)); return _const_v__ast__void_type; } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("Result type cannot be called directly"), v__ast__Expr_pos(node->left)); return _const_v__ast__void_type; } if (left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface) { if (_SLIT_EQ(method_name.str, method_name.len, "type_name")) { c->table->used_features->type_name = true; return _const_v__ast__string_type; } if (_SLIT_EQ(method_name.str, method_name.len, "type_idx")) { return _const_v__ast__int_type; } } if (left_type == _const_v__ast__void_type) { *continue_check = false; return _const_v__ast__void_type; } if (final_left_sym->kind == v__ast__Kind__array && v__token__KeywordsMatcherTrie_matches(&_const_v__checker__array_builtin_methods_chk, method_name) && !(left_sym->kind == v__ast__Kind__alias && v__ast__TypeSymbol_has_method(left_sym, method_name))) { return v__checker__Checker_array_builtin_method_call(c, node, left_type); } else if (final_left_sym->kind == v__ast__Kind__array_fixed && v__token__KeywordsMatcherTrie_matches(&_const_v__checker__fixed_array_builtin_methods_chk, method_name) && !(left_sym->kind == v__ast__Kind__alias && v__ast__TypeSymbol_has_method(left_sym, method_name))) { return v__checker__Checker_fixed_array_builtin_method_call(c, node, left_type); } else if (final_left_sym->kind == v__ast__Kind__map && (_SLIT_EQ(method_name.str, method_name.len, "clone") || _SLIT_EQ(method_name.str, method_name.len, "keys") || _SLIT_EQ(method_name.str, method_name.len, "values") || _SLIT_EQ(method_name.str, method_name.len, "move") || _SLIT_EQ(method_name.str, method_name.len, "delete")) && !(left_sym->kind == v__ast__Kind__alias && v__ast__TypeSymbol_has_method(left_sym, method_name))) { v__ast__Type unaliased_left_type = v__ast__Table_unaliased_type(c->table, left_type); return v__checker__Checker_map_builtin_method_call(c, node, unaliased_left_type); } else if (v__pref__Backend_is_js(c->pref->backend) && string_starts_with(left_sym->name, _S("Promise[")) && _SLIT_EQ(method_name.str, method_name.len, "wait")) { v__ast__Struct info = *(v__ast__Struct*)__as_cast((left_sym->info)._v__ast__Struct,(left_sym->info)._typ, 518); if (node->args.len > 0) { v__checker__Checker_error(c, _S("wait() does not have any arguments"), (*(v__ast__CallArg*)array_get(node->args, 0)).pos); } if (c->table->cur_fn != ((void*)0)) { c->table->cur_fn->has_await = true; } node->return_type = (*(v__ast__Type*)array_get(info.concrete_types, 0)); v__ast__Type_set_flag(node->return_type, v__ast__TypeFlag__option); return node->return_type; } else if ((left_sym->info)._typ == 551 /* v.ast.Thread */ && _SLIT_EQ(method_name.str, method_name.len, "wait")) { if (node->args.len > 0) { v__checker__Checker_error(c, _S("wait() does not have any arguments"), (*(v__ast__CallArg*)array_get(node->args, 0)).pos); } node->return_type = (*left_sym->info._v__ast__Thread).return_type; return (*left_sym->info._v__ast__Thread).return_type; } else if (left_sym->kind == v__ast__Kind__char && v__ast__Type_nr_muls(left_type) == 0 && _SLIT_EQ(method_name.str, method_name.len, "str")) { v__checker__Checker_error(c, _S("calling `.str()` on type `char` is not allowed, use its address or cast it to an integer instead"), v__token__Pos_extend(v__ast__Expr_pos(node->left), node->pos)); return _const_v__ast__void_type; } string unknown_method_msg = _S(""); method = ((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); has_method = false; bool is_method_from_embed = false; v__checker__Checker_method_call_defer_0 = true; _result_v__ast__Fn _t13; if (_t13 = v__ast__Table_find_method(c->table, left_sym, method_name), !_t13.is_error) { v__ast__Fn m = *(v__ast__Fn*)_t13.data; method = m; has_method = true; if (left_sym->kind == v__ast__Kind__interface && m.from_embedded_type != 0) { is_method_from_embed = true; node->from_embed_types = new_array_from_c_array(1, 1, sizeof(v__ast__Type), _MOV((v__ast__Type[1]){m.from_embedded_type})); } } else { IError err = _t13.err; if (final_left_sym->kind == v__ast__Kind__struct || final_left_sym->kind == v__ast__Kind__sum_type || final_left_sym->kind == v__ast__Kind__interface || final_left_sym->kind == v__ast__Kind__array) { v__ast__Type parent_type = _const_v__ast__void_type; if (final_left_sym->info._typ == 518 /* v.ast.Struct */) { parent_type = (*final_left_sym->info._v__ast__Struct).parent_type; } else if (final_left_sym->info._typ == 544 /* v.ast.SumType */) { parent_type = (*final_left_sym->info._v__ast__SumType).parent_type; } else if (final_left_sym->info._typ == 542 /* v.ast.Interface */) { parent_type = (*final_left_sym->info._v__ast__Interface).parent_type; } else if (final_left_sym->info._typ == 513 /* v.ast.Array */) { v__ast__Type typ = v__ast__Table_unaliased_type(c->table, (*final_left_sym->info._v__ast__Array).elem_type); parent_type = v__ast__idx_to_type(v__ast__Table_find_or_register_array(c->table, typ)); } else { } if (parent_type != 0) { v__ast__TypeSymbol* type_sym = v__ast__Table_sym(c->table, parent_type); _result_v__ast__Fn _t14; if (_t14 = v__ast__Table_find_method(c->table, type_sym, method_name), !_t14.is_error) { v__ast__Fn m = *(v__ast__Fn*)_t14.data; method = m; has_method = true; is_generic = true; if (left_sym->kind == v__ast__Kind__interface && m.from_embedded_type != 0) { is_method_from_embed = true; node->from_embed_types = new_array_from_c_array(1, 1, sizeof(v__ast__Type), _MOV((v__ast__Type[1]){m.from_embedded_type})); } } } } if (!has_method) { has_method = true; Array_v__ast__Type embed_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); _result_multi_return_v__ast__Fn_Array_v__ast__Type _t15 = v__ast__Table_find_method_from_embeds(c->table, final_left_sym, method_name); if (_t15.is_error) { IError err = _t15.err; string emsg = IError_str(err); if ((emsg).len != 0) { v__checker__Checker_error(c, emsg, node->pos); } has_method = false; *(multi_return_v__ast__Fn_Array_v__ast__Type*) _t15.data = (multi_return_v__ast__Fn_Array_v__ast__Type){.arg0=((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } multi_return_v__ast__Fn_Array_v__ast__Type mr_77483 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t15.data); method = mr_77483.arg0; embed_types = mr_77483.arg1; if (embed_types.len != 0) { is_method_from_embed = true; node->from_embed_types = embed_types; v__checker__Checker_markused_comptime_call(c, v__ast__Type_has_flag(node->left_type, v__ast__TypeFlag__generic), str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(method.receiver_type))}}, {_S("."), 0xfe10, {.d_s = method.name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } if (final_left_sym->kind == v__ast__Kind__aggregate) { unknown_method_msg = IError_name_table[err._typ]._method_msg(err._object); if (_SLIT_EQ(unknown_method_msg.str, unknown_method_msg.len, "unknown method")) { unknown_method_msg = string__plus(unknown_method_msg, string__plus(string__plus(_S(" `"), method_name), _S("`"))); } } } if (!has_method) { if (_SLIT_EQ(method_name.str, method_name.len, "str")) { if (left_sym->kind == v__ast__Kind__interface) { string iname = left_sym->name; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("interface `"), 0xfe10, {.d_s = iname}}, {_S("` does not have a .str() method. Use typeof() instead"), 0, { .d_c = 0 }}})), node->pos); } node->receiver_type = left_type; node->return_type = _const_v__ast__string_type; if (node->args.len > 0) { v__checker__Checker_error(c, _S(".str() method calls should have no arguments"), node->pos); } v__checker__Checker_fail_if_unreadable(c, node->left, left_type, _S("receiver")); if (!c->is_builtin_mod) { c->table->used_features->auto_str = true; } v__ast__Type _t16 = _const_v__ast__string_type; // Defer begin if (v__checker__Checker_method_call_defer_0) { if (has_method && node->is_method) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&method, _S("method")); } } // Defer end return _t16; } else if (_SLIT_EQ(method_name.str, method_name.len, "free")) { if (!c->is_builtin_mod && !c->inside_unsafe && !method.is_unsafe) { v__checker__Checker_warn(c, _S("manual memory management with `free()` is only allowed in unsafe code"), node->pos); } if (left_sym->kind == v__ast__Kind__array_fixed) { string name = string_replace_each(v__ast__TypeSymbol_symbol_name_except_generic(left_sym), new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S("<"), _S("["), _S(">"), _S("]")}))); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown method or field: "), 0xfe10, {.d_s = name}}, {_S(".free()"), 0, { .d_c = 0 }}})), node->pos); } v__ast__Type _t17 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_method_call_defer_0) { if (has_method && node->is_method) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&method, _S("method")); } } // Defer end return _t17; } _result_v__ast__StructField _t18; if (_t18 = v__ast__Table_find_field_with_embeds(c->table, left_sym, method_name), !_t18.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t18.data; v__ast__Type field_typ = field.typ; if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { v__ast__ScopeStructField* scope_field = v__ast__Scope_find_struct_field(node->scope, v__ast__Expr_str(&node->left), node->left_type, method_name); if (scope_field != ((void*)0)) { field_typ = (*(v__ast__Type*)array_last(scope_field->smartcasts)); node->is_unwrapped_fn_selector = true; } else { v__checker__Checker_error(c, _S("Option function field must be unwrapped first"), node->pos); } } v__ast__TypeSymbol* field_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, field_typ)); if (field_sym->kind == v__ast__Kind__function) { node->is_method = false; node->is_field = true; v__ast__FnType info = *(v__ast__FnType*)__as_cast((field_sym->info)._v__ast__FnType,(field_sym->info)._typ, 553); _result_void _t19 = v__checker__Checker_check_expected_arg_count(c, node, (voidptr)&info.func); if (_t19.is_error) { IError err = _t19.err; v__ast__Type _t20 = info.func.return_type; // Defer begin if (v__checker__Checker_method_call_defer_0) { if (has_method && node->is_method) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&method, _S("method")); } } // Defer end return _t20; } ; node->return_type = info.func.return_type; Array_v__ast__Type earg_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + i; v__ast__Type targ = v__checker__Checker_check_expr_option_or_result_call(c, arg->expr, v__checker__Checker_expr(c, &arg->expr)); arg->typ = targ; v__ast__Param _t21; /* if prepend */ if (info.func.is_variadic && i >= (int)(info.func.params.len - 1)) { _t21 = (*(v__ast__Param*)array_last(info.func.params)); } else { _t21 = (*(v__ast__Param*)array_get(info.func.params, i)); } v__ast__Param param = _t21; arg->should_be_ptr = v__ast__Type_is_ptr(param.typ) && !param.is_mut; if (v__ast__Table_sym(c->table, param.typ)->kind == v__ast__Kind__interface) { array_push((array*)&earg_types, _MOV((v__ast__Type[]){ (v__ast__Type_idx(targ) != v__ast__Type_idx(param.typ) ? (param.typ) : (targ)) })); } else { array_push((array*)&earg_types, _MOV((v__ast__Type[]){ param.typ })); } v__ast__ShareType param_share = v__ast__Type_share(param.typ); if (param_share == v__ast__ShareType__shared_t && (c->locked_names.len > 0 || c->rlocked_names.len > 0)) { v__checker__Checker_error(c, _S("method with `shared` arguments cannot be called inside `lock`/`rlock` block"), arg->pos); } if (arg->is_mut) { multi_return_string_v__token__Pos mr_81114 = v__checker__Checker_fail_if_immutable(c, &arg->expr); string to_lock = mr_81114.arg0; v__token__Pos pos = mr_81114.arg1; if (!param.is_mut) { string tok = v__ast__ShareType_str(arg->share); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = node->name}}, {_S("` parameter "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" is not `"), 0xfe10, {.d_s = tok}}, {_S("`, `"), 0xfe10, {.d_s = tok}}, {_S("` is not needed`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(arg->expr)); } else { if (param_share != arg->share) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("wrong shared type `"), 0xfe10, {.d_s = v__ast__ShareType_str(arg->share)}}, {_S("`, expected: `"), 0xfe10, {.d_s = v__ast__ShareType_str(param_share)}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(arg->expr)); } if ((to_lock).len != 0 && param_share != v__ast__ShareType__shared_t) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = to_lock}}, {_S(" is `shared` and must be `lock`ed to be passed as `mut`"), 0, { .d_c = 0 }}})), pos); } } } else { if (param.is_mut) { string tok = v__ast__Param_specifier(¶m); v__checker__Checker_error(c, str_intp(6, _MOV((StrIntpData[]){{_S("method `"), 0xfe10, {.d_s = node->name}}, {_S("` parameter "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" is `"), 0xfe10, {.d_s = tok}}, {_S("`, so use `"), 0xfe10, {.d_s = tok}}, {_S(" "), 0xfe10, {.d_s = v__ast__Expr_str(&arg->expr)}}, {_S("` instead"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(arg->expr)); } else { v__checker__Checker_fail_if_unreadable(c, arg->expr, targ, _S("argument")); } } if (i < info.func.params.len) { v__ast__Type exp_arg_typ = (*(v__ast__Param*)array_get(info.func.params, i)).typ; _result_void _t24 = v__checker__Checker_check_expected_call_arg(c, targ, v__checker__Checker_unwrap_generic(c, exp_arg_typ), node->language, *arg); if (_t24.is_error) { IError err = _t24.err; if (targ != _const_v__ast__void_type) { v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = left_sym->name}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}})), arg->pos); } ; } ; } } node->expected_arg_types = earg_types; node->is_method = true; _result_multi_return_v__ast__StructField_Array_v__ast__Type _t25 = v__ast__Table_find_field_from_embeds(c->table, left_sym, method_name); if (_t25.is_error) { IError err = _t25.err; v__ast__Type _t26 = info.func.return_type; // Defer begin if (v__checker__Checker_method_call_defer_0) { if (has_method && node->is_method) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&method, _S("method")); } } // Defer end return _t26; } multi_return_v__ast__StructField_Array_v__ast__Type mr_82409 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t25.data); node->from_embed_types = mr_82409.arg1; v__ast__Type _t27 = info.func.return_type; // Defer begin if (v__checker__Checker_method_call_defer_0) { if (has_method && node->is_method) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&method, _S("method")); } } // Defer end return _t27; } } if (left_sym->kind == v__ast__Kind__struct || left_sym->kind == v__ast__Kind__aggregate || left_sym->kind == v__ast__Kind__interface || left_sym->kind == v__ast__Kind__sum_type) { if (!v__token__Pos_struct_eq(c->smartcast_mut_pos, ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}))) { v__checker__Checker_note(c, _S("smartcasting requires either an immutable value, or an explicit mut keyword before the value"), c->smartcast_mut_pos); } if (!v__token__Pos_struct_eq(c->smartcast_cond_pos, ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}))) { v__checker__Checker_note(c, _S("smartcast can only be used on the ident or selector, e.g. match foo, match foo.bar"), c->smartcast_cond_pos); } } if (left_type != _const_v__ast__void_type) { Array_string _t28 = {0}; Array_v__ast__Fn _t28_orig = left_sym->methods; int _t28_len = _t28_orig.len; _t28 = __new_array(0, _t28_len, sizeof(string)); for (int _t30 = 0; _t30 < _t28_len; ++_t30) { v__ast__Fn it = ((v__ast__Fn*) _t28_orig.data)[_t30]; string _t29 = it.name; array_push((array*)&_t28, &_t29); } v__util__Suggestion suggestion = v__util__new_suggestion(method_name,_t28, ((v__util__SuggestionParams){.similarity_threshold = 0.5,.similarity_fn = strings__dice_coefficient,})); if ((unknown_method_msg).len == 0) { _result_v__ast__StructField _t31; if (_t31 = v__ast__Table_find_field(c->table, left_sym, method_name), !_t31.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t31.data; unknown_method_msg = str_intp(2, _MOV((StrIntpData[]){{_S("unknown method `"), 0xfe10, {.d_s = field.name}}, {_S("` did you mean to access the field with the same name instead?"), 0, { .d_c = 0 }}})); } else { IError err = _t31.err; string sname = v__ast__TypeSymbol_symbol_name_except_generic(left_sym); string name = string_replace_each(sname, new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S("<"), _S("["), _S(">"), _S("]")}))); unknown_method_msg = str_intp(3, _MOV((StrIntpData[]){{_S("unknown method or field: `"), 0xfe10, {.d_s = name}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}})); } } v__checker__Checker_error(c, v__util__Suggestion_say(suggestion, unknown_method_msg), node->pos); } v__ast__Type _t32 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_method_call_defer_0) { if (has_method && node->is_method) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&method, _S("method")); } } // Defer end return _t32; } v__ast__TypeSymbol* _t33; /* if prepend */ if (is_method_from_embed) { _t33 = v__ast__Table_final_sym(c->table, (*(v__ast__Type*)array_last(node->from_embed_types))); } else { _t33 = v__ast__Table_final_sym(c->table, node->left_type); } v__ast__TypeSymbol* rec_sym = _t33; bool _t34; /* if prepend */ if (is_method_from_embed) { _t34 = v__ast__Type_has_flag((*(v__ast__Type*)array_last(node->from_embed_types)), v__ast__TypeFlag__generic); } else { _t34 = v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic); } bool rec_is_generic = _t34; Array_v__ast__Type rec_concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); int method_generic_names_len = method.generic_names.len; if (rec_sym->info._typ == 518 /* v.ast.Struct */) { if ((*rec_sym->info._v__ast__Struct).concrete_types.len > 0) { rec_concrete_types = array_clone_to_depth(&(*rec_sym->info._v__ast__Struct).concrete_types, 0); } int concrete_types_len = node->concrete_types.len; if (rec_is_generic && concrete_types_len == 0 && method_generic_names_len == (*rec_sym->info._v__ast__Struct).generic_types.len) { node->concrete_types = (*rec_sym->info._v__ast__Struct).generic_types; } else if (rec_is_generic && concrete_types_len > 0 && method_generic_names_len > concrete_types_len && (int)((*rec_sym->info._v__ast__Struct).generic_types.len + concrete_types_len) == method_generic_names_len) { Array_v__ast__Type t_concrete_types = array_clone_to_depth(&node->concrete_types, 0); node->concrete_types = (*rec_sym->info._v__ast__Struct).generic_types; _PUSH_MANY(&node->concrete_types, (t_concrete_types), _t35, Array_v__ast__Type); } else if (!rec_is_generic && (*rec_sym->info._v__ast__Struct).concrete_types.len > 0 && concrete_types_len > 0 && (int)((*rec_sym->info._v__ast__Struct).concrete_types.len + concrete_types_len) == method_generic_names_len) { Array_v__ast__Type t_concrete_types = array_clone_to_depth(&node->concrete_types, 0); node->concrete_types = (*rec_sym->info._v__ast__Struct).concrete_types; _PUSH_MANY(&node->concrete_types, (t_concrete_types), _t36, Array_v__ast__Type); } else if (!rec_is_generic && rec_concrete_types.len > 0 && method_generic_names_len == rec_concrete_types.len) { node->concrete_types = rec_concrete_types; } } else if (rec_sym->info._typ == 544 /* v.ast.SumType */) { if ((*rec_sym->info._v__ast__SumType).concrete_types.len > 0) { rec_concrete_types = array_clone_to_depth(&(*rec_sym->info._v__ast__SumType).concrete_types, 0); } int concrete_types_len = node->concrete_types.len; if (rec_is_generic && concrete_types_len == 0 && method_generic_names_len == (*rec_sym->info._v__ast__SumType).generic_types.len) { node->concrete_types = (*rec_sym->info._v__ast__SumType).generic_types; } else if (rec_is_generic && concrete_types_len > 0 && method_generic_names_len > concrete_types_len && (int)((*rec_sym->info._v__ast__SumType).generic_types.len + concrete_types_len) == method_generic_names_len) { Array_v__ast__Type t_concrete_types = array_clone_to_depth(&node->concrete_types, 0); node->concrete_types = (*rec_sym->info._v__ast__SumType).generic_types; _PUSH_MANY(&node->concrete_types, (t_concrete_types), _t37, Array_v__ast__Type); } else if (!rec_is_generic && (*rec_sym->info._v__ast__SumType).concrete_types.len > 0 && concrete_types_len > 0 && (int)((*rec_sym->info._v__ast__SumType).concrete_types.len + concrete_types_len) == method_generic_names_len) { Array_v__ast__Type t_concrete_types = array_clone_to_depth(&node->concrete_types, 0); node->concrete_types = (*rec_sym->info._v__ast__SumType).concrete_types; _PUSH_MANY(&node->concrete_types, (t_concrete_types), _t38, Array_v__ast__Type); } else if (!rec_is_generic && rec_concrete_types.len > 0 && method_generic_names_len == rec_concrete_types.len) { node->concrete_types = rec_concrete_types; } } else if (rec_sym->info._typ == 542 /* v.ast.Interface */) { if ((*rec_sym->info._v__ast__Interface).concrete_types.len > 0) { rec_concrete_types = array_clone_to_depth(&(*rec_sym->info._v__ast__Interface).concrete_types, 0); } int concrete_types_len = node->concrete_types.len; if (rec_is_generic && concrete_types_len == 0 && method_generic_names_len == (*rec_sym->info._v__ast__Interface).generic_types.len) { node->concrete_types = (*rec_sym->info._v__ast__Interface).generic_types; } else if (rec_is_generic && concrete_types_len > 0 && method_generic_names_len > concrete_types_len && (int)((*rec_sym->info._v__ast__Interface).generic_types.len + concrete_types_len) == method_generic_names_len) { Array_v__ast__Type t_concrete_types = array_clone_to_depth(&node->concrete_types, 0); node->concrete_types = (*rec_sym->info._v__ast__Interface).generic_types; _PUSH_MANY(&node->concrete_types, (t_concrete_types), _t39, Array_v__ast__Type); } else if (!rec_is_generic && (*rec_sym->info._v__ast__Interface).concrete_types.len > 0 && concrete_types_len > 0 && (int)((*rec_sym->info._v__ast__Interface).concrete_types.len + concrete_types_len) == method_generic_names_len) { Array_v__ast__Type t_concrete_types = array_clone_to_depth(&node->concrete_types, 0); node->concrete_types = (*rec_sym->info._v__ast__Interface).concrete_types; _PUSH_MANY(&node->concrete_types, (t_concrete_types), _t40, Array_v__ast__Type); } else if (!rec_is_generic && rec_concrete_types.len > 0 && method_generic_names_len == rec_concrete_types.len) { node->concrete_types = rec_concrete_types; } } else { } Array_v__ast__Type _t41 = {0}; Array_v__ast__Type _t41_orig = node->concrete_types; int _t41_len = _t41_orig.len; _t41 = __new_array(0, _t41_len, sizeof(v__ast__Type)); for (int _t43 = 0; _t43 < _t41_len; ++_t43) { v__ast__Type it = ((v__ast__Type*) _t41_orig.data)[_t43]; v__ast__Type _t42 = v__checker__Checker_unwrap_generic(c, it); array_push((array*)&_t41, &_t42); } Array_v__ast__Type concrete_types =_t41; if (concrete_types.len > 0 && v__ast__Table_register_fn_concrete_types(c->table, v__ast__Fn_fkey(&method), concrete_types)) { c->need_recheck_generic_fns = true; } node->is_noreturn = method.is_noreturn; node->is_expand_simple_interpolation = method.is_expand_simple_interpolation; node->is_ctor_new = method.is_ctor_new; node->return_type = method.return_type; if (v__ast__Type_has_flag(method.return_type, v__ast__TypeFlag__generic)) { node->return_type_generic = method.return_type; } if (!method.is_pub && !string__eq(method.mod, c->mod)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("method `"), 0xfe10, {.d_s = left_sym->name}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_S("` is private"), 0, { .d_c = 0 }}})), node->pos); } v__ast__ShareType rec_share = v__ast__Type_share((*(v__ast__Param*)array_get(method.params, 0)).typ); if (rec_share == v__ast__ShareType__shared_t && (c->locked_names.len > 0 || c->rlocked_names.len > 0)) { v__checker__Checker_error(c, _S("method with `shared` receiver cannot be called inside `lock`/`rlock` block"), node->pos); } if ((*(v__ast__Param*)array_get(method.params, 0)).is_mut) { multi_return_string_v__token__Pos mr_86355 = v__checker__Checker_check_for_mut_receiver(c, &node->left); string to_lock = mr_86355.arg0; v__token__Pos pos = mr_86355.arg1; if ((to_lock).len != 0 && rec_share != v__ast__ShareType__shared_t) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = to_lock}}, {_S(" is `shared` and must be `lock`ed to be passed as `mut`"), 0, { .d_c = 0 }}})), pos); } } else { v__checker__Checker_fail_if_unreadable(c, node->left, left_type, _S("receiver")); } if (left_sym->language != v__ast__Language__js && (!v__ast__TypeSymbol_is_builtin(left_sym) && !fast_string_eq(method.mod, _S("builtin"))) && method.language == v__ast__Language__v && final_left_sym->kind != v__ast__Kind__interface && method.no_body) { v__checker__Checker_error(c, _S("cannot call a method that does not have a body"), node->pos); } if (node->concrete_types.len > 0 && method_generic_names_len > 0 && node->concrete_types.len != method_generic_names_len) { string plural = (method_generic_names_len == 1 ? (_S("")) : (_S("s"))); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("expected "), 0xfe07, {.d_i32 = method_generic_names_len}}, {_S(" generic parameter"), 0xfe10, {.d_s = plural}}, {_S(", got "), 0xfe07, {.d_i32 = node->concrete_types.len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->concrete_list_pos); } for (int _t44 = 0; _t44 < node->concrete_types.len; ++_t44) { v__ast__Type concrete_type = ((v__ast__Type*)node->concrete_types.data)[_t44]; v__checker__Checker_ensure_type_exists(c, concrete_type, node->concrete_list_pos); } if (method.return_type == _const_v__ast__void_type && method.is_conditional && method.ctdefine_idx != -1) { node->should_be_skipped = v__checker__Checker_evaluate_once_comptime_if_attribute(c, (voidptr)&(*(v__ast__Attr*)array_get(method.attrs, method.ctdefine_idx))); } _result_void _t45 = v__checker__Checker_check_expected_arg_count(c, node, (voidptr)&method); if (_t45.is_error) { IError err = _t45.err; v__ast__Type _t46 = method.return_type; // Defer begin if (v__checker__Checker_method_call_defer_0) { if (has_method && node->is_method) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&method, _S("method")); } } // Defer end return _t46; } ; v__ast__Type exp_arg_typ = _const_v__ast__no_type; bool param_is_mut = false; bool no_type_promotion = false; if ((left_sym->info)._typ == 550 /* v.ast.Chan */) { if (_SLIT_EQ(method_name.str, method_name.len, "try_push")) { exp_arg_typ = v__ast__Type_ref((*left_sym->info._v__ast__Chan).elem_type); } else if (_SLIT_EQ(method_name.str, method_name.len, "try_pop")) { exp_arg_typ = (*left_sym->info._v__ast__Chan).elem_type; param_is_mut = true; no_type_promotion = true; } } for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + i; if (i > 0 || exp_arg_typ == _const_v__ast__no_type) { v__ast__Type _t47; /* if prepend */ if (method.is_variadic && i >= (int)(method.params.len - 1)) { _t47 = (*(v__ast__Param*)array_last(method.params)).typ; } else { _t47 = (*(v__ast__Param*)array_get(method.params, (int)(i + 1))).typ; } exp_arg_typ = _t47; if (!c->inside_recheck) { arg->ct_expr = v__type_resolver__ResolverInfo_is_comptime(c->comptime, arg->expr); } if (is_method_from_embed && (arg->expr)._typ == 385 /* v.ast.StructInit */) { v__ast__StructInit expr = *(v__ast__StructInit*)__as_cast((arg->expr)._v__ast__StructInit,(arg->expr)._typ, 385); bool is_short_syntax = expr.is_short_syntax && expr.typ == _const_v__ast__void_type; if (is_short_syntax) { v__ast__Type embed_type = (*(v__ast__Type*)array_last(node->from_embed_types)); v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(c->table, embed_type); if ((embed_sym->info)._typ == 518 /* v.ast.Struct */) { v__ast__Struct info = (*embed_sym->info._v__ast__Struct); if (info.concrete_types.len > 0) { v__ast__Type parent_type = info.parent_type; v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(c->table, parent_type); if ((parent_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((parent_sym->info)._v__ast__Struct,(parent_sym->info)._typ, 518)).is_generic) { _option_v__ast__Fn _t48; if (_t48 = v__ast__TypeSymbol_find_method(parent_sym, method_name), _t48.state == 0) { v__ast__Fn f = *(v__ast__Fn*)_t48.data; v__ast__Type _t49; /* if prepend */ if (f.is_variadic && i >= (int)(f.params.len - 1)) { _t49 = (*(v__ast__Param*)array_last(f.params)).typ; } else { _t49 = (*(v__ast__Param*)array_get(f.params, (int)(i + 1))).typ; } exp_arg_typ = _t49; } } } } } } param_is_mut = false; no_type_promotion = false; } v__ast__TypeSymbol* exp_arg_sym = v__ast__Table_sym(c->table, exp_arg_typ); c->expected_type = exp_arg_typ; v__ast__Type got_arg_typ = v__checker__Checker_check_expr_option_or_result_call(c, arg->expr, v__checker__Checker_expr(c, &arg->expr)); (*(v__ast__CallArg*)array_get(node->args, i)).typ = got_arg_typ; if (no_type_promotion) { if (got_arg_typ != exp_arg_typ) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = v__ast__Table_sym(c->table, got_arg_typ)->name}}, {_S("` as argument for `"), 0xfe10, {.d_s = method.name}}, {_S("` (`"), 0xfe10, {.d_s = exp_arg_sym->name}}, {_S("` expected)"), 0, { .d_c = 0 }}})), arg->pos); } } if (method.is_variadic && v__ast__Type_has_flag(got_arg_typ, v__ast__TypeFlag__variadic) && (int)(node->args.len - 1) > i) { v__checker__Checker_error(c, _S("when forwarding a variadic variable, it must be the final argument"), arg->pos); } v__ast__TypeSymbol* final_arg_sym = exp_arg_sym; v__ast__Type final_arg_typ = exp_arg_typ; if (method.is_variadic && (exp_arg_sym->info)._typ == 513 /* v.ast.Array */) { final_arg_typ = (*exp_arg_sym->info._v__ast__Array).elem_type; final_arg_sym = v__ast__Table_sym(c->table, final_arg_typ); } v__ast__Param _t50; /* if prepend */ if (method.is_variadic && i >= (int)(method.params.len - 1)) { _t50 = (*(v__ast__Param*)array_last(method.params)); } else { _t50 = (*(v__ast__Param*)array_get(method.params, (int)(i + 1))); } v__ast__Param param = _t50; if (method.is_variadic && (arg->expr)._typ == 337 /* v.ast.ArrayDecompose */) { if (i > (int)(method.params.len - 2)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("too many arguments in call to `"), 0xfe10, {.d_s = method.name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } if (method.is_variadic && i >= (int)(method.params.len - 2)) { v__ast__TypeSymbol* param_sym = v__ast__Table_sym(c->table, param.typ); v__ast__Type expected_type = param.typ; if (param_sym->kind == v__ast__Kind__array) { v__ast__Array info = v__ast__TypeSymbol_array_info(param_sym); expected_type = info.elem_type; c->expected_type = expected_type; } v__ast__Type typ = v__checker__Checker_expr(c, &arg->expr); if (i == (int)(node->args.len - 1)) { if (v__ast__Table_sym(c->table, typ)->kind == v__ast__Kind__array && (arg->expr)._typ != 337 /* v.ast.ArrayDecompose */ && !(v__ast__Table_sym(c->table, expected_type)->kind == v__ast__Kind__sum_type || v__ast__Table_sym(c->table, expected_type)->kind == v__ast__Kind__interface) && !v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic) && expected_type != typ) { string styp = v__ast__Table_type_to_str(c->table, typ); string elem_styp = v__ast__Table_type_to_str(c->table, expected_type); v__checker__Checker_error(c, str_intp(6, _MOV((StrIntpData[]){{_S("to pass `"), 0xfe10, {.d_s = v__ast__Expr_str(&arg->expr)}}, {_S("` ("), 0xfe10, {.d_s = styp}}, {_S(") to `"), 0xfe10, {.d_s = method.name}}, {_S("` (which accepts type `..."), 0xfe10, {.d_s = elem_styp}}, {_S("`), use `..."), 0xfe10, {.d_s = v__ast__Expr_str(&arg->expr)}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else if ((arg->expr)._typ == 337 /* v.ast.ArrayDecompose */ && v__ast__Table_sym(c->table, expected_type)->kind == v__ast__Kind__sum_type && v__ast__Type_idx(expected_type) != v__ast__Type_idx(typ)) { string expected_type_str = v__ast__Table_type_to_str(c->table, expected_type); string got_type_str = v__ast__Table_type_to_str(c->table, typ); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("cannot use `..."), 0xfe10, {.d_s = got_type_str}}, {_S("` as `..."), 0xfe10, {.d_s = expected_type_str}}, {_S("` in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}})), arg->pos); } } } else { c->expected_type = param.typ; } param_is_mut = param_is_mut || param.is_mut; v__ast__ShareType param_share = v__ast__Type_share(param.typ); if (param_share == v__ast__ShareType__shared_t && (c->locked_names.len > 0 || c->rlocked_names.len > 0)) { v__checker__Checker_error(c, _S("method with `shared` arguments cannot be called inside `lock`/`rlock` block"), arg->pos); } if (arg->is_mut) { multi_return_string_v__token__Pos mr_91967 = v__checker__Checker_fail_if_immutable(c, &arg->expr); string to_lock = mr_91967.arg0; v__token__Pos pos = mr_91967.arg1; if (!param_is_mut) { string tok = v__ast__ShareType_str(arg->share); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = node->name}}, {_S("` parameter `"), 0xfe10, {.d_s = param.name}}, {_S("` is not `"), 0xfe10, {.d_s = tok}}, {_S("`, `"), 0xfe10, {.d_s = tok}}, {_S("` is not needed`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(arg->expr)); } else { if (param_share != arg->share) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("wrong shared type `"), 0xfe10, {.d_s = v__ast__ShareType_str(arg->share)}}, {_S("`, expected: `"), 0xfe10, {.d_s = v__ast__ShareType_str(param_share)}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(arg->expr)); } if ((to_lock).len != 0 && param_share != v__ast__ShareType__shared_t) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = to_lock}}, {_S(" is `shared` and must be `lock`ed to be passed as `mut`"), 0, { .d_c = 0 }}})), pos); } } } else { if (param_is_mut) { string tok = (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__shared_f) ? (_S("shared")) : (v__ast__ShareType_str(arg->share))); v__checker__Checker_error(c, str_intp(6, _MOV((StrIntpData[]){{_S("method `"), 0xfe10, {.d_s = node->name}}, {_S("` parameter `"), 0xfe10, {.d_s = param.name}}, {_S("` is `"), 0xfe10, {.d_s = tok}}, {_S("`, so use `"), 0xfe10, {.d_s = tok}}, {_S(" "), 0xfe10, {.d_s = v__ast__Expr_str(&arg->expr)}}, {_S("` instead"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(arg->expr)); } else { v__checker__Checker_fail_if_unreadable(c, arg->expr, got_arg_typ, _S("argument")); } } if (concrete_types.len > 0 && method_generic_names_len != rec_concrete_types.len) { multi_return_bool_Array_v__ast__Type mr_92941 = v__type_resolver__TypeResolver_resolve_fn_generic_args(&c->type_resolver, c->table->cur_fn, (voidptr)&method, node); bool need_recheck = mr_92941.arg0; Array_v__ast__Type new_concrete_types = mr_92941.arg1; concrete_types = array_clone_to_depth(&new_concrete_types, 0); if (need_recheck) { c->need_recheck_generic_fns = true; } if (!v__ast__Type_has_flag((*(v__ast__Type*)array_get(concrete_types, 0)), v__ast__TypeFlag__generic)) { v__ast__Table_register_fn_concrete_types(c->table, v__ast__Fn_fkey(&method), concrete_types); } } if (v__ast__Type_has_flag(exp_arg_typ, v__ast__TypeFlag__generic)) { Array_v__ast__Type method_concrete_types = (method_generic_names_len == rec_concrete_types.len ? (rec_concrete_types) : (concrete_types)); _option_v__ast__Type _t51; if (_t51 = v__ast__Table_convert_generic_type(c->table, exp_arg_typ, method.generic_names, method_concrete_types), _t51.state == 0) { v__ast__Type exp_utyp = *(v__ast__Type*)_t51.data; exp_arg_typ = exp_utyp; } else { IError err = _t51.err; continue; } if (v__ast__Type_has_flag(got_arg_typ, v__ast__TypeFlag__generic)) { if (c->table->cur_fn != ((void*)0) && c->table->cur_concrete_types.len > 0) { got_arg_typ = v__checker__Checker_unwrap_generic(c, got_arg_typ); } else { _option_v__ast__Type _t52; if (_t52 = v__ast__Table_convert_generic_type(c->table, got_arg_typ, method.generic_names, method_concrete_types), _t52.state == 0) { v__ast__Type got_utyp = *(v__ast__Type*)_t52.data; got_arg_typ = got_utyp; } else { IError err = _t52.err; continue; } } } } if (final_arg_sym->kind == v__ast__Kind__interface) { if (v__checker__Checker_type_implements(c, got_arg_typ, final_arg_typ, v__ast__Expr_pos(arg->expr))) { if (!v__ast__Type_is_any_kind_of_pointer(got_arg_typ) && !c->inside_unsafe) { v__ast__TypeSymbol* got_arg_typ_sym = v__ast__Table_sym(c->table, got_arg_typ); if (got_arg_typ_sym->kind != v__ast__Kind__interface) { v__checker__Checker_mark_as_referenced(c, &arg->expr, true); } } } if (!(got_arg_typ == _const_v__ast__voidptr_type || got_arg_typ == _const_v__ast__nil_type) && !v__checker__Checker_check_multiple_ptr_match(c, got_arg_typ, param.typ, param, *arg)) { multi_return_string_string mr_94522 = v__checker__Checker_get_string_names_of(c, got_arg_typ, param.typ); string got_typ_str = mr_94522.arg0; string expected_typ_str = mr_94522.arg1; v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("` in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}})), arg->pos); } continue; } if (final_arg_sym->kind == v__ast__Kind__none && v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic) && !v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("cannot use `none` as generic argument"), arg->pos); } if (v__ast__Type_is_ptr(param.typ) && !v__ast__Type_is_any_kind_of_pointer(arg->typ) && v__ast__Expr_is_literal(arg->expr) && !c->pref->translated) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("literal argument cannot be passed as reference parameter `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, param.typ)}}, {_S("`"), 0, { .d_c = 0 }}})), arg->pos); } _result_void _t53 = v__checker__Checker_check_expected_call_arg(c, v__checker__Checker_unwrap_generic(c, got_arg_typ), exp_arg_typ, node->language, *arg); if (_t53.is_error) { IError err = _t53.err; v__ast__TypeSymbol* param_typ_sym = v__ast__Table_sym(c->table, exp_arg_typ); v__ast__TypeSymbol* arg_typ_sym = v__ast__Table_sym(c->table, got_arg_typ); if ((param_typ_sym->info)._typ == 513 /* v.ast.Array */ && (arg_typ_sym->info)._typ == 513 /* v.ast.Array */) { v__ast__Type param_elem_type = v__ast__Table_unaliased_type(c->table, (*param_typ_sym->info._v__ast__Array).elem_type); v__ast__Type arg_elem_type = v__ast__Table_unaliased_type(c->table, (*arg_typ_sym->info._v__ast__Array).elem_type); if (v__ast__Type_nr_muls(exp_arg_typ) == v__ast__Type_nr_muls(got_arg_typ) && (*param_typ_sym->info._v__ast__Array).nr_dims == (*arg_typ_sym->info._v__ast__Array).nr_dims && param_elem_type == arg_elem_type) { continue; } } if (!v__ast__Type_has_flag(exp_arg_typ, v__ast__TypeFlag__variadic) && param_typ_sym->kind == v__ast__Kind__array && v__ast__Table_final_sym(c->table, got_arg_typ)->kind == v__ast__Kind__array && v__checker__Checker_check_basic(c, v__ast__Type_clear_flag(v__ast__Table_value_type(c->table, got_arg_typ), v__ast__TypeFlag__option), v__ast__Table_value_type(c->table, exp_arg_typ))) { continue; } v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = left_sym->name}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}})), arg->pos); ; } ; if ((arg->expr)._typ == 365 /* v.ast.LambdaExpr */) { v__checker__Checker_handle_generic_lambda_arg(c, node, (voidptr)&(*arg->expr._v__ast__LambdaExpr)); } v__ast__TypeSymbol* param_typ_sym = v__ast__Table_sym(c->table, exp_arg_typ); if (param_typ_sym->kind == v__ast__Kind__struct && !(got_arg_typ == _const_v__ast__voidptr_type || got_arg_typ == _const_v__ast__nil_type) && !v__checker__Checker_check_multiple_ptr_match(c, got_arg_typ, param.typ, param, *arg)) { multi_return_string_string mr_96764 = v__checker__Checker_get_string_names_of(c, got_arg_typ, param.typ); string got_typ_str = mr_96764.arg0; string expected_typ_str = mr_96764.arg1; v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_typ_str}}, {_S("` as `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("` in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}})), arg->pos); } } if (method.is_unsafe && !c->inside_unsafe) { if (!c->pref->translated && !c->file->is_translated) { v__checker__Checker_warn(c, str_intp(3, _MOV((StrIntpData[]){{_S("method `"), 0xfe10, {.d_s = left_sym->name}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_S("` must be called from an `unsafe` block"), 0, { .d_c = 0 }}})), node->pos); } } if (c->table->cur_fn != ((void*)0) && !c->table->cur_fn->is_deprecated && method.is_deprecated) { v__checker__Checker_deprecate(c, _S("method"), str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = left_sym->name}}, {_S("."), 0xfe10, {.d_s = method.name}}, {_SLIT0, 0, { .d_c = 0 }}})), method.attrs, node->pos); } v__checker__Checker_set_node_expected_arg_types(c, node, (voidptr)&method); if (is_method_from_embed) { node->receiver_type = v__ast__Type_derive((*(v__ast__Type*)array_last(node->from_embed_types)), (*(v__ast__Param*)array_get(method.params, 0)).typ); } else if (is_generic) { node->receiver_type = v__ast__Type_set_flag(v__ast__Type_derive(left_type, (*(v__ast__Param*)array_get(method.params, 0)).typ), v__ast__TypeFlag__generic); } else { node->receiver_type = (*(v__ast__Param*)array_get(method.params, 0)).typ; } v__ast__Type _t54; /* if prepend */ if (is_method_from_embed) { _t54 = v__ast__Type_derive((*(v__ast__Type*)array_last(node->from_embed_types)), (*(v__ast__Param*)array_get(method.params, 0)).typ); } else { _t54 = (*(v__ast__Param*)array_get(method.params, 0)).typ; } node->receiver_concrete_type = _t54; if (left_sym->kind == v__ast__Kind__interface && is_method_from_embed && v__ast__Type_has_flag(method.return_type, v__ast__TypeFlag__generic) && method_generic_names_len == 0) { method.generic_names = v__ast__Table_get_generic_names(c->table, (*(v__ast__Interface*)__as_cast((rec_sym->info)._v__ast__Interface,(rec_sym->info)._typ, 542)).generic_types); method_generic_names_len = method.generic_names.len; } if (method_generic_names_len != node->concrete_types.len) { v__checker__Checker_infer_fn_generic_types(c, (voidptr)&method, node); Array_v__ast__Type _t55 = {0}; Array_v__ast__Type _t55_orig = node->concrete_types; int _t55_len = _t55_orig.len; _t55 = __new_array(0, _t55_len, sizeof(v__ast__Type)); for (int _t57 = 0; _t57 < _t55_len; ++_t57) { v__ast__Type it = ((v__ast__Type*) _t55_orig.data)[_t57]; v__ast__Type _t56 = v__checker__Checker_unwrap_generic(c, it); array_push((array*)&_t55, &_t56); } concrete_types =_t55; } if (concrete_types.len > 0 && !v__ast__Type_has_flag((*(v__ast__Type*)array_get(concrete_types, 0)), v__ast__TypeFlag__generic)) { v__ast__Table_register_fn_concrete_types(c->table, v__ast__Fn_fkey(&method), concrete_types); multi_return_bool_Array_v__ast__Type mr_98752 = v__type_resolver__TypeResolver_resolve_fn_generic_args(&c->type_resolver, c->table->cur_fn, (voidptr)&method, node); bool need_recheck = mr_98752.arg0; if (need_recheck) { c->need_recheck_generic_fns = true; } } if (node->concrete_types.len > 0 && method_generic_names_len == 0) { v__checker__Checker_error(c, _S("a non generic function called like a generic one"), node->concrete_list_pos); } if (method_generic_names_len > 0 && v__ast__Type_has_flag(method.return_type, v__ast__TypeFlag__generic) && c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len == 0) { node->return_type = v__ast__Table_unwrap_generic_type(c->table, method.return_type, method.generic_names, concrete_types); } else { node->return_type = method.return_type; } if (method_generic_names_len > 0 && v__ast__Type_has_flag(method.return_type, v__ast__TypeFlag__generic)) { v__ast__Type ret_type = v__checker__Checker_resolve_fn_return_type(c, (voidptr)&method, *node, concrete_types); v__checker__Checker_register_trace_call(c, node, (voidptr)&method); node->return_type = ret_type; v__ast__Type _t58 = ret_type; // Defer begin if (v__checker__Checker_method_call_defer_0) { if (has_method && node->is_method) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&method, _S("method")); } } // Defer end return _t58; } if (method_generic_names_len > 0) { if (!v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic)) { if ((left_sym->info)._typ == 518 /* v.ast.Struct */) { if (method_generic_names_len == (*left_sym->info._v__ast__Struct).concrete_types.len) { node->concrete_types = (*left_sym->info._v__ast__Struct).concrete_types; } } } } v__checker__Checker_register_trace_call(c, node, (voidptr)&method); v__ast__Type _t59 = node->return_type; // Defer begin if (v__checker__Checker_method_call_defer_0) { if (has_method && node->is_method) { v__checker__Checker_check_must_use_call_result(c, node, (voidptr)&method, _S("method")); } } // Defer end return _t59; } VV_LOC void v__checker__Checker_handle_generic_lambda_arg(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__LambdaExpr* lambda) { if (node->concrete_types.len > 0 && lambda->func != ((void*)0) && lambda->func->decl.generic_names.len > 0) { lambda->call_ctx = node; if (v__ast__Table_register_fn_concrete_types(c->table, v__ast__FnDecl_fkey(&lambda->func->decl), node->concrete_types)) { lambda->func->decl.ninstances++; } } } VV_LOC v__ast__Type v__checker__Checker_spawn_expr(v__checker__Checker* c, v__ast__SpawnExpr* node) { v__ast__Type ret_type = v__checker__Checker_call_expr(c, (voidptr)&node->call_expr); if (node->call_expr.or_block.kind != v__ast__OrKind__absent) { v__checker__Checker_error(c, _S("option handling cannot be done in `spawn` call. Do it when calling `.wait()`"), node->call_expr.or_block.pos); } for (int _t1 = 0; _t1 < node->call_expr.args.len; ++_t1) { v__ast__CallArg arg = ((v__ast__CallArg*)node->call_expr.args.data)[_t1]; if (arg.is_mut && !v__ast__Type_is_ptr(arg.typ)) { if (arg.typ == 0) { v__checker__Checker_error(c, _S("invalid expr"), node->pos); return 0; } if (v__ast__Table_final_sym(c->table, arg.typ)->kind == v__ast__Kind__array) { continue; } v__checker__Checker_error(c, _S("function in `spawn` statement cannot contain mutable non-reference arguments"), v__ast__Expr_pos(arg.expr)); } } if (node->call_expr.is_method && v__ast__Type_is_ptr(node->call_expr.receiver_type) && !v__ast__Type_is_ptr(node->call_expr.left_type)) { v__checker__Checker_error(c, _S("method in `spawn` statement cannot have non-reference mutable receiver"), v__ast__Expr_pos(node->call_expr.left)); } if (v__pref__Backend_is_js(c->pref->backend)) { return v__ast__Table_find_or_register_promise(c->table, v__checker__Checker_unwrap_generic(c, ret_type)); } else { return v__ast__Table_find_or_register_thread(c->table, v__checker__Checker_unwrap_generic(c, ret_type)); } return 0; } VV_LOC v__ast__Type v__checker__Checker_go_expr(v__checker__Checker* c, v__ast__GoExpr* node) { v__ast__Type ret_type = v__checker__Checker_call_expr(c, (voidptr)&node->call_expr); if (node->call_expr.or_block.kind != v__ast__OrKind__absent) { v__checker__Checker_error(c, _S("option handling cannot be done in `go` call. Do it when calling `.wait()`"), node->call_expr.or_block.pos); } for (int _t1 = 0; _t1 < node->call_expr.args.len; ++_t1) { v__ast__CallArg arg = ((v__ast__CallArg*)node->call_expr.args.data)[_t1]; if (arg.is_mut && !v__ast__Type_is_ptr(arg.typ)) { v__checker__Checker_error(c, _S("function in `go` statement cannot contain mutable non-reference arguments"), v__ast__Expr_pos(arg.expr)); } } if (node->call_expr.is_method && v__ast__Type_is_ptr(node->call_expr.receiver_type) && !v__ast__Type_is_ptr(node->call_expr.left_type)) { v__checker__Checker_error(c, _S("method in `go` statement cannot have non-reference mutable receiver"), v__ast__Expr_pos(node->call_expr.left)); } if (v__pref__Backend_is_js(c->pref->backend)) { return v__ast__Table_find_or_register_promise(c->table, v__checker__Checker_unwrap_generic(c, ret_type)); } else { return v__ast__Table_find_or_register_thread(c->table, v__checker__Checker_unwrap_generic(c, ret_type)); } return 0; } VV_LOC void v__checker__Checker_set_node_expected_arg_types(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Fn* func) { if (node->expected_arg_types.len == 0) { int start_idx = (func->is_method ? (1) : (0)); for (int i = start_idx; i < func->params.len; ++i) { array_push((array*)&node->expected_arg_types, _MOV((v__ast__Type[]){ ((v__ast__Param*)func->params.data)[i].typ })); } } } VV_LOC _result_void v__checker__Checker_post_process_generic_fns(v__checker__Checker* c) { Map_string_int all_generic_fns = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int i = 0; i < c->file->generic_fns.len; ++i) { v__ast__FnDecl* node = (*(v__ast__FnDecl**)array_get(c->file->generic_fns, i)); c->mod = node->mod; string fkey = v__ast__FnDecl_fkey(node); (*(int*)map_get_and_set((map*)&all_generic_fns, &(string[]){fkey}, &(int[]){ 0 }))++; if ((*(int*)map_get(ADDR(map, all_generic_fns), &(string[]){fkey}, &(int[]){ 0 })) > 10000) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fkey}}, {_S(" generic function visited more than "), 0xfe07, {.d_i32 = _const_v__checker__generic_fn_cutoff_limit_per_fn}}, {_S(" times"), 0, { .d_c = 0 }}})), node->pos); return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("fkey: "), 0xfe10, {.d_s = fkey}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } Array_Array_v__ast__Type gtypes = (*(Array_Array_v__ast__Type*)map_get(ADDR(map, c->table->fn_generic_types), &(string[]){fkey}, &(Array_Array_v__ast__Type[]){ __new_array(0, 0, sizeof(Array_v__ast__Type)) })); #if defined(CUSTOM_DEFINE_trace_post_process_generic_fns) { eprintln(str_intp(6, _MOV((StrIntpData[]){{_S("> post_process_generic_fns "), 0xfe10, {.d_s = node->mod}}, {_S(" | "), 0xfe10, {.d_s = node->name}}, {_S(" | fkey: "), 0xfe10, {.d_s = fkey}}, {_S(" | gtypes: "), 0xfe10, {.d_s = Array_Array_v__ast__Type_str(gtypes)}}, {_S(" | c.file.generic_fns.len: "), 0xfe07, {.d_i32 = c->file->generic_fns.len}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif for (int _t3 = 0; _t3 < gtypes.len; ++_t3) { Array_v__ast__Type concrete_types = ((Array_v__ast__Type*)gtypes.data)[_t3]; c->table->cur_concrete_types = concrete_types; v__checker__Checker_fn_decl(c, node); if (fast_string_eq(node->name, _S("veb.run")) || fast_string_eq(node->name, _S("veb.run_at")) || fast_string_eq(node->name, _S("x.vweb.run")) || fast_string_eq(node->name, _S("x.vweb.run_at")) || fast_string_eq(node->name, _S("vweb.run")) || fast_string_eq(node->name, _S("vweb.run_at"))) { for (int _t4 = 0; _t4 < concrete_types.len; ++_t4) { v__ast__Type ct = ((v__ast__Type*)concrete_types.data)[_t4]; if (!(Array_v__ast__Type_contains(c->vweb_gen_types, ct))) { array_push((array*)&c->vweb_gen_types, _MOV((v__ast__Type[]){ ct })); } } } } c->table->cur_concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); #if defined(CUSTOM_DEFINE_trace_post_process_generic_fns) { if (node->generic_names.len > 0) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S(" > fn_decl node.name: "), 0xfe10, {.d_s = node->name}}, {_S(" | generic_names: "), 0xfe10, {.d_s = Array_string_str(node->generic_names)}}, {_S(" | ninstances: "), 0xfe07, {.d_i32 = node->ninstances}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } #endif } return (_result_void){0}; } VV_LOC _result_void v__checker__Checker_check_expected_arg_count(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Fn* f) { int nr_args = node->args.len; int nr_params = (node->is_method && f->params.len > 0 ? ((int)(f->params.len - 1)) : (f->params.len)); int min_required_params = f->params.len; if (node->is_method) { min_required_params--; } if (f->is_variadic) { min_required_params--; v__checker__Checker_markused_array_method(c, !c->is_builtin_mod, _S("")); } else { bool _t1 = false; Array_v__ast__CallArg _t1_orig = node->args; int _t1_len = _t1_orig.len; for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__CallArg it = ((v__ast__CallArg*) _t1_orig.data)[_t2]; if ((it.expr)._typ == 337 /* v.ast.ArrayDecompose */) { _t1 = true; break; } } bool has_decompose =_t1; if (has_decompose) { min_required_params = (int)(nr_args - 1); } } if (node->args.len == 1 && ((*(v__ast__CallArg*)array_get(node->args, 0)).expr)._typ == 344 /* v.ast.CallExpr */) { bool is_multi = (*(*(v__ast__CallArg*)array_get(node->args, 0)).expr._v__ast__CallExpr).nr_ret_values > 1; if (is_multi && !(Array_string_contains(_const_v__checker__print_everything_fns, node->name))) { nr_args = (*(*(v__ast__CallArg*)array_get(node->args, 0)).expr._v__ast__CallExpr).nr_ret_values; if (nr_args != nr_params) { v__token__Pos unexpected_args_pos = v__token__Pos_extend((*(v__ast__CallArg*)array_get(node->args, 0)).pos, (*(v__ast__CallArg*)array_last(node->args)).pos); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("expected "), 0xfe07, {.d_i32 = min_required_params}}, {_S(" arguments, but got "), 0xfe07, {.d_i32 = nr_args}}, {_S(" from multi-return "), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, (*(*(v__ast__CallArg*)array_get(node->args, 0)).expr._v__ast__CallExpr).return_type)}}, {_SLIT0, 0, { .d_c = 0 }}})), unexpected_args_pos); return (_result_void){ .is_error=true, .err=_v_error(_S("")), .data={E_STRUCT} }; } } } if (min_required_params < 0) { min_required_params = 0; } if (nr_args < min_required_params) { if (min_required_params == (int)(nr_args + 1)) { v__ast__Type last_typ = (*(v__ast__Param*)array_last(f->params)).typ; v__ast__TypeSymbol* last_sym = v__ast__Table_sym(c->table, last_typ); if ((last_sym->info)._typ == 518 /* v.ast.Struct */) { bool _t4 = false; Array_v__ast__Attr _t4_orig = (*last_sym->info._v__ast__Struct).attrs; int _t4_len = _t4_orig.len; for (int _t5 = 0; _t5 < _t4_len; ++_t5) { v__ast__Attr it = ((v__ast__Attr*) _t4_orig.data)[_t5]; if (fast_string_eq(it.name, _S("params")) && !it.has_arg) { _t4 = true; break; } } bool is_params =_t4; if (is_params) { array_push((array*)&node->args, _MOV((v__ast__CallArg[]){ ((v__ast__CallArg){.is_mut = 0,.share = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__StructInit_to_sumtype_v__ast__Expr(ADDR(v__ast__StructInit, (((v__ast__StructInit){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.no_keys = 0,.is_short_syntax = 0,.is_anon = 0,.unresolved = 0,.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.typ_str = (string){.str=(byteptr)"", .is_lit=1},.typ = last_typ,.update_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_expr_type = 0,.update_expr_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.update_expr_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_update_embed = 0,.has_update_expr = 0,.init_fields = __new_array(0, 0, sizeof(v__ast__StructInitField)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.language = 0,})))),.typ = 0,.is_tmp_autofree = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.should_be_ptr = 0,.ct_expr = 0,}) })); return (_result_void){0}; } } if ((last_sym->info)._typ == 518 /* v.ast.Struct */) { bool _t7 = (fast_string_eq(last_sym->name, _S("main.Context"))); if ( _t7 && fast_string_eq((*(v__ast__Param*)array_last(f->params)).name, _S("ctx"))) { return (_result_void){0}; } } } v__checker__Checker_fn_call_error_have_want(c, ((v__checker__HaveWantParams){.nr_params = min_required_params,.nr_args = nr_args,.args = node->args,.params = f->params,.pos = node->pos,})); return (_result_void){ .is_error=true, .err=_v_error(_S("")), .data={E_STRUCT} }; } else if (!f->is_variadic && nr_args > nr_params) { v__token__Pos unexpected_args_pos = v__token__Pos_extend((*(v__ast__CallArg*)array_get(node->args, min_required_params)).pos, (*(v__ast__CallArg*)array_last(node->args)).pos); v__checker__Checker_fn_call_error_have_want(c, ((v__checker__HaveWantParams){.nr_params = min_required_params,.nr_args = nr_args,.args = node->args,.params = f->params,.pos = unexpected_args_pos,})); return (_result_void){ .is_error=true, .err=_v_error(_S("")), .data={E_STRUCT} }; } return (_result_void){0}; } VV_LOC void v__checker__Checker_fn_call_error_have_want(v__checker__Checker* c, v__checker__HaveWantParams p) { strings__Builder sb = strings__new_builder(20); strings__Builder_write_string(&sb, _S("have (")); Array_v__ast__Type arg_types = __new_array_with_default(p.args.len, 0, sizeof(v__ast__Type), 0); for (int i = 0; i < p.args.len; ++i) { v__ast__CallArg arg = ((v__ast__CallArg*)p.args.data)[i]; v__ast__Expr e = arg.expr; array_set(&arg_types, i, &(v__ast__Type[]) { v__checker__Checker_expr(c, &e) }); } for (int i = 0; i < p.args.len; ++i) { if ((*(v__ast__Type*)array_get(arg_types, i)) == 0) { strings__Builder_write_string(&sb, _S("?")); } else { strings__Builder_write_string(&sb, v__ast__Table_type_to_str(c->table, (*(v__ast__Type*)array_get(arg_types, i)))); } if (i < (int)(p.args.len - 1)) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_string(&sb, _S(")")); v__checker__Checker_add_error_detail(c, strings__Builder_str(&sb)); strings__Builder_write_string(&sb, _S(" want (")); for (int i = 0; i < p.params.len; ++i) { v__ast__Param param = ((v__ast__Param*)p.params.data)[i]; if (i == 0 && p.nr_params == (int)(p.params.len - 1)) { continue; } strings__Builder_write_string(&sb, v__ast__Table_type_to_str(c->table, param.typ)); if (i < (int)(p.params.len - 1)) { strings__Builder_write_string(&sb, _S(", ")); } } strings__Builder_write_string(&sb, _S(")")); v__checker__Checker_add_error_detail(c, strings__Builder_str(&sb)); string args_plural = (p.nr_params == 1 ? (_S("argument")) : (_S("arguments"))); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("expected "), 0xfe07, {.d_i32 = p.nr_params}}, {_S(" "), 0xfe10, {.d_s = args_plural}}, {_S(", but got "), 0xfe07, {.d_i32 = p.nr_args}}, {_SLIT0, 0, { .d_c = 0 }}})), p.pos); } VV_LOC void v__checker__Checker_check_predicate_param(v__checker__Checker* c, bool is_map, v__ast__Type elem_typ, v__ast__CallExpr node) { if (node.args.len != 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expected 1 argument, but got "), 0xfe07, {.d_i32 = node.args.len}}, {_SLIT0, 0, { .d_c = 0 }}})), node.pos); return; } v__ast__Expr arg_expr = (*(v__ast__CallArg*)array_get(node.args, 0)).expr; if (arg_expr._typ == 336 /* v.ast.AnonFn */) { if (v__ast__Type_has_flag((*arg_expr._v__ast__AnonFn).decl.return_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("option needs to be unwrapped before using it in map/filter"), (*(v__ast__CallArg*)array_get(node.args, 0)).pos); } if ((*arg_expr._v__ast__AnonFn).decl.params.len > 1) { v__checker__Checker_error(c, _S("function needs exactly 1 argument"), (*arg_expr._v__ast__AnonFn).decl.pos); } else if (is_map && ((*arg_expr._v__ast__AnonFn).decl.return_type == _const_v__ast__void_type || (*(v__ast__Param*)array_get((*arg_expr._v__ast__AnonFn).decl.params, 0)).typ != elem_typ)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type mismatch, should use `fn(a "), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, elem_typ)}}, {_S(") T {...}`"), 0, { .d_c = 0 }}})), (*arg_expr._v__ast__AnonFn).decl.pos); } else if (!is_map && ((*arg_expr._v__ast__AnonFn).decl.return_type != _const_v__ast__bool_type || (*(v__ast__Param*)array_get((*arg_expr._v__ast__AnonFn).decl.params, 0)).typ != elem_typ)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type mismatch, should use `fn(a "), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, elem_typ)}}, {_S(") bool {...}`"), 0, { .d_c = 0 }}})), (*arg_expr._v__ast__AnonFn).decl.pos); } } else if (arg_expr._typ == 358 /* v.ast.Ident */) { if ((*arg_expr._v__ast__Ident).kind == v__ast__IdentKind__function) { _option_v__ast__Fn _t1 = v__ast__Table_find_fn(c->table, (*arg_expr._v__ast__Ident).name); if (_t1.state != 0) { IError err = _t1.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*arg_expr._v__ast__Ident).name}}, {_S(" does not exist"), 0, { .d_c = 0 }}})), (*arg_expr._v__ast__Ident).pos); return; } v__ast__Fn func = (*(v__ast__Fn*)_t1.data); if (v__ast__Type_has_flag(func.return_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("option needs to be unwrapped before using it in map/filter"), node.pos); } if (func.params.len > 1) { v__checker__Checker_error(c, _S("function needs exactly 1 argument"), node.pos); } else if (is_map && (func.return_type == _const_v__ast__void_type || (*(v__ast__Param*)array_get(func.params, 0)).typ != elem_typ)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type mismatch, should use `fn(a "), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, elem_typ)}}, {_S(") T {...}`"), 0, { .d_c = 0 }}})), (*arg_expr._v__ast__Ident).pos); } else if (!is_map && (func.return_type != _const_v__ast__bool_type || (*(v__ast__Param*)array_get(func.params, 0)).typ != elem_typ)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type mismatch, should use `fn(a "), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, elem_typ)}}, {_S(") bool {...}`"), 0, { .d_c = 0 }}})), (*arg_expr._v__ast__Ident).pos); } } else if ((*arg_expr._v__ast__Ident).kind == v__ast__IdentKind__variable) { if (((*arg_expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { v__ast__Expr expr = (*(*arg_expr._v__ast__Ident).obj._v__ast__Var).expr; if ((expr)._typ == 336 /* v.ast.AnonFn */) { if (v__ast__Type_has_flag((*expr._v__ast__AnonFn).decl.return_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("option needs to be unwrapped before using it in map/filter"), (*arg_expr._v__ast__Ident).pos); } if ((*expr._v__ast__AnonFn).decl.params.len > 1) { v__checker__Checker_error(c, _S("function needs exactly 1 argument"), (*expr._v__ast__AnonFn).decl.pos); } else if (is_map && ((*expr._v__ast__AnonFn).decl.return_type == _const_v__ast__void_type || (*(v__ast__Param*)array_get((*expr._v__ast__AnonFn).decl.params, 0)).typ != elem_typ)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type mismatch, should use `fn(a "), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, elem_typ)}}, {_S(") T {...}`"), 0, { .d_c = 0 }}})), (*expr._v__ast__AnonFn).decl.pos); } else if (!is_map && ((*expr._v__ast__AnonFn).decl.return_type != _const_v__ast__bool_type || (*(v__ast__Param*)array_get((*expr._v__ast__AnonFn).decl.params, 0)).typ != elem_typ)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type mismatch, should use `fn(a "), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, elem_typ)}}, {_S(") bool {...}`"), 0, { .d_c = 0 }}})), (*expr._v__ast__AnonFn).decl.pos); } return; } } if (!is_map && v__ast__Ident_var_info(&(*arg_expr._v__ast__Ident)).typ != _const_v__ast__bool_type) { v__checker__Checker_error(c, _S("type mismatch, should be bool"), (*arg_expr._v__ast__Ident).pos); } } } else if (arg_expr._typ == 344 /* v.ast.CallExpr */) { if (is_map && ((*arg_expr._v__ast__CallExpr).return_type == _const_v__ast__void_type || (*arg_expr._v__ast__CallExpr).return_type == (u32)0)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type mismatch, `"), 0xfe10, {.d_s = (*arg_expr._v__ast__CallExpr).name}}, {_S("` does not return anything"), 0, { .d_c = 0 }}})), (*arg_expr._v__ast__CallExpr).pos); } else if (!is_map && (*arg_expr._v__ast__CallExpr).return_type != _const_v__ast__bool_type) { if ((*arg_expr._v__ast__CallExpr).or_block.kind != v__ast__OrKind__absent && (v__ast__Type_has_flag((*arg_expr._v__ast__CallExpr).return_type, v__ast__TypeFlag__option) || v__ast__Type_has_flag((*arg_expr._v__ast__CallExpr).return_type, v__ast__TypeFlag__result)) && v__ast__Type_clear_option_and_result((*arg_expr._v__ast__CallExpr).return_type) == _const_v__ast__bool_type) { return; } v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type mismatch, `"), 0xfe10, {.d_s = (*arg_expr._v__ast__CallExpr).name}}, {_S("` must return a bool"), 0, { .d_c = 0 }}})), (*arg_expr._v__ast__CallExpr).pos); } if (v__ast__Type_has_flag((*arg_expr._v__ast__CallExpr).return_type, v__ast__TypeFlag__result) && (*arg_expr._v__ast__CallExpr).or_block.kind != v__ast__OrKind__block) { if (Array_v__ast__Type_contains(new_array_from_c_array(2, 2, sizeof(v__ast__Type), _MOV((v__ast__Type[2]){_const_v__ast__void_type, 0})), v__ast__Type_clear_option_and_result((*arg_expr._v__ast__CallExpr).return_type))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use Result type in `"), 0xfe10, {.d_s = node.name}}, {_S("`"), 0, { .d_c = 0 }}})), (*arg_expr._v__ast__CallExpr).pos); } } } else if (arg_expr._typ == 384 /* v.ast.StringLiteral */) { if (!is_map) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type mismatch, should use e.g. `"), 0xfe10, {.d_s = node.name}}, {_S("(it > 2)`"), 0, { .d_c = 0 }}})), (*arg_expr._v__ast__StringLiteral).pos); } } else if (arg_expr._typ == 383 /* v.ast.StringInterLiteral */) { if (!is_map) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type mismatch, should use e.g. `"), 0xfe10, {.d_s = node.name}}, {_S("(it > 2)`"), 0, { .d_c = 0 }}})), (*arg_expr._v__ast__StringInterLiteral).pos); } } else if (arg_expr._typ == 362 /* v.ast.InfixExpr */) { if ((*arg_expr._v__ast__InfixExpr).op == v__token__Kind__left_shift && (*arg_expr._v__ast__InfixExpr).is_stmt && v__ast__Table_final_sym(c->table, (*arg_expr._v__ast__InfixExpr).left_type)->kind == v__ast__Kind__array) { v__checker__Checker_error(c, _S("array append cannot be used in an expression"), (*arg_expr._v__ast__InfixExpr).pos); } } else if (arg_expr._typ == 365 /* v.ast.LambdaExpr */) { if (((*arg_expr._v__ast__LambdaExpr).expr)._typ == 344 /* v.ast.CallExpr */ && is_map && ((*(v__ast__CallExpr*)__as_cast(((*arg_expr._v__ast__LambdaExpr).expr)._v__ast__CallExpr,((*arg_expr._v__ast__LambdaExpr).expr)._typ, 344)).return_type == _const_v__ast__void_type || (*(v__ast__CallExpr*)__as_cast(((*arg_expr._v__ast__LambdaExpr).expr)._v__ast__CallExpr,((*arg_expr._v__ast__LambdaExpr).expr)._typ, 344)).return_type == (u32)0)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type mismatch, `"), 0xfe10, {.d_s = (*(*arg_expr._v__ast__LambdaExpr).expr._v__ast__CallExpr).name}}, {_S("` does not return anything"), 0, { .d_c = 0 }}})), (*(*arg_expr._v__ast__LambdaExpr).expr._v__ast__CallExpr).pos); } } else { if (!is_map && v__checker__Checker_expr(c, &arg_expr) != _const_v__ast__bool_type) { v__checker__Checker_error(c, _S("invalid expression, expected infix expr, lambda or function"), v__ast__Expr_pos(arg_expr)); } } } VV_LOC v__ast__Type v__checker__Checker_map_builtin_method_call(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Type left_type_) { string method_name = node->name; v__ast__Type ret_type = _const_v__ast__void_type; v__ast__Type left_type = (v__ast__Table_final_sym(c->table, left_type_)->kind == v__ast__Kind__any ? (v__checker__Checker_unwrap_generic(c, left_type_)) : (left_type_)); v__ast__TypeSymbol* left_sym = v__ast__Table_final_sym(c->table, left_type); if (_SLIT_EQ(method_name.str, method_name.len, "clone") || _SLIT_EQ(method_name.str, method_name.len, "move")) { if (node->args.len != 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` does not have any arguments"), 0, { .d_c = 0 }}})), (*(v__ast__CallArg*)array_get(node->args, 0)).pos); } if (string_at(method_name, 0) == 'm') { v__checker__Checker_check_for_mut_receiver(c, &node->left); } if (v__ast__Expr_is_auto_deref_var(node->left) || v__ast__Type_has_flag(left_type, v__ast__TypeFlag__shared_f)) { ret_type = v__ast__Type_deref(node->left_type); } else { ret_type = node->left_type; } ret_type = v__ast__Type_clear_flag(ret_type, v__ast__TypeFlag__shared_f); } else if (_SLIT_EQ(method_name.str, method_name.len, "keys") || _SLIT_EQ(method_name.str, method_name.len, "values")) { if (node->args.len != 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` does not have any arguments"), 0, { .d_c = 0 }}})), (*(v__ast__CallArg*)array_get(node->args, 0)).pos); } v__ast__Map info = *(v__ast__Map*)__as_cast((left_sym->info)._v__ast__Map,(left_sym->info)._typ, 514); int typ = (_SLIT_EQ(method_name.str, method_name.len, "keys") ? (v__ast__Table_find_or_register_array(c->table, info.key_type)) : (v__ast__Table_find_or_register_array(c->table, info.value_type))); ret_type = v__ast__idx_to_type(typ); if (v__ast__Type_has_flag(info.key_type, v__ast__TypeFlag__generic) && _SLIT_EQ(method_name.str, method_name.len, "keys")) { ret_type = v__ast__Type_set_flag(ret_type, v__ast__TypeFlag__generic); } if (v__ast__Type_has_flag(info.value_type, v__ast__TypeFlag__generic) && _SLIT_EQ(method_name.str, method_name.len, "values")) { ret_type = v__ast__Type_set_flag(ret_type, v__ast__TypeFlag__generic); } } else if (_SLIT_EQ(method_name.str, method_name.len, "delete")) { v__checker__Checker_check_for_mut_receiver(c, &node->left); if (node->args.len != 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expected 1 argument, but got "), 0xfe07, {.d_i32 = node->args.len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } v__ast__Map info = *(v__ast__Map*)__as_cast((left_sym->info)._v__ast__Map,(left_sym->info)._typ, 514); v__ast__Type arg_type = v__checker__Checker_expr(c, &(*(v__ast__CallArg*)array_get(node->args, 0)).expr); _result_void _t1 = v__checker__Checker_check_expected_call_arg(c, arg_type, info.key_type, node->language, (*(v__ast__CallArg*)array_get(node->args, 0))); if (_t1.is_error) { IError err = _t1.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument 1 to `Map.delete`"), 0, { .d_c = 0 }}})), (*(v__ast__CallArg*)array_get(node->args, 0)).pos); ; } ; } else { } node->receiver_type = v__ast__Type_ref(node->left_type); node->return_type = ret_type; return node->return_type; } VV_LOC void v__checker__Checker_ensure_same_array_return_type(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Type left_type) { node->receiver_type = v__ast__Type_ref(left_type); if (v__ast__Expr_is_auto_deref_var(node->left)) { node->return_type = v__ast__Type_deref(left_type); } else { node->return_type = v__ast__Type_set_nr_muls(node->receiver_type, 0); } if (v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__shared_f)) { node->return_type = v__ast__Type_clear_flag(node->return_type, v__ast__TypeFlag__shared_f); } } VV_LOC v__ast__Type v__checker__Checker_array_builtin_method_call(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Type left_type) { v__ast__TypeSymbol* left_sym = v__ast__Table_final_sym(c->table, left_type); string method_name = node->name; v__ast__Type elem_typ = _const_v__ast__void_type; if (!c->is_builtin_mod && _SLIT_EQ(method_name.str, method_name.len, "slice")) { v__checker__Checker_error(c, _S(".slice() is a private method, use `x[start..end]` instead"), node->pos); return _const_v__ast__void_type; } v__ast__Type unwrapped_left_type = v__checker__Checker_unwrap_generic(c, left_type); v__ast__Type unaliased_left_type = v__ast__Table_unaliased_type(c->table, unwrapped_left_type); v__ast__Array array_info = ((left_sym->info)._typ == 513 /* v.ast.Array */ ? ((*left_sym->info._v__ast__Array)) : (({ v__ast__TypeInfo _t2 = v__ast__Table_sym(c->table, unaliased_left_type)->info; *(v__ast__Array*)__as_cast(_t2._v__ast__Array,_t2._typ, 513); }))); elem_typ = array_info.elem_type; int node_args_len = node->args.len; v__ast__CallArg arg0 = (node_args_len > 0 ? ((*(v__ast__CallArg*)array_get(node->args, 0))) : (((v__ast__CallArg){.is_mut = 0,.share = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = 0,.is_tmp_autofree = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.should_be_ptr = 0,.ct_expr = 0,}))); if (_SLIT_EQ(method_name.str, method_name.len, "filter") || _SLIT_EQ(method_name.str, method_name.len, "map") || _SLIT_EQ(method_name.str, method_name.len, "any") || _SLIT_EQ(method_name.str, method_name.len, "all") || _SLIT_EQ(method_name.str, method_name.len, "count")) { if (node_args_len > 0 && (arg0.expr)._typ == 365 /* v.ast.LambdaExpr */) { if ((*arg0.expr._v__ast__LambdaExpr).params.len != 1) { v__checker__Checker_error(c, _S("lambda expressions used in the builtin array methods require exactly 1 parameter"), (*arg0.expr._v__ast__LambdaExpr).pos); return _const_v__ast__void_type; } if (_SLIT_EQ(method_name.str, method_name.len, "map")) { v__checker__Checker_lambda_expr_fix_type_of_param(c, (voidptr)&(*arg0.expr._v__ast__LambdaExpr), (voidptr)&(*(v__ast__Ident*)array_get((*arg0.expr._v__ast__LambdaExpr).params, 0)), elem_typ); v__ast__Type le_type = v__checker__Checker_expr(c, &(*arg0.expr._v__ast__LambdaExpr).expr); v__checker__Checker_support_lambda_expr_one_param(c, elem_typ, le_type, (voidptr)&(*arg0.expr._v__ast__LambdaExpr)); } else { v__checker__Checker_support_lambda_expr_one_param(c, elem_typ, _const_v__ast__bool_type, (voidptr)&(*arg0.expr._v__ast__LambdaExpr)); } } else { v__checker__scope_register_it(node->scope, node->pos, elem_typ); } } else if (_SLIT_EQ(method_name.str, method_name.len, "insert") || _SLIT_EQ(method_name.str, method_name.len, "prepend")) { if (_SLIT_EQ(method_name.str, method_name.len, "insert")) { if (node_args_len != 2) { v__checker__Checker_error(c, _S("`array.insert()` should have 2 arguments, e.g. `insert(1, val)`"), node->pos); return _const_v__ast__void_type; } else { v__ast__Type arg_type = v__checker__Checker_expr(c, &arg0.expr); if (!(arg_type == _const_v__ast__int_type || arg_type == _const_v__ast__int_literal_type)) { v__checker__Checker_error(c, _S("the first argument of `array.insert()` should be integer"), v__ast__Expr_pos(arg0.expr)); return _const_v__ast__void_type; } } c->table->used_features->arr_insert = true; } else { c->table->used_features->arr_prepend = true; if (node_args_len != 1) { v__checker__Checker_error(c, _S("`array.prepend()` should have 1 argument, e.g. `prepend(val)`"), node->pos); return _const_v__ast__void_type; } } v__checker__Checker_check_for_mut_receiver(c, &node->left); v__ast__Array info = *(v__ast__Array*)__as_cast((left_sym->info)._v__ast__Array,(left_sym->info)._typ, 513); int val_arg_n = (_SLIT_EQ(method_name.str, method_name.len, "insert") ? (1) : (0)); node->receiver_type = v__ast__Type_ref(_const_v__ast__array_type); node->return_type = _const_v__ast__void_type; _result_v__ast__Fn _t7; if (_t7 = v__ast__Table_find_method(c->table, left_sym, method_name), !_t7.is_error) { v__ast__Fn method = *(v__ast__Fn*)_t7.data; for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + i; (*(v__ast__CallArg*)array_get(node->args, i)).typ = v__checker__Checker_expr(c, &arg->expr); if (i == val_arg_n) { v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(c->table, (*(v__ast__CallArg*)array_get(node->args, i)).typ); if (!v__checker__Checker_check_types(c, (*(v__ast__CallArg*)array_get(node->args, i)).typ, info.elem_type) && !v__checker__Checker_check_types(c, left_type, (*(v__ast__CallArg*)array_get(node->args, i)).typ)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("cannot "), 0xfe10, {.d_s = method_name}}, {_S(" `"), 0xfe10, {.d_s = arg_sym->name}}, {_S("` to `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(arg->expr)); continue; } } _result_void _t8 = v__checker__Checker_check_expected_call_arg(c, arg->typ, (*(v__ast__Param*)array_get(method.params, (int)(i + 1))).typ, node->language, *arg); if (_t8.is_error) { IError err = _t8.err; v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `"), 0xfe10, {.d_s = left_sym->name}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}})), (*(v__ast__CallArg*)array_get(node->args, i)).pos); ; } ; } } } else if (_SLIT_EQ(method_name.str, method_name.len, "sort_with_compare") || _SLIT_EQ(method_name.str, method_name.len, "sorted_with_compare")) { if (node_args_len != 1) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` expected 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else { if ((arg0.expr)._typ == 365 /* v.ast.LambdaExpr */) { v__checker__Checker_support_lambda_expr_in_sort(c, v__ast__Type_ref(elem_typ), _const_v__ast__int_type, (voidptr)&(*arg0.expr._v__ast__LambdaExpr)); } v__ast__Type arg_type = v__checker__Checker_expr(c, &arg0.expr); v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(c->table, arg_type); if (arg_sym->kind == v__ast__Kind__function) { v__ast__FnType func_info = *(v__ast__FnType*)__as_cast((arg_sym->info)._v__ast__FnType,(arg_sym->info)._typ, 553); if (func_info.func.params.len == 2) { if (v__ast__Type_nr_muls((*(v__ast__Param*)array_get(func_info.func.params, 0)).typ) != (int)(v__ast__Type_nr_muls(elem_typ) + 1)) { string arg_typ_str = v__ast__Table_type_to_str(c->table, (*(v__ast__Param*)array_get(func_info.func.params, 0)).typ); string expected_typ_str = v__ast__Table_type_to_str(c->table, v__ast__Type_ref(elem_typ)); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = method_name}}, {_S(" callback function parameter `"), 0xfe10, {.d_s = (*(v__ast__Param*)array_get(func_info.func.params, 0)).name}}, {_S("` with type `"), 0xfe10, {.d_s = arg_typ_str}}, {_S("` should be `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}})), (*(v__ast__Param*)array_get(func_info.func.params, 0)).type_pos); } if (v__ast__Type_nr_muls((*(v__ast__Param*)array_get(func_info.func.params, 1)).typ) != (int)(v__ast__Type_nr_muls(elem_typ) + 1)) { string arg_typ_str = v__ast__Table_type_to_str(c->table, (*(v__ast__Param*)array_get(func_info.func.params, 1)).typ); string expected_typ_str = v__ast__Table_type_to_str(c->table, v__ast__Type_ref(elem_typ)); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = method_name}}, {_S(" callback function parameter `"), 0xfe10, {.d_s = (*(v__ast__Param*)array_get(func_info.func.params, 1)).name}}, {_S("` with type `"), 0xfe10, {.d_s = arg_typ_str}}, {_S("` should be `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}})), (*(v__ast__Param*)array_get(func_info.func.params, 1)).type_pos); } } } arg0.typ = arg_type; _result_v__ast__Fn _t9; if (_t9 = v__ast__Table_find_method(c->table, left_sym, method_name), !_t9.is_error) { v__ast__Fn method = *(v__ast__Fn*)_t9.data; _result_void _t10 = v__checker__Checker_check_expected_call_arg(c, arg_type, (*(v__ast__Param*)array_get(method.params, 1)).typ, node->language, arg0); if (_t10.is_error) { IError err = _t10.err; v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument 1 to `"), 0xfe10, {.d_s = left_sym->name}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}})), arg0.pos); ; } ; } if (_SLIT_EQ(method_name.str, method_name.len, "sort_with_compare")) { v__checker__Checker_check_for_mut_receiver(c, &node->left); node->return_type = _const_v__ast__void_type; node->receiver_type = v__ast__Type_ref(node->left_type); } else { node->return_type = node->left_type; node->receiver_type = node->left_type; } } } else if (_SLIT_EQ(method_name.str, method_name.len, "sort") || _SLIT_EQ(method_name.str, method_name.len, "sorted")) { if (_SLIT_EQ(method_name.str, method_name.len, "sort")) { if ((node->left)._typ == 344 /* v.ast.CallExpr */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("the `sort()` method can be called only on mutable receivers, but `"), 0xfe10, {.d_s = v__ast__Expr_str(&node->left)}}, {_S("` is a call expression"), 0, { .d_c = 0 }}})), node->pos); } v__checker__Checker_check_for_mut_receiver(c, &node->left); } v__checker__scope_register_a_b(node->scope, node->pos, elem_typ); if (node_args_len > 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expected 0 or 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else if (node_args_len == 1) { if ((arg0.expr)._typ == 365 /* v.ast.LambdaExpr */) { v__checker__Checker_support_lambda_expr_in_sort(c, v__ast__Type_ref(elem_typ), _const_v__ast__bool_type, (voidptr)&(*arg0.expr._v__ast__LambdaExpr)); } else if ((arg0.expr)._typ == 362 /* v.ast.InfixExpr */) { v__checker__Checker_check_sort_external_variable_access(c, arg0.expr); if (!((*arg0.expr._v__ast__InfixExpr).op == v__token__Kind__gt || (*arg0.expr._v__ast__InfixExpr).op == v__token__Kind__lt)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` can only use `<` or `>` comparison"), 0, { .d_c = 0 }}})), node->pos); } u8 left_name = string_at(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*arg0.expr._v__ast__InfixExpr).left)}}, {_SLIT0, 0, { .d_c = 0 }}})), 0); u8 right_name = string_at(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*arg0.expr._v__ast__InfixExpr).right)}}, {_SLIT0, 0, { .d_c = 0 }}})), 0); if (!(left_name == 'a' || left_name == 'b') || !(right_name == 'a' || right_name == 'b')) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` can only use `a` or `b` as argument, e.g. `arr."), 0xfe10, {.d_s = method_name}}, {_S("(a < b)`"), 0, { .d_c = 0 }}})), node->pos); } else if (left_name == right_name) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` cannot use same argument"), 0, { .d_c = 0 }}})), node->pos); } if (!(((*arg0.expr._v__ast__InfixExpr).left)._typ == 344 /* v.ast.CallExpr */ || ((*arg0.expr._v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ || ((*arg0.expr._v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ || ((*arg0.expr._v__ast__InfixExpr).left)._typ == 361 /* v.ast.IndexExpr */) || !(((*arg0.expr._v__ast__InfixExpr).right)._typ == 344 /* v.ast.CallExpr */ || ((*arg0.expr._v__ast__InfixExpr).right)._typ == 358 /* v.ast.Ident */ || ((*arg0.expr._v__ast__InfixExpr).right)._typ == 379 /* v.ast.SelectorExpr */ || ((*arg0.expr._v__ast__InfixExpr).right)._typ == 361 /* v.ast.IndexExpr */)) { v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` can only use ident, index, selector or call as argument, \ne.g. `arr."), 0xfe10, {.d_s = method_name}}, {_S("(a < b)`, `arr."), 0xfe10, {.d_s = method_name}}, {_S("(a.id < b.id)`, `arr."), 0xfe10, {.d_s = method_name}}, {_S("(a[0] < b[0])`"), 0, { .d_c = 0 }}})), node->pos); } } else { v__checker__Checker_error(c, string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` requires a `<` or `>` comparison as the first and only argument"), 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S("\ne.g. `users."), 0xfe10, {.d_s = method_name}}, {_S("(a.id < b.id)`"), 0, { .d_c = 0 }}}))), node->pos); } } else if (!(v__ast__TypeSymbol_has_method(v__ast__Table_sym(c->table, elem_typ), _S("<")) || (Array_v__ast__Type_contains(new_array_from_c_array(18, 18, sizeof(v__ast__Type), _MOV((v__ast__Type[18]){ _const_v__ast__int_type, v__ast__Type_ref(_const_v__ast__int_type), _const_v__ast__string_type, v__ast__Type_ref(_const_v__ast__string_type), _const_v__ast__i8_type, _const_v__ast__i16_type, _const_v__ast__i64_type, _const_v__ast__u8_type, _const_v__ast__rune_type, _const_v__ast__u16_type, _const_v__ast__u32_type, _const_v__ast__u64_type, _const_v__ast__f32_type, _const_v__ast__f64_type, _const_v__ast__char_type, _const_v__ast__bool_type, _const_v__ast__float_literal_type, _const_v__ast__int_literal_type})), v__ast__Table_unalias_num_type(c->table, elem_typ))))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("custom sorting condition must be supplied for type `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, elem_typ)}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } else if (_SLIT_EQ(method_name.str, method_name.len, "wait")) { v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(c->table, elem_typ); if (elem_sym->kind == v__ast__Kind__thread) { if (node_args_len != 0) { v__checker__Checker_error(c, _S("`.wait()` does not have any arguments"), arg0.pos); } v__ast__Type thread_ret_type = v__checker__Checker_unwrap_generic(c, v__ast__TypeSymbol_thread_info(elem_sym).return_type); if (v__ast__Type_has_flag(thread_ret_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("`.wait()` cannot be called for an array when thread functions return options. Iterate over the arrays elements instead and handle each returned option with `or`."), node->pos); } else if (v__ast__Type_has_flag(thread_ret_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("`.wait()` cannot be called for an array when thread functions return results. Iterate over the arrays elements instead and handle each returned result with `or`."), node->pos); } node->return_type = v__ast__Table_find_or_register_array(c->table, thread_ret_type); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = left_sym->name}}, {_S("` has no method `wait()` (only thread handles and arrays of them have)"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); } } v__ast__Type arg_type = unaliased_left_type; for (int _t11 = 0; _t11 < node->args.len; ++_t11) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + _t11; arg_type = v__checker__Checker_check_expr_option_or_result_call(c, arg->expr, v__checker__Checker_expr(c, &arg->expr)); } if (_SLIT_EQ(method_name.str, method_name.len, "map")) { v__checker__Checker_check_predicate_param(c, true, elem_typ, *node); v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(c->table, arg_type); v__ast__Type ret_type = ((arg_sym->info._typ == 553 /* v.ast.FnType */)? (((arg0.expr)._typ == 379 /* v.ast.SelectorExpr */ ? (arg_type) : ((*arg_sym->info._v__ast__FnType).func.return_type))) : (arg_type)); node->return_type = v__ast__Table_find_or_register_array(c->table, v__checker__Checker_unwrap_generic(c, ret_type)); if (v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__shared_f)) { node->return_type = v__ast__Type_deref(v__ast__Type_clear_flag(node->return_type, v__ast__TypeFlag__shared_f)); } v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, ret_type); if (ret_sym->kind == v__ast__Kind__multi_return) { v__checker__Checker_error(c, _S("returning multiple values is not supported in .map() calls"), node->pos); } } else if (_SLIT_EQ(method_name.str, method_name.len, "filter")) { if (v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__shared_f)) { node->return_type = v__ast__Type_deref(v__ast__Type_clear_flag(node->return_type, v__ast__TypeFlag__shared_f)); } else if (v__ast__Expr_is_auto_deref_var(node->left)) { node->return_type = v__ast__Type_deref(node->return_type); } v__checker__Checker_check_predicate_param(c, false, elem_typ, *node); } else if (_SLIT_EQ(method_name.str, method_name.len, "any") || _SLIT_EQ(method_name.str, method_name.len, "all")) { v__checker__Checker_check_predicate_param(c, false, elem_typ, *node); node->return_type = _const_v__ast__bool_type; } else if (_SLIT_EQ(method_name.str, method_name.len, "count")) { v__checker__Checker_check_predicate_param(c, false, elem_typ, *node); node->return_type = _const_v__ast__int_type; } else if (_SLIT_EQ(method_name.str, method_name.len, "clone")) { if (node_args_len != 0) { v__checker__Checker_error(c, _S("`.clone()` does not have any arguments"), arg0.pos); } v__checker__Checker_ensure_same_array_return_type(c, node, left_type); } else if (_SLIT_EQ(method_name.str, method_name.len, "sorted")) { v__checker__Checker_ensure_same_array_return_type(c, node, left_type); } else if (_SLIT_EQ(method_name.str, method_name.len, "sort_with_compare") || _SLIT_EQ(method_name.str, method_name.len, "sorted_with_compare")) { if (_SLIT_EQ(method_name.str, method_name.len, "sorted_with_compare")) { v__checker__Checker_ensure_same_array_return_type(c, node, left_type); } (*(v__ast__CallArg*)array_get(node->args, 0)).expr = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = _const_v__ast__voidptr_type,.expr = arg0.expr,.typname = _S("voidptr"),.expr_type = v__checker__Checker_expr(c, &arg0.expr),.has_arg = 0,.pos = node->pos,})))); } else if (_SLIT_EQ(method_name.str, method_name.len, "sort")) { node->return_type = _const_v__ast__void_type; } else if (_SLIT_EQ(method_name.str, method_name.len, "contains")) { if (node_args_len != 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`.contains()` expected 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else if (!v__ast__TypeSymbol_has_method(left_sym, _S("contains"))) { v__ast__Type arg_typ = v__checker__Checker_unwrap_generic(c, v__checker__Checker_expr(c, &arg0.expr)); _result_void _t12 = v__checker__Checker_check_expected_call_arg(c, arg_typ, v__checker__Checker_unwrap_generic(c, elem_typ), node->language, arg0); if (_t12.is_error) { IError err = _t12.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument 1 to `.contains()`"), 0, { .d_c = 0 }}})), arg0.pos); ; } ; } for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + i; (*(v__ast__CallArg*)array_get(node->args, i)).typ = v__checker__Checker_expr(c, &arg->expr); } node->return_type = _const_v__ast__bool_type; } else if (_SLIT_EQ(method_name.str, method_name.len, "index")) { if (node_args_len != 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`.index()` expected 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else if (!v__ast__TypeSymbol_has_method(left_sym, _S("index"))) { v__ast__Type arg_typ = v__checker__Checker_unwrap_generic(c, v__checker__Checker_expr(c, &arg0.expr)); _result_void _t13 = v__checker__Checker_check_expected_call_arg(c, arg_typ, v__checker__Checker_unwrap_generic(c, elem_typ), node->language, arg0); if (_t13.is_error) { IError err = _t13.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument 1 to `.index()`"), 0, { .d_c = 0 }}})), arg0.pos); ; } ; } for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + i; (*(v__ast__CallArg*)array_get(node->args, i)).typ = v__checker__Checker_expr(c, &arg->expr); } node->return_type = _const_v__ast__int_type; } else if (_SLIT_EQ(method_name.str, method_name.len, "first") || _SLIT_EQ(method_name.str, method_name.len, "last") || _SLIT_EQ(method_name.str, method_name.len, "pop")) { v__checker__Checker_markused_array_method(c, !c->is_builtin_mod, method_name); if (node_args_len != 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` does not have any arguments"), 0, { .d_c = 0 }}})), arg0.pos); } node->return_type = array_info.elem_type; if (_SLIT_EQ(method_name.str, method_name.len, "pop")) { v__checker__Checker_check_for_mut_receiver(c, &node->left); node->receiver_type = v__ast__Type_ref(node->left_type); } else { node->receiver_type = node->left_type; } } else if (_SLIT_EQ(method_name.str, method_name.len, "delete")) { v__checker__Checker_markused_array_method(c, !c->is_builtin_mod, method_name); v__checker__Checker_check_for_mut_receiver(c, &node->left); v__ast__TypeSymbol* unwrapped_left_sym = v__ast__Table_sym(c->table, unwrapped_left_type); _result_v__ast__Fn _t14; if (_t14 = v__ast__Table_find_method(c->table, unwrapped_left_sym, method_name), !_t14.is_error) { v__ast__Fn method = *(v__ast__Fn*)_t14.data; node->receiver_type = method.receiver_type; } if (node_args_len != 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`.delete()` expected 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else { v__ast__Type arg_typ = v__checker__Checker_unwrap_generic(c, v__checker__Checker_expr(c, &arg0.expr)); _result_void _t15 = v__checker__Checker_check_expected_call_arg(c, arg_typ, _const_v__ast__int_type, node->language, arg0); if (_t15.is_error) { IError err = _t15.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument 1 to `.delete()`"), 0, { .d_c = 0 }}})), arg0.pos); ; } ; } node->return_type = _const_v__ast__void_type; } else if (_SLIT_EQ(method_name.str, method_name.len, "delete_many")) { if (node_args_len != 2) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`.delete_many()` expected 2 arguments, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else { for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + i; v__ast__Type arg_typ = v__checker__Checker_expr(c, &arg->expr); _result_void _t16 = v__checker__Checker_check_expected_call_arg(c, arg_typ, _const_v__ast__int_type, node->language, *arg); if (_t16.is_error) { IError err = _t16.err; v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument "), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(" to `.delete_many()`"), 0, { .d_c = 0 }}})), arg->pos); ; } ; } } node->return_type = _const_v__ast__void_type; } else if (_SLIT_EQ(method_name.str, method_name.len, "reverse")) { c->table->used_features->arr_reverse = true; } return node->return_type; } VV_LOC v__ast__Type v__checker__Checker_fixed_array_builtin_method_call(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Type left_type) { v__ast__TypeSymbol* left_sym = v__ast__Table_final_sym(c->table, left_type); string method_name = node->name; v__ast__Type unwrapped_left_type = v__checker__Checker_unwrap_generic(c, left_type); v__ast__Type unaliased_left_type = v__ast__Table_unaliased_type(c->table, unwrapped_left_type); v__ast__ArrayFixed array_info = ((left_sym->info)._typ == 549 /* v.ast.ArrayFixed */ ? ((*left_sym->info._v__ast__ArrayFixed)) : (({ v__ast__TypeInfo _t1 = v__ast__Table_sym(c->table, unaliased_left_type)->info; *(v__ast__ArrayFixed*)__as_cast(_t1._v__ast__ArrayFixed,_t1._typ, 549); }))); int node_args_len = node->args.len; v__ast__CallArg arg0 = (node_args_len > 0 ? ((*(v__ast__CallArg*)array_get(node->args, 0))) : (((v__ast__CallArg){.is_mut = 0,.share = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = 0,.is_tmp_autofree = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.should_be_ptr = 0,.ct_expr = 0,}))); v__ast__Type elem_typ = array_info.elem_type; if (_SLIT_EQ(method_name.str, method_name.len, "index")) { if (node_args_len != 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`.index()` expected 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__int_type; } else if (!v__ast__TypeSymbol_has_method(left_sym, _S("index"))) { v__ast__Type arg_typ = v__checker__Checker_expr(c, &arg0.expr); _result_void _t3 = v__checker__Checker_check_expected_call_arg(c, arg_typ, elem_typ, node->language, arg0); if (_t3.is_error) { IError err = _t3.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument 1 to `.index()`"), 0, { .d_c = 0 }}})), arg0.pos); return _const_v__ast__int_type; } ; } for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + i; (*(v__ast__CallArg*)array_get(node->args, i)).typ = v__checker__Checker_expr(c, &arg->expr); } node->return_type = _const_v__ast__int_type; } else if (_SLIT_EQ(method_name.str, method_name.len, "contains")) { if (node_args_len != 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`.contains()` expected 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__bool_type; } else if (!v__ast__TypeSymbol_has_method(left_sym, _S("contains"))) { v__ast__Type arg_typ = v__checker__Checker_expr(c, &arg0.expr); _result_void _t6 = v__checker__Checker_check_expected_call_arg(c, arg_typ, elem_typ, node->language, arg0); if (_t6.is_error) { IError err = _t6.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument 1 to `.contains()`"), 0, { .d_c = 0 }}})), arg0.pos); return _const_v__ast__bool_type; } ; } for (int i = 0; i < node->args.len; ++i) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + i; (*(v__ast__CallArg*)array_get(node->args, i)).typ = v__checker__Checker_expr(c, &arg->expr); } node->return_type = _const_v__ast__bool_type; } else if (_SLIT_EQ(method_name.str, method_name.len, "any") || _SLIT_EQ(method_name.str, method_name.len, "all")) { if (node_args_len != 1) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("` expected 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__bool_type; } if (node_args_len > 0 && (arg0.expr)._typ == 365 /* v.ast.LambdaExpr */) { if ((*arg0.expr._v__ast__LambdaExpr).params.len != 1) { v__checker__Checker_error(c, _S("lambda expressions used in the builtin array methods require exactly 1 parameter"), (*arg0.expr._v__ast__LambdaExpr).pos); return _const_v__ast__bool_type; } v__checker__Checker_support_lambda_expr_one_param(c, elem_typ, _const_v__ast__bool_type, (voidptr)&(*arg0.expr._v__ast__LambdaExpr)); } else { v__checker__scope_register_it(node->scope, node->pos, elem_typ); } v__checker__Checker_expr(c, &arg0.expr); v__checker__Checker_check_predicate_param(c, false, elem_typ, *node); node->return_type = _const_v__ast__bool_type; } else if (_SLIT_EQ(method_name.str, method_name.len, "count")) { if (node_args_len != 1) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("` expected 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__bool_type; } if (node_args_len > 0 && (arg0.expr)._typ == 365 /* v.ast.LambdaExpr */) { if ((*arg0.expr._v__ast__LambdaExpr).params.len != 1) { v__checker__Checker_error(c, _S("lambda expressions used in the builtin array methods require exactly 1 parameter"), (*arg0.expr._v__ast__LambdaExpr).pos); return _const_v__ast__bool_type; } v__checker__Checker_support_lambda_expr_one_param(c, elem_typ, _const_v__ast__bool_type, (voidptr)&(*arg0.expr._v__ast__LambdaExpr)); } else { v__checker__scope_register_it(node->scope, node->pos, elem_typ); } v__checker__Checker_expr(c, &arg0.expr); v__checker__Checker_check_predicate_param(c, false, elem_typ, *node); node->return_type = _const_v__ast__int_type; } else if (_SLIT_EQ(method_name.str, method_name.len, "wait")) { v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(c->table, elem_typ); if (elem_sym->kind == v__ast__Kind__thread) { if (node_args_len != 0) { v__checker__Checker_error(c, _S("`.wait()` does not have any arguments"), arg0.pos); } v__ast__Type thread_ret_type = v__checker__Checker_unwrap_generic(c, v__ast__TypeSymbol_thread_info(elem_sym).return_type); if (v__ast__Type_has_flag(thread_ret_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("`.wait()` cannot be called for an array when thread functions return options. Iterate over the arrays elements instead and handle each returned option with `or`."), node->pos); } else if (v__ast__Type_has_flag(thread_ret_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("`.wait()` cannot be called for an array when thread functions return results. Iterate over the arrays elements instead and handle each returned result with `or`."), node->pos); } node->return_type = v__ast__Table_find_or_register_array(c->table, thread_ret_type); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = left_sym->name}}, {_S("` has no method `wait()` (only thread handles and arrays of them have)"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); } } else if (_SLIT_EQ(method_name.str, method_name.len, "map")) { if (node_args_len != 1) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("` expected 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__void_type; } if ((arg0.expr)._typ == 365 /* v.ast.LambdaExpr */) { if ((*arg0.expr._v__ast__LambdaExpr).params.len != 1) { v__checker__Checker_error(c, _S("lambda expressions used in the builtin array methods require exactly 1 parameter"), (*arg0.expr._v__ast__LambdaExpr).pos); return _const_v__ast__void_type; } v__checker__Checker_lambda_expr_fix_type_of_param(c, (voidptr)&(*arg0.expr._v__ast__LambdaExpr), (voidptr)&(*(v__ast__Ident*)array_get((*arg0.expr._v__ast__LambdaExpr).params, 0)), elem_typ); v__ast__Type le_type = v__checker__Checker_expr(c, &(*arg0.expr._v__ast__LambdaExpr).expr); v__checker__Checker_support_lambda_expr_one_param(c, elem_typ, le_type, (voidptr)&(*arg0.expr._v__ast__LambdaExpr)); } else { v__checker__scope_register_it(node->scope, node->pos, elem_typ); } v__checker__Checker_check_predicate_param(c, true, elem_typ, *node); v__ast__Type arg_type = v__checker__Checker_check_expr_option_or_result_call(c, arg0.expr, v__checker__Checker_expr(c, &arg0.expr)); v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(c->table, arg_type); v__ast__Type ret_type = ((arg_sym->info._typ == 553 /* v.ast.FnType */)? (((arg0.expr)._typ == 379 /* v.ast.SelectorExpr */ ? (arg_type) : ((*arg_sym->info._v__ast__FnType).func.return_type))) : (arg_type)); node->return_type = v__ast__Table_find_or_register_array_fixed(c->table, v__checker__Checker_unwrap_generic(c, ret_type), array_info.size, array_info.size_expr, false); if (v__ast__Type_has_flag(node->return_type, v__ast__TypeFlag__shared_f)) { node->return_type = v__ast__Type_deref(v__ast__Type_clear_flag(node->return_type, v__ast__TypeFlag__shared_f)); } v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, ret_type); if (ret_sym->kind == v__ast__Kind__multi_return) { v__checker__Checker_error(c, _S("returning multiple values is not supported in .map() calls"), node->pos); } } else if (_SLIT_EQ(method_name.str, method_name.len, "sort") || _SLIT_EQ(method_name.str, method_name.len, "sorted")) { if (_SLIT_EQ(method_name.str, method_name.len, "sort")) { if ((node->left)._typ == 344 /* v.ast.CallExpr */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("the `sort()` method can be called only on mutable receivers, but `"), 0xfe10, {.d_s = v__ast__Expr_str(&node->left)}}, {_S("` is a call expression"), 0, { .d_c = 0 }}})), node->pos); } v__checker__Checker_check_for_mut_receiver(c, &node->left); } v__checker__scope_register_a_b(node->scope, node->pos, elem_typ); if (node_args_len > 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expected 0 or 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else if (node_args_len == 1) { if ((arg0.expr)._typ == 365 /* v.ast.LambdaExpr */) { v__checker__Checker_support_lambda_expr_in_sort(c, v__ast__Type_ref(elem_typ), _const_v__ast__bool_type, (voidptr)&(*arg0.expr._v__ast__LambdaExpr)); } else if ((arg0.expr)._typ == 362 /* v.ast.InfixExpr */) { v__checker__Checker_check_sort_external_variable_access(c, arg0.expr); if (!((*arg0.expr._v__ast__InfixExpr).op == v__token__Kind__gt || (*arg0.expr._v__ast__InfixExpr).op == v__token__Kind__lt)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` can only use `<` or `>` comparison"), 0, { .d_c = 0 }}})), node->pos); } u8 left_name = string_at(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*arg0.expr._v__ast__InfixExpr).left)}}, {_SLIT0, 0, { .d_c = 0 }}})), 0); u8 right_name = string_at(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*arg0.expr._v__ast__InfixExpr).right)}}, {_SLIT0, 0, { .d_c = 0 }}})), 0); if (!(left_name == 'a' || left_name == 'b') || !(right_name == 'a' || right_name == 'b')) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` can only use `a` or `b` as argument, e.g. `arr."), 0xfe10, {.d_s = method_name}}, {_S("(a < b)`"), 0, { .d_c = 0 }}})), node->pos); } else if (left_name == right_name) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` cannot use same argument"), 0, { .d_c = 0 }}})), node->pos); } if (!(((*arg0.expr._v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ || ((*arg0.expr._v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ || ((*arg0.expr._v__ast__InfixExpr).left)._typ == 361 /* v.ast.IndexExpr */) || !(((*arg0.expr._v__ast__InfixExpr).right)._typ == 358 /* v.ast.Ident */ || ((*arg0.expr._v__ast__InfixExpr).right)._typ == 379 /* v.ast.SelectorExpr */ || ((*arg0.expr._v__ast__InfixExpr).right)._typ == 361 /* v.ast.IndexExpr */)) { v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` can only use ident, index or selector as argument, \ne.g. `arr."), 0xfe10, {.d_s = method_name}}, {_S("(a < b)`, `arr."), 0xfe10, {.d_s = method_name}}, {_S("(a.id < b.id)`, `arr."), 0xfe10, {.d_s = method_name}}, {_S("(a[0] < b[0])`"), 0, { .d_c = 0 }}})), node->pos); } } else { v__checker__Checker_error(c, string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` requires a `<` or `>` comparison as the first and only argument"), 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S("\ne.g. `users."), 0xfe10, {.d_s = method_name}}, {_S("(a.id < b.id)`"), 0, { .d_c = 0 }}}))), node->pos); } } else if (!(v__ast__TypeSymbol_has_method(v__ast__Table_sym(c->table, elem_typ), _S("<")) || (Array_v__ast__Type_contains(new_array_from_c_array(18, 18, sizeof(v__ast__Type), _MOV((v__ast__Type[18]){ _const_v__ast__int_type, v__ast__Type_ref(_const_v__ast__int_type), _const_v__ast__string_type, v__ast__Type_ref(_const_v__ast__string_type), _const_v__ast__i8_type, _const_v__ast__i16_type, _const_v__ast__i64_type, _const_v__ast__u8_type, _const_v__ast__rune_type, _const_v__ast__u16_type, _const_v__ast__u32_type, _const_v__ast__u64_type, _const_v__ast__f32_type, _const_v__ast__f64_type, _const_v__ast__char_type, _const_v__ast__bool_type, _const_v__ast__float_literal_type, _const_v__ast__int_literal_type})), v__ast__Table_unalias_num_type(c->table, elem_typ))))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("custom sorting condition must be supplied for type `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, elem_typ)}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } for (int _t14 = 0; _t14 < node->args.len; ++_t14) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + _t14; v__checker__Checker_check_expr_option_or_result_call(c, arg->expr, v__checker__Checker_expr(c, &arg->expr)); } if (_SLIT_EQ(method_name.str, method_name.len, "sort")) { node->return_type = _const_v__ast__void_type; } else { node->return_type = node->left_type; } } else if (_SLIT_EQ(method_name.str, method_name.len, "sort_with_compare") || _SLIT_EQ(method_name.str, method_name.len, "sorted_with_compare")) { if (node_args_len != 1) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("()` expected 1 argument, but got "), 0xfe07, {.d_i32 = node_args_len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else { if ((arg0.expr)._typ == 365 /* v.ast.LambdaExpr */) { v__checker__Checker_support_lambda_expr_in_sort(c, v__ast__Type_ref(elem_typ), _const_v__ast__int_type, (voidptr)&(*arg0.expr._v__ast__LambdaExpr)); } v__ast__Type arg_type = v__checker__Checker_expr(c, &arg0.expr); v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(c->table, arg_type); if (arg_sym->kind == v__ast__Kind__function) { v__ast__FnType func_info = *(v__ast__FnType*)__as_cast((arg_sym->info)._v__ast__FnType,(arg_sym->info)._typ, 553); if (func_info.func.params.len == 2) { if (v__ast__Type_nr_muls((*(v__ast__Param*)array_get(func_info.func.params, 0)).typ) != (int)(v__ast__Type_nr_muls(elem_typ) + 1)) { string arg_typ_str = v__ast__Table_type_to_str(c->table, (*(v__ast__Param*)array_get(func_info.func.params, 0)).typ); string expected_typ_str = v__ast__Table_type_to_str(c->table, v__ast__Type_ref(elem_typ)); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = method_name}}, {_S(" callback function parameter `"), 0xfe10, {.d_s = (*(v__ast__Param*)array_get(func_info.func.params, 0)).name}}, {_S("` with type `"), 0xfe10, {.d_s = arg_typ_str}}, {_S("` should be `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}})), (*(v__ast__Param*)array_get(func_info.func.params, 0)).type_pos); } if (v__ast__Type_nr_muls((*(v__ast__Param*)array_get(func_info.func.params, 1)).typ) != (int)(v__ast__Type_nr_muls(elem_typ) + 1)) { string arg_typ_str = v__ast__Table_type_to_str(c->table, (*(v__ast__Param*)array_get(func_info.func.params, 1)).typ); string expected_typ_str = v__ast__Table_type_to_str(c->table, v__ast__Type_ref(elem_typ)); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = method_name}}, {_S(" callback function parameter `"), 0xfe10, {.d_s = (*(v__ast__Param*)array_get(func_info.func.params, 1)).name}}, {_S("` with type `"), 0xfe10, {.d_s = arg_typ_str}}, {_S("` should be `"), 0xfe10, {.d_s = expected_typ_str}}, {_S("`"), 0, { .d_c = 0 }}})), (*(v__ast__Param*)array_get(func_info.func.params, 1)).type_pos); } } } arg0.typ = arg_type; _result_v__ast__Fn _t15; if (_t15 = v__ast__Table_find_method(c->table, left_sym, method_name), !_t15.is_error) { v__ast__Fn method = *(v__ast__Fn*)_t15.data; _result_void _t16 = v__checker__Checker_check_expected_call_arg(c, arg_type, (*(v__ast__Param*)array_get(method.params, 1)).typ, node->language, arg0); if (_t16.is_error) { IError err = _t16.err; v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_S(" in argument 1 to `"), 0xfe10, {.d_s = left_sym->name}}, {_S("."), 0xfe10, {.d_s = method_name}}, {_S("`"), 0, { .d_c = 0 }}})), arg0.pos); ; } ; } for (int _t17 = 0; _t17 < node->args.len; ++_t17) { v__ast__CallArg* arg = ((v__ast__CallArg*)node->args.data) + _t17; v__checker__Checker_check_expr_option_or_result_call(c, arg->expr, v__checker__Checker_expr(c, &arg->expr)); } if (_SLIT_EQ(method_name.str, method_name.len, "sort_with_compare")) { v__checker__Checker_check_for_mut_receiver(c, &node->left); node->return_type = _const_v__ast__void_type; node->receiver_type = v__ast__Type_ref(node->left_type); } else { node->return_type = node->left_type; node->receiver_type = node->left_type; } } } else if (_SLIT_EQ(method_name.str, method_name.len, "reverse") || _SLIT_EQ(method_name.str, method_name.len, "reverse_in_place")) { if (node_args_len != 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = method_name}}, {_S("` does not have any arguments"), 0, { .d_c = 0 }}})), arg0.pos); } else { if (_SLIT_EQ(method_name.str, method_name.len, "reverse")) { node->return_type = node->left_type; } else { v__checker__Checker_check_for_mut_receiver(c, &node->left); node->return_type = _const_v__ast__void_type; } } } return node->return_type; } VV_LOC multi_return_string_v__token__Pos v__checker__Checker_check_for_mut_receiver(v__checker__Checker* c, v__ast__Expr* expr) { multi_return_string_v__token__Pos mr_140126 = v__checker__Checker_fail_if_immutable(c, expr); string to_lock = mr_140126.arg0; v__token__Pos pos = mr_140126.arg1; if (!v__ast__Expr_is_lvalue(*expr)) { v__checker__Checker_error(c, _S("cannot pass expression as `mut`"), v__ast__Expr_pos(*expr)); } return (multi_return_string_v__token__Pos){.arg0=to_lock, .arg1=pos}; } VV_LOC void v__checker__scope_register_it(v__ast__Scope* s, v__token__Pos pos, v__ast__Type typ) { v__checker__scope_register_var_name(s, pos, typ, _S("it")); } VV_LOC void v__checker__scope_register_a_b(v__ast__Scope* s, v__token__Pos pos, v__ast__Type typ) { v__checker__scope_register_var_name(s, pos, v__ast__Type_ref(typ), _S("a")); v__checker__scope_register_var_name(s, pos, v__ast__Type_ref(typ), _S("b")); } VV_LOC void v__checker__scope_register_var_name(v__ast__Scope* s, v__token__Pos pos, v__ast__Type typ, string name) { v__ast__Scope_register(s, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = name,.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = typ,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = pos,.is_used = true,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,}))))); } VV_LOC v__ast__Type v__checker__Checker_resolve_fn_return_type(v__checker__Checker* c, v__ast__Fn* func, v__ast__CallExpr node, Array_v__ast__Type concrete_types) { v__ast__Type ret_type = func->return_type; if (node.is_method) { if (func->generic_names.len > 0 && v__ast__Type_has_flag(func->return_type, v__ast__TypeFlag__generic) && c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len == 0) { ret_type = v__ast__Table_unwrap_generic_type(c->table, func->return_type, func->generic_names, concrete_types); } bool _t1 = (node.concrete_types.len > 0); bool _t2 = true; if (_t1) { Array_v__ast__Type _t2_orig = node.concrete_types; int _t2_len = _t2_orig.len; for (int _t3 = 0; _t3 < _t2_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t2_orig.data)[_t3]; if (!(!v__ast__Type_has_flag(it, v__ast__TypeFlag__generic))) { _t2 = false; break; } } } if ( _t1 &&_t2 && v__ast__Type_has_flag(func->return_type, v__ast__TypeFlag__generic) && func->generic_names.len > 0 && func->generic_names.len == node.concrete_types.len) { _option_v__ast__Type _t4; if (_t4 = v__ast__Table_convert_generic_type(c->table, func->return_type, func->generic_names, concrete_types), _t4.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t4.data; return typ; } else { IError err = _t4.err; return v__ast__Table_unwrap_generic_type(c->table, func->return_type, func->generic_names, concrete_types); } } } else { if (node.concrete_types.len > 0 && func->return_type != 0 && c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len == 0) { _option_v__ast__Type _t7; if (_t7 = v__ast__Table_convert_generic_type(c->table, func->return_type, func->generic_names, concrete_types), _t7.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t7.data; return typ; } return ret_type; } if (func->generic_names.len > 0) { bool _t10 = false; Array_v__ast__Type _t10_orig = node.raw_concrete_types; int _t10_len = _t10_orig.len; for (int _t11 = 0; _t11 < _t10_len; ++_t11) { v__ast__Type it = ((v__ast__Type*) _t10_orig.data)[_t11]; if (v__ast__Type_has_flag(it, v__ast__TypeFlag__generic)) { _t10 = true; break; } } bool has_generic =_t10; bool _t12 = false; Array_v__ast__Type _t12_orig = node.concrete_types; int _t12_len = _t12_orig.len; for (int _t13 = 0; _t13 < _t12_len; ++_t13) { v__ast__Type it = ((v__ast__Type*) _t12_orig.data)[_t13]; if (v__ast__Type_has_flag(it, v__ast__TypeFlag__generic)) { _t12 = true; break; } } bool has_any_generic =_t12; if (has_generic || has_any_generic) { _option_v__ast__Type _t14; if (_t14 = v__ast__Table_convert_generic_type(c->table, func->return_type, func->generic_names, node.concrete_types), _t14.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t14.data; if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { return typ; } } } else { if (node.concrete_types.len > 0 && !has_any_generic) { _option_v__ast__Type _t16; if (_t16 = v__ast__Table_convert_generic_type(c->table, func->return_type, func->generic_names, node.concrete_types), _t16.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t16.data; return typ; } } _option_v__ast__Type _t18; if (_t18 = v__ast__Table_convert_generic_type(c->table, func->return_type, func->generic_names, concrete_types), _t18.state == 0) { v__ast__Type typ = *(v__ast__Type*)_t18.data; return typ; } } } } return ret_type; } VV_LOC void v__checker__Checker_check_must_use_call_result(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Fn* f, string label) { if (node->is_return_used) { return; } if (f->return_type == _const_v__ast__void_type) { return; } if (f->is_must_use) { v__checker__Checker_warn(c, str_intp(3, _MOV((StrIntpData[]){{_S("return value must be used, "), 0xfe10, {.d_s = label}}, {_S(" `"), 0xfe10, {.d_s = f->name}}, {_S("` was tagged with `@[must_use]`"), 0, { .d_c = 0 }}})), node->pos); return; } if (c->pref->is_check_return) { v__checker__Checker_note(c, _S("return value must be used"), node->pos); } } VV_LOC bool v__checker__Checker_has_veb_context(v__checker__Checker* c, v__ast__Type typ) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); if (fast_string_eq(sym->name, _S("veb.Context"))) { return true; } else if ((sym->info)._typ == 518 /* v.ast.Struct */) { for (int _t2 = 0; _t2 < (*sym->info._v__ast__Struct).embeds.len; ++_t2) { v__ast__Type embed = ((v__ast__Type*)(*sym->info._v__ast__Struct).embeds.data)[_t2]; if (fast_string_eq(v__ast__Table_sym(c->table, embed)->name, _S("veb.Context"))) { return true; } } } return false; } VV_LOC void v__checker__Checker_for_c_stmt(v__checker__Checker* c, v__ast__ForCStmt* node) { c->in_for_count++; Array_string prev_loop_labels = c->loop_labels; if (node->has_init) { v__checker__Checker_stmt(c, &node->init); } v__checker__Checker_expr(c, &node->cond); if (node->has_inc) { if ((node->inc)._typ == 392 /* v.ast.AssignStmt */) { v__ast__AssignStmt assign = (*node->inc._v__ast__AssignStmt); if (assign.op == v__token__Kind__decl_assign) { v__checker__Checker_error(c, _S("for loop post statement cannot be a variable declaration"), assign.pos); } } v__checker__Checker_stmt(c, &node->inc); } v__checker__Checker_check_loop_labels(c, node->label, node->pos); v__checker__Checker_stmts(c, &node->stmts); c->loop_labels = prev_loop_labels; c->in_for_count--; } VV_LOC void v__checker__Checker_for_in_stmt(v__checker__Checker* c, v__ast__ForInStmt* node) { bool v__checker__Checker_for_in_stmt_defer_0 = false; bool v__checker__Checker_for_in_stmt_defer_1 = false; bool v__checker__Checker_for_in_stmt_defer_2 = false; bool v__checker__Checker_for_in_stmt_defer_3 = false; bool v__checker__Checker_for_in_stmt_defer_4 = false; c->in_for_count++; Array_string prev_loop_labels = c->loop_labels; v__ast__Type typ = v__checker__Checker_expr(c, &node->cond); if (node->key_var.len > 0 && !fast_string_eq(node->key_var, _S("_"))) { v__checker__Checker_check_valid_snake_case(c, node->key_var, _S("variable name"), node->pos); if (v__token__KeywordsMatcherTrie_matches(&_const_v__checker__reserved_type_names_chk, node->key_var)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid use of reserved type `"), 0xfe10, {.d_s = node->key_var}}, {_S("` as key name"), 0, { .d_c = 0 }}})), node->pos); } } if (node->val_var.len > 0 && !fast_string_eq(node->val_var, _S("_"))) { v__checker__Checker_check_valid_snake_case(c, node->val_var, _S("variable name"), node->pos); if (v__token__KeywordsMatcherTrie_matches(&_const_v__checker__reserved_type_names_chk, node->val_var)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid use of reserved type `"), 0xfe10, {.d_s = node->val_var}}, {_S("` as value name"), 0, { .d_c = 0 }}})), node->pos); } } _option_v__ast__ConstField_ptr _t1; if (_t1 = v__ast__Scope_find_const(c->file->global_scope, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->mod}}, {_S("."), 0xfe10, {.d_s = node->key_var}}, {_SLIT0, 0, { .d_c = 0 }}}))), _t1.state == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("duplicate of a const name `"), 0xfe10, {.d_s = c->mod}}, {_S("."), 0xfe10, {.d_s = node->key_var}}, {_S("`"), 0, { .d_c = 0 }}})), node->kv_pos); } _option_v__ast__ConstField_ptr _t2; if (_t2 = v__ast__Scope_find_const(c->file->global_scope, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->mod}}, {_S("."), 0xfe10, {.d_s = node->val_var}}, {_SLIT0, 0, { .d_c = 0 }}}))), _t2.state == 0) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("duplicate of a const name `"), 0xfe10, {.d_s = c->mod}}, {_S("."), 0xfe10, {.d_s = node->val_var}}, {_S("`"), 0, { .d_c = 0 }}})), node->vv_pos); } if (node->is_range) { int typ_idx = v__ast__Type_idx(typ); v__ast__Type high_type = v__checker__Checker_expr(c, &node->high); int high_type_idx = v__ast__Type_idx(high_type); if ((Array_int_contains(_const_v__ast__integer_type_idxs, typ_idx)) && !(Array_int_contains(_const_v__ast__integer_type_idxs, high_type_idx)) && high_type_idx != 1) { v__checker__Checker_error(c, _S("range types do not match"), v__ast__Expr_pos(node->cond)); } else if (v__ast__Table_final_sym(c->table, typ)->kind == v__ast__Kind__multi_return && v__ast__Table_final_sym(c->table, high_type)->kind == v__ast__Kind__multi_return) { v__checker__Checker_error(c, _S("multi-returns cannot be used in ranges. A range is from a single value to a single higher value."), v__token__Pos_extend(v__ast__Expr_pos(node->cond), v__ast__Expr_pos(node->high))); } else if (!(Array_int_contains(_const_v__ast__integer_type_idxs, typ_idx))) { v__checker__Checker_error(c, _S("range type can only be an integer type"), v__token__Pos_extend(v__ast__Expr_pos(node->cond), v__ast__Expr_pos(node->high))); } else if (v__ast__Type_has_option_or_result(high_type)) { v__checker__Checker_error(c, _S("the `high` value in a `for x in low..high {` loop, cannot be Result or Option"), v__ast__Expr_pos(node->high)); } else if ((node->cond)._typ == 358 /* v.ast.Ident */ && string__eq(node->val_var, (*(v__ast__Ident*)__as_cast((node->cond)._v__ast__Ident,(node->cond)._typ, 358)).name)) { if (node->is_range) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("in a `for x in ` loop, the key or value iteration variable `"), 0xfe10, {.d_s = node->val_var}}, {_S("` can not be the same as the low variable"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->cond)); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("in a `for x in array` loop, the key or value iteration variable `"), 0xfe10, {.d_s = node->val_var}}, {_S("` can not be the same as the low variable"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->cond)); } } else if ((node->high)._typ == 358 /* v.ast.Ident */ && string__eq(node->val_var, (*(v__ast__Ident*)__as_cast((node->high)._v__ast__Ident,(node->high)._typ, 358)).name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("in a `for x in ` loop, the key or value iteration variable `"), 0xfe10, {.d_s = node->val_var}}, {_S("` can not be the same as the high variable"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->high)); } if (high_type == _const_v__ast__int_type || high_type == _const_v__ast__int_literal_type) { node->val_type = typ; } else { node->val_type = high_type; } node->high_type = high_type; v__ast__Scope_update_var_type(node->scope, node->val_var, node->val_type); } else { if ((node->cond)._typ == 358 /* v.ast.Ident */ && (string__eq((*(v__ast__Ident*)__as_cast((node->cond)._v__ast__Ident,(node->cond)._typ, 358)).name, node->key_var) || string__eq((*(v__ast__Ident*)__as_cast((node->cond)._v__ast__Ident,(node->cond)._typ, 358)).name, node->val_var))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("in a `for x in array` loop, the key or value iteration variable `"), 0xfe10, {.d_s = node->val_var}}, {_S("` can not be the same as the low variable"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->cond)); } bool is_comptime = false; if (((node->cond)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node->cond)._v__ast__Ident,(node->cond)._typ, 358)).ct_expr) || (node->cond)._typ == 350 /* v.ast.ComptimeSelector */) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(&c->type_resolver, node->cond); if (ctyp != _const_v__ast__void_type) { is_comptime = true; typ = ctyp; } } v__ast__TypeSymbol* sym = v__ast__Table_final_sym(c->table, typ); if (sym->kind != v__ast__Kind__string) { if (node->cond._typ == 376 /* v.ast.PrefixExpr */) { node->val_is_ref = (*node->cond._v__ast__PrefixExpr).op == v__token__Kind__amp; } else if (node->cond._typ == 350 /* v.ast.ComptimeSelector */) { v__ast__Type comptime_typ = v__type_resolver__TypeResolver_get_comptime_selector_type(&c->type_resolver, (*node->cond._v__ast__ComptimeSelector), _const_v__ast__void_type); if (comptime_typ != _const_v__ast__void_type) { sym = v__ast__Table_final_sym(c->table, comptime_typ); typ = comptime_typ; } } else if (node->cond._typ == 358 /* v.ast.Ident */) { if ((*node->cond._v__ast__Ident).info._typ == 477 /* v.ast.IdentVar */) { node->val_is_ref = !v__ast__Ident_is_mut(&(*node->cond._v__ast__Ident)) && v__ast__Type_is_ptr((*(*node->cond._v__ast__Ident).info._v__ast__IdentVar).typ); } else { } } else { } } else if (node->val_is_mut) { v__checker__Checker_error(c, _S("string type is immutable, it cannot be changed"), node->pos); return; } if (sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__interface) { _option_v__ast__Fn _t3 = v__ast__TypeSymbol_find_method_with_generic_parent(sym, _S("next")); if (_t3.state != 0) { IError err = _t3.err; string kind_str = (sym->kind == v__ast__Kind__struct ? (_S("struct")) : (_S("interface"))); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("a "), 0xfe10, {.d_s = kind_str}}, {_S(" must have a `next()` method to be an iterator"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->cond)); return; } v__ast__Fn next_fn = (*(v__ast__Fn*)_t3.data); if (!v__ast__Type_has_flag(next_fn.return_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("iterator method `next()` must return an Option"), v__ast__Expr_pos(node->cond)); } v__ast__TypeSymbol* return_sym = v__ast__Table_sym(c->table, next_fn.return_type); if (return_sym->kind == v__ast__Kind__multi_return) { v__checker__Checker_error(c, _S("iterator method `next()` must not return multiple values"), v__ast__Expr_pos(node->cond)); } if (next_fn.params.len != 1) { v__checker__Checker_error(c, _S("iterator method `next()` must have 0 parameters"), v__ast__Expr_pos(node->cond)); } v__ast__Type val_type = v__ast__Type_clear_option_and_result(next_fn.return_type); if (node->val_is_mut) { val_type = v__ast__Type_ref(val_type); } node->cond_type = typ; node->kind = sym->kind; node->val_type = val_type; if (v__ast__Type_has_flag(node->val_type, v__ast__TypeFlag__generic)) { if (v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, node->val_type))->kind == v__ast__Kind__any) { v__checker__Checker_add_error_detail(c, _S("type parameters defined by `next()` method should be bounded by method owner type")); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot infer from generic type `"), 0xfe10, {.d_s = v__ast__Table_get_type_name(c->table, v__checker__Checker_unwrap_generic(c, node->val_type))}}, {_S("`"), 0, { .d_c = 0 }}})), node->vv_pos); } } v__ast__Scope_update_var_type(node->scope, node->val_var, val_type); if (is_comptime) { v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, node->val_var, val_type); v__ast__Scope_update_ct_var_kind(node->scope, node->val_var, v__ast__ComptimeVarKind__value_var); v__checker__Checker_for_in_stmt_defer_0 = true; } } else if (sym->kind == v__ast__Kind__any) { node->cond_type = typ; node->kind = sym->kind; v__ast__Type unwrapped_typ = v__checker__Checker_unwrap_generic(c, typ); v__ast__TypeSymbol* unwrapped_sym = v__ast__Table_sym(c->table, unwrapped_typ); map_set(&c->table->used_features->comptime_calls, &(string[]){str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(unwrapped_typ))}}, {_S(".next"), 0, { .d_c = 0 }}}))}, &(bool[]) { true }); if (node->key_var.len > 0) { v__ast__Type key_type = ((unwrapped_sym->kind == (v__ast__Kind__map))? (v__ast__TypeSymbol_map_info(unwrapped_sym).key_type) : (_const_v__ast__int_type)); node->key_type = key_type; v__ast__Scope_update_var_type(node->scope, node->key_var, key_type); if (is_comptime) { v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, node->key_var, key_type); v__ast__Scope_update_ct_var_kind(node->scope, node->key_var, v__ast__ComptimeVarKind__key_var); v__checker__Checker_for_in_stmt_defer_1 = true; } } v__ast__Type value_type = v__ast__Table_value_type(c->table, unwrapped_typ); if (node->val_is_mut) { value_type = v__ast__Type_ref(value_type); } v__ast__Scope_update_var_type(node->scope, node->val_var, value_type); node->val_type = value_type; if (is_comptime) { v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, node->val_var, value_type); v__ast__Scope_update_ct_var_kind(node->scope, node->val_var, v__ast__ComptimeVarKind__value_var); v__checker__Checker_for_in_stmt_defer_2 = true; } } else { if (sym->kind == v__ast__Kind__map && !(node->key_var.len > 0 && node->val_var.len > 0)) { v__checker__Checker_error(c, _S("declare a key and a value variable when ranging a map: `for key, val in map {`\nuse `_` if you do not need the variable"), node->pos); } if (!c->is_builtin_mod && !fast_string_eq(c->mod, _S("strings"))) { c->table->used_features->used_maps++; } if (node->key_var.len > 0) { v__ast__Type key_type = ((sym->kind == (v__ast__Kind__map))? (v__ast__TypeSymbol_map_info(sym).key_type) : (_const_v__ast__int_type)); node->key_type = key_type; v__ast__Scope_update_var_type(node->scope, node->key_var, key_type); if (is_comptime) { v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, node->key_var, key_type); v__ast__Scope_update_ct_var_kind(node->scope, node->key_var, v__ast__ComptimeVarKind__key_var); v__checker__Checker_for_in_stmt_defer_3 = true; } } v__ast__Type value_type = v__ast__Table_value_type(c->table, typ); bool _t4 = sym->kind == v__ast__Kind__string; bool _t5; if (!(_t4)) { bool _t6 = (sym->kind == v__ast__Kind__aggregate); bool _t7 = true; if (_t6) { Array_v__ast__Type _t7_orig = (*(v__ast__Aggregate*)__as_cast((sym->info)._v__ast__Aggregate,(sym->info)._typ, 537)).types; int _t7_len = _t7_orig.len; for (int _t8 = 0; _t8 < _t7_len; ++_t8) { v__ast__Type it = ((v__ast__Type*) _t7_orig.data)[_t8]; if (!((Array_v__ast__Kind_contains(new_array_from_c_array(4, 4, sizeof(v__ast__Kind), _MOV((v__ast__Kind[4]){v__ast__Kind__array, v__ast__Kind__array_fixed, v__ast__Kind__string, v__ast__Kind__map})), v__ast__Table_type_kind(c->table, it))))) { _t7 = false; break; } } } _t5 = _t6 &&_t7; } if (_t4) { value_type = _const_v__ast__u8_type; } else if (_t5) { value_type = v__ast__Table_value_type(c->table, (*(v__ast__Type*)array_get((*(v__ast__Aggregate*)__as_cast((sym->info)._v__ast__Aggregate,(sym->info)._typ, 537)).types, 0))); } if (value_type == _const_v__ast__void_type || v__ast__Type_has_flag(typ, v__ast__TypeFlag__result)) { if (typ != _const_v__ast__void_type) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("for in: cannot index `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, typ)}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->cond)); } } if (node->val_is_mut) { value_type = v__ast__Type_ref(value_type); if (node->cond._typ == 358 /* v.ast.Ident */) { if (((*node->cond._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { if (!(*(*node->cond._v__ast__Ident).obj._v__ast__Var).is_mut) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = (*(*node->cond._v__ast__Ident).obj._v__ast__Var).name}}, {_S("` is immutable, it cannot be changed"), 0, { .d_c = 0 }}})), (*node->cond._v__ast__Ident).pos); } } } else if (node->cond._typ == 338 /* v.ast.ArrayInit */) { v__checker__Checker_error(c, _S("array literal is immutable, it cannot be changed"), (*node->cond._v__ast__ArrayInit).pos); } else if (node->cond._typ == 368 /* v.ast.MapInit */) { v__checker__Checker_error(c, _S("map literal is immutable, it cannot be changed"), (*node->cond._v__ast__MapInit).pos); } else if (node->cond._typ == 379 /* v.ast.SelectorExpr */) { _option_v__ast__Ident _t9; if (_t9 = v__ast__SelectorExpr_root_ident(&(*node->cond._v__ast__SelectorExpr)), _t9.state == 0) { v__ast__Ident root_ident = *(v__ast__Ident*)_t9.data; if (root_ident.kind != v__ast__IdentKind__unresolved) { _option_v__ast__Var_ptr _t10; if (_t10 = v__ast__Scope_find_var(node->scope, root_ident.name), _t10.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t10.data; if (!var->is_mut) { v__ast__TypeSymbol* sym2 = v__ast__Table_sym(c->table, (*(root_ident.obj.typ))); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = sym2->name}}, {_S("."), 0xfe10, {.d_s = (*node->cond._v__ast__SelectorExpr).field_name}}, {_S("` is immutable, it cannot be changed"), 0, { .d_c = 0 }}})), (*node->cond._v__ast__SelectorExpr).pos); } } } } } else { } } else if (node->val_is_ref) { value_type = v__ast__Type_ref(value_type); } node->cond_type = typ; node->kind = sym->kind; node->val_type = value_type; v__ast__Scope_update_var_type(node->scope, node->val_var, value_type); if (is_comptime) { v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, node->val_var, value_type); v__ast__Scope_update_ct_var_kind(node->scope, node->val_var, v__ast__ComptimeVarKind__value_var); v__checker__Checker_for_in_stmt_defer_4 = true; } } } v__checker__Checker_check_loop_labels(c, node->label, node->pos); v__checker__Checker_stmts(c, &node->stmts); c->loop_labels = prev_loop_labels; c->in_for_count--; // Defer begin if (v__checker__Checker_for_in_stmt_defer_4) { map_delete(&c->type_resolver.type_map, &(string[]){node->val_var}); } // Defer end // Defer begin if (v__checker__Checker_for_in_stmt_defer_3) { map_delete(&c->type_resolver.type_map, &(string[]){node->key_var}); } // Defer end // Defer begin if (v__checker__Checker_for_in_stmt_defer_2) { map_delete(&c->type_resolver.type_map, &(string[]){node->val_var}); } // Defer end // Defer begin if (v__checker__Checker_for_in_stmt_defer_1) { map_delete(&c->type_resolver.type_map, &(string[]){node->key_var}); } // Defer end // Defer begin if (v__checker__Checker_for_in_stmt_defer_0) { map_delete(&c->type_resolver.type_map, &(string[]){node->val_var}); } // Defer end } VV_LOC void v__checker__Checker_for_stmt(v__checker__Checker* c, v__ast__ForStmt* node) { c->in_for_count++; Array_string prev_loop_labels = c->loop_labels; c->expected_type = _const_v__ast__bool_type; if ((node->cond)._typ != 354 /* v.ast.EmptyExpr */) { v__ast__Type typ = v__checker__Checker_expr(c, &node->cond); if (!node->is_inf && v__ast__Type_idx(typ) != 19 && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, _S("non-bool used as for condition"), node->pos); } } if ((node->cond)._typ == 362 /* v.ast.InfixExpr */ && (*(v__ast__InfixExpr*)__as_cast((node->cond)._v__ast__InfixExpr,(node->cond)._typ, 362)).op == v__token__Kind__key_is) { if (((*node->cond._v__ast__InfixExpr).right)._typ == 386 /* v.ast.TypeNode */ && (((*node->cond._v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ || ((*node->cond._v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */)) { if (Array_v__ast__Kind_contains(new_array_from_c_array(2, 2, sizeof(v__ast__Kind), _MOV((v__ast__Kind[2]){v__ast__Kind__sum_type, v__ast__Kind__interface})), v__ast__Table_type_kind(c->table, (*node->cond._v__ast__InfixExpr).left_type))) { v__checker__Checker_smartcast(c, &(*node->cond._v__ast__InfixExpr).left, (*node->cond._v__ast__InfixExpr).left_type, (*node->cond._v__ast__InfixExpr).right_type, node->scope, false, false); } } } v__checker__Checker_check_loop_labels(c, node->label, node->pos); v__checker__Checker_stmts(c, &node->stmts); c->loop_labels = prev_loop_labels; c->in_for_count--; if (!v__token__Pos_struct_eq(c->smartcast_mut_pos, ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}))) { c->smartcast_mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); } } VV_LOC v__checker__ComptimeBranchSkipState v__checker__Checker_check_compatible_types(v__checker__Checker* c, v__ast__Type left_type, v__ast__TypeNode right) { v__ast__Type right_type = v__checker__Checker_unwrap_generic(c, right.typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, right_type); if (v__ast__Type_has_flag(right_type, v__ast__TypeFlag__option) != v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option)) { return v__checker__ComptimeBranchSkipState__skip; } if (sym->kind == v__ast__Kind__interface) { v__ast__Type checked_type = v__checker__Checker_unwrap_generic(c, left_type); return (v__ast__Table_does_type_implement_interface(c->table, checked_type, right_type) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else { return (left_type == right_type ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } return 0; } VV_LOC v__ast__Type v__checker__Checker_if_expr(v__checker__Checker* c, v__ast__IfExpr* node) { bool v__checker__Checker_if_expr_defer_0 = false; bool v__checker__Checker_if_expr_defer_1 = false; bool last_in_comptime_if; string if_kind = (node->is_comptime ? (_S("$if")) : (_S("if"))); bool node_is_expr = false; if (node->branches.len > 0 && node->has_else) { Array_v__ast__Stmt stmts = (*(v__ast__IfBranch*)array_get(node->branches, 0)).stmts; bool _t2 = (stmts.len > 0); bool _t1 = _t2 && ((*(v__ast__Stmt*)array_last(stmts)))._typ == 401 /* v.ast.ExprStmt */ && (({ v__ast__Stmt _t3 = (*(v__ast__Stmt*)array_last(stmts)); *(v__ast__ExprStmt*)__as_cast(_t3._v__ast__ExprStmt,_t3._typ, 401); })).typ != _const_v__ast__void_type; bool _t4; if (!(_t1)) { _t4 = node->is_expr; } if (_t1) { node_is_expr = true; } else if (_t4) { node_is_expr = true; } } if (c->expected_type == _const_v__ast__void_type && node_is_expr) { c->expected_type = c->expected_or_type; } bool expr_required = c->expected_type != _const_v__ast__void_type; v__ast__Type former_expected_type = c->expected_type; if (node_is_expr) { c->expected_expr_type = c->expected_type; v__checker__Checker_if_expr_defer_0 = true; } node->typ = _const_v__ast__void_type; int nbranches_with_return = 0; int nbranches_without_return = 0; v__checker__ComptimeBranchSkipState skip_state = v__checker__ComptimeBranchSkipState__unknown; bool found_branch = false; bool is_comptime_type_is_expr = false; last_in_comptime_if = c->comptime->inside_comptime_if; v__checker__Checker_if_expr_defer_1 = true; for (int i = 0; i < node->branches.len; ++i) { v__ast__IfBranch branch = (*(v__ast__IfBranch*)array_get(node->branches, i)); if ((branch.cond)._typ == 374 /* v.ast.ParExpr */ && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_warn(c, str_intp(4, _MOV((StrIntpData[]){{_S("unnecessary `()` in `"), 0xfe10, {.d_s = if_kind}}, {_S("` condition, use `"), 0xfe10, {.d_s = if_kind}}, {_S(" expr {` instead of `"), 0xfe10, {.d_s = if_kind}}, {_S(" (expr) {`."), 0, { .d_c = 0 }}})), branch.pos); } if (!node->has_else || i < (int)(node->branches.len - 1)) { if (node->is_comptime) { skip_state = v__checker__Checker_comptime_if_cond(c, &branch.cond, branch.pos); (*(v__ast__IfBranch*)array_get(node->branches, i)).pkg_exist = (skip_state == v__checker__ComptimeBranchSkipState__eval ? (true) : (false)); } else { c->expected_type = _const_v__ast__bool_type; v__ast__Type cond_typ = v__ast__Table_unaliased_type(c->table, v__checker__Checker_unwrap_generic(c, v__checker__Checker_expr(c, &branch.cond))); if ((v__ast__Type_idx(cond_typ) != 19 || v__ast__Type_has_flag(cond_typ, v__ast__TypeFlag__option) || v__ast__Type_has_flag(cond_typ, v__ast__TypeFlag__result)) && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("non-bool type `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, cond_typ)}}, {_S("` used as if condition"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(branch.cond)); } } } if ((branch.cond)._typ == 360 /* v.ast.IfGuardExpr */) { if (v__ast__Type_clear_option_and_result((*branch.cond._v__ast__IfGuardExpr).expr_type) == _const_v__ast__void_type && !((*branch.cond._v__ast__IfGuardExpr).vars.len == 1 && fast_string_eq((*(v__ast__IfGuardVar*)array_get((*branch.cond._v__ast__IfGuardExpr).vars, 0)).name, _S("_")))) { v__checker__Checker_error(c, _S("if guard expects non-propagate option or result"), branch.pos); continue; } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, (*branch.cond._v__ast__IfGuardExpr).expr_type); if (sym->kind == v__ast__Kind__multi_return) { v__ast__MultiReturn mr_info = *(v__ast__MultiReturn*)__as_cast((sym->info)._v__ast__MultiReturn,(sym->info)._typ, 552); if ((*branch.cond._v__ast__IfGuardExpr).vars.len != mr_info.types.len) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("if guard expects "), 0xfe07, {.d_i32 = mr_info.types.len}}, {_S(" variables, but got "), 0xfe07, {.d_i32 = (*branch.cond._v__ast__IfGuardExpr).vars.len}}, {_SLIT0, 0, { .d_c = 0 }}})), branch.pos); continue; } else { for (int vi = 0; vi < (*branch.cond._v__ast__IfGuardExpr).vars.len; ++vi) { v__ast__IfGuardVar var = ((v__ast__IfGuardVar*)(*branch.cond._v__ast__IfGuardExpr).vars.data)[vi]; v__ast__Scope_update_var_type(branch.scope, var.name, (*(v__ast__Type*)array_get(mr_info.types, vi))); } } } else { for (int _t5 = 0; _t5 < (*branch.cond._v__ast__IfGuardExpr).vars.len; ++_t5) { v__ast__IfGuardVar var = ((v__ast__IfGuardVar*)(*branch.cond._v__ast__IfGuardExpr).vars.data)[_t5]; if (fast_string_eq(var.name, _S("_"))) { continue; } _option_v__ast__Var_ptr _t6; if (_t6 = v__ast__Scope_find_var(branch.scope, var.name), _t6.state == 0) { v__ast__Var* w = *(v__ast__Var**)_t6.data; if (!_IN_MAP(ADDR(string, var.name), ADDR(map, branch.scope->objects))) { map_set(&branch.scope->objects, &(string[]){var.name}, &(v__ast__ScopeObject[]) { v__ast__Var_to_sumtype_v__ast__ScopeObject(w) }); } v__ast__Scope_update_var_type(branch.scope, var.name, v__ast__Type_clear_option_and_result((*branch.cond._v__ast__IfGuardExpr).expr_type)); } } } } if (node->is_comptime) { string comptime_field_name = _S(""); if ((branch.cond)._typ == 379 /* v.ast.SelectorExpr */ && skip_state != v__checker__ComptimeBranchSkipState__unknown) { is_comptime_type_is_expr = true; } else if ((branch.cond)._typ == 376 /* v.ast.PrefixExpr */) { if (((*branch.cond._v__ast__PrefixExpr).right)._typ == 379 /* v.ast.SelectorExpr */ && skip_state != v__checker__ComptimeBranchSkipState__unknown) { is_comptime_type_is_expr = true; } } else if ((branch.cond)._typ == 362 /* v.ast.InfixExpr */) { if ((*branch.cond._v__ast__InfixExpr).op == v__token__Kind__not_is || (*branch.cond._v__ast__InfixExpr).op == v__token__Kind__key_is) { v__ast__Expr left = (*branch.cond._v__ast__InfixExpr).left; v__ast__Expr right = (*branch.cond._v__ast__InfixExpr).right; if (!((right)._typ == 386 /* v.ast.TypeNode */ || (right)._typ == 351 /* v.ast.ComptimeType */)) { v__checker__Checker_error(c, _S("invalid `$if` condition: expected a type"), v__ast__Expr_pos((*branch.cond._v__ast__InfixExpr).right)); v__ast__Type _t7 = 0; // Defer begin if (v__checker__Checker_if_expr_defer_1) { c->comptime->inside_comptime_if = last_in_comptime_if; } // Defer end // Defer begin if (v__checker__Checker_if_expr_defer_0) { c->expected_expr_type = _const_v__ast__void_type; } // Defer end return _t7; } if ((right)._typ == 351 /* v.ast.ComptimeType */) { v__ast__Type checked_type = _const_v__ast__void_type; if ((left)._typ == 386 /* v.ast.TypeNode */) { is_comptime_type_is_expr = true; checked_type = v__checker__Checker_unwrap_generic(c, (*left._v__ast__TypeNode).typ); skip_state = (v__type_resolver__TypeResolver_is_comptime_type(&c->type_resolver, checked_type, (*right._v__ast__ComptimeType)) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((left)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((left)._v__ast__Ident,(left)._typ, 358)).info)._typ == 477 /* v.ast.IdentVar */) { is_comptime_type_is_expr = true; _option_v__ast__Var_ptr _t8; if (_t8 = v__ast__Scope_find_var((*left._v__ast__Ident).scope, (*left._v__ast__Ident).name), _t8.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t8.data; checked_type = v__checker__Checker_unwrap_generic(c, var->typ); if (var->smartcasts.len > 0) { checked_type = v__checker__Checker_unwrap_generic(c, (*(v__ast__Type*)array_last(var->smartcasts))); } } skip_state = (v__type_resolver__TypeResolver_is_comptime_type(&c->type_resolver, checked_type, (*right._v__ast__ComptimeType)) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((left)._typ == 379 /* v.ast.SelectorExpr */) { comptime_field_name = v__ast__Expr_str(&(*left._v__ast__SelectorExpr).expr); is_comptime_type_is_expr = true; } } else { v__ast__Type got_type = v__checker__Checker_unwrap_generic(c, (*(v__ast__TypeNode*)__as_cast((right)._v__ast__TypeNode,(right)._typ, 386)).typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, got_type); if (sym->kind == v__ast__Kind__placeholder || v__ast__Type_has_flag(got_type, v__ast__TypeFlag__generic)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos((*branch.cond._v__ast__InfixExpr).right)); } if ((left)._typ == 379 /* v.ast.SelectorExpr */) { comptime_field_name = v__ast__Expr_str(&(*left._v__ast__SelectorExpr).expr); is_comptime_type_is_expr = true; if (string__eq(comptime_field_name, c->comptime->comptime_for_field_var)) { v__ast__Type left_type = v__checker__Checker_unwrap_generic(c, c->comptime->comptime_for_field_type); if (fast_string_eq((*left._v__ast__SelectorExpr).field_name, _S("typ"))) { skip_state = v__checker__Checker_check_compatible_types(c, left_type, *(v__ast__TypeNode*)__as_cast((right)._v__ast__TypeNode,(right)._typ, 386)); } else if (fast_string_eq((*left._v__ast__SelectorExpr).field_name, _S("unaliased_typ"))) { skip_state = v__checker__Checker_check_compatible_types(c, v__ast__Table_unaliased_type(c->table, left_type), *(v__ast__TypeNode*)__as_cast((right)._v__ast__TypeNode,(right)._typ, 386)); } } else if (v__type_resolver__ResolverInfo_check_comptime_is_field_selector_bool(c->comptime, (*left._v__ast__SelectorExpr))) { skip_state = (v__type_resolver__TypeResolver_get_comptime_selector_bool_field(&c->type_resolver, (*left._v__ast__SelectorExpr).field_name) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if (string__eq(comptime_field_name, c->comptime->comptime_for_method_var) && fast_string_eq((*left._v__ast__SelectorExpr).field_name, _S("return_type"))) { skip_state = v__checker__Checker_check_compatible_types(c, v__checker__Checker_unwrap_generic(c, c->comptime->comptime_for_method_ret_type), *(v__ast__TypeNode*)__as_cast((right)._v__ast__TypeNode,(right)._typ, 386)); } else if (string__eq(comptime_field_name, c->comptime->comptime_for_variant_var) || string__eq(comptime_field_name, c->comptime->comptime_for_enum_var)) { if (fast_string_eq((*left._v__ast__SelectorExpr).field_name, _S("typ"))) { skip_state = v__checker__Checker_check_compatible_types(c, v__type_resolver__TypeResolver_get_ct_type_or_default(&c->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = comptime_field_name}}, {_S(".typ"), 0, { .d_c = 0 }}})), _const_v__ast__void_type), *(v__ast__TypeNode*)__as_cast((right)._v__ast__TypeNode,(right)._typ, 386)); } } } else if ((left)._typ == 386 /* v.ast.TypeNode */) { is_comptime_type_is_expr = true; v__ast__Type left_type = v__checker__Checker_unwrap_generic(c, (*left._v__ast__TypeNode).typ); skip_state = v__checker__Checker_check_compatible_types(c, left_type, *(v__ast__TypeNode*)__as_cast((right)._v__ast__TypeNode,(right)._typ, 386)); } else if ((left)._typ == 358 /* v.ast.Ident */) { v__ast__Type checked_type = _const_v__ast__void_type; is_comptime_type_is_expr = true; _option_v__ast__Var_ptr _t9; if (_t9 = v__ast__Scope_find_var((*left._v__ast__Ident).scope, (*left._v__ast__Ident).name), _t9.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t9.data; checked_type = v__checker__Checker_unwrap_generic(c, var->typ); if (var->smartcasts.len > 0) { checked_type = v__checker__Checker_unwrap_generic(c, (*(v__ast__Type*)array_last(var->smartcasts))); } } if ((sym->info)._typ == 553 /* v.ast.FnType */ && string__eq(c->comptime->comptime_for_method_var, (*left._v__ast__Ident).name)) { skip_state = (string__eq(v__ast__Table_fn_signature(c->table, (voidptr)&(*sym->info._v__ast__FnType).func, ((v__ast__FnSignatureOpts){.skip_receiver = true,.type_only = true,})), v__ast__Table_fn_signature(c->table, c->comptime->comptime_for_method, ((v__ast__FnSignatureOpts){.skip_receiver = true,.type_only = true,}))) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else { skip_state = v__checker__Checker_check_compatible_types(c, checked_type, *(v__ast__TypeNode*)__as_cast((right)._v__ast__TypeNode,(right)._typ, 386)); } } } if ((*branch.cond._v__ast__InfixExpr).op == v__token__Kind__not_is && skip_state != v__checker__ComptimeBranchSkipState__unknown) { skip_state = (skip_state == v__checker__ComptimeBranchSkipState__eval ? (v__checker__ComptimeBranchSkipState__skip) : (v__checker__ComptimeBranchSkipState__eval)); } } else if ((*branch.cond._v__ast__InfixExpr).op == v__token__Kind__eq || (*branch.cond._v__ast__InfixExpr).op == v__token__Kind__ne || (*branch.cond._v__ast__InfixExpr).op == v__token__Kind__gt || (*branch.cond._v__ast__InfixExpr).op == v__token__Kind__lt || (*branch.cond._v__ast__InfixExpr).op == v__token__Kind__ge || (*branch.cond._v__ast__InfixExpr).op == v__token__Kind__le) { v__ast__Expr left = (*branch.cond._v__ast__InfixExpr).left; v__ast__Expr right = (*branch.cond._v__ast__InfixExpr).right; if ((left)._typ == 379 /* v.ast.SelectorExpr */ && (right)._typ == 363 /* v.ast.IntegerLiteral */) { comptime_field_name = v__ast__Expr_str(&(*left._v__ast__SelectorExpr).expr); is_comptime_type_is_expr = true; if (string__eq(comptime_field_name, c->comptime->comptime_for_field_var)) { if (fast_string_eq((*left._v__ast__SelectorExpr).field_name, _S("indirections"))) { v__checker__ComptimeBranchSkipState _t10 = 0; if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__gt)) { _t10 = (v__ast__Type_nr_muls(c->comptime->comptime_for_field_type) > string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__lt)) { _t10 = (v__ast__Type_nr_muls(c->comptime->comptime_for_field_type) < string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__ge)) { _t10 = (v__ast__Type_nr_muls(c->comptime->comptime_for_field_type) >= string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__le)) { _t10 = (v__ast__Type_nr_muls(c->comptime->comptime_for_field_type) <= string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__ne)) { _t10 = (v__ast__Type_nr_muls(c->comptime->comptime_for_field_type) != string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__eq)) { _t10 = (v__ast__Type_nr_muls(c->comptime->comptime_for_field_type) == string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else { _t10 = v__checker__ComptimeBranchSkipState__skip; }skip_state = _t10; } } else if (string__eq(comptime_field_name, c->comptime->comptime_for_method_var)) { if (fast_string_eq((*left._v__ast__SelectorExpr).field_name, _S("return_type"))) { skip_state = (v__ast__Type_idx(v__checker__Checker_unwrap_generic(c, c->comptime->comptime_for_method_ret_type)) == string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } } else if (((*left._v__ast__SelectorExpr).expr)._typ == 387 /* v.ast.TypeOf */) { skip_state = (v__ast__Type_nr_muls((*(*left._v__ast__SelectorExpr).expr._v__ast__TypeOf).typ) == string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } } else if (((*branch.cond._v__ast__InfixExpr).op == v__token__Kind__eq || (*branch.cond._v__ast__InfixExpr).op == v__token__Kind__ne) && (left)._typ == 379 /* v.ast.SelectorExpr */ && (right)._typ == 384 /* v.ast.StringLiteral */) { string _t11 = v__ast__Expr_str(&(*left._v__ast__SelectorExpr).expr); if (fast_string_eq(_t11, c->comptime->comptime_for_field_var)) { if (fast_string_eq((*left._v__ast__SelectorExpr).field_name, _S("name"))) { is_comptime_type_is_expr = true; if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__eq)) { skip_state = (string__eq(c->comptime->comptime_for_field_value.name, string_str((*right._v__ast__StringLiteral).val)) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__ne)) { skip_state = (string__eq(c->comptime->comptime_for_field_value.name, string_str((*right._v__ast__StringLiteral).val)) ? (v__checker__ComptimeBranchSkipState__skip) : (v__checker__ComptimeBranchSkipState__eval)); } else { } } } else if (fast_string_eq(_t11, c->comptime->comptime_for_method_var)) { if (fast_string_eq((*left._v__ast__SelectorExpr).field_name, _S("name"))) { is_comptime_type_is_expr = true; if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__eq)) { skip_state = (string__eq(c->comptime->comptime_for_method->name, string_str((*right._v__ast__StringLiteral).val)) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__ne)) { skip_state = (string__eq(c->comptime->comptime_for_method->name, string_str((*right._v__ast__StringLiteral).val)) ? (v__checker__ComptimeBranchSkipState__skip) : (v__checker__ComptimeBranchSkipState__eval)); } else { } } } else { } } else if ((left)._typ == 380 /* v.ast.SizeOf */ && (right)._typ == 363 /* v.ast.IntegerLiteral */) { v__ast__Type typ = v__checker__Checker_unwrap_generic(c, (*left._v__ast__SizeOf).typ); if (typ == 0) { v__checker__Checker_error(c, _S("invalid `$if` condition: expected a type"), v__ast__Expr_pos((*branch.cond._v__ast__InfixExpr).left)); } else { multi_return_int_int mr_12656 = v__ast__Table_type_size(c->table, v__checker__Checker_unwrap_generic(c, typ)); int s = mr_12656.arg0; v__checker__ComptimeBranchSkipState _t12 = 0; if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__gt)) { _t12 = (s > string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__lt)) { _t12 = (s < string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__ge)) { _t12 = (s >= string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__le)) { _t12 = (s <= string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__ne)) { _t12 = (s != string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else if ((*branch.cond._v__ast__InfixExpr).op == (v__token__Kind__eq)) { _t12 = (s == string_i64((*right._v__ast__IntegerLiteral).val) ? (v__checker__ComptimeBranchSkipState__eval) : (v__checker__ComptimeBranchSkipState__skip)); } else { _t12 = v__checker__ComptimeBranchSkipState__skip; }skip_state = _t12; } } } } bool cur_skip_flags = c->skip_flags; if (found_branch) { c->skip_flags = true; } else if (skip_state == v__checker__ComptimeBranchSkipState__skip) { c->skip_flags = true; skip_state = v__checker__ComptimeBranchSkipState__unknown; } else if (skip_state == v__checker__ComptimeBranchSkipState__eval) { found_branch = true; c->skip_flags = skip_state == v__checker__ComptimeBranchSkipState__skip; } if (c->fn_level == 0 && c->pref->output_cross_c) { found_branch = false; c->skip_flags = false; array_push((array*)&c->ct_cond_stack, _MOV((v__ast__Expr[]){ branch.cond })); } if (!c->skip_flags) { if (node_is_expr) { v__checker__Checker_stmts_ending_with_expression(c, &branch.stmts, c->expected_or_type); } else { v__checker__Checker_stmts(c, &branch.stmts); v__checker__Checker_check_non_expr_branch_last_stmt(c, branch.stmts); } } else if (c->pref->output_cross_c) { bool is_freestanding_block = false; if ((branch.cond)._typ == 358 /* v.ast.Ident */) { if (fast_string_eq((*branch.cond._v__ast__Ident).name, _S("freestanding"))) { is_freestanding_block = true; } } if (is_freestanding_block) { branch.stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); (*(v__ast__IfBranch*)array_get(node->branches, i)).stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); } if (node_is_expr) { v__checker__Checker_stmts_ending_with_expression(c, &branch.stmts, c->expected_or_type); } else { v__checker__Checker_stmts(c, &branch.stmts); v__checker__Checker_check_non_expr_branch_last_stmt(c, branch.stmts); } } else if (!is_comptime_type_is_expr) { (*(v__ast__IfBranch*)array_get(node->branches, i)).stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); } if (comptime_field_name.len > 0) { if (string__eq(comptime_field_name, c->comptime->comptime_for_method_var)) { v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, comptime_field_name, c->comptime->comptime_for_method_ret_type); } else if (string__eq(comptime_field_name, c->comptime->comptime_for_field_var)) { v__type_resolver__TypeResolver_update_ct_type(&c->type_resolver, comptime_field_name, c->comptime->comptime_for_field_type); } } c->skip_flags = cur_skip_flags; if (c->fn_level == 0 && c->pref->output_cross_c && c->ct_cond_stack.len > 0) { array_delete_last(&c->ct_cond_stack); } } else { v__checker__Checker_smartcast_if_conds(c, &branch.cond, branch.scope, v__ast__IfExpr_to_sumtype_v__ast__Expr(node)); if (node_is_expr) { v__checker__Checker_stmts_ending_with_expression(c, &branch.stmts, c->expected_or_type); } else { v__checker__Checker_stmts(c, &branch.stmts); v__checker__Checker_check_non_expr_branch_last_stmt(c, branch.stmts); } c->smartcast_mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); c->smartcast_cond_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); } if (expr_required) { if (branch.stmts.len > 0) { v__ast__Stmt stmt = (*(v__ast__Stmt*)array_last(branch.stmts)); if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { if (((*stmt._v__ast__ExprStmt).expr)._typ == 352 /* v.ast.ConcatExpr */) { for (int _t14 = 0; _t14 < (*(*stmt._v__ast__ExprStmt).expr._v__ast__ConcatExpr).vals.len; ++_t14) { v__ast__Expr* val = ((v__ast__Expr*)(*(*stmt._v__ast__ExprStmt).expr._v__ast__ConcatExpr).vals.data) + _t14; v__checker__Checker_check_expr_option_or_result_call(c, *val, v__checker__Checker_expr(c, val)); } } c->expected_type = former_expected_type; if (v__ast__Table_type_kind(c->table, c->expected_type) == v__ast__Kind__sum_type && v__ast__Table_is_sumtype_or_in_variant(c->table, c->expected_type, node->typ)) { node->is_expr = true; node->typ = c->expected_type; } if (v__ast__Type_has_option_or_result(c->expected_type)) { if (node->typ == _const_v__ast__void_type) { node->is_expr = true; node->typ = c->expected_type; } } if (v__ast__Type_has_flag(c->expected_type, v__ast__TypeFlag__generic)) { if (node->typ == _const_v__ast__void_type) { node->is_expr = true; node->typ = v__checker__Checker_unwrap_generic(c, c->expected_type); } continue; } if (c->expected_expr_type != _const_v__ast__void_type) { c->expected_type = c->expected_expr_type; } (*stmt._v__ast__ExprStmt).typ = v__checker__Checker_expr(c, &(*stmt._v__ast__ExprStmt).expr); if (v__ast__Table_type_kind(c->table, c->expected_type) == v__ast__Kind__multi_return && v__ast__Table_type_kind(c->table, (*stmt._v__ast__ExprStmt).typ) == v__ast__Kind__multi_return) { if (node->typ == _const_v__ast__void_type) { node->is_expr = true; node->typ = c->expected_type; } } if ((*stmt._v__ast__ExprStmt).typ == _const_v__ast__void_type && !v__checker__is_noreturn_callexpr((*stmt._v__ast__ExprStmt).expr) && !c->skip_flags) { v__checker__Checker_error(c, _S("the final expression in `if` or `match`, must have a value of a non-void type"), (*stmt._v__ast__ExprStmt).pos); continue; } if (!v__checker__Checker_check_types(c, (*stmt._v__ast__ExprStmt).typ, node->typ)) { if (node->typ == _const_v__ast__void_type) { node->is_expr = true; if (v__ast__Expr_is_auto_deref_var((*stmt._v__ast__ExprStmt).expr)) { node->typ = v__ast__Type_deref((*stmt._v__ast__ExprStmt).typ); } else { node->typ = (*stmt._v__ast__ExprStmt).typ; } c->expected_expr_type = node->typ; continue; } else if (node->typ == _const_v__ast__float_literal_type || node->typ == _const_v__ast__int_literal_type) { if (node->typ == _const_v__ast__int_literal_type) { if (v__ast__Type_is_int((*stmt._v__ast__ExprStmt).typ) || v__ast__Type_is_float((*stmt._v__ast__ExprStmt).typ)) { node->typ = (*stmt._v__ast__ExprStmt).typ; continue; } } else { if (v__ast__Type_is_float((*stmt._v__ast__ExprStmt).typ)) { node->typ = (*stmt._v__ast__ExprStmt).typ; continue; } } } if ((*stmt._v__ast__ExprStmt).typ == _const_v__ast__float_literal_type || (*stmt._v__ast__ExprStmt).typ == _const_v__ast__int_literal_type) { if ((*stmt._v__ast__ExprStmt).typ == _const_v__ast__int_literal_type) { if (v__ast__Type_is_int(node->typ) || v__ast__Type_is_float(node->typ)) { continue; } } else { if (v__ast__Type_is_float(node->typ)) { continue; } } } if (node->is_expr && v__ast__Table_sym(c->table, former_expected_type)->kind == v__ast__Kind__sum_type) { node->typ = former_expected_type; continue; } if (v__checker__is_noreturn_callexpr((*stmt._v__ast__ExprStmt).expr)) { continue; } if ((v__ast__Type_has_option_or_result(node->typ)) && v__ast__Table_sym(c->table, (*stmt._v__ast__ExprStmt).typ)->kind == v__ast__Kind__struct && v__checker__Checker_type_implements(c, (*stmt._v__ast__ExprStmt).typ, _const_v__ast__error_type, node->pos)) { (*stmt._v__ast__ExprStmt).expr = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = _const_v__ast__error_type,.expr = (*stmt._v__ast__ExprStmt).expr,.typname = _S("IError"),.expr_type = (*stmt._v__ast__ExprStmt).typ,.has_arg = 0,.pos = node->pos,})))); (*stmt._v__ast__ExprStmt).typ = _const_v__ast__error_type; continue; } if ((node->typ == _const_v__ast__none_type && (*stmt._v__ast__ExprStmt).typ != _const_v__ast__none_type) || ((*stmt._v__ast__ExprStmt).typ == _const_v__ast__none_type && node->typ != _const_v__ast__none_type)) { node->typ = ((*stmt._v__ast__ExprStmt).typ != _const_v__ast__none_type ? (v__ast__Type_set_flag((*stmt._v__ast__ExprStmt).typ, v__ast__TypeFlag__option)) : (v__ast__Type_set_flag(node->typ, v__ast__TypeFlag__option))); continue; } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, node->typ)}}, {_S("` and `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, (*stmt._v__ast__ExprStmt).typ)}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else { if (node->is_expr == false && v__type_resolver__TypeResolver_is_generic_param_var(&c->type_resolver, (*stmt._v__ast__ExprStmt).expr)) { node->is_expr = true; } if (c->inside_assign && node->is_expr && !v__ast__Type_has_flag(node->typ, v__ast__TypeFlag__shared_f) && (*stmt._v__ast__ExprStmt).typ != _const_v__ast__voidptr_type) { if (v__ast__Type_is_ptr((*stmt._v__ast__ExprStmt).typ) != v__ast__Type_is_ptr(node->typ)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, node->typ)}}, {_S("` and `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, (*stmt._v__ast__ExprStmt).typ)}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else if ((*stmt._v__ast__ExprStmt).typ != _const_v__ast__none_type) { if (!v__ast__Type_has_flag(node->typ, v__ast__TypeFlag__option) && v__ast__Type_has_flag((*stmt._v__ast__ExprStmt).typ, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, node->typ)}}, {_S("` and `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, (*stmt._v__ast__ExprStmt).typ)}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else if (!v__ast__Type_has_flag(node->typ, v__ast__TypeFlag__result) && v__ast__Type_has_flag((*stmt._v__ast__ExprStmt).typ, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, node->typ)}}, {_S("` and `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, (*stmt._v__ast__ExprStmt).typ)}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } } } } else if (!node->is_comptime && !((stmt)._typ == 412 /* v.ast.Return */ || (stmt)._typ == 394 /* v.ast.BranchStmt */)) { v__token__Pos pos = (node_is_expr ? ((*(stmt.pos))) : (branch.pos)); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = if_kind}}, {_S("` expression requires an expression as the last statement of every branch"), 0, { .d_c = 0 }}})), pos); } } else if (!node->is_comptime) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = if_kind}}, {_S("` expression requires an expression as the last statement of every branch"), 0, { .d_c = 0 }}})), branch.pos); } } _option_bool _t15; if (_t15 = v__checker__Checker_has_return(c, branch.stmts), _t15.state == 0) { bool has_return = *(bool*)_t15.data; if (has_return) { nbranches_with_return++; } else { nbranches_without_return++; } } } if (nbranches_with_return > 0) { if (nbranches_with_return == node->branches.len) { c->returns = true; } if (!node->has_else) { c->returns = false; } if (nbranches_without_return > 0) { c->returns = false; } } if (node->typ == _const_v__ast__none_type) { v__checker__Checker_error(c, _S("invalid if expression, must supply at least one value other than `none`"), node->pos); } node->typ = v__ast__mktyp(node->typ); if (expr_required && !node->has_else) { string d = (node->is_comptime ? (_S("$")) : (_S(""))); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = if_kind}}, {_S("` expression needs `"), 0xfe10, {.d_s = d}}, {_S("else` clause"), 0, { .d_c = 0 }}})), node->pos); } v__ast__Type _t16 = node->typ; // Defer begin if (v__checker__Checker_if_expr_defer_1) { c->comptime->inside_comptime_if = last_in_comptime_if; } // Defer end // Defer begin if (v__checker__Checker_if_expr_defer_0) { c->expected_expr_type = _const_v__ast__void_type; } // Defer end return _t16; } VV_LOC void v__checker__Checker_smartcast_if_conds(v__checker__Checker* c, v__ast__Expr* node, v__ast__Scope* scope, v__ast__Expr control_expr) { if ((node)->_typ == 362 /* v.ast.InfixExpr */) { if ((*node->_v__ast__InfixExpr).op == v__token__Kind__and) { v__checker__Checker_smartcast_if_conds(c, &(*node->_v__ast__InfixExpr).left, scope, control_expr); v__checker__Checker_smartcast_if_conds(c, &(*node->_v__ast__InfixExpr).right, scope, control_expr); } else if ((((*node->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ || ((*node->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */) && (*node->_v__ast__InfixExpr).op == v__token__Kind__ne && ((*node->_v__ast__InfixExpr).right)._typ == 371 /* v.ast.None */) { if ((((*node->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*node->_v__ast__InfixExpr).left)._v__ast__Ident,((*node->_v__ast__InfixExpr).left)._typ, 358)).is_mut) || (((*node->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ && (*(v__ast__SelectorExpr*)__as_cast(((*node->_v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*node->_v__ast__InfixExpr).left)._typ, 379)).is_mut)) { v__checker__Checker_fail_if_immutable(c, &(*node->_v__ast__InfixExpr).left); } if (((*node->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ && v__type_resolver__ResolverInfo_get_ct_type_var(c->comptime, v__ast__Ident_to_sumtype_v__ast__Expr((v__ast__Ident*)__as_cast(((*node->_v__ast__InfixExpr).left)._v__ast__Ident,((*node->_v__ast__InfixExpr).left)._typ, 358))) == v__ast__ComptimeVarKind__smartcast) { (*node->_v__ast__InfixExpr).left_type = v__type_resolver__TypeResolver_get_type(&c->type_resolver, (*node->_v__ast__InfixExpr).left); v__checker__Checker_smartcast(c, &(*node->_v__ast__InfixExpr).left, (*node->_v__ast__InfixExpr).left_type, v__ast__Type_clear_flag((*node->_v__ast__InfixExpr).left_type, v__ast__TypeFlag__option), scope, true, true); } else { v__checker__Checker_smartcast(c, &(*node->_v__ast__InfixExpr).left, (*node->_v__ast__InfixExpr).left_type, v__ast__Type_clear_flag((*node->_v__ast__InfixExpr).left_type, v__ast__TypeFlag__option), scope, false, true); } } else if ((*node->_v__ast__InfixExpr).op == v__token__Kind__key_is) { if (((*node->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*node->_v__ast__InfixExpr).left)._v__ast__Ident,((*node->_v__ast__InfixExpr).left)._typ, 358)).ct_expr) { (*node->_v__ast__InfixExpr).left_type = v__type_resolver__TypeResolver_get_type(&c->type_resolver, (*node->_v__ast__InfixExpr).left); } else { (*node->_v__ast__InfixExpr).left_type = v__checker__Checker_expr(c, &(*node->_v__ast__InfixExpr).left); } bool is_comptime = false; v__ast__Expr right_expr = (*node->_v__ast__InfixExpr).right; v__ast__Type _t1 = 0; if (right_expr._typ == 386 /* v.ast.TypeNode */) { _t1 = (*right_expr._v__ast__TypeNode).typ; } else if (right_expr._typ == 371 /* v.ast.None */) { _t1 = _const_v__ast__none_type_idx; } else if (right_expr._typ == 358 /* v.ast.Ident */) { v__ast__Type _t2; /* if prepend */ if (string__eq((*right_expr._v__ast__Ident).name, c->comptime->comptime_for_variant_var)) { is_comptime = true; _t2 = v__type_resolver__TypeResolver_get_ct_type_or_default(&c->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->comptime->comptime_for_variant_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), _const_v__ast__no_type); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid type `"), 0xfe10, {.d_s = v__ast__Ident_str((*right_expr._v__ast__Ident))}}, {_S("`"), 0, { .d_c = 0 }}})), (*right_expr._v__ast__Ident).pos); _t2 = _const_v__ast__no_type; } _t1 = _t2; } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid type `"), 0xfe10, {.d_s = v__ast__Expr_str(&right_expr)}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right_expr)); _t1 = _const_v__ast__no_type; } v__ast__Type right_type = _t1; if (right_type != _const_v__ast__no_type) { v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type); v__ast__Type expr_type = v__checker__Checker_unwrap_generic(c, (*node->_v__ast__InfixExpr).left_type); v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, expr_type); if (left_sym->kind == v__ast__Kind__aggregate) { expr_type = (*(v__ast__Aggregate*)__as_cast((left_sym->info)._v__ast__Aggregate,(left_sym->info)._typ, 537)).sum_type; } if (left_sym->kind == v__ast__Kind__interface) { if (right_sym->kind != v__ast__Kind__interface) { v__checker__Checker_type_implements(c, right_type, expr_type, (*node->_v__ast__InfixExpr).pos); } } else if (!v__checker__Checker_check_types(c, right_type, expr_type) && left_sym->kind != v__ast__Kind__sum_type) { string expect_str = v__ast__Table_type_to_str(c->table, right_type); string expr_str = v__ast__Table_type_to_str(c->table, expr_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use type `"), 0xfe10, {.d_s = expect_str}}, {_S("` as type `"), 0xfe10, {.d_s = expr_str}}, {_S("`"), 0, { .d_c = 0 }}})), (*node->_v__ast__InfixExpr).pos); } if ((((*node->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ || ((*node->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */) && (((*node->_v__ast__InfixExpr).right)._typ == 351 /* v.ast.ComptimeType */ || ((*node->_v__ast__InfixExpr).right)._typ == 386 /* v.ast.TypeNode */ || ((*node->_v__ast__InfixExpr).right)._typ == 358 /* v.ast.Ident */)) { bool is_variable = (((*node->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ ? ((*(*node->_v__ast__InfixExpr).left._v__ast__Ident).kind == v__ast__IdentKind__variable) : (true)); if (is_variable) { if ((((*node->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*node->_v__ast__InfixExpr).left)._v__ast__Ident,((*node->_v__ast__InfixExpr).left)._typ, 358)).is_mut) || (((*node->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ && (*(v__ast__SelectorExpr*)__as_cast(((*node->_v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*node->_v__ast__InfixExpr).left)._typ, 379)).is_mut)) { v__checker__Checker_fail_if_immutable(c, &(*node->_v__ast__InfixExpr).left); } if (((*node->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ && (left_sym->kind == v__ast__Kind__interface && right_sym->kind != v__ast__Kind__interface)) { _option_v__ast__Var_ptr _t3 = v__ast__Scope_find_var(scope, (*(*node->_v__ast__InfixExpr).left._v__ast__Ident).name); if (_t3.state != 0) { IError err = _t3.err; *(v__ast__Var**) _t3.data = ((v__ast__Var*)memdup(&(v__ast__Var){.name = (string){.str=(byteptr)"", .is_lit=1},.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = 0,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,}, sizeof(v__ast__Var))); } v__ast__Var* v = (*(v__ast__Var**)_t3.data); if (v->is_mut && !(*(*node->_v__ast__InfixExpr).left._v__ast__Ident).is_mut) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("smart casting a mutable interface value requires `if mut "), 0xfe10, {.d_s = (*(*node->_v__ast__InfixExpr).left._v__ast__Ident).name}}, {_S(" is ...`"), 0, { .d_c = 0 }}})), (*(*node->_v__ast__InfixExpr).left._v__ast__Ident).pos); } } if (left_sym->kind == v__ast__Kind__interface || left_sym->kind == v__ast__Kind__sum_type) { v__checker__Checker_smartcast(c, &(*node->_v__ast__InfixExpr).left, (*node->_v__ast__InfixExpr).left_type, right_type, scope, is_comptime, false); } } } } } } else if ((node)->_typ == 366 /* v.ast.Likely */) { v__checker__Checker_smartcast_if_conds(c, &(*node->_v__ast__Likely).expr, scope, control_expr); } else if ((control_expr)._typ == 359 /* v.ast.IfExpr */ && (node)->_typ == 335 /* v.ast.NodeError */) { if ((*control_expr._v__ast__IfExpr).branches.len != 2) { return; } v__ast__Expr first_cond = (*(v__ast__IfBranch*)array_get((*control_expr._v__ast__IfExpr).branches, 0)).cond; if ((first_cond)._typ == 362 /* v.ast.InfixExpr */) { if ((((*first_cond._v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ || ((*first_cond._v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */) && (*first_cond._v__ast__InfixExpr).op == v__token__Kind__eq && ((*first_cond._v__ast__InfixExpr).right)._typ == 371 /* v.ast.None */) { if (v__type_resolver__ResolverInfo_get_ct_type_var(c->comptime, (*first_cond._v__ast__InfixExpr).left) == v__ast__ComptimeVarKind__smartcast) { (*first_cond._v__ast__InfixExpr).left_type = v__type_resolver__TypeResolver_get_type(&c->type_resolver, (*first_cond._v__ast__InfixExpr).left); v__checker__Checker_smartcast(c, &(*first_cond._v__ast__InfixExpr).left, (*first_cond._v__ast__InfixExpr).left_type, v__ast__Type_clear_flag((*first_cond._v__ast__InfixExpr).left_type, v__ast__TypeFlag__option), scope, true, true); } else { v__checker__Checker_smartcast(c, &(*first_cond._v__ast__InfixExpr).left, (*first_cond._v__ast__InfixExpr).left_type, v__ast__Type_clear_flag((*first_cond._v__ast__InfixExpr).left_type, v__ast__TypeFlag__option), scope, false, true); } } } } } VV_LOC void v__checker__Checker_check_non_expr_branch_last_stmt(v__checker__Checker* c, Array_v__ast__Stmt stmts) { if (stmts.len == 0) { return; } v__ast__Stmt last_stmt = (*(v__ast__Stmt*)array_last(stmts)); if ((last_stmt)._typ == 401 /* v.ast.ExprStmt */ && (((*(v__ast__ExprStmt*)__as_cast((last_stmt)._v__ast__ExprStmt,(last_stmt)._typ, 401)).expr)._typ == 362 /* v.ast.InfixExpr */ && !((*(v__ast__InfixExpr*)__as_cast(((*(v__ast__ExprStmt*)__as_cast((last_stmt)._v__ast__ExprStmt,(last_stmt)._typ, 401)).expr)._v__ast__InfixExpr,((*(v__ast__ExprStmt*)__as_cast((last_stmt)._v__ast__ExprStmt,(last_stmt)._typ, 401)).expr)._typ, 362)).op == v__token__Kind__left_shift || (*(v__ast__InfixExpr*)__as_cast(((*(v__ast__ExprStmt*)__as_cast((last_stmt)._v__ast__ExprStmt,(last_stmt)._typ, 401)).expr)._v__ast__InfixExpr,((*(v__ast__ExprStmt*)__as_cast((last_stmt)._v__ast__ExprStmt,(last_stmt)._typ, 401)).expr)._typ, 362)).op == v__token__Kind__right_shift || (*(v__ast__InfixExpr*)__as_cast(((*(v__ast__ExprStmt*)__as_cast((last_stmt)._v__ast__ExprStmt,(last_stmt)._typ, 401)).expr)._v__ast__InfixExpr,((*(v__ast__ExprStmt*)__as_cast((last_stmt)._v__ast__ExprStmt,(last_stmt)._typ, 401)).expr)._typ, 362)).op == v__token__Kind__unsigned_right_shift || (*(v__ast__InfixExpr*)__as_cast(((*(v__ast__ExprStmt*)__as_cast((last_stmt)._v__ast__ExprStmt,(last_stmt)._typ, 401)).expr)._v__ast__InfixExpr,((*(v__ast__ExprStmt*)__as_cast((last_stmt)._v__ast__ExprStmt,(last_stmt)._typ, 401)).expr)._typ, 362)).op == v__token__Kind__arrow))) { v__checker__Checker_error(c, _S("expression evaluated but not used"), (*last_stmt._v__ast__ExprStmt).pos); } } VV_LOC v__ast__Type v__checker__Checker_infix_expr(v__checker__Checker* c, v__ast__InfixExpr* node) { bool v__checker__Checker_infix_expr_defer_0 = false; v__ast__Type former_expected_type; bool v__checker__Checker_infix_expr_defer_1 = false; v__ast__Type left_type; v__ast__Type right_type; bool v__checker__Checker_infix_expr_defer_2 = false; former_expected_type = c->expected_type; v__checker__Checker_infix_expr_defer_0 = true; left_type = v__checker__Checker_expr(c, &node->left); v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, left_type); node->left_type = left_type; c->expected_type = left_type; if (left_sym->kind == v__ast__Kind__chan) { v__ast__Chan chan_info = v__ast__TypeSymbol_chan_info(left_sym); c->expected_type = chan_info.elem_type; } if (!node->left_ct_expr && !v__ast__Expr_is_literal(node->left)) { node->left_ct_expr = v__type_resolver__ResolverInfo_is_comptime(c->comptime, node->left); } if (!node->right_ct_expr && !v__ast__Expr_is_literal(node->right)) { node->right_ct_expr = v__type_resolver__ResolverInfo_is_comptime(c->comptime, node->right); } if (!c->inside_sql && node->op == v__token__Kind__and) { v__ast__Expr left_node = node->left; for (;;) { if (!((left_node)._typ == 362 /* v.ast.InfixExpr */)) break; if ((*left_node._v__ast__InfixExpr).op == v__token__Kind__and && ((*left_node._v__ast__InfixExpr).right)._typ == 362 /* v.ast.InfixExpr */) { if ((*(*left_node._v__ast__InfixExpr).right._v__ast__InfixExpr).op == v__token__Kind__key_is) { v__ast__Type from_type = v__checker__Checker_expr(c, &(*(*left_node._v__ast__InfixExpr).right._v__ast__InfixExpr).left); v__ast__Type to_type = v__checker__Checker_expr(c, &(*(*left_node._v__ast__InfixExpr).right._v__ast__InfixExpr).right); v__checker__Checker_autocast_in_if_conds(c, &node->right, (*(*left_node._v__ast__InfixExpr).right._v__ast__InfixExpr).left, from_type, to_type); } } if ((*left_node._v__ast__InfixExpr).op == v__token__Kind__key_is) { v__ast__Type from_type = v__checker__Checker_expr(c, &(*left_node._v__ast__InfixExpr).left); v__ast__Type to_type = v__checker__Checker_expr(c, &(*left_node._v__ast__InfixExpr).right); v__checker__Checker_autocast_in_if_conds(c, &node->right, (*left_node._v__ast__InfixExpr).left, from_type, to_type); break; } else if ((*left_node._v__ast__InfixExpr).op == v__token__Kind__and) { left_node = (*left_node._v__ast__InfixExpr).left; } else { break; } } } if (node->op == v__token__Kind__key_is) { c->inside_x_is_type = true; } if (node->op == v__token__Kind__left_shift && v__ast__Table_sym(c->table, left_type)->kind == v__ast__Kind__array) { if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("cannot push to Option array that was not unwrapped first"), v__ast__Expr_pos(node->left)); } v__checker__Checker_markused_infixexpr(c, !c->is_builtin_mod && !fast_string_eq(c->mod, _S("strings"))); if ((node->right)._typ == 359 /* v.ast.IfExpr */) { if ((*node->right._v__ast__IfExpr).is_expr && (*node->right._v__ast__IfExpr).branches.len > 0) { v__ast__Stmt last_stmt = (*(v__ast__Stmt*)array_last((*(v__ast__IfBranch*)array_get((*node->right._v__ast__IfExpr).branches, 0)).stmts)); if ((last_stmt)._typ == 401 /* v.ast.ExprStmt */) { v__ast__Type expr_typ = v__checker__Checker_expr(c, &(*last_stmt._v__ast__ExprStmt).expr); v__ast__Array info = v__ast__TypeSymbol_array_info(v__ast__Table_sym(c->table, left_type)); if (expr_typ == info.elem_type) { c->expected_type = info.elem_type; } } } } } right_type = v__checker__Checker_expr(c, &node->right); if (node->op == v__token__Kind__key_is) { c->inside_x_is_type = false; } if (node->op == v__token__Kind__amp && v__ast__Type_is_bool(left_type) && v__ast__Type_is_bool(right_type) && v__ast__Type_is_ptr(right_type)) { v__token__Pos pos = v__token__Pos_extend(node->pos, v__ast__Expr_pos(node->right)); v__checker__Checker_error(c, _S("the right expression should be separated from the `&&` by a space"), pos); node->promoted_type = _const_v__ast__bool_type; v__ast__Type _t1 = _const_v__ast__bool_type; // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t1; } node->right_type = right_type; if (!v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option) && v__ast__Type_is_number(left_type) && !v__ast__Type_is_ptr(left_type) && (right_type == _const_v__ast__int_literal_type || right_type == _const_v__ast__float_literal_type)) { node->right_type = left_type; if ((left_type == _const_v__ast__f32_type_idx || left_type == _const_v__ast__f64_type_idx) && right_type == _const_v__ast__float_literal_type) { v__checker__Checker_infix_expr_defer_1 = true; } } if (v__ast__Type_is_number(right_type) && !v__ast__Type_is_ptr(right_type) && (left_type == _const_v__ast__int_literal_type || left_type == _const_v__ast__float_literal_type)) { node->left_type = right_type; if ((right_type == _const_v__ast__f32_type_idx || right_type == _const_v__ast__f64_type_idx) && left_type == _const_v__ast__float_literal_type) { v__checker__Checker_infix_expr_defer_2 = true; } } v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type); v__ast__TypeSymbol* right_final_sym = v__ast__Table_final_sym(c->table, v__checker__Checker_unwrap_generic(c, right_type)); v__ast__TypeSymbol* left_final_sym = v__ast__Table_final_sym(c->table, v__checker__Checker_unwrap_generic(c, left_type)); v__token__Pos left_pos = v__ast__Expr_pos(node->left); v__token__Pos right_pos = v__ast__Expr_pos(node->right); v__token__Pos left_right_pos = v__token__Pos_extend(left_pos, right_pos); if (left_sym->kind == v__ast__Kind__none && right_sym->kind == v__ast__Kind__none) { v__checker__Checker_invalid_operator_error(c, node->op, left_type, right_type, left_right_pos); } if (left_sym->kind == v__ast__Kind__multi_return && right_sym->kind == v__ast__Kind__multi_return) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid number of operand for `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("`. Only one allowed on each side."), 0, { .d_c = 0 }}})), left_right_pos); } if (v__ast__Type_is_any_kind_of_pointer(left_type) && !v__ast__Expr_is_auto_deref_var(node->left) && (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus || node->op == v__token__Kind__mul || node->op == v__token__Kind__div || node->op == v__token__Kind__mod || node->op == v__token__Kind__xor || node->op == v__token__Kind__amp || node->op == v__token__Kind__pipe)) { if (!c->pref->translated && ((v__ast__Type_is_any_kind_of_pointer(right_type) && node->op != v__token__Kind__minus) || (!v__ast__Type_is_any_kind_of_pointer(right_type) && !(node->op == v__token__Kind__plus || node->op == v__token__Kind__minus)))) { _option_v__ast__Fn _t2; if (_t2 = v__ast__TypeSymbol_find_method(left_sym, v__token__Kind_str(node->op)), _t2.state == 0) { if (left_sym->kind == v__ast__Kind__alias && right_sym->kind == v__ast__Kind__alias) { } else { v__checker__Checker_invalid_operator_error(c, node->op, left_type, right_type, left_right_pos); } } else { IError err = _t2.err; v__checker__Checker_invalid_operator_error(c, node->op, left_type, right_type, left_right_pos); } } else if (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus) { if (!c->inside_unsafe && !v__ast__Expr_is_auto_deref_var(node->left) && !v__ast__Expr_is_auto_deref_var(node->right)) { if (!c->pref->translated && !c->file->is_translated) { v__checker__Checker_warn(c, _S("pointer arithmetic is only allowed in `unsafe` blocks"), left_right_pos); } } if ((left_type == _const_v__ast__voidptr_type || left_type == _const_v__ast__nil_type) && !c->pref->translated) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` cannot be used with `voidptr`"), 0, { .d_c = 0 }}})), left_pos); } } } v__ast__Type return_type = left_type; if (node->op != v__token__Kind__key_is) { if (node->left._typ == 358 /* v.ast.Ident */) { if (!(node->op == v__token__Kind__ne && (node->right)._typ == 371 /* v.ast.None */)) { if ((*node->left._v__ast__Ident).is_mut) { v__checker__Checker_error(c, _S("the `mut` keyword is invalid here"), (*node->left._v__ast__Ident).mut_pos); } } } else if (node->left._typ == 379 /* v.ast.SelectorExpr */) { if (!(node->op == v__token__Kind__ne && (node->right)._typ == 371 /* v.ast.None */)) { if ((*node->left._v__ast__SelectorExpr).is_mut) { v__checker__Checker_error(c, _S("the `mut` keyword is invalid here"), (*node->left._v__ast__SelectorExpr).mut_pos); } } } else { } } if (node->right._typ == 358 /* v.ast.Ident */) { if ((*node->right._v__ast__Ident).is_mut) { v__checker__Checker_error(c, _S("the `mut` keyword is invalid here"), (*node->right._v__ast__Ident).mut_pos); } } else if (node->right._typ == 379 /* v.ast.SelectorExpr */) { if ((*node->right._v__ast__SelectorExpr).is_mut) { v__checker__Checker_error(c, _S("the `mut` keyword is invalid here"), (*node->right._v__ast__SelectorExpr).mut_pos); } } else { } bool eq_ne = (node->op == v__token__Kind__eq || node->op == v__token__Kind__ne); switch (node->op) { case v__token__Kind__eq: case v__token__Kind__ne: { if ((node->left)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast((node->left)._v__ast__CallExpr,(node->left)._typ, 344)).or_block.stmts.len > 0) { v__checker__Checker_check_expr_option_or_result_call(c, node->left, left_type); } if ((node->right)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast((node->right)._v__ast__CallExpr,(node->right)._typ, 344)).or_block.stmts.len > 0) { v__checker__Checker_check_expr_option_or_result_call(c, node->right, right_type); } if ((Array_int_contains(_const_v__ast__integer_type_idxs, left_type)) && (Array_int_contains(_const_v__ast__integer_type_idxs, right_type))) { bool is_left_type_signed = (Array_int_contains(_const_v__ast__signed_integer_type_idxs, left_type)); bool is_right_type_signed = (Array_int_contains(_const_v__ast__signed_integer_type_idxs, right_type)); if (!is_left_type_signed && (node->right)._typ == 363 /* v.ast.IntegerLiteral */) { if (string_int((*node->right._v__ast__IntegerLiteral).val) < 0 && (Array_int_contains(_const_v__ast__int_promoted_type_idxs, left_type))) { string lt = v__ast__Table_sym(c->table, left_type)->name; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = lt}}, {_S("` cannot be compared with negative value"), 0, { .d_c = 0 }}})), (*node->right._v__ast__IntegerLiteral).pos); } } else if (!is_right_type_signed && (node->left)._typ == 363 /* v.ast.IntegerLiteral */) { if (string_int((*node->left._v__ast__IntegerLiteral).val) < 0 && (Array_int_contains(_const_v__ast__int_promoted_type_idxs, right_type))) { string rt = v__ast__Table_sym(c->table, right_type)->name; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("negative value cannot be compared with `"), 0xfe10, {.d_s = rt}}, {_S("`"), 0, { .d_c = 0 }}})), (*node->left._v__ast__IntegerLiteral).pos); } } else if (is_left_type_signed != is_right_type_signed && left_type != 28 && right_type != 28) { multi_return_int_int mr_7601 = v__ast__Table_type_size(c->table, left_type); int ls = mr_7601.arg0; multi_return_int_int mr_7644 = v__ast__Table_type_size(c->table, right_type); int rs = mr_7644.arg0; if (!c->pref->translated && ((is_left_type_signed && ls < rs) || (is_right_type_signed && rs < ls))) { string lt = v__ast__Table_sym(c->table, left_type)->name; string rt = v__ast__Table_sym(c->table, right_type)->name; v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = lt}}, {_S("` cannot be compared with `"), 0xfe10, {.d_s = rt}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } } if (v__ast__Expr_is_nil(node->left)) { v__ast__Type final_type = right_type; if ((right_sym->info)._typ == 539 /* v.ast.Alias */ && v__ast__Type_is_any_kind_of_pointer((*(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 539)).parent_type)) { final_type = (*right_sym->info._v__ast__Alias).parent_type; } if (!v__ast__Type_is_any_kind_of_pointer(final_type) && (right_final_sym->kind != v__ast__Kind__function || (right_final_sym->language != v__ast__Language__c && right_final_sym->kind == v__ast__Kind__placeholder)) && !v__ast__TypeSymbol_is_heap(right_final_sym)) { string rt = v__ast__Table_sym(c->table, right_type)->name; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot compare with `nil` because `"), 0xfe10, {.d_s = rt}}, {_S("` is not a pointer"), 0, { .d_c = 0 }}})), node->pos); } } if (v__ast__Expr_is_nil(node->right)) { v__ast__Type final_type = left_type; if ((left_sym->info)._typ == 539 /* v.ast.Alias */ && v__ast__Type_is_any_kind_of_pointer((*(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 539)).parent_type)) { final_type = (*left_sym->info._v__ast__Alias).parent_type; } if (!v__ast__Type_is_any_kind_of_pointer(final_type) && (left_final_sym->kind != v__ast__Kind__function || (left_final_sym->language != v__ast__Language__c && left_final_sym->kind == v__ast__Kind__placeholder)) && !v__ast__TypeSymbol_is_heap(left_final_sym)) { string lt = v__ast__Table_sym(c->table, left_type)->name; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot compare with `nil` because `"), 0xfe10, {.d_s = lt}}, {_S("` is not a pointer"), 0, { .d_c = 0 }}})), node->pos); } } break; } case v__token__Kind__key_in: case v__token__Kind__not_in: { if (right_final_sym->kind == (v__ast__Kind__array)) { if (!(left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface)) { v__ast__Type elem_type = v__ast__TypeSymbol_array_info(right_final_sym).elem_type; if (v__ast__Expr_is_auto_deref_var(node->left)) { left_type = v__ast__Type_deref(left_type); } _result_void _t3 = v__checker__Checker_check_expected(c, left_type, elem_type); if (_t3.is_error) { IError err = _t3.err; v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("left operand to `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` does not match the array element type: "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); ; } ; if ((node->right)._typ == 338 /* v.ast.ArrayInit */) { v__checker__Checker_check_duplicated_items(c, (voidptr)&(*node->right._v__ast__ArrayInit)); } } else { if ((node->right)._typ == 338 /* v.ast.ArrayInit */) { for (int i = 0; i < (*node->right._v__ast__ArrayInit).expr_types.len; ++i) { v__ast__Type typ = ((v__ast__Type*)(*node->right._v__ast__ArrayInit).expr_types.data)[i]; v__checker__Checker_ensure_type_exists(c, typ, v__ast__Expr_pos((*(v__ast__Expr*)array_get((*node->right._v__ast__ArrayInit).exprs, i)))); } } else { v__ast__Type elem_type = v__ast__TypeSymbol_array_info(right_final_sym).elem_type; if (v__ast__Expr_is_auto_deref_var(node->left)) { left_type = v__ast__Type_deref(left_type); } _result_void _t4 = v__checker__Checker_check_expected(c, left_type, elem_type); if (_t4.is_error) { IError err = _t4.err; v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("left operand to `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` does not match the array element type: "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); ; } ; } } } else if (right_final_sym->kind == (v__ast__Kind__map)) { v__ast__Map map_info = v__ast__TypeSymbol_map_info(right_final_sym); _result_void _t5 = v__checker__Checker_check_expected(c, left_type, map_info.key_type); if (_t5.is_error) { IError err = _t5.err; v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("left operand to `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` does not match the map key type: "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); ; } ; node->left_type = map_info.key_type; } else if (right_final_sym->kind == (v__ast__Kind__array_fixed)) { if (!(left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface)) { v__ast__Type elem_type = v__ast__TypeSymbol_array_fixed_info(right_final_sym).elem_type; _result_void _t6 = v__checker__Checker_check_expected(c, left_type, elem_type); if (_t6.is_error) { IError err = _t6.err; v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("left operand to `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` does not match the fixed array element type: "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); ; } ; } } else { if ((node->right)._typ == 377 /* v.ast.RangeExpr */) { if (!v__ast__TypeSymbol_is_number(left_final_sym) && left_final_sym->kind != v__ast__Kind__rune) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = left_final_sym->name}}, {_S("` is an invalid type for range expression"), 0, { .d_c = 0 }}})), node->pos); } } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` can only be used with arrays and maps"), 0, { .d_c = 0 }}})), node->pos); } } if ((node->left)._typ == 344 /* v.ast.CallExpr */) { if (v__ast__Type_has_flag((*node->left._v__ast__CallExpr).return_type, v__ast__TypeFlag__option) || v__ast__Type_has_flag((*node->left._v__ast__CallExpr).return_type, v__ast__TypeFlag__result)) { string option_or_result = (v__ast__Type_has_flag((*node->left._v__ast__CallExpr).return_type, v__ast__TypeFlag__option) ? (_S("option")) : (_S("result"))); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("unwrapped "), 0xfe10, {.d_s = option_or_result}}, {_S(" cannot be used with `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("`"), 0, { .d_c = 0 }}})), left_pos); } } node->promoted_type = _const_v__ast__bool_type; v__ast__Type _t7 = _const_v__ast__bool_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t7; } case v__token__Kind__plus: case v__token__Kind__minus: case v__token__Kind__mul: case v__token__Kind__div: case v__token__Kind__mod: case v__token__Kind__xor: case v__token__Kind__amp: case v__token__Kind__pipe: { v__ast__Type unwrapped_left_type = v__checker__Checker_unwrap_generic(c, left_type); left_sym = v__ast__Table_sym(c->table, unwrapped_left_type); v__ast__Type unwrapped_right_type = v__checker__Checker_unwrap_generic(c, right_type); right_sym = v__ast__Table_sym(c->table, unwrapped_right_type); if ((right_sym->info)._typ == 539 /* v.ast.Alias */ && ((*(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 539)).language != v__ast__Language__c && string__eq(c->mod, (*(string*)array_get(string_split(v__ast__Table_type_to_str(c->table, unwrapped_right_type), _S(".")), 0))) && (v__ast__TypeSymbol_is_primitive(right_final_sym) || right_final_sym->kind == v__ast__Kind__enum))) { right_sym = right_final_sym; } if ((left_sym->info)._typ == 539 /* v.ast.Alias */ && ((*(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 539)).language != v__ast__Language__c && string__eq(c->mod, (*(string*)array_get(string_split(v__ast__Table_type_to_str(c->table, unwrapped_left_type), _S(".")), 0))) && (v__ast__TypeSymbol_is_primitive(left_final_sym) || left_final_sym->kind == v__ast__Kind__enum))) { left_sym = left_final_sym; } string op_str = v__token__Kind_str(node->op); if (c->pref->translated && (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus || node->op == v__token__Kind__mul) && v__ast__Type_is_any_kind_of_pointer(unwrapped_left_type) && v__ast__Type_is_any_kind_of_pointer(unwrapped_right_type)) { return_type = left_type; } else if (!c->pref->translated && (left_sym->info)._typ == 539 /* v.ast.Alias */ && !v__ast__TypeSymbol_is_primitive(left_final_sym)) { if (v__ast__TypeSymbol_has_method(left_sym, op_str)) { _option_v__ast__Fn _t8; if (_t8 = v__ast__TypeSymbol_find_method(left_sym, op_str), _t8.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t8.data; return_type = method.return_type; } else { IError err = _t8.err; return_type = left_type; } } else if (v__ast__TypeSymbol_has_method_with_generic_parent(left_final_sym, op_str)) { _option_v__ast__Fn _t9; if (_t9 = v__ast__TypeSymbol_find_method_with_generic_parent(left_final_sym, op_str), _t9.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t9.data; return_type = method.return_type; } else { IError err = _t9.err; return_type = left_type; } } else { string left_name = v__ast__Table_type_to_str(c->table, unwrapped_left_type); string right_name = v__ast__Table_type_to_str(c->table, unwrapped_right_type); if (string__eq(left_name, right_name)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("undefined operation `"), 0xfe10, {.d_s = left_name}}, {_S("` "), 0xfe10, {.d_s = op_str}}, {_S(" `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } } } else if (!c->pref->translated && (right_sym->info)._typ == 539 /* v.ast.Alias */ && !v__ast__TypeSymbol_is_primitive(right_final_sym)) { if (v__ast__TypeSymbol_has_method(right_sym, op_str)) { _option_v__ast__Fn _t10; if (_t10 = v__ast__TypeSymbol_find_method(right_sym, op_str), _t10.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t10.data; return_type = method.return_type; } else { IError err = _t10.err; return_type = right_type; } } else if (v__ast__TypeSymbol_has_method_with_generic_parent(right_final_sym, op_str)) { _option_v__ast__Fn _t11; if (_t11 = v__ast__TypeSymbol_find_method_with_generic_parent(right_final_sym, op_str), _t11.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t11.data; return_type = method.return_type; } else { IError err = _t11.err; return_type = right_type; } } else if (v__ast__TypeSymbol_has_method(left_sym, op_str)) { _option_v__ast__Fn _t12; if (_t12 = v__ast__TypeSymbol_find_method(left_sym, op_str), _t12.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t12.data; return_type = method.return_type; } else { IError err = _t12.err; return_type = left_type; } } else if (v__ast__TypeSymbol_has_method_with_generic_parent(left_final_sym, op_str)) { _option_v__ast__Fn _t13; if (_t13 = v__ast__TypeSymbol_find_method_with_generic_parent(left_final_sym, op_str), _t13.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t13.data; return_type = method.return_type; } else { IError err = _t13.err; return_type = left_type; } } else { string left_name = v__ast__Table_type_to_str(c->table, unwrapped_left_type); string right_name = v__ast__Table_type_to_str(c->table, unwrapped_right_type); if (string__eq(left_name, right_name)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("undefined operation `"), 0xfe10, {.d_s = left_name}}, {_S("` "), 0xfe10, {.d_s = op_str}}, {_S(" `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } } } if (((v__ast__Type_is_ptr(unwrapped_left_type) && !v__ast__Expr_is_auto_deref_var(node->left)) || (v__ast__Type_is_ptr(unwrapped_right_type) && !v__ast__Expr_is_auto_deref_var(node->right))) && !(node->op == v__token__Kind__plus || node->op == v__token__Kind__minus)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("infix `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` is not defined for pointer values"), 0, { .d_c = 0 }}})), left_right_pos); } if (!c->pref->translated && (left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed || left_sym->kind == v__ast__Kind__map || left_sym->kind == v__ast__Kind__struct)) { if (v__ast__TypeSymbol_has_method_with_generic_parent(left_sym, op_str)) { _option_v__ast__Fn _t14; if (_t14 = v__ast__TypeSymbol_find_method_with_generic_parent(left_sym, op_str), _t14.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t14.data; return_type = method.return_type; } else { IError err = _t14.err; return_type = left_type; } } else { string left_name = v__ast__Table_type_to_str(c->table, unwrapped_left_type); string right_name = v__ast__Table_type_to_str(c->table, unwrapped_right_type); if (string__eq(left_name, right_name)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("undefined operation `"), 0xfe10, {.d_s = left_name}}, {_S("` "), 0xfe10, {.d_s = op_str}}, {_S(" `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } } } else if (!c->pref->translated && (right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__array_fixed || right_sym->kind == v__ast__Kind__map || right_sym->kind == v__ast__Kind__struct)) { if (v__ast__TypeSymbol_has_method_with_generic_parent(right_sym, op_str)) { _option_v__ast__Fn _t15; if (_t15 = v__ast__TypeSymbol_find_method_with_generic_parent(right_sym, op_str), _t15.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t15.data; return_type = method.return_type; } else { IError err = _t15.err; return_type = right_type; } } else { string left_name = v__ast__Table_type_to_str(c->table, unwrapped_left_type); string right_name = v__ast__Table_type_to_str(c->table, unwrapped_right_type); if (string__eq(left_name, right_name)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("undefined operation `"), 0xfe10, {.d_s = left_name}}, {_S("` "), 0xfe10, {.d_s = op_str}}, {_S(" `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } } } else if (v__ast__Expr_is_auto_deref_var(node->left) || v__ast__Expr_is_auto_deref_var(node->right)) { v__ast__Type deref_left_type = (v__ast__Expr_is_auto_deref_var(node->left) ? (v__ast__Type_deref(unwrapped_left_type)) : (unwrapped_left_type)); v__ast__Type deref_right_type = (v__ast__Expr_is_auto_deref_var(node->right) ? (v__ast__Type_deref(unwrapped_right_type)) : (unwrapped_right_type)); string left_name = v__ast__Table_type_to_str(c->table, v__ast__mktyp(deref_left_type)); string right_name = v__ast__Table_type_to_str(c->table, v__ast__mktyp(deref_right_type)); if (!string__eq(left_name, right_name)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } } else { v__ast__Type unaliased_left_type = v__ast__Table_unalias_num_type(c->table, unwrapped_left_type); v__ast__Type unalias_right_type = v__ast__Table_unalias_num_type(c->table, unwrapped_right_type); v__ast__Type promoted_type = v__checker__Checker_promote_keeping_aliases(c, unaliased_left_type, unalias_right_type, left_sym->kind, right_sym->kind); bool is_allowed_pointer_arithmetic = v__ast__Type_is_any_kind_of_pointer(left_type) && v__ast__Type_is_any_kind_of_pointer(right_type) && node->op == v__token__Kind__minus; if (is_allowed_pointer_arithmetic) { promoted_type = _const_v__ast__int_type; } if (v__ast__Type_idx(promoted_type) == 1) { string left_name = v__ast__Table_type_to_str(c->table, unwrapped_left_type); string right_name = v__ast__Table_type_to_str(c->table, unwrapped_right_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } else if (v__ast__Type_has_option_or_result(promoted_type)) { string s = v__ast__Table_type_to_str(c->table, promoted_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` cannot be used with `"), 0xfe10, {.d_s = s}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else if (v__ast__Type_is_float(promoted_type)) { if (node->op == v__token__Kind__mod || node->op == v__token__Kind__xor || node->op == v__token__Kind__amp || node->op == v__token__Kind__pipe) { string side = (unwrapped_left_type == promoted_type ? (_S("left")) : (_S("right"))); v__token__Pos pos = (unwrapped_left_type == promoted_type ? (left_pos) : (right_pos)); string name = (unwrapped_left_type == promoted_type ? (left_sym->name) : (right_sym->name)); if (node->op == v__token__Kind__mod) { v__checker__Checker_error(c, _S("float modulo not allowed, use math.fmod() instead"), pos); } else { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = side}}, {_S(" type of `"), 0xfe10, {.d_s = op_str}}, {_S("` cannot be non-integer type `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}})), pos); } } } if (node->op == v__token__Kind__div || node->op == v__token__Kind__mod) { v__checker__Checker_check_div_mod_by_zero(c, node->right, node->op); } left_sym = v__ast__Table_sym(c->table, unwrapped_left_type); right_sym = v__ast__Table_sym(c->table, unwrapped_right_type); if ((left_sym->info)._typ == 539 /* v.ast.Alias */ && v__ast__TypeSymbol_is_primitive(left_final_sym)) { if (v__ast__TypeSymbol_has_method(left_sym, op_str)) { _option_v__ast__Fn _t16; if (_t16 = v__ast__TypeSymbol_find_method(left_sym, op_str), _t16.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t16.data; return_type = method.return_type; } } } else if ((right_sym->info)._typ == 539 /* v.ast.Alias */ && v__ast__TypeSymbol_is_primitive(right_final_sym)) { if (v__ast__TypeSymbol_has_method(right_sym, op_str)) { _option_v__ast__Fn _t17; if (_t17 = v__ast__TypeSymbol_find_method(right_sym, op_str), _t17.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t17.data; return_type = method.return_type; } } } v__ast__TypeSymbol* return_sym = v__ast__Table_sym(c->table, return_type); if ((return_sym->info)._typ != 539 /* v.ast.Alias */) { return_type = promoted_type; } } break; } case v__token__Kind__gt: case v__token__Kind__lt: case v__token__Kind__ge: case v__token__Kind__le: { v__ast__Type unwrapped_left_type = v__checker__Checker_unwrap_generic(c, left_type); left_sym = v__ast__Table_sym(c->table, unwrapped_left_type); if (left_sym->kind == v__ast__Kind__alias && !v__ast__TypeSymbol_has_method_with_generic_parent(left_sym, v__token__Kind_str(node->op))) { left_sym = v__ast__Table_final_sym(c->table, unwrapped_left_type); } v__ast__Type unwrapped_right_type = v__checker__Checker_unwrap_generic(c, right_type); right_sym = v__ast__Table_sym(c->table, unwrapped_right_type); if (right_sym->kind == v__ast__Kind__alias && !v__ast__TypeSymbol_has_method_with_generic_parent(right_sym, v__token__Kind_str(node->op))) { right_sym = v__ast__Table_final_sym(c->table, unwrapped_right_type); } if ((left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed) && (right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__array_fixed)) { v__checker__Checker_error(c, _S("only `==` and `!=` are defined on arrays"), node->pos); } else if ((left_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((left_sym->info)._v__ast__Struct,(left_sym->info)._typ, 518)).generic_types.len > 0) { node->promoted_type = _const_v__ast__bool_type; v__ast__Type _t18 = _const_v__ast__bool_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t18; } else if (left_sym->kind == v__ast__Kind__struct && right_sym->kind == v__ast__Kind__struct && (node->op == v__token__Kind__eq || node->op == v__token__Kind__lt)) { if (!(v__ast__TypeSymbol_has_method(left_sym, v__token__Kind_str(node->op)) && v__ast__TypeSymbol_has_method(right_sym, v__token__Kind_str(node->op)))) { string left_name = v__ast__Table_type_to_str(c->table, unwrapped_left_type); string right_name = v__ast__Table_type_to_str(c->table, unwrapped_right_type); if (string__eq(left_name, right_name)) { if (!(node->op == v__token__Kind__lt && c->pref->translated)) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("undefined operation `"), 0xfe10, {.d_s = left_name}}, {_S("` "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("mismatched types `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } } } if (left_sym->kind == v__ast__Kind__struct && right_sym->kind == v__ast__Kind__struct) { if (!v__ast__TypeSymbol_has_method(left_sym, _S("<")) && (node->op == v__token__Kind__ge || node->op == v__token__Kind__le)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` as `<` operator method is not defined"), 0, { .d_c = 0 }}})), left_right_pos); } else if (!v__ast__TypeSymbol_has_method(left_sym, _S("<")) && node->op == v__token__Kind__gt) { v__checker__Checker_error(c, _S("cannot use `>` as `<=` operator method is not defined"), left_right_pos); } } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic) && v__ast__Type_has_flag(right_type, v__ast__TypeFlag__generic)) { v__ast__Type left_gen_type = v__checker__Checker_unwrap_generic(c, left_type); v__ast__TypeSymbol* gen_sym = v__ast__Table_sym(c->table, left_gen_type); bool need_overload = (gen_sym->kind == v__ast__Kind__struct || gen_sym->kind == v__ast__Kind__interface); if (need_overload && !v__ast__TypeSymbol_has_method_with_generic_parent(gen_sym, _S("<")) && (node->op == v__token__Kind__ge || node->op == v__token__Kind__le)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` as `<` operator method is not defined"), 0, { .d_c = 0 }}})), left_right_pos); } else if (need_overload && !v__ast__TypeSymbol_has_method_with_generic_parent(gen_sym, _S("<")) && node->op == v__token__Kind__gt) { v__checker__Checker_error(c, _S("cannot use `>` as `<=` operator method is not defined"), left_right_pos); } } else if ((Array_int_contains(_const_v__ast__integer_type_idxs, left_type)) && (Array_int_contains(_const_v__ast__integer_type_idxs, right_type))) { bool is_left_type_signed = (Array_int_contains(_const_v__ast__signed_integer_type_idxs, left_type)) || left_type == 28; bool is_right_type_signed = (Array_int_contains(_const_v__ast__signed_integer_type_idxs, right_type)) || right_type == 28; if (is_left_type_signed != is_right_type_signed) { if (is_right_type_signed) { if ((node->right)._typ == 363 /* v.ast.IntegerLiteral */) { if (string_int((*node->right._v__ast__IntegerLiteral).val) < 0) { v__checker__Checker_error(c, _S("unsigned integer cannot be compared with negative value"), (*node->right._v__ast__IntegerLiteral).pos); } } } else if (is_left_type_signed) { if ((node->left)._typ == 363 /* v.ast.IntegerLiteral */) { if (string_int((*node->left._v__ast__IntegerLiteral).val) < 0) { v__checker__Checker_error(c, _S("unsigned integer cannot be compared with negative value"), (*node->left._v__ast__IntegerLiteral).pos); } } } } } else if (!((node->left)._typ == 358 /* v.ast.Ident */ || (node->left)._typ == 379 /* v.ast.SelectorExpr */ || (node->left)._typ == 350 /* v.ast.ComptimeSelector */) && (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option) || v__ast__Type_has_flag(right_type, v__ast__TypeFlag__option))) { v__token__Pos opt_comp_pos = (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option) ? (left_pos) : (right_pos)); v__checker__Checker_error(c, _S("unwrapped Option cannot be compared in an infix expression"), opt_comp_pos); } if (v__ast__Expr_is_nil(node->left) || v__ast__Expr_is_nil(node->right)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` with `nil`"), 0, { .d_c = 0 }}})), node->pos); } break; } case v__token__Kind__key_like: { node->promoted_type = _const_v__ast__bool_type; v__ast__Type _t19 = v__checker__Checker_check_like_operator(c, node); // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t19; } case v__token__Kind__key_ilike: { node->promoted_type = _const_v__ast__bool_type; v__ast__Type _t20 = v__checker__Checker_check_like_operator(c, node); // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t20; } case v__token__Kind__left_shift: { if (left_final_sym->kind == v__ast__Kind__array || v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, left_type))->kind == v__ast__Kind__array) { v__ast__Type _t21 = v__checker__Checker_check_append(c, node, left_type, right_type, *right_final_sym); // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t21; } else { node->promoted_type = v__checker__Checker_check_shift(c, node, left_type, right_type); v__ast__Type _t22 = node->promoted_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t22; } break; } case v__token__Kind__right_shift: { node->promoted_type = v__checker__Checker_check_shift(c, node, left_type, right_type); v__ast__Type _t23 = node->promoted_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t23; } case v__token__Kind__unsigned_right_shift: { v__ast__Type _t24; /* if prepend */ if (!v__ast__Type_is_int(left_type)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid operation: shift on type `"), 0xfe10, {.d_s = v__ast__Table_sym(c->table, left_type)->name}}, {_S("`"), 0, { .d_c = 0 }}})), left_pos); _t24 = _const_v__ast__void_type; } else if (v__ast__Type_is_int_literal(left_type)) { _t24 = _const_v__ast__u32_type; } else if (v__ast__Type_is_unsigned(left_type)) { _t24 = left_type; } else { int _t25 = v__ast__Type_idx(left_type); _t24 = v__ast__idx_to_type(((_t25 == (_const_v__ast__i8_type_idx))? (_const_v__ast__u8_type_idx) : (_t25 == (_const_v__ast__i16_type_idx))? (_const_v__ast__u16_type_idx) : (_t25 == (_const_v__ast__i32_type_idx))? (_const_v__ast__u32_type_idx) : (_t25 == (_const_v__ast__int_type_idx))? (_const_v__ast__u32_type_idx) : (_t25 == (_const_v__ast__i64_type_idx))? (_const_v__ast__u64_type_idx) : (_t25 == (_const_v__ast__isize_type_idx))? (_const_v__ast__usize_type_idx) : (0))); } v__ast__Type modified_left_type = _t24; if (modified_left_type == 0) { v__ast__Type _t26 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t26; } *node = ((v__ast__InfixExpr){ .op = v__token__Kind__right_shift, .pos = node->pos, .is_stmt = false, .left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = modified_left_type,.expr = node->left,.typname = v__ast__Table_type_str(c->table, modified_left_type),.expr_type = left_type,.has_arg = 0,.pos = node->pos,})))), .right = node->right, .left_type = left_type, .right_type = right_type, .promoted_type = _const_v__ast__void_type, .auto_locked = node->auto_locked, .or_block = node->or_block, .ct_left_value_evaled = 0, .ct_left_value = _const_v__ast__empty_comptime_const_value, .left_ct_expr = 0, .ct_right_value_evaled = 0, .ct_right_value = _const_v__ast__empty_comptime_const_value, .right_ct_expr = 0, .before_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .after_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)), }); node->promoted_type = v__checker__Checker_check_shift(c, node, left_type, right_type); v__ast__Type _t27 = node->promoted_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t27; } case v__token__Kind__key_is: case v__token__Kind__not_is: { v__ast__Expr right_expr = node->right; v__ast__Type _t28 = 0; if (right_expr._typ == 386 /* v.ast.TypeNode */) { _t28 = (*right_expr._v__ast__TypeNode).typ; } else if (right_expr._typ == 371 /* v.ast.None */) { _t28 = _const_v__ast__none_type_idx; } else if (right_expr._typ == 358 /* v.ast.Ident */) { v__ast__Type _t29; /* if prepend */ if (string__eq((*right_expr._v__ast__Ident).name, c->comptime->comptime_for_variant_var)) { _t29 = v__type_resolver__TypeResolver_get_ct_type_or_default(&c->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->comptime->comptime_for_variant_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), _const_v__ast__void_type); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid type `"), 0xfe10, {.d_s = v__ast__Ident_str((*right_expr._v__ast__Ident))}}, {_S("`"), 0, { .d_c = 0 }}})), (*right_expr._v__ast__Ident).pos); _t29 = _const_v__ast__no_type; } _t28 = _t29; } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid type `"), 0xfe10, {.d_s = v__ast__Expr_str(&right_expr)}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right_expr)); _t28 = _const_v__ast__no_type; } v__ast__Type typ = _t28; if (typ != _const_v__ast__no_type) { v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, typ); string op = v__token__Kind_str(node->op); if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option) && !c->inside_sql) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&node->left)}}, {_S(" is an Optional, it needs to be unwrapped first"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); } if (typ_sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = op}}, {_S(": type `"), 0xfe10, {.d_s = typ_sym->name}}, {_S("` does not exist"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right_expr)); } if ((left_sym->info)._typ == 537 /* v.ast.Aggregate */) { v__ast__Type parent_left_type = (*left_sym->info._v__ast__Aggregate).sum_type; left_sym = v__ast__Table_sym(c->table, parent_left_type); } if (c->inside_sql) { if (typ != 20) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = op}}, {_S("` can only be used to test for none in sql"), 0, { .d_c = 0 }}})), node->pos); } } else if (!(left_sym->kind == v__ast__Kind__interface || left_sym->kind == v__ast__Kind__sum_type) && !v__type_resolver__ResolverInfo_is_comptime(c->comptime, node->left)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = op}}, {_S("` can only be used with interfaces and sum types"), 0, { .d_c = 0 }}})), node->pos); } else if ((left_sym->info)._typ == 544 /* v.ast.SumType */) { if (!(Array_v__ast__Type_contains((*left_sym->info._v__ast__SumType).variants, typ)) && !(Array_v__ast__Type_contains((*left_sym->info._v__ast__SumType).variants, v__checker__Checker_unwrap_generic(c, typ)))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = left_sym->name}}, {_S("` has no variant `"), 0xfe10, {.d_s = right_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), right_pos); } } else if ((left_sym->info)._typ == 542 /* v.ast.Interface */) { if (typ_sym->kind != v__ast__Kind__interface && !v__checker__Checker_type_implements(c, typ, left_type, right_pos)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = typ_sym->name}}, {_S("` doesn't implement interface `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), right_pos); } } } node->promoted_type = _const_v__ast__bool_type; v__ast__Type _t30 = _const_v__ast__bool_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t30; } case v__token__Kind__arrow: { if (left_sym->kind == v__ast__Kind__chan) { v__ast__Chan chan_info = v__ast__TypeSymbol_chan_info(left_sym); v__ast__Type elem_type = chan_info.elem_type; if (!v__checker__Checker_check_types(c, right_type, elem_type)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot push `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, right_type)}}, {_S("` on `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), right_pos); } if (chan_info.is_mut) { v__checker__Checker_fail_if_immutable(c, &node->right); } if (v__ast__Type_is_ptr(elem_type) && !v__ast__Type_is_ptr(right_type)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot push non-reference `"), 0xfe10, {.d_s = right_sym->name}}, {_S("` on `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), right_pos); } else if (v__ast__Type_is_ptr(right_type) != v__ast__Type_is_ptr(elem_type)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot push `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, right_type)}}, {_S("` on `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), right_pos); } v__checker__Checker_stmts_ending_with_expression(c, &node->or_block.stmts, c->expected_or_type); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot push on non-channel `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), left_pos); } v__ast__Type _t31 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t31; } case v__token__Kind__and: case v__token__Kind__logical_or: { if (!c->pref->translated && !c->file->is_translated) { if (left_final_sym->kind != v__ast__Kind__bool) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("left operand for `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` is not a boolean"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); } if (right_final_sym->kind != v__ast__Kind__bool) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("right operand for `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` is not a boolean"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->right)); } } if ((node->left)._typ == 362 /* v.ast.InfixExpr */) { if ((*node->left._v__ast__InfixExpr).op != node->op && ((*node->left._v__ast__InfixExpr).op == v__token__Kind__logical_or || (*node->left._v__ast__InfixExpr).op == v__token__Kind__and)) { v__checker__Checker_error(c, _S("ambiguous boolean expression. use `()` to ensure correct order of operations"), node->pos); } } break; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_interface: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { break; } } } if (!c->is_builtin_mod && (node->op == v__token__Kind__amp || node->op == v__token__Kind__left_shift || node->op == v__token__Kind__right_shift)) { if ((node->left)._typ == 362 /* v.ast.InfixExpr */) { if ((*node->left._v__ast__InfixExpr).op != node->op && ((*node->left._v__ast__InfixExpr).op == v__token__Kind__amp || (*node->left._v__ast__InfixExpr).op == v__token__Kind__left_shift || (*node->left._v__ast__InfixExpr).op == v__token__Kind__right_shift)) { v__checker__Checker_note(c, _S("ambiguous expression. use `()` to ensure correct order of operations"), node->pos); } } } if (left_type == _const_v__ast__bool_type && !(node->op == v__token__Kind__eq || node->op == v__token__Kind__ne || node->op == v__token__Kind__logical_or || node->op == v__token__Kind__and)) { v__checker__Checker_error(c, _S("bool types only have the following operators defined: `==`, `!=`, `||`, and `&&`"), node->pos); } else if (left_type == _const_v__ast__string_type && !(node->op == v__token__Kind__plus || node->op == v__token__Kind__eq || node->op == v__token__Kind__ne || node->op == v__token__Kind__lt || node->op == v__token__Kind__gt || node->op == v__token__Kind__le || node->op == v__token__Kind__ge)) { v__checker__Checker_error(c, _S("string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`"), node->pos); } else if (!eq_ne && (left_sym->info)._typ == 548 /* v.ast.Enum */ && (right_sym->info)._typ == 548 /* v.ast.Enum */) { if ((*left_sym->info._v__ast__Enum).is_flag && (*right_sym->info._v__ast__Enum).is_flag) { if (!(node->op == v__token__Kind__pipe || node->op == v__token__Kind__amp || node->op == v__token__Kind__xor || node->op == v__token__Kind__bit_not)) { v__checker__Checker_error(c, _S("only `==`, `!=`, `|`, `&`, `^` and `~` are defined on `@[flag]` tagged `enum`, use an explicit cast to `int` if needed"), node->pos); } } else if (!c->pref->translated && !c->file->is_translated && !v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic) && !v__ast__Type_has_flag(right_type, v__ast__TypeFlag__generic)) { v__checker__Checker_error(c, _S("only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed"), node->pos); } } if (v__ast__Table_type_kind(c->table, left_type) == v__ast__Kind__sum_type && !eq_ne) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use operator `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` with `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } else if (v__ast__Table_type_kind(c->table, right_type) == v__ast__Kind__sum_type && !eq_ne) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use operator `"), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S("` with `"), 0xfe10, {.d_s = right_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } bool left_is_option = v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option); bool right_is_option = v__ast__Type_has_flag(right_type, v__ast__TypeFlag__option); if (left_is_option || right_is_option) { v__token__Pos opt_infix_pos = (left_is_option ? (left_pos) : (right_pos)); if ((!((node->left)._typ == 358 /* v.ast.Ident */ || (node->left)._typ == 361 /* v.ast.IndexExpr */ || (node->left)._typ == 379 /* v.ast.SelectorExpr */ || (node->left)._typ == 350 /* v.ast.ComptimeSelector */) || ((node->op == v__token__Kind__eq || node->op == v__token__Kind__ne) && !right_is_option) || (node->op == v__token__Kind__lt || node->op == v__token__Kind__gt || node->op == v__token__Kind__le || node->op == v__token__Kind__ge)) && right_sym->kind != v__ast__Kind__none && !c->inside_sql) { v__checker__Checker_error(c, _S("unwrapped Option cannot be used in an infix expression"), opt_infix_pos); } } bool left_is_result = v__ast__Type_has_flag(left_type, v__ast__TypeFlag__result); bool right_is_result = v__ast__Type_has_flag(right_type, v__ast__TypeFlag__result); if (left_is_result || right_is_result) { v__token__Pos opt_infix_pos = (left_is_result ? (left_pos) : (right_pos)); v__checker__Checker_error(c, _S("unwrapped Result cannot be used in an infix expression"), opt_infix_pos); } if ((node->left)._typ != 349 /* v.ast.ComptimeCall */ && (node->right)._typ != 349 /* v.ast.ComptimeCall */) { if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic)) { left_type = v__checker__Checker_unwrap_generic(c, left_type); left_sym = v__ast__Table_sym(c->table, left_type); } if (v__ast__Type_has_flag(right_type, v__ast__TypeFlag__generic)) { right_type = v__checker__Checker_unwrap_generic(c, right_type); right_sym = v__ast__Table_sym(c->table, right_type); } if (!(v__checker__Checker_symmetric_check(c, left_type, right_type) && v__checker__Checker_symmetric_check(c, right_type, left_type)) && !c->pref->translated && !c->file->is_translated && !v__ast__Expr_is_auto_deref_var(node->left) && !v__ast__Expr_is_auto_deref_var(node->right)) { if (left_type == _const_v__ast__void_type || right_type == _const_v__ast__void_type) { v__ast__Type _t32 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t32; } if (v__ast__Type_nr_muls(left_type) > 0 && v__ast__Type_is_int(right_type)) { node->promoted_type = return_type; v__ast__Type _t33 = return_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t33; } if ((node->right)._typ == 371 /* v.ast.None */ && left_is_option) { v__ast__Type _t34 = _const_v__ast__bool_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t34; } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("infix expr: cannot use `"), 0xfe10, {.d_s = right_sym->name}}, {_S("` (right expression) as `"), 0xfe10, {.d_s = left_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), left_right_pos); } else if (v__ast__Type_is_ptr(left_type)) { bool for_ptr_op = v__ast__Table_type_is_for_pointer_arithmetic(c->table, left_type); if (left_sym->language == v__ast__Language__v && !c->pref->translated && !c->inside_unsafe && !for_ptr_op && v__ast__Type_is_int(right_type)) { string sugg = _S(" (you can use it inside an `unsafe` block)"); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("infix expr: cannot use `"), 0xfe10, {.d_s = right_sym->name}}, {_S("` (right expression) as `"), 0xfe10, {.d_s = left_sym->name}}, {_S("` "), 0xfe10, {.d_s = sugg}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); } } } if (node->op == v__token__Kind__plus && c->pref->warn_about_allocs && left_type == 21 && right_type == 21) { v__checker__Checker_warn_alloc(c, _S("string concatenation"), node->pos); } node->promoted_type = (v__token__Kind_is_relational(node->op) ? (_const_v__ast__bool_type) : (return_type)); v__ast__Type _t35 = node->promoted_type; // Defer begin if (v__checker__Checker_infix_expr_defer_2) { node->left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = right_type,.expr = node->left,.typname = v__ast__Table_get_type_name(c->table, right_type),.expr_type = left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_1) { node->right = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = left_type,.expr = node->right,.typname = v__ast__Table_get_type_name(c->table, left_type),.expr_type = right_type,.has_arg = 0,.pos = v__ast__Expr_pos(node->right),})))); } // Defer end // Defer begin if (v__checker__Checker_infix_expr_defer_0) { c->expected_type = former_expected_type; } // Defer end return _t35; } VV_LOC void v__checker__Checker_check_div_mod_by_zero(v__checker__Checker* c, v__ast__Expr expr, v__token__Kind op_kind) { if (expr._typ == 356 /* v.ast.FloatLiteral */) { if (string_f64((*expr._v__ast__FloatLiteral).val) == ((f64)(0.0))) { string oper = (op_kind == v__token__Kind__div ? (_S("division")) : (_S("modulo"))); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = oper}}, {_S(" by zero"), 0, { .d_c = 0 }}})), (*expr._v__ast__FloatLiteral).pos); } } else if (expr._typ == 363 /* v.ast.IntegerLiteral */) { if (string_int((*expr._v__ast__IntegerLiteral).val) == 0) { string oper = (op_kind == v__token__Kind__div ? (_S("division")) : (_S("modulo"))); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = oper}}, {_S(" by zero"), 0, { .d_c = 0 }}})), (*expr._v__ast__IntegerLiteral).pos); } } else if (expr._typ == 345 /* v.ast.CastExpr */) { v__checker__Checker_check_div_mod_by_zero(c, (*expr._v__ast__CastExpr).expr, op_kind); } else { } } VV_LOC void v__checker__Checker_check_duplicated_items(v__checker__Checker* c, v__ast__ArrayInit* node) { Array_string unique_items = __new_array_with_default(0, node->exprs.len, sizeof(string), 0); for (int _t1 = 0; _t1 < node->exprs.len; ++_t1) { v__ast__Expr item = ((v__ast__Expr*)node->exprs.data)[_t1]; string item_str = v__ast__Expr_str(&item); if ((Array_string_contains(unique_items, item_str))) { v__checker__Checker_note(c, str_intp(2, _MOV((StrIntpData[]){{_S("item `"), 0xfe10, {.d_s = item_str}}, {_S("` is duplicated in the list"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(item)); } else { array_push((array*)&unique_items, _MOV((string[]){ string_clone(item_str) })); } } } VV_LOC v__ast__Type v__checker__Checker_check_like_operator(v__checker__Checker* c, v__ast__InfixExpr* node) { if ((node->left)._typ != 358 /* v.ast.Ident */ || !v__ast__Type_is_string(node->left_type)) { v__checker__Checker_error(c, _S("the left operand of the `like` operator must be an identifier with a string type"), v__ast__Expr_pos(node->left)); } if (!v__ast__Type_is_string(node->right_type)) { v__checker__Checker_error(c, _S("the right operand of the `like` operator must be a string type"), v__ast__Expr_pos(node->right)); } return node->promoted_type; } VV_LOC void v__checker__Checker_invalid_operator_error(v__checker__Checker* c, v__token__Kind op, v__ast__Type left_type, v__ast__Type right_type, v__token__Pos pos) { string left_name = v__ast__Table_type_to_str(c->table, left_type); string right_name = v__ast__Table_type_to_str(c->table, right_type); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("invalid operator `"), 0xfe10, {.d_s = v__token__Kind_str(op)}}, {_S("` to `"), 0xfe10, {.d_s = left_name}}, {_S("` and `"), 0xfe10, {.d_s = right_name}}, {_S("`"), 0, { .d_c = 0 }}})), pos); } VV_LOC void v__checker__Checker_autocast_in_if_conds(v__checker__Checker* c, v__ast__Expr* right, v__ast__Expr from_expr, v__ast__Type from_type, v__ast__Type to_type) { if (string__eq(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(right)}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_str(&from_expr))) { *right = v__ast__AsCast_to_sumtype_v__ast__Expr(ADDR(v__ast__AsCast, (((v__ast__AsCast){.typ = to_type,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.expr = from_expr,.expr_type = from_type,})))); return; } if (right->_typ == 379 /* v.ast.SelectorExpr */) { if (string__eq(v__ast__Expr_str(&(*right->_v__ast__SelectorExpr).expr), v__ast__Expr_str(&from_expr))) { (*right->_v__ast__SelectorExpr).expr = v__ast__ParExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__ParExpr, (((v__ast__ParExpr){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.expr = v__ast__AsCast_to_sumtype_v__ast__Expr(ADDR(v__ast__AsCast, (((v__ast__AsCast){.typ = to_type,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.expr = from_expr,.expr_type = from_type,})))),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),})))); } else { v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__SelectorExpr).expr, from_expr, from_type, to_type); } } else if (right->_typ == 374 /* v.ast.ParExpr */) { v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__ParExpr).expr, from_expr, from_type, to_type); } else if (right->_typ == 339 /* v.ast.AsCast */) { if ((*right->_v__ast__AsCast).typ != to_type) { v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__AsCast).expr, from_expr, from_type, to_type); } } else if (right->_typ == 376 /* v.ast.PrefixExpr */) { v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__PrefixExpr).right, from_expr, from_type, to_type); } else if (right->_typ == 344 /* v.ast.CallExpr */) { if (string__eq(v__ast__Expr_str(&(*right->_v__ast__CallExpr).left), v__ast__Expr_str(&from_expr)) && v__ast__TypeSymbol_has_method_with_generic_parent(v__ast__Table_sym(c->table, to_type), (*right->_v__ast__CallExpr).name)) { (*right->_v__ast__CallExpr).left = v__ast__ParExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__ParExpr, (((v__ast__ParExpr){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.expr = v__ast__AsCast_to_sumtype_v__ast__Expr(ADDR(v__ast__AsCast, (((v__ast__AsCast){.typ = to_type,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.expr = from_expr,.expr_type = from_type,})))),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),})))); } if (((*right->_v__ast__CallExpr).left)._typ != 358 /* v.ast.Ident */) { v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__CallExpr).left, from_expr, from_type, to_type); } for (int _t1 = 0; _t1 < (*right->_v__ast__CallExpr).args.len; ++_t1) { v__ast__CallArg* arg = ((v__ast__CallArg*)(*right->_v__ast__CallExpr).args.data) + _t1; v__checker__Checker_autocast_in_if_conds(c, &arg->expr, from_expr, from_type, to_type); } } else if (right->_typ == 362 /* v.ast.InfixExpr */) { v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__InfixExpr).left, from_expr, from_type, to_type); v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__InfixExpr).right, from_expr, from_type, to_type); } else if (right->_typ == 361 /* v.ast.IndexExpr */) { v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__IndexExpr).left, from_expr, from_type, to_type); v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__IndexExpr).index, from_expr, from_type, to_type); } else if (right->_typ == 377 /* v.ast.RangeExpr */) { v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__RangeExpr).low, from_expr, from_type, to_type); v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__RangeExpr).high, from_expr, from_type, to_type); } else if (right->_typ == 383 /* v.ast.StringInterLiteral */) { for (int _t2 = 0; _t2 < (*right->_v__ast__StringInterLiteral).exprs.len; ++_t2) { v__ast__Expr* expr = ((v__ast__Expr*)(*right->_v__ast__StringInterLiteral).exprs.data) + _t2; v__checker__Checker_autocast_in_if_conds(c, expr, from_expr, from_type, to_type); } } else if (right->_typ == 388 /* v.ast.UnsafeExpr */) { v__checker__Checker_autocast_in_if_conds(c, &(*right->_v__ast__UnsafeExpr).expr, from_expr, from_type, to_type); } else { } } VV_LOC bool v__checker__Checker_check_sort_external_variable_access(v__checker__Checker* c, v__ast__Expr node) { if (node._typ == 362 /* v.ast.InfixExpr */) { if (!v__checker__Checker_check_sort_external_variable_access(c, (*node._v__ast__InfixExpr).left)) { return false; } if (!v__checker__Checker_check_sort_external_variable_access(c, (*node._v__ast__InfixExpr).right)) { return false; } } else if (node._typ == 358 /* v.ast.Ident */) { if (!(fast_string_eq((*node._v__ast__Ident).name, _S("a")) || fast_string_eq((*node._v__ast__Ident).name, _S("b")))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("can not access external variable `"), 0xfe10, {.d_s = (*node._v__ast__Ident).name}}, {_S("`"), 0, { .d_c = 0 }}})), (*node._v__ast__Ident).pos); return false; } } else if (node._typ == 344 /* v.ast.CallExpr */) { return v__checker__Checker_check_sort_external_variable_access(c, (*node._v__ast__CallExpr).left); } else if (node._typ == 379 /* v.ast.SelectorExpr */) { return v__checker__Checker_check_sort_external_variable_access(c, (*node._v__ast__SelectorExpr).expr); } else if (node._typ == 361 /* v.ast.IndexExpr */) { if (!v__checker__Checker_check_sort_external_variable_access(c, (*node._v__ast__IndexExpr).left)) { return false; } if (!v__checker__Checker_check_sort_external_variable_access(c, (*node._v__ast__IndexExpr).index)) { return false; } } else { return true; } return true; } VV_LOC void v__checker__Checker_interface_decl(v__checker__Checker* c, v__ast__InterfaceDecl* node) { v__checker__Checker_check_valid_pascal_case(c, node->name, _S("interface name"), node->pos); v__ast__TypeSymbol* decl_sym = v__ast__Table_sym(c->table, node->typ); bool is_js = node->language == v__ast__Language__js; if ((decl_sym->info)._typ == 542 /* v.ast.Interface */) { bool has_generic_types = false; if (node->embeds.len > 0) { Array_v__ast__InterfaceEmbedding all_embeds = v__checker__Checker_expand_iface_embeds(c, node, 0, node->embeds); node->embeds = all_embeds; Map_string_int emnames = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_bool emnames_ds = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_bool emnames_ds_info = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_int efnames = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_bool efnames_ds_info = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int i = 0; i < node->methods.len; ++i) { v__ast__FnDecl m = ((v__ast__FnDecl*)node->methods.data)[i]; map_set(&emnames, &(string[]){m.name}, &(int[]) { i }); map_set(&emnames_ds, &(string[]){m.name}, &(bool[]) { true }); map_set(&emnames_ds_info, &(string[]){m.name}, &(bool[]) { true }); } for (int i = 0; i < node->fields.len; ++i) { v__ast__StructField f = ((v__ast__StructField*)node->fields.data)[i]; map_set(&efnames, &(string[]){f.name}, &(int[]) { i }); map_set(&efnames_ds_info, &(string[]){f.name}, &(bool[]) { true }); } for (int _t1 = 0; _t1 < all_embeds.len; ++_t1) { v__ast__InterfaceEmbedding embed = ((v__ast__InterfaceEmbedding*)all_embeds.data)[_t1]; v__ast__TypeSymbol* isym = v__ast__Table_sym(c->table, embed.typ); if (v__ast__Type_has_flag(embed.typ, v__ast__TypeFlag__generic)) { has_generic_types = true; } if (isym->kind != v__ast__Kind__interface) { v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("interface `"), 0xfe10, {.d_s = node->name}}, {_S("` tries to embed `"), 0xfe10, {.d_s = isym->name}}, {_S("`, but `"), 0xfe10, {.d_s = isym->name}}, {_S("` is not an interface, but `"), 0xfe10, {.d_s = v__ast__Kind_str(isym->kind)}}, {_S("`"), 0, { .d_c = 0 }}})), embed.pos); continue; } if (node->generic_types.len > 0 && v__ast__Type_has_flag(embed.typ, v__ast__TypeFlag__generic)) { Array_string embed_generic_names = v__ast__Table_generic_type_names(c->table, embed.typ); Array_string _t2 = {0}; Array_v__ast__Type _t2_orig = node->generic_types; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Type it = ((v__ast__Type*) _t2_orig.data)[_t4]; string _t3 = v__ast__Table_type_to_str(c->table, it); array_push((array*)&_t2, &_t3); } Array_string node_generic_names =_t2; for (int _t5 = 0; _t5 < embed_generic_names.len; ++_t5) { string name = ((string*)embed_generic_names.data)[_t5]; if (!(Array_string_contains(node_generic_names, name))) { string interface_generic_names = Array_string_join(node_generic_names, _S(", ")); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("generic type name `"), 0xfe10, {.d_s = name}}, {_S("` is not mentioned in interface `"), 0xfe10, {.d_s = node->name}}, {_S("<"), 0xfe10, {.d_s = interface_generic_names}}, {_S(">`"), 0, { .d_c = 0 }}})), embed.pos); } } } v__ast__Interface isym_info = *(v__ast__Interface*)__as_cast((isym->info)._v__ast__Interface,(isym->info)._typ, 542); for (int _t6 = 0; _t6 < isym_info.fields.len; ++_t6) { v__ast__StructField f = ((v__ast__StructField*)isym_info.fields.data)[_t6]; if (!(*(bool*)map_get(ADDR(map, efnames_ds_info), &(string[]){f.name}, &(bool[]){ 0 }))) { map_set(&efnames_ds_info, &(string[]){f.name}, &(bool[]) { true }); array_push((array*)&(*decl_sym->info._v__ast__Interface).fields, _MOV((v__ast__StructField[]){ f })); } } for (int _t8 = 0; _t8 < isym_info.methods.len; ++_t8) { v__ast__Fn m = ((v__ast__Fn*)isym_info.methods.data)[_t8]; if (!(*(bool*)map_get(ADDR(map, emnames_ds_info), &(string[]){m.name}, &(bool[]){ 0 }))) { map_set(&emnames_ds_info, &(string[]){m.name}, &(bool[]) { true }); array_push((array*)&(*decl_sym->info._v__ast__Interface).methods, _MOV((v__ast__Fn[]){ v__ast__Fn_new_method_with_receiver_type(&m, node->typ) })); } } for (int _t10 = 0; _t10 < isym->methods.len; ++_t10) { v__ast__Fn m = ((v__ast__Fn*)isym->methods.data)[_t10]; if (!(*(bool*)map_get(ADDR(map, emnames_ds), &(string[]){m.name}, &(bool[]){ 0 }))) { map_set(&emnames_ds, &(string[]){m.name}, &(bool[]) { true }); array_push((array*)&decl_sym->methods, _MOV((v__ast__Fn[]){ v__ast__Fn_new_method_with_receiver_type(&m, node->typ) })); } } v__ast__InterfaceDecl* _t13 = (v__ast__InterfaceDecl*)(map_get_check(ADDR(map, c->table->interfaces), &(int[]){embed.typ})); _option_v__ast__InterfaceDecl _t12 = {0}; if (_t13) { *((v__ast__InterfaceDecl*)&_t12.data) = *((v__ast__InterfaceDecl*)_t13); } else { _t12.state = 2; _t12.err = _v_error(_S("map key does not exist")); } if (_t12.state == 0) { v__ast__InterfaceDecl embed_decl = (*(v__ast__InterfaceDecl*)_t12.data); for (int _t14 = 0; _t14 < embed_decl.fields.len; ++_t14) { v__ast__StructField f = ((v__ast__StructField*)embed_decl.fields.data)[_t14]; if (_IN_MAP(ADDR(string, f.name), ADDR(map, efnames))) { v__ast__StructField ifield = (*(v__ast__StructField*)array_get(node->fields, (*(int*)map_get(ADDR(map, efnames), &(string[]){f.name}, &(int[]){ 0 })))); _result_v__ast__StructField _t15; if (_t15 = v__ast__Table_find_field_with_embeds(c->table, isym, f.name), !_t15.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t15.data; if (ifield.typ != field.typ) { string exp = v__ast__Table_type_to_str(c->table, ifield.typ); string got = v__ast__Table_type_to_str(c->table, field.typ); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("embedded interface `"), 0xfe10, {.d_s = embed_decl.name}}, {_S("` conflicts existing field: `"), 0xfe10, {.d_s = ifield.name}}, {_S("`, expecting type: `"), 0xfe10, {.d_s = exp}}, {_S("`, got type: `"), 0xfe10, {.d_s = got}}, {_S("`"), 0, { .d_c = 0 }}})), ifield.pos); } } } else { map_set(&efnames, &(string[]){f.name}, &(int[]) { node->fields.len }); array_push((array*)&node->fields, _MOV((v__ast__StructField[]){ f })); } } for (int _t17 = 0; _t17 < embed_decl.methods.len; ++_t17) { v__ast__FnDecl m = ((v__ast__FnDecl*)embed_decl.methods.data)[_t17]; if (_IN_MAP(ADDR(string, m.name), ADDR(map, emnames))) { v__ast__FnDecl imethod = (*(v__ast__FnDecl*)array_get(node->methods, (*(int*)map_get(ADDR(map, emnames), &(string[]){m.name}, &(int[]){ 0 })))); _option_v__ast__Fn _t18; if (_t18 = v__ast__TypeSymbol_find_method(decl_sym, imethod.name), _t18.state == 0) { v__ast__Fn em_fn = *(v__ast__Fn*)_t18.data; _option_v__ast__Fn _t19; if (_t19 = v__ast__TypeSymbol_find_method(isym, m.name), _t19.state == 0) { v__ast__Fn m_fn = *(v__ast__Fn*)_t19.data; string msg = v__ast__Table_is_same_method(c->table, (voidptr)&m_fn, (voidptr)&em_fn); if (msg.len > 0) { string em_sig = v__ast__Table_fn_signature(c->table, (voidptr)&em_fn, ((v__ast__FnSignatureOpts){.skip_receiver = true,.type_only = 0,})); string m_sig = v__ast__Table_fn_signature(c->table, (voidptr)&m_fn, ((v__ast__FnSignatureOpts){.skip_receiver = true,.type_only = 0,})); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("embedded interface `"), 0xfe10, {.d_s = embed_decl.name}}, {_S("` causes conflict: "), 0xfe10, {.d_s = msg}}, {_S(", for interface method `"), 0xfe10, {.d_s = em_sig}}, {_S("` vs `"), 0xfe10, {.d_s = m_sig}}, {_S("`"), 0, { .d_c = 0 }}})), imethod.pos); } } } } else { map_set(&emnames, &(string[]){m.name}, &(int[]) { node->methods.len }); v__ast__FnDecl new_method = v__ast__FnDecl_new_method_with_receiver_type(&m, node->typ); new_method.pos = embed.pos; array_push((array*)&node->methods, _MOV((v__ast__FnDecl[]){ new_method })); } } } } } for (int i = 0; i < node->methods.len; ++i) { v__ast__FnDecl method = ((v__ast__FnDecl*)node->methods.data)[i]; if (node->language == v__ast__Language__v) { v__checker__Checker_check_valid_snake_case(c, method.name, _S("method name"), method.pos); } if (!v__checker__Checker_ensure_type_exists(c, method.return_type, method.return_type_pos)) { continue; } if (is_js) { v__ast__TypeSymbol* mtyp = v__ast__Table_sym(c->table, method.return_type); if (!v__ast__TypeSymbol_is_js_compatible(mtyp)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("method "), 0xfe10, {.d_s = method.name}}, {_S(" returns non JS type"), 0, { .d_c = 0 }}})), method.pos); } } if (v__ast__Type_has_flag(method.return_type, v__ast__TypeFlag__generic)) { has_generic_types = true; if (node->generic_types.len > 0) { Array_string method_generic_names = v__ast__Table_generic_type_names(c->table, method.return_type); Array_string _t21 = {0}; Array_v__ast__Type _t21_orig = node->generic_types; int _t21_len = _t21_orig.len; _t21 = __new_array(0, _t21_len, sizeof(string)); for (int _t23 = 0; _t23 < _t21_len; ++_t23) { v__ast__Type it = ((v__ast__Type*) _t21_orig.data)[_t23]; string _t22 = v__ast__Table_type_to_str(c->table, it); array_push((array*)&_t21, &_t22); } Array_string node_generic_names =_t21; for (int _t24 = 0; _t24 < method_generic_names.len; ++_t24) { string name = ((string*)method_generic_names.data)[_t24]; if (!(Array_string_contains(node_generic_names, name))) { string interface_generic_names = Array_string_join(node_generic_names, _S(", ")); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("generic type name `"), 0xfe10, {.d_s = name}}, {_S("` is not mentioned in interface `"), 0xfe10, {.d_s = node->name}}, {_S("<"), 0xfe10, {.d_s = interface_generic_names}}, {_S(">`"), 0, { .d_c = 0 }}})), method.return_type_pos); } } } } else if (!v__ast__Type_has_option_or_result(method.return_type)) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, method.return_type); if ((ret_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && !(*(v__ast__ArrayFixed*)__as_cast((ret_sym->info)._v__ast__ArrayFixed,(ret_sym->info)._typ, 549)).is_fn_ret) { v__checker__Checker_cast_to_fixed_array_ret(c, method.return_type, *ret_sym); } else if ((ret_sym->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(c->table, (*ret_sym->info._v__ast__Alias).parent_type); if ((parent_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && !(*(v__ast__ArrayFixed*)__as_cast((parent_sym->info)._v__ast__ArrayFixed,(parent_sym->info)._typ, 549)).is_fn_ret) { v__checker__Checker_cast_to_fixed_array_ret(c, (*ret_sym->info._v__ast__Alias).parent_type, *parent_sym); } } } for (int j = 0; j < method.params.len; ++j) { v__ast__Param param = ((v__ast__Param*)method.params.data)[j]; if (j == 0 && is_js) { continue; } if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { has_generic_types = true; } if (!v__checker__Checker_ensure_type_exists(c, param.typ, param.pos)) { continue; } if (v__token__KeywordsMatcherTrie_matches(&_const_v__checker__reserved_type_names_chk, param.name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid use of reserved type `"), 0xfe10, {.d_s = param.name}}, {_S("` as a parameter name"), 0, { .d_c = 0 }}})), param.pos); } if (node->generic_types.len > 0 && v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { Array_string method_generic_names = v__ast__Table_generic_type_names(c->table, param.typ); Array_string _t25 = {0}; Array_v__ast__Type _t25_orig = node->generic_types; int _t25_len = _t25_orig.len; _t25 = __new_array(0, _t25_len, sizeof(string)); for (int _t27 = 0; _t27 < _t25_len; ++_t27) { v__ast__Type it = ((v__ast__Type*) _t25_orig.data)[_t27]; string _t26 = v__ast__Table_type_to_str(c->table, it); array_push((array*)&_t25, &_t26); } Array_string node_generic_names =_t25; for (int _t28 = 0; _t28 < method_generic_names.len; ++_t28) { string name = ((string*)method_generic_names.data)[_t28]; if (!(Array_string_contains(node_generic_names, name))) { string interface_generic_names = Array_string_join(node_generic_names, _S(", ")); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("generic type name `"), 0xfe10, {.d_s = name}}, {_S("` is not mentioned in interface `"), 0xfe10, {.d_s = node->name}}, {_S("<"), 0xfe10, {.d_s = interface_generic_names}}, {_S(">`"), 0, { .d_c = 0 }}})), param.type_pos); } } } if (is_js) { v__ast__TypeSymbol* ptyp = v__ast__Table_sym(c->table, param.typ); if (!v__ast__TypeSymbol_is_js_compatible(ptyp) && !(j == (int)(method.params.len - 1) && method.is_variadic)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("method `"), 0xfe10, {.d_s = method.name}}, {_S("` accepts non JS type as parameter"), 0, { .d_c = 0 }}})), method.pos); } } } for (int _t29 = 0; _t29 < node->fields.len; ++_t29) { v__ast__StructField field = ((v__ast__StructField*)node->fields.data)[_t29]; v__ast__TypeSymbol* field_sym = v__ast__Table_sym(c->table, field.typ); if (string__eq(field.name, method.name) && field_sym->kind == v__ast__Kind__function) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("type `"), 0xfe10, {.d_s = decl_sym->name}}, {_S("` has both field and method named `"), 0xfe10, {.d_s = method.name}}, {_S("`"), 0, { .d_c = 0 }}})), method.pos); } } for (int j = 0; j < i; ++j) { if (string__eq(method.name, (*(v__ast__FnDecl*)array_get(node->methods, j)).name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate method name `"), 0xfe10, {.d_s = method.name}}, {_S("`"), 0, { .d_c = 0 }}})), method.pos); } } } for (int i = 0; i < node->fields.len; ++i) { v__ast__StructField field = ((v__ast__StructField*)node->fields.data)[i]; if (node->language == v__ast__Language__v) { v__checker__Checker_check_valid_snake_case(c, field.name, _S("field name"), field.pos); } if (!v__checker__Checker_ensure_type_exists(c, field.typ, field.pos)) { continue; } if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__generic)) { has_generic_types = true; } if (is_js) { v__ast__TypeSymbol* tsym = v__ast__Table_sym(c->table, field.typ); if (!v__ast__TypeSymbol_is_js_compatible(tsym)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = field.name}}, {_S("` uses non JS type"), 0, { .d_c = 0 }}})), field.pos); } } if (field.typ == node->typ && node->language != v__ast__Language__js) { v__checker__Checker_error(c, _S("recursive interface fields are not allowed because they cannot be initialised"), field.type_pos); } for (int j = 0; j < i; ++j) { if (string__eq(field.name, (*(v__ast__StructField*)array_get(node->fields, j)).name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("field name `"), 0xfe10, {.d_s = field.name}}, {_S("` duplicate"), 0, { .d_c = 0 }}})), field.pos); } } } if (node->generic_types.len == 0 && has_generic_types) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic interface `"), 0xfe10, {.d_s = node->name}}, {_S("` declaration must specify the generic type names, e.g. "), 0xfe10, {.d_s = node->name}}, {_S("[T]"), 0, { .d_c = 0 }}})), node->pos); } } } VV_LOC v__ast__Type v__checker__Checker_unwrap_generic_interface(v__checker__Checker* c, v__ast__Type typ, v__ast__Type interface_type, v__token__Pos pos) { v__ast__Type utyp = v__checker__Checker_unwrap_generic(c, typ); v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, utyp); v__ast__TypeSymbol* inter_sym = v__ast__Table_sym(c->table, interface_type); if ((inter_sym->info)._typ == 542 /* v.ast.Interface */) { if ((*inter_sym->info._v__ast__Interface).is_generic) { Array_v__ast__Type inferred_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); Array_string _t1 = {0}; Array_v__ast__Type _t1_orig = (*inter_sym->info._v__ast__Interface).generic_types; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t3]; string _t2 = v__ast__Table_get_type_name(c->table, it); array_push((array*)&_t1, &_t2); } Array_string generic_names =_t1; for (int _t4 = 0; _t4 < generic_names.len; ++_t4) { string gt_name = ((string*)generic_names.data)[_t4]; v__ast__Type inferred_type = _const_v__ast__void_type; for (int _t5 = 0; _t5 < (*inter_sym->info._v__ast__Interface).fields.len; ++_t5) { v__ast__StructField ifield = ((v__ast__StructField*)(*inter_sym->info._v__ast__Interface).fields.data)[_t5]; if (v__ast__Type_has_flag(ifield.typ, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_get_type_name(c->table, ifield.typ), gt_name)) { _result_v__ast__StructField _t6; if (_t6 = v__ast__Table_find_field_with_embeds(c->table, typ_sym, ifield.name), !_t6.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t6.data; inferred_type = field.typ; } } } for (int _t7 = 0; _t7 < (*inter_sym->info._v__ast__Interface).methods.len; ++_t7) { v__ast__Fn imethod = ((v__ast__Fn*)(*inter_sym->info._v__ast__Interface).methods.data)[_t7]; _option_v__ast__Fn _t8 = v__ast__TypeSymbol_find_method_with_generic_parent(typ_sym, imethod.name); if (_t8.state != 0) { IError err = _t8.err; v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("can not find method `"), 0xfe10, {.d_s = imethod.name}}, {_S("` on `"), 0xfe10, {.d_s = typ_sym->name}}, {_S("`, needed for interface: `"), 0xfe10, {.d_s = inter_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), pos); return 0; } v__ast__Fn method = (*(v__ast__Fn*)_t8.data); if (v__ast__Type_has_flag(imethod.return_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* imret_sym = v__ast__Table_sym(c->table, imethod.return_type); v__ast__TypeSymbol* mret_sym = v__ast__Table_sym(c->table, method.return_type); if (method.return_type == _const_v__ast__void_type && imethod.return_type != method.return_type) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("interface method `"), 0xfe10, {.d_s = imethod.name}}, {_S("` returns `"), 0xfe10, {.d_s = imret_sym->name}}, {_S("`, but implementation method `"), 0xfe10, {.d_s = method.name}}, {_S("` returns no value"), 0, { .d_c = 0 }}})), pos); return 0; } if (imethod.return_type == _const_v__ast__void_type && imethod.return_type != method.return_type) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("interface method `"), 0xfe10, {.d_s = imethod.name}}, {_S("` returns no value, but implementation method `"), 0xfe10, {.d_s = method.name}}, {_S("` returns `"), 0xfe10, {.d_s = mret_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), pos); return 0; } if ((imret_sym->info)._typ == 552 /* v.ast.MultiReturn */ && (mret_sym->info)._typ == 552 /* v.ast.MultiReturn */) { for (int i = 0; i < (*imret_sym->info._v__ast__MultiReturn).types.len; ++i) { v__ast__Type mr_typ = ((v__ast__Type*)(*imret_sym->info._v__ast__MultiReturn).types.data)[i]; if (v__ast__Type_has_flag(mr_typ, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_get_type_name(c->table, mr_typ), gt_name)) { inferred_type = (*(v__ast__Type*)array_get((*mret_sym->info._v__ast__MultiReturn).types, i)); } } } else if (string__eq(v__ast__Table_get_type_name(c->table, imethod.return_type), gt_name)) { v__ast__Type ret_typ = method.return_type; if (v__ast__Type_has_flag(imethod.return_type, v__ast__TypeFlag__option)) { ret_typ = v__ast__Type_clear_flag(ret_typ, v__ast__TypeFlag__option); } else if (v__ast__Type_has_flag(imethod.return_type, v__ast__TypeFlag__result)) { ret_typ = v__ast__Type_clear_flag(ret_typ, v__ast__TypeFlag__result); } inferred_type = ret_typ; } else if ((imret_sym->info)._typ == 544 /* v.ast.SumType */ && (mret_sym->info)._typ == 544 /* v.ast.SumType */) { Array_string _t12 = {0}; Array_v__ast__Type _t12_orig = (*imret_sym->info._v__ast__SumType).generic_types; int _t12_len = _t12_orig.len; _t12 = __new_array(0, _t12_len, sizeof(string)); for (int _t14 = 0; _t14 < _t12_len; ++_t14) { v__ast__Type it = ((v__ast__Type*) _t12_orig.data)[_t14]; string _t13 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t12, &_t13); } Array_string im_generic_names =_t12; if ((Array_string_contains(im_generic_names, gt_name)) && (*imret_sym->info._v__ast__SumType).generic_types.len == (*mret_sym->info._v__ast__SumType).concrete_types.len) { int idx = Array_string_index(im_generic_names, gt_name); inferred_type = (*(v__ast__Type*)array_get((*mret_sym->info._v__ast__SumType).concrete_types, idx)); } } else if ((imret_sym->info)._typ == 542 /* v.ast.Interface */ && (mret_sym->info)._typ == 542 /* v.ast.Interface */) { Array_string _t15 = {0}; Array_v__ast__Type _t15_orig = (*imret_sym->info._v__ast__Interface).generic_types; int _t15_len = _t15_orig.len; _t15 = __new_array(0, _t15_len, sizeof(string)); for (int _t17 = 0; _t17 < _t15_len; ++_t17) { v__ast__Type it = ((v__ast__Type*) _t15_orig.data)[_t17]; string _t16 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t15, &_t16); } Array_string im_generic_names =_t15; if ((Array_string_contains(im_generic_names, gt_name)) && (*imret_sym->info._v__ast__Interface).generic_types.len == (*mret_sym->info._v__ast__Interface).concrete_types.len) { int idx = Array_string_index(im_generic_names, gt_name); inferred_type = (*(v__ast__Type*)array_get((*mret_sym->info._v__ast__Interface).concrete_types, idx)); } } else if ((imret_sym->info)._typ == 518 /* v.ast.Struct */ && (mret_sym->info)._typ == 518 /* v.ast.Struct */) { Array_string _t18 = {0}; Array_v__ast__Type _t18_orig = (*imret_sym->info._v__ast__Struct).generic_types; int _t18_len = _t18_orig.len; _t18 = __new_array(0, _t18_len, sizeof(string)); for (int _t20 = 0; _t20 < _t18_len; ++_t20) { v__ast__Type it = ((v__ast__Type*) _t18_orig.data)[_t20]; string _t19 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t18, &_t19); } Array_string im_generic_names =_t18; if ((Array_string_contains(im_generic_names, gt_name)) && (*imret_sym->info._v__ast__Struct).generic_types.len == (*mret_sym->info._v__ast__Struct).concrete_types.len) { int idx = Array_string_index(im_generic_names, gt_name); inferred_type = (*(v__ast__Type*)array_get((*mret_sym->info._v__ast__Struct).concrete_types, idx)); } } } for (int i = 0; i < imethod.params.len; ++i) { v__ast__Param iparam = ((v__ast__Param*)imethod.params.data)[i]; v__ast__Param* _t22 = (v__ast__Param*)(array_get_with_check(method.params, i)); _option_v__ast__Param _t21 = {0}; if (_t22) { *((v__ast__Param*)&_t21.data) = *((v__ast__Param*)_t22); } else { _t21.state = 2; _t21.err = _v_error(_S("array index out of range")); } ; if (_t21.state != 0) { IError err = _t21.err; *(v__ast__Param*) _t21.data = ((v__ast__Param){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_shared = 0,.is_atomic = 0,.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_hidden = 0,.on_newline = 0,.typ = 0,}); } v__ast__Param param = (*(v__ast__Param*)_t21.data); bool need_inferred_type = false; if (!v__ast__Type_has_flag(iparam.typ, v__ast__TypeFlag__generic) && iparam.typ == param.typ && imethod.return_type == method.return_type && string__eq(imethod.name, method.name)) { need_inferred_type = true; } if (v__ast__Type_has_flag(iparam.typ, v__ast__TypeFlag__generic) || need_inferred_type) { v__ast__TypeSymbol* param_sym = v__ast__Table_sym(c->table, iparam.typ); v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(c->table, param.typ); if (string__eq(v__ast__Table_get_type_name(c->table, iparam.typ), gt_name) || need_inferred_type) { inferred_type = param.typ; } else if ((arg_sym->info)._typ == 513 /* v.ast.Array */ && (param_sym->info)._typ == 513 /* v.ast.Array */) { v__ast__Type arg_elem_typ = (*arg_sym->info._v__ast__Array).elem_type; v__ast__Type param_elem_typ = (*param_sym->info._v__ast__Array).elem_type; v__ast__TypeSymbol* arg_elem_sym = v__ast__Table_sym(c->table, arg_elem_typ); v__ast__TypeSymbol* param_elem_sym = v__ast__Table_sym(c->table, param_elem_typ); for (;;) { if ((arg_elem_sym->info)._typ == 513 /* v.ast.Array */ && (param_elem_sym->info)._typ == 513 /* v.ast.Array */) { arg_elem_typ = (*arg_elem_sym->info._v__ast__Array).elem_type; param_elem_typ = (*param_elem_sym->info._v__ast__Array).elem_type; arg_elem_sym = v__ast__Table_sym(c->table, arg_elem_typ); param_elem_sym = v__ast__Table_sym(c->table, param_elem_typ); } else { if (string__eq(param_elem_sym->name, gt_name)) { inferred_type = arg_elem_typ; } break; } } } else if ((arg_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && (param_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { v__ast__Type arg_elem_typ = (*arg_sym->info._v__ast__ArrayFixed).elem_type; v__ast__Type param_elem_typ = (*param_sym->info._v__ast__ArrayFixed).elem_type; v__ast__TypeSymbol* arg_elem_sym = v__ast__Table_sym(c->table, arg_elem_typ); v__ast__TypeSymbol* param_elem_sym = v__ast__Table_sym(c->table, param_elem_typ); for (;;) { if ((arg_elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && (param_elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { arg_elem_typ = (*arg_elem_sym->info._v__ast__ArrayFixed).elem_type; param_elem_typ = (*param_elem_sym->info._v__ast__ArrayFixed).elem_type; arg_elem_sym = v__ast__Table_sym(c->table, arg_elem_typ); param_elem_sym = v__ast__Table_sym(c->table, param_elem_typ); } else { if (string__eq(param_elem_sym->name, gt_name)) { inferred_type = arg_elem_typ; } break; } } } else if ((arg_sym->info)._typ == 514 /* v.ast.Map */ && (param_sym->info)._typ == 514 /* v.ast.Map */) { if (v__ast__Type_has_flag((*param_sym->info._v__ast__Map).key_type, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_sym(c->table, (*param_sym->info._v__ast__Map).key_type)->name, gt_name)) { inferred_type = (*arg_sym->info._v__ast__Map).key_type; } if (v__ast__Type_has_flag((*param_sym->info._v__ast__Map).value_type, v__ast__TypeFlag__generic) && string__eq(v__ast__Table_sym(c->table, (*param_sym->info._v__ast__Map).value_type)->name, gt_name)) { inferred_type = (*arg_sym->info._v__ast__Map).value_type; } } } } } if (inferred_type == _const_v__ast__void_type) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("could not infer generic type `"), 0xfe10, {.d_s = gt_name}}, {_S("` in interface `"), 0xfe10, {.d_s = inter_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), pos); return interface_type; } array_push((array*)&inferred_types, _MOV((v__ast__Type[]){ inferred_type })); } for (int _t25 = 0; _t25 < (*inter_sym->info._v__ast__Interface).methods.len; ++_t25) { v__ast__Fn imethod = ((v__ast__Fn*)(*inter_sym->info._v__ast__Interface).methods.data)[_t25]; string im_fkey = v__ast__Fn_fkey(&imethod); if (!(Array_Array_v__ast__Type_contains((*(Array_Array_v__ast__Type*)map_get(ADDR(map, c->table->fn_generic_types), &(string[]){im_fkey}, &(Array_Array_v__ast__Type[]){ __new_array(0, 0, sizeof(Array_v__ast__Type)) })), inferred_types))) { array_push((array*)&(*(Array_Array_v__ast__Type*)map_get_and_set((map*)&c->table->fn_generic_types, &(string[]){im_fkey}, &(Array_Array_v__ast__Type[]){ __new_array(0, 0, sizeof(Array_v__ast__Type)) })), &inferred_types); } } (*inter_sym->info._v__ast__Interface).concrete_types = inferred_types; return v__ast__Table_unwrap_generic_type(c->table, interface_type, generic_names, (*inter_sym->info._v__ast__Interface).concrete_types); } } return interface_type; } v__ast__Type v__checker__Checker_lambda_expr(v__checker__Checker* c, v__ast__LambdaExpr* node, v__ast__Type exp_typ) { if (node->is_checked) { return node->typ; } if (exp_typ == 0 || exp_typ == _const_v__ast__void_type) { v__checker__Checker_fatal(c, _S("lambda expressions are allowed only in places expecting function callbacks"), node->pos); return _const_v__ast__void_type; } v__ast__TypeSymbol* exp_sym = v__ast__Table_sym(c->table, exp_typ); if (exp_sym->kind != v__ast__Kind__function) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("a lambda expression was used, but `"), 0xfe10, {.d_s = v__ast__Kind_str(exp_sym->kind)}}, {_S("` was expected"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__void_type; } if ((exp_sym->info)._typ == 553 /* v.ast.FnType */) { if (node->params.len != (*exp_sym->info._v__ast__FnType).func.params.len) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("lambda expression has "), 0xfe07, {.d_i32 = node->params.len}}, {_S(" params, but the expected fn callback needs "), 0xfe07, {.d_i32 = (*exp_sym->info._v__ast__FnType).func.params.len}}, {_S(" params"), 0, { .d_c = 0 }}})), node->pos); return _const_v__ast__void_type; } Array_v__ast__Param params = __new_array_with_default(0, 0, sizeof(v__ast__Param), 0); Map_v__ast__Type_bool generic_types = new_map(sizeof(v__ast__Type), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop) ; for (int idx = 0; idx < node->params.len; ++idx) { v__ast__Ident* x = ((v__ast__Ident*)node->params.data) + idx; v__ast__Param eparam = (*(v__ast__Param*)array_get((*exp_sym->info._v__ast__FnType).func.params, idx)); v__ast__Type eparam_type = eparam.typ; v__checker__Checker_lambda_expr_fix_type_of_param(c, node, x, eparam_type); if (v__ast__Type_has_flag(eparam_type, v__ast__TypeFlag__generic)) { map_set(&generic_types, &(v__ast__Type[]){eparam_type}, &(bool[]) { true }); } array_push((array*)¶ms, _MOV((v__ast__Param[]){ ((v__ast__Param){.pos = x->pos,.name = x->name,.is_mut = 0,.is_shared = 0,.is_atomic = 0,.type_pos = x->pos,.is_hidden = 0,.on_newline = 0,.typ = eparam_type,}) })); } bool is_variadic = false; v__ast__Type return_type = (*exp_sym->info._v__ast__FnType).func.return_type; v__token__Pos return_type_pos = node->pos; if (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__generic)) { map_set(&generic_types, &(v__ast__Type[]){return_type}, &(bool[]) { true }); } Array_string generic_names = __new_array_with_default(0, 0, sizeof(string), 0); int _t7 = generic_types.key_values.len; for (int _t6 = 0; _t6 < _t7; ++_t6 ) { int _t8 = generic_types.key_values.len - _t7; _t7 = generic_types.key_values.len; if (_t8 < 0) { _t6 = -1; continue; } if (!DenseArray_has_index(&generic_types.key_values, _t6)) {continue;} v__ast__Type t = *(v__ast__Type*)DenseArray_key(&generic_types.key_values, _t6); Array_string gtnames = v__ast__Table_generic_type_names(c->table, t); for (int _t9 = 0; _t9 < gtnames.len; ++_t9) { string x = ((string*)gtnames.data)[_t9]; if (!(Array_string_contains(generic_names, x))) { array_push((array*)&generic_names, _MOV((string[]){ string_clone(x) })); } } } Array_v__ast__Stmt stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); bool has_return = false; if (v__ast__Type_clear_option_and_result(return_type) == _const_v__ast__void_type) { array_push((array*)&stmts, _MOV((v__ast__Stmt[]){ v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (((v__ast__ExprStmt){.pos = node->pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = node->expr,.is_expr = false,.typ = return_type,})))) })); if ((node->expr)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast((node->expr)._v__ast__CallExpr,(node->expr)._typ, 344)).is_return_used) { (*node->expr._v__ast__CallExpr).is_return_used = false; } } else { array_push((array*)&stmts, _MOV((v__ast__Stmt[]){ v__ast__Return_to_sumtype_v__ast__Stmt(ADDR(v__ast__Return, (((v__ast__Return){.pos = node->pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.exprs = new_array_from_c_array(1, 1, sizeof(v__ast__Expr), _MOV((v__ast__Expr[1]){node->expr})),.types = __new_array(0, 0, sizeof(v__ast__Type)),})))) })); has_return = true; } v__ast__Fn func = ((v__ast__Fn){.is_variadic = is_variadic,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = false,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = return_type,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = params,.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); string name = v__ast__Table_get_anon_fn_name(c->table, c->file->unique_prefix, (voidptr)&func, node->pos.pos); func.name = name; int idx = v__ast__Table_find_or_register_fn_type(c->table, func, true, false); v__ast__Type typ = v__ast__new_type(idx); node->func = ((v__ast__AnonFn*)memdup(&(v__ast__AnonFn){.decl = ((v__ast__FnDecl){ .name = name, .short_name = _S(""), .mod = c->file->mod.name, .is_deprecated = 0, .is_pub = 0, .is_c_variadic = 0, .is_c_extern = 0, .is_variadic = is_variadic, .is_anon = true, .is_noreturn = 0, .is_manualfree = 0, .is_main = 0, .is_test = 0, .is_conditional = 0, .is_exported = 0, .is_keep_alive = 0, .is_unsafe = 0, .is_must_use = 0, .is_markused = 0, .is_file_translated = 0, .receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}), .receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_method = false, .is_static_type_method = 0, .static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .method_idx = 0, .rec_mut = 0, .has_prev_newline = 0, .has_break_line = 0, .rec_share = 0, .language = 0, .file_mode = 0, .no_body = false, .is_builtin = 0, .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .file = c->file->path, .generic_names = generic_names, .is_direct_arr = 0, .attrs = __new_array(0, 0, sizeof(v__ast__Attr)), .ctdefine_idx = -1, .idx = 0, .params = params, .stmts = stmts, .defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)), .trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .return_type = return_type, .return_type_pos = return_type_pos, .has_return = has_return, .should_be_skipped = 0, .ninstances = 0, .has_await = 0, .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .end_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .next_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .source_file = ((void*)0), .scope = node->scope->parent, .label_names = __new_array(0, 0, sizeof(string)), .pos = v__token__Pos_extend(node->pos, node->pos_end), .end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_expand_simple_interpolation = 0, }),.inherited_vars = __new_array(0, 0, sizeof(v__ast__Param)),.typ = typ,.has_gen = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}, sizeof(v__ast__AnonFn))); if (node->func->decl.generic_names.len > 0) { v__ast__Table_register_fn_generic_types(c->table, v__ast__FnDecl_fkey(&node->func->decl)); } v__checker__Checker_anon_fn(c, node->func); } node->is_checked = true; node->typ = exp_typ; return exp_typ; } void v__checker__Checker_lambda_expr_fix_type_of_param(v__checker__Checker* c, v__ast__LambdaExpr* node, v__ast__Ident* pident, v__ast__Type ptype) { _option_v__ast__Var_ptr _t1; if (_t1 = v__ast__Scope_find_var(node->scope, pident->name), _t1.state == 0) { v__ast__Var* v = *(v__ast__Var**)_t1.data; v->is_arg = true; v->typ = ptype; v->is_auto_deref = v__ast__Type_is_ptr(ptype); v->expr = _const_v__ast__empty_expr; if (v__ast__Type_has_flag(ptype, v__ast__TypeFlag__generic)) { v->ct_type_var = v__ast__ComptimeVarKind__generic_param; } } if (pident->kind != v__ast__IdentKind__blank_ident) { v__checker__Checker_ident(c, pident); (*(pident->obj.typ)) = ptype; } } void v__checker__Checker_support_lambda_expr_in_sort(v__checker__Checker* c, v__ast__Type param_type, v__ast__Type return_type, v__ast__LambdaExpr* expr) { v__ast__Fn expected_fn = ((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = return_type,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = new_array_from_c_array(2, 2, sizeof(v__ast__Param), _MOV((v__ast__Param[2]){((v__ast__Param){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = _S("zza"),.is_mut = 0,.is_shared = 0,.is_atomic = 0,.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_hidden = 0,.on_newline = 0,.typ = param_type,}), ((v__ast__Param){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = _S("zzb"),.is_mut = 0,.is_shared = 0,.is_atomic = 0,.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_hidden = 0,.on_newline = 0,.typ = param_type,})})),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); v__ast__Type expected_fn_type = v__ast__new_type(v__ast__Table_find_or_register_fn_type(c->table, expected_fn, true, false)); v__checker__Checker_lambda_expr(c, expr, expected_fn_type); } void v__checker__Checker_support_lambda_expr_one_param(v__checker__Checker* c, v__ast__Type param_type, v__ast__Type return_type, v__ast__LambdaExpr* expr) { v__ast__Fn expected_fn = ((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = (v__ast__Table_final_sym(c->table, return_type)->kind == v__ast__Kind__function ? (_const_v__ast__voidptr_type) : (return_type)),.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = new_array_from_c_array(1, 1, sizeof(v__ast__Param), _MOV((v__ast__Param[1]){((v__ast__Param){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = _S("xx"),.is_mut = 0,.is_shared = 0,.is_atomic = 0,.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_hidden = 0,.on_newline = 0,.typ = (v__ast__Table_final_sym(c->table, param_type)->kind == v__ast__Kind__function ? (_const_v__ast__voidptr_type) : (param_type)),})})),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); int cb_type = v__ast__Table_find_or_register_fn_type(c->table, expected_fn, true, false); v__ast__Type expected_fn_type = v__ast__new_type(cb_type); v__checker__Checker_lambda_expr(c, expr, expected_fn_type); } VV_LOC v__ast__Type v__checker__Checker_match_expr(v__checker__Checker* c, v__ast__MatchExpr* node) { bool v__checker__Checker_match_expr_defer_0 = false; node->is_expr = c->expected_type != _const_v__ast__void_type; node->expected_type = c->expected_type; if ((node->cond)._typ == 374 /* v.ast.ParExpr */ && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_warn(c, _S("unnecessary `()` in `match` condition, use `match expr {` instead of `match (expr) {`."), (*node->cond._v__ast__ParExpr).pos); } if (node->is_expr) { c->expected_expr_type = c->expected_type; v__checker__Checker_match_expr_defer_0 = true; } v__ast__Type cond_type = v__checker__Checker_expr(c, &node->cond); node->cond_type = v__ast__mktyp(cond_type); if (((node->cond)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node->cond)._v__ast__Ident,(node->cond)._typ, 358)).is_mut) || ((node->cond)._typ == 379 /* v.ast.SelectorExpr */ && (*(v__ast__SelectorExpr*)__as_cast((node->cond)._v__ast__SelectorExpr,(node->cond)._typ, 379)).is_mut)) { v__checker__Checker_fail_if_immutable(c, &node->cond); } if (!v__checker__Checker_ensure_type_exists(c, node->cond_type, node->pos)) { v__ast__Type _t1 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_match_expr_defer_0) { c->expected_expr_type = _const_v__ast__void_type; } // Defer end return _t1; } v__checker__Checker_check_expr_option_or_result_call(c, node->cond, cond_type); v__ast__TypeSymbol* cond_type_sym = v__ast__Table_sym(c->table, cond_type); bool cond_is_option = v__ast__Type_has_flag(cond_type, v__ast__TypeFlag__option); node->is_sum_type = (cond_type_sym->kind == v__ast__Kind__interface || cond_type_sym->kind == v__ast__Kind__sum_type); v__checker__Checker_match_exprs(c, node, *cond_type_sym); c->expected_type = cond_type; bool first_iteration = true; v__ast__Type infer_cast_type = _const_v__ast__void_type; bool need_explicit_cast = false; v__ast__Type ret_type = _const_v__ast__void_type; int nbranches_with_return = 0; int nbranches_without_return = 0; bool must_be_option = false; for (int _t2 = 0; _t2 < node->branches.len; ++_t2) { v__ast__MatchBranch* branch = ((v__ast__MatchBranch*)node->branches.data) + _t2; if (node->is_expr) { v__checker__Checker_stmts_ending_with_expression(c, &branch->stmts, c->expected_or_type); } else { v__checker__Checker_stmts(c, &branch->stmts); } c->smartcast_mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); c->smartcast_cond_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (node->is_expr) { if (branch->stmts.len == 0 && ret_type != _const_v__ast__void_type) { v__checker__Checker_error(c, _S("`match` expression requires an expression as the last statement of every branch"), branch->branch_pos); } } bool _t3 = (!branch->is_else && cond_is_option); bool _t4 = false; if (_t3) { Array_v__ast__Expr _t4_orig = branch->exprs; int _t4_len = _t4_orig.len; for (int _t5 = 0; _t5 < _t4_len; ++_t5) { v__ast__Expr it = ((v__ast__Expr*) _t4_orig.data)[_t5]; if ((it)._typ != 371 /* v.ast.None */) { _t4 = true; break; } } } if ( _t3 &&_t4) { v__checker__Checker_error(c, _S("`match` expression with Option type only checks against `none`, to match its value you must unwrap it first `var?`"), branch->pos); } if (cond_type_sym->kind == v__ast__Kind__none) { v__checker__Checker_error(c, _S("`none` cannot be a match condition"), node->pos); } if (branch->stmts.len > 0 && node->is_expr) { v__ast__Stmt stmt = (*(v__ast__Stmt*)array_last(branch->stmts)); if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { c->expected_type = (c->expected_expr_type != _const_v__ast__void_type ? (c->expected_expr_type) : (node->expected_type)); v__ast__Type expr_type = v__checker__Checker_unwrap_generic(c, (((*stmt._v__ast__ExprStmt).expr)._typ == 344 /* v.ast.CallExpr */ ? ((*stmt._v__ast__ExprStmt).typ) : (v__checker__Checker_expr(c, &(*stmt._v__ast__ExprStmt).expr)))); v__ast__Type unwrapped_expected_type = v__checker__Checker_unwrap_generic(c, node->expected_type); must_be_option = must_be_option || expr_type == _const_v__ast__none_type; (*stmt._v__ast__ExprStmt).typ = expr_type; if (first_iteration) { if (v__ast__Type_has_option_or_result(unwrapped_expected_type) || (Array_v__ast__Kind_contains(new_array_from_c_array(2, 2, sizeof(v__ast__Kind), _MOV((v__ast__Kind[2]){v__ast__Kind__sum_type, v__ast__Kind__multi_return})), v__ast__Table_type_kind(c->table, unwrapped_expected_type)))) { v__checker__Checker_check_match_branch_last_stmt(c, (*stmt._v__ast__ExprStmt), unwrapped_expected_type, expr_type); ret_type = node->expected_type; } else { ret_type = expr_type; if (v__ast__Type_is_ptr(expr_type)) { if (((*stmt._v__ast__ExprStmt).expr)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast(((*stmt._v__ast__ExprStmt).expr)._v__ast__Ident,((*stmt._v__ast__ExprStmt).expr)._typ, 358)).obj)._typ == 422 /* v.ast.Var */ && v__ast__Table_is_interface_var(c->table, (*(v__ast__Ident*)__as_cast(((*stmt._v__ast__ExprStmt).expr)._v__ast__Ident,((*stmt._v__ast__ExprStmt).expr)._typ, 358)).obj)) { ret_type = v__ast__Type_deref(expr_type); } else if (((*stmt._v__ast__ExprStmt).expr)._typ == 376 /* v.ast.PrefixExpr */ && ((*(v__ast__PrefixExpr*)__as_cast(((*stmt._v__ast__ExprStmt).expr)._v__ast__PrefixExpr,((*stmt._v__ast__ExprStmt).expr)._typ, 376)).right)._typ == 358 /* v.ast.Ident */) { v__ast__Ident ident = (*(*(*stmt._v__ast__ExprStmt).expr._v__ast__PrefixExpr).right._v__ast__Ident); if ((ident.obj)._typ == 422 /* v.ast.Var */ && v__ast__Table_is_interface_var(c->table, v__ast__Var_to_sumtype_v__ast__ScopeObject((v__ast__Var*)__as_cast((ident.obj)._v__ast__Var,(ident.obj)._typ, 422)))) { ret_type = v__ast__Type_deref(expr_type); } } } c->expected_expr_type = expr_type; } infer_cast_type = (*stmt._v__ast__ExprStmt).typ; if (((*stmt._v__ast__ExprStmt).expr)._typ == 345 /* v.ast.CastExpr */) { need_explicit_cast = true; infer_cast_type = (*(*stmt._v__ast__ExprStmt).expr._v__ast__CastExpr).typ; } } else { if (v__ast__Type_idx(ret_type) != v__ast__Type_idx(expr_type)) { if (v__ast__Type_has_option_or_result(unwrapped_expected_type) && v__ast__Table_sym(c->table, (*stmt._v__ast__ExprStmt).typ)->kind == v__ast__Kind__struct && !v__checker__Checker_check_types(c, expr_type, v__checker__Checker_unwrap_generic(c, ret_type)) && v__checker__Checker_type_implements(c, (*stmt._v__ast__ExprStmt).typ, _const_v__ast__error_type, node->pos)) { (*stmt._v__ast__ExprStmt).expr = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = _const_v__ast__error_type,.expr = (*stmt._v__ast__ExprStmt).expr,.typname = _S("IError"),.expr_type = (*stmt._v__ast__ExprStmt).typ,.has_arg = 0,.pos = node->pos,})))); (*stmt._v__ast__ExprStmt).typ = _const_v__ast__error_type; } else { v__checker__Checker_check_match_branch_last_stmt(c, (*stmt._v__ast__ExprStmt), v__checker__Checker_unwrap_generic(c, ret_type), expr_type); if (v__ast__Type_is_number(ret_type) && v__ast__Type_is_number(expr_type) && !c->inside_return) { ret_type = v__checker__Checker_promote_num(c, ret_type, expr_type); } } } if (must_be_option && ret_type == _const_v__ast__none_type && expr_type != ret_type) { ret_type = v__ast__Type_set_flag(expr_type, v__ast__TypeFlag__option); } if ((*stmt._v__ast__ExprStmt).typ != _const_v__ast__error_type && !v__checker__is_noreturn_callexpr((*stmt._v__ast__ExprStmt).expr)) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, ret_type); v__ast__TypeSymbol* stmt_sym = v__ast__Table_sym(c->table, (*stmt._v__ast__ExprStmt).typ); if (!(ret_sym->kind == v__ast__Kind__sum_type || ret_sym->kind == v__ast__Kind__interface) && (stmt_sym->kind == v__ast__Kind__sum_type || stmt_sym->kind == v__ast__Kind__interface)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("return type mismatch, it should be `"), 0xfe10, {.d_s = ret_sym->name}}, {_S("`, but it is instead `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, expr_type)}}, {_S("`"), 0, { .d_c = 0 }}})), (*stmt._v__ast__ExprStmt).pos); } if (v__ast__Type_nr_muls(ret_type) != v__ast__Type_nr_muls((*stmt._v__ast__ExprStmt).typ) && !(Array_int_contains(new_array_from_c_array(2, 2, sizeof(int), _MOV((int[2]){_const_v__ast__voidptr_type_idx, _const_v__ast__nil_type_idx})), v__ast__Type_idx((*stmt._v__ast__ExprStmt).typ)))) { string type_name = string__plus(string_repeat(_S("&"), v__ast__Type_nr_muls(ret_type)), ret_sym->name); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("return type mismatch, it should be `"), 0xfe10, {.d_s = type_name}}, {_S("`, but it is instead `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, expr_type)}}, {_S("`"), 0, { .d_c = 0 }}})), (*stmt._v__ast__ExprStmt).pos); } } if (!node->is_sum_type) { if (((*stmt._v__ast__ExprStmt).expr)._typ == 345 /* v.ast.CastExpr */) { v__ast__TypeSymbol* expr_typ_sym = v__ast__Table_sym(c->table, (*(*stmt._v__ast__ExprStmt).expr._v__ast__CastExpr).typ); if (need_explicit_cast) { if (infer_cast_type != (*(*stmt._v__ast__ExprStmt).expr._v__ast__CastExpr).typ && !(expr_typ_sym->kind == v__ast__Kind__interface || expr_typ_sym->kind == v__ast__Kind__sum_type)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("the type of the last expression in the first match branch was an explicit `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, infer_cast_type)}}, {_S("`, not `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, (*(*stmt._v__ast__ExprStmt).expr._v__ast__CastExpr).typ)}}, {_S("`"), 0, { .d_c = 0 }}})), (*stmt._v__ast__ExprStmt).pos); } } else { if (infer_cast_type != (*(*stmt._v__ast__ExprStmt).expr._v__ast__CastExpr).typ && !(expr_typ_sym->kind == v__ast__Kind__interface || expr_typ_sym->kind == v__ast__Kind__sum_type) && v__checker__Checker_promote_num(c, (*(*stmt._v__ast__ExprStmt).expr._v__ast__CastExpr).typ, _const_v__ast__int_type) != _const_v__ast__int_type) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("the type of the last expression of the first match branch was `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, infer_cast_type)}}, {_S("`, which is not compatible with `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, (*(*stmt._v__ast__ExprStmt).expr._v__ast__CastExpr).typ)}}, {_S("`"), 0, { .d_c = 0 }}})), (*stmt._v__ast__ExprStmt).pos); } } } else { if (((*stmt._v__ast__ExprStmt).expr)._typ == 363 /* v.ast.IntegerLiteral */) { v__ast__TypeSymbol* cast_type_sym = v__ast__Table_sym(c->table, infer_cast_type); i64 num = string_i64((*(*stmt._v__ast__ExprStmt).expr._v__ast__IntegerLiteral).val); bool needs_explicit_cast = false; if (cast_type_sym->kind == (v__ast__Kind__u8)) { if (!(num >= _const_min_u8 && num <= _const_max_u8)) { needs_explicit_cast = true; } } else if (cast_type_sym->kind == (v__ast__Kind__u16)) { if (!(num >= _const_min_u16 && num <= _const_max_u16)) { needs_explicit_cast = true; } } else if (cast_type_sym->kind == (v__ast__Kind__u32)) { if (!(_us64_le(_const_min_u32,num) && _us64_ge(_const_max_u32,num))) { needs_explicit_cast = true; } } else if (cast_type_sym->kind == (v__ast__Kind__u64)) { if (!(_us64_le(_const_min_u64,num) && _us64_ge(_const_max_u64,num))) { needs_explicit_cast = true; } } else if (cast_type_sym->kind == (v__ast__Kind__i8)) { if (!(num >= _const_min_i32 && num <= _const_max_i32)) { needs_explicit_cast = true; } } else if (cast_type_sym->kind == (v__ast__Kind__i16)) { if (!(num >= _const_min_i16 && num <= _const_max_i16)) { needs_explicit_cast = true; } } else if (cast_type_sym->kind == (v__ast__Kind__i32) || cast_type_sym->kind == (v__ast__Kind__int)) { if (!(num >= _const_min_i32 && num <= _const_max_i32)) { needs_explicit_cast = true; } } else if (cast_type_sym->kind == (v__ast__Kind__i64)) { if (!(num >= _const_min_i64 && num <= _const_max_i64)) { needs_explicit_cast = true; } } else if (cast_type_sym->kind == (v__ast__Kind__int_literal)) { needs_explicit_cast = false; } else { } if (needs_explicit_cast) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe09, {.d_i64 = num}}, {_S(" does not fit the range of `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, infer_cast_type)}}, {_S("`"), 0, { .d_c = 0 }}})), (*stmt._v__ast__ExprStmt).pos); } } } } } } else if (!((stmt)._typ == 412 /* v.ast.Return */ || (stmt)._typ == 394 /* v.ast.BranchStmt */)) { if (ret_type != _const_v__ast__void_type) { v__checker__Checker_error(c, _S("`match` expression requires an expression as the last statement of every branch"), (*(stmt.pos))); } } } first_iteration = false; _option_bool _t6; if (_t6 = v__checker__Checker_has_return(c, branch->stmts), _t6.state == 0) { bool has_return = *(bool*)_t6.data; if (has_return) { nbranches_with_return++; } else { nbranches_without_return++; } } } if (nbranches_with_return > 0) { if (nbranches_with_return == node->branches.len) { c->returns = true; } if (nbranches_without_return > 0) { c->returns = false; } } if (ret_type == _const_v__ast__none_type) { v__checker__Checker_error(c, _S("invalid match expression, must supply at least one value other than `none`"), node->pos); } node->return_type = (must_be_option ? (v__ast__Type_set_flag(ret_type, v__ast__TypeFlag__option)) : (ret_type)); string cond_var = v__checker__Checker_get_base_name(c, &node->cond); if ((cond_var).len != 0) { bool cond_is_auto_heap = false; for (int _t7 = 0; _t7 < node->branches.len; ++_t7) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)node->branches.data)[_t7]; _option_v__ast__Var_ptr _t8; if (_t8 = v__ast__Scope_find_var(branch.scope, cond_var), _t8.state == 0) { v__ast__Var* v = *(v__ast__Var**)_t8.data; if (v->is_auto_heap) { cond_is_auto_heap = true; break; } } } if (cond_is_auto_heap) { for (int _t9 = 0; _t9 < node->branches.len; ++_t9) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)node->branches.data)[_t9]; _option_v__ast__Var_ptr _t10 = v__ast__Scope_find_var(branch.scope, cond_var); if (_t10.state != 0) { IError err = _t10.err; continue; } v__ast__Var* v = (*(v__ast__Var**)_t10.data); v->is_auto_heap = true; } } } v__ast__Type _t11 = node->return_type; // Defer begin if (v__checker__Checker_match_expr_defer_0) { c->expected_expr_type = _const_v__ast__void_type; } // Defer end return _t11; } VV_LOC void v__checker__Checker_check_match_branch_last_stmt(v__checker__Checker* c, v__ast__ExprStmt last_stmt, v__ast__Type ret_type, v__ast__Type expr_type) { if (!v__checker__Checker_check_types(c, ret_type, expr_type) && !v__checker__Checker_check_types(c, expr_type, ret_type)) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(c->table, ret_type); bool is_noreturn = v__checker__is_noreturn_callexpr(last_stmt.expr); if (!(ret_sym->kind == v__ast__Kind__sum_type && (v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__generic) || v__ast__Table_is_sumtype_or_in_variant(c->table, ret_type, expr_type))) && !is_noreturn) { v__ast__TypeSymbol* expr_sym = v__ast__Table_sym(c->table, expr_type); if (expr_sym->kind == v__ast__Kind__multi_return && ret_sym->kind == v__ast__Kind__multi_return) { Array_v__ast__Type ret_types = v__ast__TypeSymbol_mr_info(ret_sym).types; Array_v__ast__Type _t1 = {0}; Array_v__ast__Type _t1_orig = v__ast__TypeSymbol_mr_info(expr_sym).types; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t3]; v__ast__Type _t2 = v__ast__mktyp(it); array_push((array*)&_t1, &_t2); } Array_v__ast__Type expr_types =_t1; if (Array_v__ast__Type_arr_eq(expr_types, ret_types)) { return; } } if (expr_type != _const_v__ast__none_type && ret_type != _const_v__ast__none_type) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("return type mismatch, it should be `"), 0xfe10, {.d_s = ret_sym->name}}, {_S("`, but it is instead `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, expr_type)}}, {_S("`"), 0, { .d_c = 0 }}})), last_stmt.pos); } } } else if (expr_type == _const_v__ast__void_type && v__ast__Type_idx(ret_type) == 1 && v__ast__Type_has_option_or_result(ret_type)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__ast__Expr_str(&last_stmt.expr)}}, {_S("` used as value"), 0, { .d_c = 0 }}})), last_stmt.pos); } } VV_LOC _option_i64 v__checker__Checker_get_comptime_number_value(v__checker__Checker* c, v__ast__Expr* expr) { if ((expr)->_typ == 347 /* v.ast.CharLiteral */) { _option_i64 _t1; _option_ok(&(i64[]) { string_at((*expr->_v__ast__CharLiteral).val, 0) }, (_option*)(&_t1), sizeof(i64)); return _t1; } if ((expr)->_typ == 363 /* v.ast.IntegerLiteral */) { _option_i64 _t2; _option_ok(&(i64[]) { string_i64((*expr->_v__ast__IntegerLiteral).val) }, (_option*)(&_t2), sizeof(i64)); return _t2; } if ((expr)->_typ == 345 /* v.ast.CastExpr */ && ((*(v__ast__CastExpr*)__as_cast((expr)->_v__ast__CastExpr,(expr)->_typ, 345)).expr)._typ == 363 /* v.ast.IntegerLiteral */) { _option_i64 _t3; _option_ok(&(i64[]) { string_i64((*(*expr->_v__ast__CastExpr).expr._v__ast__IntegerLiteral).val) }, (_option*)(&_t3), sizeof(i64)); return _t3; } if ((expr)->_typ == 358 /* v.ast.Ident */) { _option_v__ast__ConstField_ptr _t4; if (_t4 = v__ast__Scope_find_const(c->table->global_scope, v__ast__Ident_full_name(&(*expr->_v__ast__Ident))), _t4.state == 0) { v__ast__ConstField* obj = *(v__ast__ConstField**)_t4.data; if (obj->typ == 0) { obj->typ = v__checker__Checker_expr(c, &obj->expr); } return v__checker__Checker_get_comptime_number_value(c, &obj->expr); } } return (_option_i64){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } VV_LOC void v__checker__Checker_match_exprs(v__checker__Checker* c, v__ast__MatchExpr* node, v__ast__TypeSymbol cond_type_sym) { c->expected_type = node->expected_type; v__ast__TypeSymbol* cond_sym = v__ast__Table_sym(c->table, node->cond_type); bool enum_ref_checked = false; Map_string_int branch_exprs = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int branch_i = 0; branch_i < node->branches.len; ++branch_i) { v__ast__MatchBranch branch = (*(v__ast__MatchBranch*)array_get(node->branches, branch_i)); Array_v__ast__TypeNode expr_types = __new_array_with_default(0, 0, sizeof(v__ast__TypeNode), 0); for (int k = 0; k < branch.exprs.len; ++k) { v__ast__Expr* expr = ((v__ast__Expr*)branch.exprs.data) + k; string key = _S(""); if ((expr)->_typ != 355 /* v.ast.EnumVal */) { v__checker__Checker_expr(c, expr); } if ((expr)->_typ == 386 /* v.ast.TypeNode */ && cond_sym->kind == v__ast__Kind__struct) { v__checker__Checker_error(c, _S("struct instances cannot be matched by type name, they can only be matched to other instances of the same struct type"), branch.pos); } bool is_comptime = false; if (c->comptime->inside_comptime_for) { if ((node->cond)._typ == 379 /* v.ast.SelectorExpr */) { is_comptime = (*node->cond._v__ast__SelectorExpr).expr_type == c->field_data_type && fast_string_eq((*node->cond._v__ast__SelectorExpr).field_name, _S("typ")); } } if ((expr)->_typ == 386 /* v.ast.TypeNode */ && v__ast__TypeSymbol_is_primitive(cond_sym) && !is_comptime) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("matching by type can only be done for sum types, generics, interfaces, `"), 0xfe10, {.d_s = v__ast__Expr_str(&node->cond)}}, {_S("` is none of those"), 0, { .d_c = 0 }}})), branch.pos); } if ((expr)->_typ == 377 /* v.ast.RangeExpr */) { if (cond_sym->kind != v__ast__Kind__enum && !v__checker__Checker_check_types(c, (*expr->_v__ast__RangeExpr).typ, node->cond_type)) { string mcstype = v__ast__Table_type_to_str(c->table, node->cond_type); string brstype = v__ast__Table_type_to_str(c->table, (*expr->_v__ast__RangeExpr).typ); v__checker__Checker_add_error_detail(c, _S("")); v__checker__Checker_add_error_detail(c, str_intp(2, _MOV((StrIntpData[]){{_S("match condition type: "), 0xfe10, {.d_s = mcstype}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__checker__Checker_add_error_detail(c, str_intp(2, _MOV((StrIntpData[]){{_S(" range type: "), 0xfe10, {.d_s = brstype}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__checker__Checker_error(c, _S("the range type and the match condition type should match"), (*expr->_v__ast__RangeExpr).pos); } bool low_value_higher_than_high_value = false; i64 low = ((i64)(0)); i64 high = ((i64)(0)); bool both_low_and_high_are_known = false; _option_i64 _t1; if (_t1 = v__checker__Checker_get_comptime_number_value(c, &(*expr->_v__ast__RangeExpr).low), _t1.state == 0) { i64 low_value = *(i64*)_t1.data; low = low_value; _option_i64 _t2; if (_t2 = v__checker__Checker_get_comptime_number_value(c, &(*expr->_v__ast__RangeExpr).high), _t2.state == 0) { i64 high_value = *(i64*)_t2.data; high = high_value; both_low_and_high_are_known = true; if (low_value > high_value) { low_value_higher_than_high_value = true; } } else { IError err = _t2.err; if (((*expr->_v__ast__RangeExpr).high)._typ != 355 /* v.ast.EnumVal */) { v__checker__Checker_error(c, _S("match branch range expressions need the end value to be known at compile time (only enums, const or literals are supported)"), v__ast__Expr_pos((*expr->_v__ast__RangeExpr).high)); } } } else { IError err = _t1.err; if (((*expr->_v__ast__RangeExpr).low)._typ != 355 /* v.ast.EnumVal */) { v__checker__Checker_error(c, _S("match branch range expressions need the start value to be known at compile time (only enums, const or literals are supported)"), v__ast__Expr_pos((*expr->_v__ast__RangeExpr).low)); } } if (low_value_higher_than_high_value) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("the start value `"), 0xfe09, {.d_i64 = low}}, {_S("` should be lower than the end value `"), 0xfe09, {.d_i64 = high}}, {_S("`"), 0, { .d_c = 0 }}})), branch.pos); } if (both_low_and_high_are_known) { int high_low_cutoff = 1000; if ((i64)(high - low) > high_low_cutoff) { v__checker__Checker_note(c, str_intp(4, _MOV((StrIntpData[]){{_S("more than "), 0xfe07, {.d_i32 = high_low_cutoff}}, {_S(" possibilities ("), 0xfe09, {.d_i64 = low}}, {_S(" ... "), 0xfe09, {.d_i64 = high}}, {_S(") in match range may affect compile time"), 0, { .d_c = 0 }}})), branch.pos); } for (i64 i = low; i < (i64)(high + 1); ++i) { key = i64_str(i); int val = (_IN_MAP(ADDR(string, key), ADDR(map, branch_exprs)) ? ((*(int*)map_get(ADDR(map, branch_exprs), &(string[]){key}, &(int[]){ 0 }))) : (0)); if (val == 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("match case `"), 0xfe10, {.d_s = key}}, {_S("` is handled more than once"), 0, { .d_c = 0 }}})), branch.pos); } map_set(&branch_exprs, &(string[]){key}, &(int[]) { (int)(val + 1) }); } } continue; } bool is_type_node = (expr)->_typ == 386 /* v.ast.TypeNode */; if (expr->_typ == 386 /* v.ast.TypeNode */) { key = v__ast__Table_type_to_str(c->table, (*expr->_v__ast__TypeNode).typ); array_push((array*)&expr_types, _MOV((v__ast__TypeNode[]){ (*expr->_v__ast__TypeNode) })); } else if (expr->_typ == 355 /* v.ast.EnumVal */) { key = (*expr->_v__ast__EnumVal).val; if (!enum_ref_checked) { enum_ref_checked = true; if (v__ast__Type_is_ptr(node->cond_type)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("missing `*` dereferencing `"), 0xfe10, {.d_s = v__ast__Expr_str(&node->cond)}}, {_S("` in match statement"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->cond)); } } } else { key = v__ast__Expr_str(&(*expr)); } int val = (_IN_MAP(ADDR(string, key), ADDR(map, branch_exprs)) ? ((*(int*)map_get(ADDR(map, branch_exprs), &(string[]){key}, &(int[]){ 0 }))) : (0)); if (val == 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("match case `"), 0xfe10, {.d_s = key}}, {_S("` is handled more than once"), 0, { .d_c = 0 }}})), branch.pos); } c->expected_type = node->cond_type; if (is_type_node) { c->inside_x_matches_type = true; } v__ast__Type expr_type = v__checker__Checker_expr(c, expr); if (v__ast__Type_idx(expr_type) == 0) { return; } v__ast__TypeSymbol* expr_type_sym = v__ast__Table_sym(c->table, expr_type); if (cond_type_sym.kind == v__ast__Kind__interface) { v__token__Pos expr_pos = v__ast__Expr_pos(*expr); if (v__checker__Checker_type_implements(c, expr_type, c->expected_type, expr_pos)) { if (!v__ast__Type_is_any_kind_of_pointer(expr_type) && !c->inside_unsafe) { if (expr_type_sym->kind != v__ast__Kind__interface) { v__checker__Checker_mark_as_referenced(c, &(*(v__ast__Expr*)array_get(branch.exprs, k)), true); } } } } else if ((cond_type_sym.info)._typ == 544 /* v.ast.SumType */) { if (!(Array_v__ast__Type_contains((*cond_type_sym.info._v__ast__SumType).variants, expr_type))) { string expr_str = v__ast__Table_type_to_str(c->table, expr_type); string expect_str = v__ast__Table_type_to_str(c->table, node->cond_type); Array_string _t4 = {0}; Array_v__ast__Type _t4_orig = (*cond_type_sym.info._v__ast__SumType).variants; int _t4_len = _t4_orig.len; _t4 = __new_array(0, _t4_len, sizeof(string)); for (int _t6 = 0; _t6 < _t4_len; ++_t6) { v__ast__Type it = ((v__ast__Type*) _t4_orig.data)[_t6]; string _t5 = v__ast__Table_type_to_str_using_aliases(c->table, it, new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ); array_push((array*)&_t4, &_t5); } Array_string sumtype_variant_names =_t4; v__util__Suggestion suggestion = v__util__new_suggestion(expr_str, sumtype_variant_names, ((v__util__SuggestionParams){.similarity_threshold = 0.5,.similarity_fn = strings__dice_coefficient,})); v__checker__Checker_error(c, v__util__Suggestion_say(suggestion, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = expect_str}}, {_S("` has no variant `"), 0xfe10, {.d_s = expr_str}}, {_S("`"), 0, { .d_c = 0 }}}))), v__ast__Expr_pos(*expr)); } } else if ((cond_type_sym.info)._typ == 539 /* v.ast.Alias */ && (expr_type_sym->info)._typ == 518 /* v.ast.Struct */) { string expr_str = v__ast__Table_type_to_str(c->table, expr_type); string expect_str = v__ast__Table_type_to_str(c->table, node->cond_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot match alias type `"), 0xfe10, {.d_s = expect_str}}, {_S("` with `"), 0xfe10, {.d_s = expr_str}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*expr)); } else if (!v__checker__Checker_check_types(c, expr_type, node->cond_type) && !is_comptime) { string expr_str = v__ast__Table_type_to_str(c->table, expr_type); string expect_str = v__ast__Table_type_to_str(c->table, node->cond_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot match `"), 0xfe10, {.d_s = expect_str}}, {_S("` with `"), 0xfe10, {.d_s = expr_str}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*expr)); } map_set(&branch_exprs, &(string[]){key}, &(int[]) { (int)(val + 1) }); } if (expr_types.len > 0) { if (cond_type_sym.kind == v__ast__Kind__sum_type || cond_type_sym.kind == v__ast__Kind__interface) { v__ast__Type expr_type = _const_v__ast__no_type; if (expr_types.len > 1) { strings__Builder agg_name = strings__new_builder(20); strings__Builder agg_cname = strings__new_builder(20); strings__Builder_write_string(&agg_name, _S("(")); for (int i = 0; i < expr_types.len; ++i) { v__ast__TypeNode expr = ((v__ast__TypeNode*)expr_types.data)[i]; if (i > 0) { strings__Builder_write_string(&agg_name, _S(" | ")); strings__Builder_write_string(&agg_cname, _S("___")); } string type_str = v__ast__Table_type_to_str(c->table, expr.typ); string name = (c->is_builtin_mod ? (type_str) : (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->mod}}, {_S("."), 0xfe10, {.d_s = type_str}}, {_SLIT0, 0, { .d_c = 0 }}})))); strings__Builder_write_string(&agg_name, name); strings__Builder_write_string(&agg_cname, v__util__no_dots(name)); } strings__Builder_write_string(&agg_name, _S(")")); string name = strings__Builder_str(&agg_name); int existing_idx = (*(int*)map_get(ADDR(map, c->table->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (existing_idx > 0) { expr_type = existing_idx; } else { Array_v__ast__Type _t7 = {0}; Array_v__ast__TypeNode _t7_orig = expr_types; int _t7_len = _t7_orig.len; _t7 = __new_array(0, _t7_len, sizeof(v__ast__Type)); for (int _t9 = 0; _t9 < _t7_len; ++_t9) { v__ast__TypeNode it = ((v__ast__TypeNode*) _t7_orig.data)[_t9]; v__ast__Type _t8 = it.typ; array_push((array*)&_t7, &_t8); } expr_type = v__ast__Table_register_sym(c->table, ((v__ast__TypeSymbol){.parent_idx = 0,.info = v__ast__Aggregate_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Aggregate, (((v__ast__Aggregate){.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sum_type = node->cond_type,.types =_t7,})))),.kind = v__ast__Kind__aggregate,.name = name,.cname = strings__Builder_str(&agg_cname),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = c->mod,.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); } } else { expr_type = (*(v__ast__TypeNode*)array_get(expr_types, 0)).typ; } v__checker__Checker_smartcast(c, &node->cond, node->cond_type, expr_type, branch.scope, false, false); } } } bool is_exhaustive = true; Array_string unhandled = __new_array_with_default(0, 0, sizeof(string), 0); if (node->cond_type == _const_v__ast__bool_type) { Array_string variants = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("true"), _S("false")})); for (int _t10 = 0; _t10 < variants.len; ++_t10) { string v = ((string*)variants.data)[_t10]; if (!_IN_MAP(ADDR(string, v), ADDR(map, branch_exprs))) { is_exhaustive = false; array_push((array*)&unhandled, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v}}, {_S("`"), 0, { .d_c = 0 }}})) })); } } } else { if (cond_type_sym.info._typ == 544 /* v.ast.SumType */) { for (int _t12 = 0; _t12 < (*cond_type_sym.info._v__ast__SumType).variants.len; ++_t12) { v__ast__Type v = ((v__ast__Type*)(*cond_type_sym.info._v__ast__SumType).variants.data)[_t12]; string v_str = v__ast__Table_type_to_str(c->table, v); if (!_IN_MAP(ADDR(string, v_str), ADDR(map, branch_exprs))) { is_exhaustive = false; array_push((array*)&unhandled, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v_str}}, {_S("`"), 0, { .d_c = 0 }}})) })); } } } else if (cond_type_sym.info._typ == 548 /* v.ast.Enum */) { for (int _t14 = 0; _t14 < (*cond_type_sym.info._v__ast__Enum).vals.len; ++_t14) { string v = ((string*)(*cond_type_sym.info._v__ast__Enum).vals.data)[_t14]; if (!_IN_MAP(ADDR(string, v), ADDR(map, branch_exprs))) { is_exhaustive = false; array_push((array*)&unhandled, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("`."), 0xfe10, {.d_s = v}}, {_S("`"), 0, { .d_c = 0 }}})) })); } } if ((*cond_type_sym.info._v__ast__Enum).is_flag) { is_exhaustive = false; } } else { is_exhaustive = false; } } if (node->branches.len == 0) { v__checker__Checker_error(c, _S("`match` must have at least two branches including `else`, or an exhaustive set of branches"), node->pos); return; } v__ast__MatchBranch else_branch = (*(v__ast__MatchBranch*)array_last(node->branches)); bool has_else = else_branch.is_else; bool has_non_else = !else_branch.is_else; Array_v__ast__MatchBranch _t16 = array_slice(node->branches, 0, (int)(node->branches.len - 1)); for (int _t17 = 0; _t17 < _t16.len; ++_t17) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)_t16.data)[_t17]; if (branch.is_else) { if (has_else) { v__checker__Checker_error(c, _S("`match` can have only one `else` branch"), branch.pos); } v__checker__Checker_error(c, _S("`else` must be the last branch of `match`"), branch.pos); else_branch = branch; has_else = true; } else { has_non_else = true; } } if (!has_non_else) { v__checker__Checker_error(c, _S("`match` must have at least one non `else` branch"), else_branch.pos); } if (is_exhaustive) { if (has_else && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, _S("match expression is exhaustive, `else` is unnecessary"), else_branch.pos); } return; } if (has_else) { return; } string err_details = _S("match must be exhaustive"); if (unhandled.len > 0) { err_details = string__plus(err_details, _S(" (add match branches for: ")); if (unhandled.len < c->match_exhaustive_cutoff_limit) { err_details = string__plus(err_details, Array_string_join(unhandled, _S(", "))); } else { int remaining = (int)(unhandled.len - c->match_exhaustive_cutoff_limit); err_details = string__plus(err_details, Array_string_join(array_slice(unhandled, 0, c->match_exhaustive_cutoff_limit), _S(", "))); if (remaining > 0) { err_details = string__plus(err_details, str_intp(2, _MOV((StrIntpData[]){{_S(", and "), 0xfe07, {.d_i32 = remaining}}, {_S(" others ..."), 0, { .d_c = 0 }}}))); } } err_details = string__plus(err_details, _S(" or `else {}` at the end)")); } else { err_details = string__plus(err_details, _S(" (add `else {}` at the end)")); } v__checker__Checker_error(c, err_details, node->pos); } VV_LOC v__ast__Type v__checker__Checker_sql_expr(v__checker__Checker* c, v__ast__SqlExpr* node) { bool v__checker__Checker_sql_expr_defer_0 = false; bool v__checker__Checker_sql_expr_defer_1 = false; v__ast__TypeSymbol old_ts; c->inside_sql = true; v__checker__Checker_sql_expr_defer_0 = true; if (!v__checker__Checker_check_db_expr(c, &node->db_expr)) { v__ast__Type _t1 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_expr_defer_0) { c->inside_sql = false; } // Defer end return _t1; } if (!v__checker__Checker_ensure_type_exists(c, node->table_expr.typ, node->pos)) { v__ast__Type _t2 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_expr_defer_0) { c->inside_sql = false; } // Defer end return _t2; } v__ast__TypeSymbol* table_sym = v__ast__Table_sym(c->table, node->table_expr.typ); if (!v__checker__Checker_check_orm_table_expr_type(c, (voidptr)&node->table_expr)) { v__ast__Type _t3 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_expr_defer_0) { c->inside_sql = false; } // Defer end return _t3; } old_ts = c->cur_orm_ts; c->cur_orm_ts = *table_sym; v__checker__Checker_sql_expr_defer_1 = true; v__ast__Struct info = *(v__ast__Struct*)__as_cast((table_sym->info)._v__ast__Struct,(table_sym->info)._typ, 518); Array_v__ast__StructField fields = v__checker__Checker_fetch_and_check_orm_fields(c, info, node->table_expr.pos, table_sym->name); Array_v__ast__StructField non_primitive_fields = v__checker__Checker_get_orm_non_primitive_fields(c, fields); Map_int_v__ast__SqlExpr sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlExpr), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop) ; bool has_primary = false; v__ast__StructField primary_field = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}); for (int _t4 = 0; _t4 < fields.len; ++_t4) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t4]; multi_return_v__ast__Type_ref_v__ast__TypeSymbol mr_1201 = v__checker__Checker_get_non_array_type(c, field.typ); v__ast__Type field_typ = mr_1201.arg0; v__ast__TypeSymbol* field_sym = mr_1201.arg1; if (field_sym->kind == v__ast__Kind__struct && (v__ast__Type_idx(field_typ) == v__ast__Type_idx(node->table_expr.typ) || v__checker__Checker_check_recursive_structs(c, field_sym, table_sym->name))) { v__checker__Checker_orm_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid recursive struct `"), 0xfe10, {.d_s = field_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), field.pos); v__ast__Type _t5 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_expr_defer_1) { c->cur_orm_ts = old_ts; } // Defer end // Defer begin if (v__checker__Checker_sql_expr_defer_0) { c->inside_sql = false; } // Defer end return _t5; } if (Array_v__ast__Attr_contains(field.attrs, _S("primary"))) { if (has_primary) { v__checker__Checker_orm_error(c, _S("a struct can only have one primary key"), field.pos); } has_primary = true; primary_field = field; } } for (int _t6 = 0; _t6 < non_primitive_fields.len; ++_t6) { v__ast__StructField field = ((v__ast__StructField*)non_primitive_fields.data)[_t6]; if (v__ast__Table_sym(c->table, field.typ)->kind == v__ast__Kind__array && !has_primary) { v__checker__Checker_orm_error(c, _S("a struct that has a field that holds an array must have a primary key"), field.pos); } v__checker__Checker_check_orm_non_primitive_struct_field_attrs(c, field); v__ast__Type foreign_typ = v__checker__Checker_get_field_foreign_table_type(c, (voidptr)&field); v__ast__SqlExpr subquery_expr = ((v__ast__SqlExpr){ .is_count = 0, .is_insert = 0, .inserted_var = (string){.str=(byteptr)"", .is_lit=1}, .has_where = true, .has_order = 0, .has_limit = 0, .has_offset = 0, .has_desc = 0, .is_array = 0, .is_generated = true, .pos = node->pos, .typ = v__ast__Type_set_flag(v__ast__Type_clear_flag(field.typ, v__ast__TypeFlag__option), v__ast__TypeFlag__result), .db_expr = node->db_expr, .where_expr = v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))), .order_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .limit_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .offset_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .table_expr = ((v__ast__TypeNode){.pos = node->table_expr.pos,.typ = foreign_typ,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}), .fields = __new_array(0, 0, sizeof(v__ast__StructField)), .sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlExpr), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), }); bool tmp_inside_sql = c->inside_sql; v__checker__Checker_sql_expr(c, (voidptr)&subquery_expr); c->inside_sql = tmp_inside_sql; subquery_expr.where_expr = v__ast__InfixExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__InfixExpr, (((v__ast__InfixExpr){ .op = v__token__Kind__eq, .pos = subquery_expr.pos, .is_stmt = 0, .left = v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (((v__ast__Ident){ .language = v__ast__Language__v, .tok_kind = v__token__Kind__eq, .pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .comptime = 0, .scope = c->fn_scope, .obj = v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = (string){.str=(byteptr)"", .is_lit=1},.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = 0,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,})))), .mod = _S("main"), .name = _S("id"), .full_name = (string){.str=(byteptr)"", .is_lit=1}, .cached_name = (string){.str=(byteptr)"", .is_lit=1}, .kind = v__ast__IdentKind__unresolved, .info = v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentVar, (((v__ast__IdentVar){.typ = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_option = 0,.share = 0,})))), .is_mut = false, .or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .ct_expr = 0, })))), .right = v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (((v__ast__Ident){ .language = v__ast__Language__c, .tok_kind = v__token__Kind__eq, .pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .comptime = 0, .scope = c->fn_scope, .obj = v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = (string){.str=(byteptr)"", .is_lit=1},.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = 0,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,})))), .mod = _S("main"), .name = (string){.str=(byteptr)"", .is_lit=1}, .full_name = (string){.str=(byteptr)"", .is_lit=1}, .cached_name = (string){.str=(byteptr)"", .is_lit=1}, .kind = 0, .info = v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentVar, (((v__ast__IdentVar){.typ = _const_v__ast__int_type,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_option = 0,.share = 0,})))), .is_mut = false, .or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .ct_expr = 0, })))), .left_type = _const_v__ast__int_type, .right_type = _const_v__ast__int_type, .promoted_type = _const_v__ast__void_type, .auto_locked = _S(""), .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .ct_left_value_evaled = 0, .ct_left_value = _const_v__ast__empty_comptime_const_value, .left_ct_expr = 0, .ct_right_value_evaled = 0, .ct_right_value = _const_v__ast__empty_comptime_const_value, .right_ct_expr = 0, .before_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .after_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)), })))); if (v__ast__Table_sym(c->table, field.typ)->kind == v__ast__Kind__array) { v__ast__Expr where_expr = subquery_expr.where_expr; if ((where_expr)._typ == 362 /* v.ast.InfixExpr */) { (*where_expr._v__ast__InfixExpr).left_type = primary_field.typ; (*where_expr._v__ast__InfixExpr).right_type = primary_field.typ; v__ast__Expr left = (*where_expr._v__ast__InfixExpr).left; if ((left)._typ == 358 /* v.ast.Ident */) { (*left._v__ast__Ident).name = primary_field.name; } v__ast__Expr right = (*where_expr._v__ast__InfixExpr).right; if ((right)._typ == 358 /* v.ast.Ident */) { v__ast__IdentInfo right_info = (*right._v__ast__Ident).info; if ((right_info)._typ == 477 /* v.ast.IdentVar */) { (*right_info._v__ast__IdentVar).typ = primary_field.typ; } } } } (*(v__ast__SqlExpr*)map_get_and_set((map*)&sub_structs, &(int[]){((int)(field.typ))}, &(v__ast__SqlExpr[]){ (v__ast__SqlExpr){.is_count = 0,.is_insert = 0,.inserted_var = (string){.str=(byteptr)"", .is_lit=1},.has_where = 0,.has_order = 0,.has_limit = 0,.has_offset = 0,.has_desc = 0,.is_array = 0,.is_generated = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.db_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.order_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.limit_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.offset_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.table_expr = (v__ast__TypeNode){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),},.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlExpr), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.or_expr = (v__ast__OrExpr){.kind = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),},} })) = subquery_expr; } if (node->is_count) { fields = new_array_from_c_array(1, 1, sizeof(v__ast__StructField), _MOV((v__ast__StructField[1]){((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = _const_v__ast__int_type,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),})})); } node->fields = fields; node->sub_structs = map_move(&sub_structs); Array_string _t7 = {0}; Array_v__ast__StructField _t7_orig = fields; int _t7_len = _t7_orig.len; _t7 = __new_array(0, _t7_len, sizeof(string)); for (int _t9 = 0; _t9 < _t7_len; ++_t9) { v__ast__StructField it = ((v__ast__StructField*) _t7_orig.data)[_t9]; string _t8 = it.name; array_push((array*)&_t7, &_t8); } Array_string field_names =_t7; if (node->has_where) { v__checker__Checker_expr(c, &node->where_expr); v__checker__Checker_check_expr_has_no_fn_calls_with_non_orm_return_type(c, &node->where_expr); v__checker__Checker_check_where_expr_has_no_pointless_exprs(c, table_sym, field_names, &node->where_expr); } if (node->has_order) { if ((node->order_expr)._typ == 358 /* v.ast.Ident */) { string order_ident_name = (*node->order_expr._v__ast__Ident).name; if (!v__ast__TypeSymbol_has_field(table_sym, order_ident_name)) { v__checker__Checker_orm_error(c, v__util__Suggestion_say(v__util__new_suggestion(order_ident_name, field_names, ((v__util__SuggestionParams){.similarity_threshold = 0.5,.similarity_fn = strings__dice_coefficient,})), str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = table_sym->name}}, {_S("` structure has no field with name `"), 0xfe10, {.d_s = order_ident_name}}, {_S("`"), 0, { .d_c = 0 }}}))), (*node->order_expr._v__ast__Ident).pos); v__ast__Type _t10 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_expr_defer_1) { c->cur_orm_ts = old_ts; } // Defer end // Defer begin if (v__checker__Checker_sql_expr_defer_0) { c->inside_sql = false; } // Defer end return _t10; } } else { v__checker__Checker_orm_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expected `"), 0xfe10, {.d_s = table_sym->name}}, {_S("` structure's field"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->order_expr)); v__ast__Type _t11 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_expr_defer_1) { c->cur_orm_ts = old_ts; } // Defer end // Defer begin if (v__checker__Checker_sql_expr_defer_0) { c->inside_sql = false; } // Defer end return _t11; } v__checker__Checker_expr(c, &node->order_expr); } if (node->has_limit) { v__checker__Checker_expr(c, &node->limit_expr); v__checker__Checker_check_sql_value_expr_is_comptime_with_natural_number_or_expr_with_int_type(c, &node->limit_expr, _S("limit")); } if (node->has_offset) { v__checker__Checker_expr(c, &node->offset_expr); v__checker__Checker_check_sql_value_expr_is_comptime_with_natural_number_or_expr_with_int_type(c, &node->offset_expr, _S("offset")); } v__checker__Checker_expr(c, &node->db_expr); if (node->is_insert) { node->typ = _const_v__ast__int_type; } v__checker__Checker_check_orm_or_expr(c, HEAP(v__checker__ORMExpr, v__ast__SqlExpr_to_sumtype_v__checker__ORMExpr(node))); if (node->is_insert) { v__ast__Type _t12 = _const_v__ast__int_type; // Defer begin if (v__checker__Checker_sql_expr_defer_1) { c->cur_orm_ts = old_ts; } // Defer end // Defer begin if (v__checker__Checker_sql_expr_defer_0) { c->inside_sql = false; } // Defer end return _t12; } v__ast__Type _t13 = v__ast__Type_clear_flag(node->typ, v__ast__TypeFlag__result); // Defer begin if (v__checker__Checker_sql_expr_defer_1) { c->cur_orm_ts = old_ts; } // Defer end // Defer begin if (v__checker__Checker_sql_expr_defer_0) { c->inside_sql = false; } // Defer end return _t13; } VV_LOC v__ast__Type v__checker__Checker_sql_stmt(v__checker__Checker* c, v__ast__SqlStmt* node) { if (!v__checker__Checker_check_db_expr(c, &node->db_expr)) { return _const_v__ast__void_type; } node->db_expr_type = v__ast__Table_unaliased_type(c->table, v__checker__Checker_expr(c, &node->db_expr)); for (int _t2 = 0; _t2 < node->lines.len; ++_t2) { v__ast__SqlStmtLine* line = ((v__ast__SqlStmtLine*)node->lines.data) + _t2; v__checker__Checker_sql_stmt_line(c, line); } v__checker__Checker_check_orm_or_expr(c, HEAP(v__checker__ORMExpr, v__ast__SqlStmt_to_sumtype_v__checker__ORMExpr(node))); return _const_v__ast__void_type; } VV_LOC v__ast__Type v__checker__Checker_sql_stmt_line(v__checker__Checker* c, v__ast__SqlStmtLine* node) { bool v__checker__Checker_sql_stmt_line_defer_0 = false; bool v__checker__Checker_sql_stmt_line_defer_1 = false; v__ast__TypeSymbol old_ts; c->inside_sql = true; v__checker__Checker_sql_stmt_line_defer_0 = true; if (!v__checker__Checker_ensure_type_exists(c, node->table_expr.typ, node->pos)) { v__ast__Type _t1 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_stmt_line_defer_0) { c->inside_sql = false; } // Defer end return _t1; } v__ast__TypeSymbol* table_sym = v__ast__Table_sym(c->table, node->table_expr.typ); if (!v__checker__Checker_check_orm_table_expr_type(c, (voidptr)&node->table_expr)) { v__ast__Type _t2 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_stmt_line_defer_0) { c->inside_sql = false; } // Defer end return _t2; } old_ts = c->cur_orm_ts; c->cur_orm_ts = *table_sym; v__checker__Checker_sql_stmt_line_defer_1 = true; string inserting_object_name = node->object_var; if (node->kind == v__ast__SqlStmtKind__insert && !node->is_generated) { _option_v__ast__ScopeObject _t3 = v__ast__Scope_find(node->scope, inserting_object_name); if (_t3.state != 0) { IError err = _t3.err; v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("undefined ident: `"), 0xfe10, {.d_s = inserting_object_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); v__ast__Type _t4 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_stmt_line_defer_1) { c->cur_orm_ts = old_ts; } // Defer end // Defer begin if (v__checker__Checker_sql_stmt_line_defer_0) { c->inside_sql = false; } // Defer end return _t4; } v__ast__ScopeObject inserting_object = (*(v__ast__ScopeObject*)_t3.data); v__ast__Type inserting_object_type = (*(inserting_object.typ)); if (v__ast__Type_is_ptr(inserting_object_type)) { inserting_object_type = v__ast__Type_deref((*(inserting_object.typ))); } if (inserting_object_type != node->table_expr.typ && !v__ast__Table_sumtype_has_variant(c->table, inserting_object_type, node->table_expr.typ, false)) { string table_name = table_sym->name; string inserting_type_name = v__ast__Table_sym(c->table, inserting_object_type)->name; v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = inserting_type_name}}, {_S("` as `"), 0xfe10, {.d_s = table_name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); v__ast__Type _t5 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_stmt_line_defer_1) { c->cur_orm_ts = old_ts; } // Defer end // Defer begin if (v__checker__Checker_sql_stmt_line_defer_0) { c->inside_sql = false; } // Defer end return _t5; } } if ((table_sym->info)._typ != 518 /* v.ast.Struct */) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = table_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); v__ast__Type _t6 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_stmt_line_defer_1) { c->cur_orm_ts = old_ts; } // Defer end // Defer begin if (v__checker__Checker_sql_stmt_line_defer_0) { c->inside_sql = false; } // Defer end return _t6; } v__ast__Struct info = *(v__ast__Struct*)__as_cast((table_sym->info)._v__ast__Struct,(table_sym->info)._typ, 518); Array_v__ast__StructField fields = v__checker__Checker_fetch_and_check_orm_fields(c, info, node->table_expr.pos, table_sym->name); for (int _t7 = 0; _t7 < fields.len; ++_t7) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t7]; v__checker__Checker_check_orm_struct_field_attrs(c, *node, field); } Map_int_v__ast__SqlStmtLine sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop) ; Array_v__ast__StructField non_primitive_fields = v__checker__Checker_get_orm_non_primitive_fields(c, fields); for (int _t8 = 0; _t8 < non_primitive_fields.len; ++_t8) { v__ast__StructField field = ((v__ast__StructField*)non_primitive_fields.data)[_t8]; multi_return_v__ast__Type_ref_v__ast__TypeSymbol mr_7188 = v__checker__Checker_get_non_array_type(c, field.typ); v__ast__Type field_typ = mr_7188.arg0; v__ast__TypeSymbol* field_sym = mr_7188.arg1; if (field_sym->kind == v__ast__Kind__struct && (v__ast__Type_idx(field_typ) == v__ast__Type_idx(node->table_expr.typ) || v__checker__Checker_check_recursive_structs(c, field_sym, table_sym->name))) { v__checker__Checker_orm_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("invalid recursive struct `"), 0xfe10, {.d_s = field_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), field.pos); v__ast__Type _t9 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_stmt_line_defer_1) { c->cur_orm_ts = old_ts; } // Defer end // Defer begin if (v__checker__Checker_sql_stmt_line_defer_0) { c->inside_sql = false; } // Defer end return _t9; } if (v__checker__Checker_check_field_of_inserting_struct_is_uninitialized(c, node, field.name)) { array_delete(&fields, Array_v__ast__StructField_index(fields, field)); continue; } v__checker__Checker_check_orm_non_primitive_struct_field_attrs(c, field); v__ast__Type foreign_typ = v__checker__Checker_get_field_foreign_table_type(c, (voidptr)&field); v__ast__SqlStmtLine subquery_expr = ((v__ast__SqlStmtLine){.kind = node->kind,.pos = node->pos,.is_generated = true,.scope = ((void*)0),.object_var = field.name,.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = ((v__ast__TypeNode){.pos = node->table_expr.pos,.typ = foreign_typ,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); bool tmp_inside_sql = c->inside_sql; v__checker__Checker_sql_stmt_line(c, (voidptr)&subquery_expr); c->inside_sql = tmp_inside_sql; (*(v__ast__SqlStmtLine*)map_get_and_set((map*)&sub_structs, &(int[]){field.typ}, &(v__ast__SqlStmtLine[]){ (v__ast__SqlStmtLine){.kind = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = (v__ast__TypeNode){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),},.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),} })) = subquery_expr; } node->fields = fields; node->sub_structs = map_move(&sub_structs); for (int i = 0; i < node->updated_columns.len; ++i) { string column = ((string*)node->updated_columns.data)[i]; Array_v__ast__StructField _t10 = {0}; Array_v__ast__StructField _t10_orig = node->fields; int _t10_len = _t10_orig.len; _t10 = __new_array(0, _t10_len, sizeof(v__ast__StructField)); for (int _t11 = 0; _t11 < _t10_len; ++_t11) { v__ast__StructField it = ((v__ast__StructField*) _t10_orig.data)[_t11]; if (string__eq(it.name, column)) { array_push((array*)&_t10, &it); } } Array_v__ast__StructField updated_fields =_t10; if (updated_fields.len == 0) { v__checker__Checker_orm_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("type `"), 0xfe10, {.d_s = table_sym->name}}, {_S("` has no field named `"), 0xfe10, {.d_s = column}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); continue; } v__ast__StructField field = (*(v__ast__StructField*)array_first(updated_fields)); array_set(&node->updated_columns, i, &(string[]) { v__checker__Checker_fetch_field_name(c, field) }); } if (node->kind == v__ast__SqlStmtKind__update) { for (int i = 0; i < node->update_exprs.len; ++i) { v__ast__Expr* expr = ((v__ast__Expr*)node->update_exprs.data) + i; if ((expr)->_typ == 355 /* v.ast.EnumVal */) { string column = (*(string*)array_get(node->updated_columns, i)); Array_v__ast__StructField _t12 = {0}; Array_v__ast__StructField _t12_orig = node->fields; int _t12_len = _t12_orig.len; _t12 = __new_array(0, _t12_len, sizeof(v__ast__StructField)); for (int _t13 = 0; _t13 < _t12_len; ++_t13) { v__ast__StructField it = ((v__ast__StructField*) _t12_orig.data)[_t13]; if (string__eq(it.name, column)) { array_push((array*)&_t12, &it); } } v__ast__StructField field = (*(v__ast__StructField*)array_get(_t12, 0)); c->expected_type = field.typ; } v__checker__Checker_expr(c, expr); } } if ((node->where_expr)._typ != 354 /* v.ast.EmptyExpr */) { v__checker__Checker_expr(c, &node->where_expr); } v__ast__Type _t14 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_sql_stmt_line_defer_1) { c->cur_orm_ts = old_ts; } // Defer end // Defer begin if (v__checker__Checker_sql_stmt_line_defer_0) { c->inside_sql = false; } // Defer end return _t14; } VV_LOC void v__checker__Checker_check_orm_struct_field_attrs(v__checker__Checker* c, v__ast__SqlStmtLine node, v__ast__StructField field) { for (int _t1 = 0; _t1 < field.attrs.len; ++_t1) { v__ast__Attr attr = ((v__ast__Attr*)field.attrs.data)[_t1]; if (fast_string_eq(attr.name, _S("nonull"))) { v__checker__Checker_warn(c, _S("`nonull` attribute is deprecated; non-optional fields are always \"NOT NULL\", use Option fields where they can be NULL"), node.pos); } } } VV_LOC void v__checker__Checker_check_orm_non_primitive_struct_field_attrs(v__checker__Checker* c, v__ast__StructField field) { v__ast__TypeSymbol* field_type = v__ast__Table_sym(c->table, field.typ); bool has_fkey_attr = false; for (int _t1 = 0; _t1 < field.attrs.len; ++_t1) { v__ast__Attr attr = ((v__ast__Attr*)field.attrs.data)[_t1]; if (fast_string_eq(attr.name, _S("fkey"))) { if (field_type->kind != v__ast__Kind__array && field_type->kind != v__ast__Kind__struct) { v__checker__Checker_orm_error(c, _S("the `fkey` attribute must be used only with arrays and structures"), attr.pos); return; } if (!attr.has_arg) { v__checker__Checker_orm_error(c, _S("the `fkey` attribute must have an argument"), attr.pos); return; } v__ast__TypeSymbol* field_struct_type = ((field_type->info)._typ == 513 /* v.ast.Array */ ? (v__ast__Table_sym(c->table, (*field_type->info._v__ast__Array).elem_type)) : (field_type)); _option_v__ast__StructField _t2 = v__ast__TypeSymbol_find_field(field_struct_type, attr.arg); if (_t2.state != 0) { IError err = _t2.err; v__checker__Checker_orm_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = field_struct_type->name}}, {_S("` struct has no field with name `"), 0xfe10, {.d_s = attr.arg}}, {_S("`"), 0, { .d_c = 0 }}})), attr.pos); return; } ; has_fkey_attr = true; } } if (field_type->kind == v__ast__Kind__array && !has_fkey_attr) { v__checker__Checker_orm_error(c, _S("a field that holds an array must be defined with the `fkey` attribute"), field.pos); } } VV_LOC Array_v__ast__StructField v__checker__Checker_fetch_and_check_orm_fields(v__checker__Checker* c, v__ast__Struct info, v__token__Pos pos, string table_name) { Array_v__ast__StructField* _t2 = (Array_v__ast__StructField*)(map_get_check(ADDR(map, c->orm_table_fields), &(string[]){table_name})); _option_Array_v__ast__StructField _t1 = {0}; if (_t2) { *((Array_v__ast__StructField*)&_t1.data) = *((Array_v__ast__StructField*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { Array_v__ast__StructField cache = (*(Array_v__ast__StructField*)_t1.data); return cache; } Array_v__ast__StructField fields = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); for (int _t4 = 0; _t4 < info.fields.len; ++_t4) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[_t4]; bool _t5 = (Array_v__ast__Attr_contains(field.attrs, _S("skip"))); if ( _t5 || Array_v__ast__Attr_contains_arg(field.attrs, _S("sql"), _S("-"))) { continue; } v__ast__TypeSymbol* field_sym = v__ast__Table_sym(c->table, field.typ); v__ast__Type final_field_typ = v__ast__Table_final_type(c->table, field.typ); bool is_primitive = v__ast__Type_is_string(final_field_typ) || v__ast__Type_is_bool(final_field_typ) || v__ast__Type_is_number(final_field_typ); bool is_struct = field_sym->kind == v__ast__Kind__struct; bool is_array = field_sym->kind == v__ast__Kind__array; bool is_enum = field_sym->kind == v__ast__Kind__enum; bool is_array_of_structs = false; if (is_array) { v__ast__Array array_info = v__ast__TypeSymbol_array_info(field_sym); v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(c->table, array_info.elem_type); is_array_of_structs = elem_sym->kind == v__ast__Kind__struct; _option_v__ast__Attr _t6; if (_t6 = Array_v__ast__Attr_find_first(field.attrs, _S("fkey")), _t6.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t6.data; if ((attr.arg).len == 0) { v__checker__Checker_orm_error(c, _S("fkey attribute must have an argument"), attr.pos); } } else { IError err = _t6.err; v__checker__Checker_orm_error(c, _S("array fields must have an fkey attribute"), field.pos); } if (array_info.nr_dims > 1 || elem_sym->kind == v__ast__Kind__array) { v__checker__Checker_orm_error(c, _S("multi-dimension array fields are not supported"), field.pos); } } _option_v__ast__Attr _t7; if (_t7 = Array_v__ast__Attr_find_first(field.attrs, _S("sql")), _t7.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t7.data; if ((attr.arg).len == 0) { v__checker__Checker_orm_error(c, _S("sql attribute must have an argument"), attr.pos); } } if (is_primitive || is_struct || is_enum || is_array_of_structs) { array_push((array*)&fields, _MOV((v__ast__StructField[]){ field })); } } if (fields.len == 0) { v__checker__Checker_orm_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("select: empty fields in `"), 0xfe10, {.d_s = table_name}}, {_S("`"), 0, { .d_c = 0 }}})), pos); } _option_v__ast__Attr _t9; if (_t9 = Array_v__ast__Attr_find_first(info.attrs, _S("table")), _t9.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t9.data; if ((attr.arg).len == 0) { v__checker__Checker_orm_error(c, _S("table attribute must have an argument"), attr.pos); } } (*(Array_v__ast__StructField*)map_get_and_set((map*)&c->orm_table_fields, &(string[]){table_name}, &(Array_v__ast__StructField[]){ __new_array(0, 0, sizeof(v__ast__StructField)) })) = fields; return fields; } VV_LOC void v__checker__Checker_check_sql_value_expr_is_comptime_with_natural_number_or_expr_with_int_type(v__checker__Checker* c, v__ast__Expr* expr, string sql_keyword) { _option_i64 _t1 = v__checker__Checker_get_comptime_number_value(c, expr); if (_t1.state != 0) { IError err = _t1.err; v__checker__Checker_check_sql_expr_type_is_int(c, expr, sql_keyword); return; } i64 comptime_number = (*(i64*)_t1.data); if (comptime_number < 0) { v__checker__Checker_orm_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = sql_keyword}}, {_S("` must be greater than or equal to zero"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*expr)); } } VV_LOC void v__checker__Checker_check_sql_expr_type_is_int(v__checker__Checker* c, v__ast__Expr* expr, string sql_keyword) { if ((expr)->_typ == 358 /* v.ast.Ident */) { if (v__ast__Type_is_int((*((*expr->_v__ast__Ident).obj.typ)))) { return; } } else if ((expr)->_typ == 379 /* v.ast.SelectorExpr */) { if (v__ast__Type_is_int((*expr->_v__ast__SelectorExpr).typ)) { return; } } else if ((expr)->_typ == 344 /* v.ast.CallExpr */) { if ((*expr->_v__ast__CallExpr).return_type == 0) { return; } v__ast__TypeSymbol* type_symbol = v__ast__Table_sym(c->table, (*expr->_v__ast__CallExpr).return_type); bool is_error_type = v__ast__Type_has_flag((*expr->_v__ast__CallExpr).return_type, v__ast__TypeFlag__result) || v__ast__Type_has_flag((*expr->_v__ast__CallExpr).return_type, v__ast__TypeFlag__option); bool is_acceptable_type = v__ast__TypeSymbol_is_int(type_symbol) && !is_error_type; if (!is_acceptable_type) { string error_type_symbol = v__checker__Checker_fn_return_type_flag_to_string(c, (*expr->_v__ast__CallExpr).return_type); v__checker__Checker_orm_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("function calls in `"), 0xfe10, {.d_s = sql_keyword}}, {_S("` must return only an integer type, but `"), 0xfe10, {.d_s = (*expr->_v__ast__CallExpr).name}}, {_S("` returns `"), 0xfe10, {.d_s = error_type_symbol}}, {_SLIT0, 0xfe10, {.d_s = type_symbol->name}}, {_S("`"), 0, { .d_c = 0 }}})), (*expr->_v__ast__CallExpr).pos); } return; } else if ((expr)->_typ == 374 /* v.ast.ParExpr */) { v__checker__Checker_check_sql_expr_type_is_int(c, &(*expr->_v__ast__ParExpr).expr, sql_keyword); return; } v__checker__Checker_orm_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("the type of `"), 0xfe10, {.d_s = sql_keyword}}, {_S("` must be an integer type"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(*expr)); } VV_LOC void v__checker__Checker_orm_error(v__checker__Checker* c, string message, v__token__Pos pos) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("ORM: "), 0xfe10, {.d_s = message}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); } VV_LOC void v__checker__Checker_check_expr_has_no_fn_calls_with_non_orm_return_type(v__checker__Checker* c, v__ast__Expr* expr) { if ((expr)->_typ == 344 /* v.ast.CallExpr */) { if ((*expr->_v__ast__CallExpr).return_type == 0) { return; } v__ast__TypeSymbol* type_symbol = v__ast__Table_sym(c->table, (*expr->_v__ast__CallExpr).return_type); bool is_time = fast_string_eq(type_symbol->cname, _S("time__Time")); bool is_not_pointer = !v__ast__TypeSymbol_is_pointer(type_symbol); bool is_error_type = v__ast__Type_has_flag((*expr->_v__ast__CallExpr).return_type, v__ast__TypeFlag__result) || v__ast__Type_has_flag((*expr->_v__ast__CallExpr).return_type, v__ast__TypeFlag__option); bool is_acceptable_type = (v__ast__TypeSymbol_is_primitive(type_symbol) || is_time) && is_not_pointer && !is_error_type; if (!is_acceptable_type) { string error_type_symbol = v__checker__Checker_fn_return_type_flag_to_string(c, (*expr->_v__ast__CallExpr).return_type); v__checker__Checker_orm_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("function calls must return only primitive types and time.Time, but `"), 0xfe10, {.d_s = (*expr->_v__ast__CallExpr).name}}, {_S("` returns `"), 0xfe10, {.d_s = error_type_symbol}}, {_SLIT0, 0xfe10, {.d_s = type_symbol->name}}, {_S("`"), 0, { .d_c = 0 }}})), (*expr->_v__ast__CallExpr).pos); } } else if ((expr)->_typ == 374 /* v.ast.ParExpr */) { v__checker__Checker_check_expr_has_no_fn_calls_with_non_orm_return_type(c, &(*expr->_v__ast__ParExpr).expr); } else if ((expr)->_typ == 362 /* v.ast.InfixExpr */) { v__checker__Checker_check_expr_has_no_fn_calls_with_non_orm_return_type(c, &(*expr->_v__ast__InfixExpr).left); v__checker__Checker_check_expr_has_no_fn_calls_with_non_orm_return_type(c, &(*expr->_v__ast__InfixExpr).right); if (v__ast__Type_has_flag((*expr->_v__ast__InfixExpr).right_type, v__ast__TypeFlag__option) && !((*expr->_v__ast__InfixExpr).op == v__token__Kind__key_is || (*expr->_v__ast__InfixExpr).op == v__token__Kind__not_is)) { v__checker__Checker_warn(c, _S("comparison with Option value probably isn\'t intended; use \"is none\" and \"!is none\" to select by NULL"), (*expr->_v__ast__InfixExpr).pos); } else if ((*expr->_v__ast__InfixExpr).right_type == _const_v__ast__none_type && !((*expr->_v__ast__InfixExpr).op == v__token__Kind__key_is || (*expr->_v__ast__InfixExpr).op == v__token__Kind__not_is)) { v__checker__Checker_warn(c, _S("comparison with none probably isn\'t intended; use \"is none\" and \"!is none\" to select by NULL"), (*expr->_v__ast__InfixExpr).pos); } } } VV_LOC void v__checker__Checker_check_where_expr_has_no_pointless_exprs(v__checker__Checker* c, v__ast__TypeSymbol* table_type_symbol, Array_string field_names, v__ast__Expr* expr) { if ((expr)->_typ == 371 /* v.ast.None */) { return; } if ((expr)->_typ == 362 /* v.ast.InfixExpr */) { string has_no_field_error = str_intp(3, _MOV((StrIntpData[]){{_S("left side of the `"), 0xfe10, {.d_s = v__token__Kind_str((*expr->_v__ast__InfixExpr).op)}}, {_S("` expression must be one of the `"), 0xfe10, {.d_s = table_type_symbol->name}}, {_S("`'s fields"), 0, { .d_c = 0 }}})); if (((*expr->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */) { string left_ident_name = (*(*expr->_v__ast__InfixExpr).left._v__ast__Ident).name; if (!v__ast__TypeSymbol_has_field(table_type_symbol, left_ident_name)) { v__checker__Checker_orm_error(c, v__util__Suggestion_say(v__util__new_suggestion(left_ident_name, field_names, ((v__util__SuggestionParams){.similarity_threshold = 0.5,.similarity_fn = strings__dice_coefficient,})), has_no_field_error), (*(*expr->_v__ast__InfixExpr).left._v__ast__Ident).pos); } } else if (((*expr->_v__ast__InfixExpr).left)._typ == 362 /* v.ast.InfixExpr */ || ((*expr->_v__ast__InfixExpr).left)._typ == 374 /* v.ast.ParExpr */ || ((*expr->_v__ast__InfixExpr).left)._typ == 376 /* v.ast.PrefixExpr */) { v__checker__Checker_check_where_expr_has_no_pointless_exprs(c, table_type_symbol, field_names, &(*expr->_v__ast__InfixExpr).left); } else if (!(((*expr->_v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ && v__type_resolver__ResolverInfo_is_comptime_selector_field_name(c->comptime, *(v__ast__SelectorExpr*)__as_cast(((*expr->_v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*expr->_v__ast__InfixExpr).left)._typ, 379), _S("name")))) { v__checker__Checker_orm_error(c, has_no_field_error, v__ast__Expr_pos((*expr->_v__ast__InfixExpr).left)); } if (((*expr->_v__ast__InfixExpr).right)._typ == 362 /* v.ast.InfixExpr */ || ((*expr->_v__ast__InfixExpr).right)._typ == 374 /* v.ast.ParExpr */ || ((*expr->_v__ast__InfixExpr).right)._typ == 376 /* v.ast.PrefixExpr */) { v__checker__Checker_check_where_expr_has_no_pointless_exprs(c, table_type_symbol, field_names, &(*expr->_v__ast__InfixExpr).right); } } else if ((expr)->_typ == 374 /* v.ast.ParExpr */) { v__checker__Checker_check_where_expr_has_no_pointless_exprs(c, table_type_symbol, field_names, &(*expr->_v__ast__ParExpr).expr); } else if ((expr)->_typ == 376 /* v.ast.PrefixExpr */) { v__checker__Checker_check_where_expr_has_no_pointless_exprs(c, table_type_symbol, field_names, &(*expr->_v__ast__PrefixExpr).right); } else { v__checker__Checker_orm_error(c, _S("`where` expression must have at least one comparison for filtering rows"), v__ast__Expr_pos(*expr)); } } VV_LOC string v__checker__Checker_fn_return_type_flag_to_string(v__checker__Checker* _d1, v__ast__Type typ) { bool is_result_type = v__ast__Type_has_flag(typ, v__ast__TypeFlag__result); bool is_option_type = v__ast__Type_has_flag(typ, v__ast__TypeFlag__option); return (is_result_type ? (_S("!")) : is_option_type ? (_S("?")) : (_S(""))); } VV_LOC void v__checker__Checker_check_orm_or_expr(v__checker__Checker* c, v__checker__ORMExpr* expr) { if ((expr)->_typ == 382 /* v.ast.SqlExpr */) { if ((*expr->_v__ast__SqlExpr).is_generated) { return; } } v__ast__Type return_type = ((expr)->_typ == 382 /* v.ast.SqlExpr */ ? ((*expr->_v__ast__SqlExpr).typ) : (v__ast__Type_set_flag(_const_v__ast__void_type, v__ast__TypeFlag__result))); if ((*(expr->or_expr)).kind == v__ast__OrKind__absent) { if (c->inside_defer) { v__checker__Checker_error(c, _S("ORM returns a result, so it should have an `or {}` block at the end"), (*(expr->pos))); } else { v__checker__Checker_error(c, _S("ORM returns a result, so it should have either an `or {}` block, or `!` at the end"), (*(expr->pos))); } } else { v__checker__Checker_check_or_expr(c, (*(expr->or_expr)), v__ast__Type_clear_flag(return_type, v__ast__TypeFlag__result), return_type, ((expr)->_typ == 382 /* v.ast.SqlExpr */ ? (v__ast__SqlExpr_to_sumtype_v__ast__Expr(&(*expr->_v__ast__SqlExpr))) : (_const_v__ast__empty_expr))); } if ((*(expr->or_expr)).kind == v__ast__OrKind__block) { c->expected_or_type = v__ast__Type_clear_flag(return_type, v__ast__TypeFlag__result); v__checker__Checker_stmts_ending_with_expression(c, &(*(expr->or_expr)).stmts, c->expected_or_type); c->expected_or_type = _const_v__ast__void_type; } } VV_LOC bool v__checker__Checker_check_db_expr(v__checker__Checker* c, v__ast__Expr* db_expr) { v__ast__Type connection_type_index = v__ast__Table_find_type(c->table, _S("orm.Connection")); v__ast__Type connection_typ = connection_type_index; v__ast__Type db_expr_type = v__checker__Checker_expr(c, db_expr); if (connection_type_index == 0) { v__checker__Checker_error(c, _S("expected a type that implements the `orm.Connection` interface"), v__ast__Expr_pos(*db_expr)); return false; } bool is_implemented = v__checker__Checker_type_implements(c, db_expr_type, connection_typ, v__ast__Expr_pos(*db_expr)); bool is_option = v__ast__Type_has_flag(db_expr_type, v__ast__TypeFlag__option); if (is_implemented && is_option) { v__checker__Checker_error(c, v__checker__Checker_expected_msg(c, db_expr_type, v__ast__Type_clear_flag(db_expr_type, v__ast__TypeFlag__option)), v__ast__Expr_pos(*db_expr)); return false; } return true; } VV_LOC bool v__checker__Checker_check_orm_table_expr_type(v__checker__Checker* c, v__ast__TypeNode* type_node) { v__ast__TypeSymbol* table_sym = v__ast__Table_sym(c->table, type_node->typ); if ((table_sym->info)._typ != 518 /* v.ast.Struct */) { v__checker__Checker_orm_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("the table symbol `"), 0xfe10, {.d_s = table_sym->name}}, {_S("` has to be a struct"), 0, { .d_c = 0 }}})), type_node->pos); return false; } return true; } VV_LOC v__ast__Type v__checker__Checker_get_field_foreign_table_type(v__checker__Checker* c, v__ast__StructField* table_field) { if (v__ast__Table_sym(c->table, table_field->typ)->kind == v__ast__Kind__struct) { return table_field->typ; } else if (v__ast__Table_sym(c->table, table_field->typ)->kind == v__ast__Kind__array) { return v__ast__TypeSymbol_array_info(v__ast__Table_sym(c->table, table_field->typ)).elem_type; } else { return _const_v__ast__no_type; } return 0; } VV_LOC Array_v__ast__StructField v__checker__Checker_get_orm_non_primitive_fields(v__checker__Checker* c, Array_v__ast__StructField fields) { Array_v__ast__StructField res = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); for (int _t1 = 0; _t1 < fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t1]; v__ast__Type type_with_no_option_flag = v__ast__Type_clear_flag(field.typ, v__ast__TypeFlag__option); bool is_struct = (*(v__ast__TypeSymbol**)array_get(c->table->type_symbols, ((int)(type_with_no_option_flag))))->kind == v__ast__Kind__struct; bool is_array = v__ast__Table_sym(c->table, type_with_no_option_flag)->kind == v__ast__Kind__array; bool is_array_with_struct_elements = is_array && v__ast__Table_sym(c->table, v__ast__TypeSymbol_array_info(v__ast__Table_sym(c->table, type_with_no_option_flag)).elem_type)->kind == v__ast__Kind__struct; bool is_time = string__eq(v__ast__Table_get_type_name(c->table, type_with_no_option_flag), _S("time.Time")); if ((is_struct || is_array_with_struct_elements) && !is_time) { array_push((array*)&res, _MOV((v__ast__StructField[]){ field })); } } return res; } VV_LOC bool v__checker__Checker_check_field_of_inserting_struct_is_uninitialized(v__checker__Checker* _d1, v__ast__SqlStmtLine* node, string field_name) { _option_v__ast__Var_ptr _t1 = v__ast__Scope_find_var(node->scope, node->object_var); if (_t1.state != 0) { IError err = _t1.err; return false; } v__ast__Var* struct_scope = (*(v__ast__Var**)_t1.data); if ((struct_scope->expr)._typ == 385 /* v.ast.StructInit */) { Array_v__ast__StructInitField _t4 = {0}; Array_v__ast__StructInitField _t4_orig = (*struct_scope->expr._v__ast__StructInit).init_fields; int _t4_len = _t4_orig.len; _t4 = __new_array(0, _t4_len, sizeof(v__ast__StructInitField)); for (int _t5 = 0; _t5 < _t4_len; ++_t5) { v__ast__StructInitField it = ((v__ast__StructInitField*) _t4_orig.data)[_t5]; if (string__eq(it.name, field_name)) { array_push((array*)&_t4, &it); } } return _t4.len == 0; } return false; } VV_LOC bool v__checker__Checker_check_recursive_structs(v__checker__Checker* c, v__ast__TypeSymbol* ts, string struct_name) { if ((ts->info)._typ == 518 /* v.ast.Struct */) { for (int _t1 = 0; _t1 < (*ts->info._v__ast__Struct).fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)(*ts->info._v__ast__Struct).fields.data)[_t1]; multi_return_v__ast__Type_ref_v__ast__TypeSymbol mr_22141 = v__checker__Checker_get_non_array_type(c, field.typ); v__ast__TypeSymbol* field_sym = mr_22141.arg1; if (field_sym->kind == v__ast__Kind__struct && string__eq(field_sym->name, struct_name)) { return true; } } } return false; } VV_LOC multi_return_v__ast__Type_ref_v__ast__TypeSymbol v__checker__Checker_get_non_array_type(v__checker__Checker* c, v__ast__Type typ_) { v__ast__Type typ = typ_; v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); for (;;) { if (sym->kind == v__ast__Kind__array) { typ = v__ast__TypeSymbol_array_info(sym).elem_type; sym = v__ast__Table_sym(c->table, typ); } else { break; } } return (multi_return_v__ast__Type_ref_v__ast__TypeSymbol){.arg0=typ, .arg1=sym}; } VV_LOC v__ast__Type v__checker__Checker_postfix_expr(v__checker__Checker* c, v__ast__PostfixExpr* node) { v__ast__Type typ = v__checker__Checker_unwrap_generic(c, v__type_resolver__TypeResolver_get_type_or_default(&c->type_resolver, v__ast__PostfixExpr_to_sumtype_v__ast__Expr(node), v__checker__Checker_expr(c, &node->expr))); v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, typ); bool is_non_void_pointer = v__ast__Type_is_any_kind_of_pointer(typ) && typ_sym->kind != v__ast__Kind__voidptr; if ((node->op == v__token__Kind__inc || node->op == v__token__Kind__dec) && !v__ast__Expr_is_lvalue(node->expr)) { multi_return_string_string mr_379 = (node->op == v__token__Kind__inc ? ((multi_return_string_string){.arg0=_S("increment"),.arg1=_S("+")}) : ((multi_return_string_string){.arg0=_S("decrement"),.arg1=_S("-")})); string op_kind = mr_379.arg0; string bin_op_alt = mr_379.arg1; v__checker__Checker_add_error_detail(c, str_intp(3, _MOV((StrIntpData[]){{_S("try rewrite this as `"), 0xfe10, {.d_s = v__ast__Expr_str(&node->expr)}}, {_S(" "), 0xfe10, {.d_s = bin_op_alt}}, {_S(" 1`"), 0, { .d_c = 0 }}}))); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot "), 0xfe10, {.d_s = op_kind}}, {_S(" `"), 0xfe10, {.d_s = v__ast__Expr_str(&node->expr)}}, {_S("` because it is non lvalue expression"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->expr)); } if (node->op != v__token__Kind__question && !c->inside_unsafe && is_non_void_pointer && !v__ast__Expr_is_auto_deref_var(node->expr)) { if (!c->pref->translated && !c->file->is_translated) { v__checker__Checker_warn(c, _S("pointer arithmetic is only allowed in `unsafe` blocks"), node->pos); } } if (!(v__ast__TypeSymbol_is_number(typ_sym) || ((c->inside_unsafe || c->pref->translated) && is_non_void_pointer))) { if ((c->comptime->comptime_for_field_var).len != 0) { if (v__type_resolver__ResolverInfo_is_comptime(c->comptime, node->expr) || (node->expr)._typ == 350 /* v.ast.ComptimeSelector */) { node->typ = v__checker__Checker_unwrap_generic(c, v__type_resolver__TypeResolver_get_type(&c->type_resolver, node->expr)); if (node->op == v__token__Kind__question) { node->typ = v__ast__Type_clear_flag(node->typ, v__ast__TypeFlag__option); } return node->typ; } } string typ_str = v__ast__Table_type_to_str(c->table, typ); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("invalid operation: "), 0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_S(" (non-numeric type `"), 0xfe10, {.d_s = typ_str}}, {_S("`)"), 0, { .d_c = 0 }}})), node->pos); } else { if (node->op != v__token__Kind__question) { multi_return_string_v__token__Pos mr_1473 = v__checker__Checker_fail_if_immutable(c, &node->expr); node->auto_locked = mr_1473.arg0; } } node->typ = typ; return typ; } VV_LOC string v__checker__Checker_error_type_name(v__checker__Checker* c, v__ast__Type exp_type) { return (exp_type == v__ast__Type_set_flag(_const_v__ast__void_type, v__ast__TypeFlag__result) ? (_S("Result type")) : exp_type == v__ast__Type_set_flag(_const_v__ast__void_type, v__ast__TypeFlag__option) ? (_S("Option type")) : (str_intp(2, _MOV((StrIntpData[]){{_S("type `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, exp_type)}}, {_S("`"), 0, { .d_c = 0 }}})))); } VV_LOC void v__checker__Checker_return_stmt(v__checker__Checker* c, v__ast__Return* node) { bool v__checker__Checker_return_stmt_defer_0 = false; bool prev_inside_return; if (c->table->cur_fn == ((void*)0)) { return; } prev_inside_return = c->inside_return; c->inside_return = true; v__checker__Checker_return_stmt_defer_0 = true; c->expected_type = c->table->cur_fn->return_type; v__ast__Type expected_type = v__checker__Checker_unwrap_generic(c, c->expected_type); if (expected_type != 0 && v__ast__Table_sym(c->table, expected_type)->kind == v__ast__Kind__alias) { v__ast__Type unaliased_type = v__ast__Table_unaliased_type(c->table, expected_type); if (v__ast__Type_has_option_or_result(unaliased_type)) { expected_type = unaliased_type; } } v__ast__TypeSymbol* expected_type_sym = v__ast__Table_sym(c->table, expected_type); if ((expected_type_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { v__ast__Table_find_or_register_array_fixed(c->table, (*expected_type_sym->info._v__ast__ArrayFixed).elem_type, (*expected_type_sym->info._v__ast__ArrayFixed).size, (*expected_type_sym->info._v__ast__ArrayFixed).size_expr, true); } if (node->exprs.len > 0 && c->table->cur_fn->return_type == _const_v__ast__void_type) { v__checker__Checker_error(c, _S("unexpected argument, current function does not return anything"), v__ast__Expr_pos((*(v__ast__Expr*)array_get(node->exprs, 0)))); // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } else if (node->exprs.len > 1 && c->table->cur_fn->return_type == v__ast__Type_set_flag(_const_v__ast__void_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("can only return `none` from an Option-only return function"), v__ast__Expr_pos((*(v__ast__Expr*)array_get(node->exprs, 0)))); // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } else if (node->exprs.len > 1 && c->table->cur_fn->return_type == v__ast__Type_set_flag(_const_v__ast__void_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("functions with Result-only return types can only return an error"), v__ast__Expr_pos((*(v__ast__Expr*)array_get(node->exprs, 0)))); // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } else if (node->exprs.len == 0 && !(c->expected_type == _const_v__ast__void_type || expected_type_sym->kind == v__ast__Kind__void)) { string stype = v__ast__Table_type_to_str(c->table, expected_type); string arg = (expected_type_sym->kind == v__ast__Kind__multi_return ? (_S("arguments")) : (_S("argument"))); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("expected `"), 0xfe10, {.d_s = stype}}, {_S("` "), 0xfe10, {.d_s = arg}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } if (node->exprs.len == 0) { // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } bool exp_is_option = v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__option); bool exp_is_result = v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__result); Array_v__ast__Type expected_types = new_array_from_c_array(1, 1, sizeof(v__ast__Type), _MOV((v__ast__Type[1]){expected_type})); if ((expected_type_sym->info)._typ == 552 /* v.ast.MultiReturn */) { expected_types = array_clone_to_depth(&(*expected_type_sym->info._v__ast__MultiReturn).types, 0); if (c->table->cur_concrete_types.len > 0) { Array_v__ast__Type _t1 = {0}; Array_v__ast__Type _t1_orig = expected_types; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t3]; v__ast__Type _t2 = v__checker__Checker_unwrap_generic(c, it); array_push((array*)&_t1, &_t2); } expected_types =_t1; map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__ast__Table_find_or_register_multi_return(c->table, expected_types)}, &(bool[]) { true }); } } Array_v__ast__Type got_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); Array_int expr_idxs = __new_array_with_default(0, 0, sizeof(int), 0); for (int i = 0; i < node->exprs.len; ++i) { v__ast__Expr* expr = ((v__ast__Expr*)node->exprs.data) + i; v__ast__Type typ = v__checker__Checker_expr(c, expr); if (typ == 0) { // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } if ((expr)->_typ == 388 /* v.ast.UnsafeExpr */ && ((*(v__ast__UnsafeExpr*)__as_cast((expr)->_v__ast__UnsafeExpr,(expr)->_typ, 388)).expr)._typ == 371 /* v.ast.None */) { v__checker__Checker_error(c, _S("cannot return `none` in unsafe block"), (*(*expr->_v__ast__UnsafeExpr).expr._v__ast__None).pos); } if (typ == _const_v__ast__void_type) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__ast__Expr_str(expr)}}, {_S("` used as value"), 0, { .d_c = 0 }}})), node->pos); // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, typ); if (sym->kind == v__ast__Kind__multi_return) { if (i > 0 || i != (int)(node->exprs.len - 1)) { v__checker__Checker_error(c, _S("cannot use multi-return with other return types"), v__ast__Expr_pos(*expr)); } for (int _t4 = 0; _t4 < v__ast__TypeSymbol_mr_info(sym).types.len; ++_t4) { v__ast__Type t = ((v__ast__Type*)v__ast__TypeSymbol_mr_info(sym).types.data)[_t4]; array_push((array*)&got_types, _MOV((v__ast__Type[]){ t })); array_push((array*)&expr_idxs, _MOV((int[]){ i })); } } else { if ((expr)->_typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((expr)->_v__ast__Ident,(expr)->_typ, 358)).obj)._typ == 422 /* v.ast.Var */) { if ((*(*expr->_v__ast__Ident).obj._v__ast__Var).smartcasts.len > 0) { typ = v__checker__Checker_unwrap_generic(c, (*(v__ast__Type*)array_last((*(*expr->_v__ast__Ident).obj._v__ast__Var).smartcasts))); } if ((*(*expr->_v__ast__Ident).obj._v__ast__Var).ct_type_var != v__ast__ComptimeVarKind__no_comptime) { typ = v__type_resolver__TypeResolver_get_type_or_default(&c->type_resolver, v__ast__Ident_to_sumtype_v__ast__Expr(&(*expr->_v__ast__Ident)), typ); } if (((*(*expr->_v__ast__Ident).obj._v__ast__Var).expr)._typ == 360 /* v.ast.IfGuardExpr */) { _option_v__ast__Var_ptr _t7; if (_t7 = v__ast__Scope_find_var((*expr->_v__ast__Ident).scope, (*expr->_v__ast__Ident).name), _t7.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t7.data; typ = var->typ; } } } array_push((array*)&got_types, _MOV((v__ast__Type[]){ typ })); array_push((array*)&expr_idxs, _MOV((int[]){ i })); } } node->types = got_types; #if defined(CUSTOM_DEFINE_debug_manualfree) { v__ast__FnDecl* cfn = c->table->cur_fn; if (cfn->is_manualfree) { Array_string _t11 = {0}; Array_v__ast__Param _t11_orig = cfn->params; int _t11_len = _t11_orig.len; _t11 = __new_array(0, _t11_len, sizeof(string)); for (int _t13 = 0; _t13 < _t11_len; ++_t13) { v__ast__Param it = ((v__ast__Param*) _t11_orig.data)[_t13]; string _t12 = it.name; array_push((array*)&_t11, &_t12); } Array_string pnames =_t11; for (int _t14 = 0; _t14 < node->exprs.len; ++_t14) { v__ast__Expr expr = ((v__ast__Expr*)node->exprs.data)[_t14]; if ((expr)._typ == 358 /* v.ast.Ident */) { if ((Array_string_contains(pnames, (*expr._v__ast__Ident).name))) { v__checker__Checker_note(c, _S("returning a parameter in a fn marked with `@[manualfree]` can cause double freeing in the caller"), node->pos); } } } } } #endif int option_type_idx = (*(int*)map_get(ADDR(map, c->table->type_idxs), &(string[]){_S("_option")}, &(int[]){ 0 })); int result_type_idx = (*(int*)map_get(ADDR(map, c->table->type_idxs), &(string[]){_S("_result")}, &(int[]){ 0 })); int got_types_0_idx = v__ast__Type_idx((*(v__ast__Type*)array_get(got_types, 0))); if (exp_is_option && got_types_0_idx == 30) { v__checker__Checker_error(c, _S("Option and Result types have been split, use `!Foo` to return errors"), node->pos); } else if (exp_is_result && got_types_0_idx == 20) { v__checker__Checker_error(c, _S("Option and Result types have been split, use `?` to return none"), node->pos); } bool expected_fn_return_type_has_option = v__ast__Type_has_flag(c->table->cur_fn->return_type, v__ast__TypeFlag__option); bool expected_fn_return_type_has_result = v__ast__Type_has_flag(c->table->cur_fn->return_type, v__ast__TypeFlag__result); if (exp_is_option && expected_fn_return_type_has_result) { if (got_types_0_idx == 20) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use `none` as "), 0xfe10, {.d_s = v__checker__Checker_error_type_name(c, v__ast__Table_unaliased_type(c->table, c->table->cur_fn->return_type))}}, {_S(" in return argument"), 0, { .d_c = 0 }}})), node->pos); // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } if (exp_is_result && expected_fn_return_type_has_option) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expecting to return a ?Type, but you are returning "), 0xfe10, {.d_s = v__checker__Checker_error_type_name(c, expected_type)}}, {_S(" instead"), 0, { .d_c = 0 }}})), node->pos); // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } if ((exp_is_option && (got_types_0_idx == _const_v__ast__none_type_idx || got_types_0_idx == _const_v__ast__error_type_idx || got_types_0_idx == option_type_idx)) || (exp_is_result && (got_types_0_idx == _const_v__ast__error_type_idx || got_types_0_idx == result_type_idx))) { // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } if (expected_types.len > 0 && expected_types.len != got_types.len) { if ((exp_is_option || exp_is_result) && node->exprs.len == 1) { v__ast__Expr expr_ = (*(v__ast__Expr*)array_get(node->exprs, 0)); v__ast__Type got_type = v__checker__Checker_expr(c, &expr_); v__ast__TypeSymbol* got_type_sym = v__ast__Table_sym(c->table, got_type); if (got_type_sym->kind == v__ast__Kind__struct && v__checker__Checker_type_implements(c, got_type, _const_v__ast__error_type, node->pos)) { array_set(&node->exprs, 0, &(v__ast__Expr[]) { v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = _const_v__ast__error_type,.expr = (*(v__ast__Expr*)array_get(node->exprs, 0)),.typname = _S("IError"),.expr_type = got_type,.has_arg = 0,.pos = node->pos,})))) }); array_set(&node->types, 0, &(v__ast__Type[]) { _const_v__ast__error_type }); // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } } string arg = (expected_types.len == 1 ? (_S("argument")) : (_S("arguments"))); int midx = int_max(0, int_min(expected_types.len, (int)(expr_idxs.len - 1))); v__token__Pos mismatch_pos = v__ast__Expr_pos((*(v__ast__Expr*)array_get(node->exprs, (*(int*)array_get(expr_idxs, midx))))); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("expected "), 0xfe07, {.d_i32 = expected_types.len}}, {_S(" "), 0xfe10, {.d_s = arg}}, {_S(", but got "), 0xfe07, {.d_i32 = got_types.len}}, {_SLIT0, 0, { .d_c = 0 }}})), mismatch_pos); // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end return; } for (int i = 0; i < expected_types.len; ++i) { v__ast__Type exp_type = ((v__ast__Type*)expected_types.data)[i]; v__ast__Expr exprv = (*(v__ast__Expr*)array_get(node->exprs, (*(int*)array_get(expr_idxs, i)))); if ((exprv)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((exprv)._v__ast__Ident,(exprv)._typ, 358)).or_expr.kind == v__ast__OrKind__propagate_option) { if (v__ast__Type_has_flag(exp_type, v__ast__TypeFlag__option)) { v__checker__Checker_warn(c, _S("unwrapping option is redundant as the function returns option"), node->pos); } else { v__checker__Checker_error(c, _S("should not unwrap option var on return, it could be none"), node->pos); } } v__ast__Type got_type = v__checker__Checker_unwrap_generic(c, (*(v__ast__Type*)array_get(got_types, i))); if (v__ast__Type_has_flag(got_type, v__ast__TypeFlag__option) && (!v__ast__Type_has_flag(exp_type, v__ast__TypeFlag__option) || !v__checker__Checker_check_types(c, v__ast__Type_clear_flag(got_type, v__ast__TypeFlag__option), v__ast__Type_clear_flag(exp_type, v__ast__TypeFlag__option)))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, got_type)}}, {_S("` as "), 0xfe10, {.d_s = v__checker__Checker_error_type_name(c, exp_type)}}, {_S(" in return argument"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(exprv)); } if (v__ast__Type_has_flag(got_type, v__ast__TypeFlag__result) && (!v__ast__Type_has_flag(exp_type, v__ast__TypeFlag__result) || !string__eq(v__ast__Table_type_to_str(c->table, got_type), v__ast__Table_type_to_str(c->table, exp_type)))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, got_type)}}, {_S("` as "), 0xfe10, {.d_s = v__checker__Checker_error_type_name(c, exp_type)}}, {_S(" in return argument"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(exprv)); } if ((exprv)._typ == 349 /* v.ast.ComptimeCall */ && (*(v__ast__ComptimeCall*)__as_cast((exprv)._v__ast__ComptimeCall,(exprv)._typ, 349)).kind == v__ast__ComptimeCallKind__tmpl && v__ast__Table_final_sym(c->table, exp_type)->kind != v__ast__Kind__string) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use `string` as type `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, exp_type)}}, {_S("` in return argument"), 0, { .d_c = 0 }}})), (*exprv._v__ast__ComptimeCall).pos); } if ((exprv)._typ != 349 /* v.ast.ComptimeCall */) { v__ast__TypeSymbol* got_type_sym = v__ast__Table_sym(c->table, got_type); v__ast__TypeSymbol* exp_type_sym = v__ast__Table_sym(c->table, exp_type); if (v__checker__Checker_check_types(c, got_type, exp_type)) { if (v__ast__Type_is_unsigned(exp_type) && v__ast__Type_is_int_literal(got_type)) { if ((exprv)._typ == 363 /* v.ast.IntegerLiteral */) { string var = (*(v__ast__IntegerLiteral*)__as_cast(((*(v__ast__Expr*)array_get(node->exprs, (*(int*)array_get(expr_idxs, i)))))._v__ast__IntegerLiteral,((*(v__ast__Expr*)array_get(node->exprs, (*(int*)array_get(expr_idxs, i)))))._typ, 363)).val; if (string_at(var, 0) == '-') { v__checker__Checker_note(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use a negative value as value of "), 0xfe10, {.d_s = v__checker__Checker_error_type_name(c, exp_type)}}, {_S(" in return argument"), 0, { .d_c = 0 }}})), (*exprv._v__ast__IntegerLiteral).pos); } } } } else { if (c->pref->skip_unused && v__ast__Type_has_flag((*(v__ast__Type*)array_get(got_types, i)), v__ast__TypeFlag__generic)) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){got_type}, &(bool[]) { true }); } if (exp_type_sym->kind == v__ast__Kind__interface) { if (v__checker__Checker_type_implements(c, got_type, exp_type, node->pos)) { if (!v__ast__Type_is_any_kind_of_pointer(got_type) && got_type_sym->kind != v__ast__Kind__interface && !c->inside_unsafe) { v__checker__Checker_mark_as_referenced(c, &(*(v__ast__Expr*)array_get(node->exprs, (*(int*)array_get(expr_idxs, i)))), true); } } continue; } v__ast__TypeSymbol* exp_final_sym = v__ast__Table_final_sym(c->table, exp_type); v__ast__TypeSymbol* got_final_sym = v__ast__Table_final_sym(c->table, got_type); if (exp_final_sym->kind == v__ast__Kind__array_fixed && got_final_sym->kind == v__ast__Kind__array_fixed) { v__ast__TypeSymbol* got_arr_sym = v__ast__Table_sym(c->table, v__checker__Checker_cast_to_fixed_array_ret(c, got_type, *got_final_sym)); if (v__ast__ArrayFixed_is_compatible(((v__ast__ArrayFixed*)__as_cast((exp_final_sym->info)._v__ast__ArrayFixed,(exp_final_sym->info)._typ, 549)), *(v__ast__ArrayFixed*)__as_cast((got_arr_sym->info)._v__ast__ArrayFixed,(got_arr_sym->info)._typ, 549))) { continue; } } if (expected_fn_return_type_has_result && got_type_sym->kind == v__ast__Kind__struct && v__checker__Checker_type_implements(c, got_type, _const_v__ast__error_type, node->pos)) { array_set(&node->exprs, (*(int*)array_get(expr_idxs, i)), &(v__ast__Expr[]) { v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = _const_v__ast__error_type,.expr = exprv,.typname = _S("IError"),.expr_type = got_type,.has_arg = 0,.pos = node->pos,})))) }); array_set(&node->types, (*(int*)array_get(expr_idxs, i)), &(v__ast__Type[]) { _const_v__ast__error_type }); continue; } string got_type_name = (got_type_sym->kind == v__ast__Kind__function ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, got_type)}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (got_type_sym->name)); if (c->inside_lambda && v__ast__Type_has_flag(exp_type, v__ast__TypeFlag__generic)) { continue; } v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = got_type_name}}, {_S("` as "), 0xfe10, {.d_s = v__checker__Checker_error_type_name(c, exp_type)}}, {_S(" in return argument"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(exprv)); } } if (v__ast__Type_is_any_kind_of_pointer(got_type) && !v__ast__Type_is_any_kind_of_pointer(exp_type) && !v__ast__Type_is_any_kind_of_pointer(v__ast__Table_unaliased_type(c->table, exp_type))) { if (v__ast__Expr_is_auto_deref_var(exprv)) { continue; } v__checker__Checker_add_error_detail(c, _S("use `return *pointer` instead of `return pointer`, and just `return value` instead of `return &value`")); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("fn `"), 0xfe10, {.d_s = c->table->cur_fn->name}}, {_S("` expects you to return a non reference type `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, exp_type)}}, {_S("`, but you are returning `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, got_type)}}, {_S("` instead"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(exprv)); } if (v__ast__Type_is_any_kind_of_pointer(exp_type) && !v__ast__Type_is_any_kind_of_pointer(got_type) && !v__ast__Type_is_any_kind_of_pointer(v__ast__Table_unaliased_type(c->table, got_type)) && got_type != _const_v__ast__int_literal_type && !c->pref->translated && !c->file->is_translated) { if (v__ast__Expr_is_auto_deref_var(exprv)) { continue; } v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("fn `"), 0xfe10, {.d_s = c->table->cur_fn->name}}, {_S("` expects you to return a reference type `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, exp_type)}}, {_S("`, but you are returning `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, got_type)}}, {_S("` instead"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(exprv)); } if (v__ast__Type_is_ptr(exp_type) && v__ast__Type_is_ptr(got_type)) { v__ast__Expr* r_expr = &(*(v__ast__Expr*)array_get(node->exprs, (*(int*)array_get(expr_idxs, i)))); if ((r_expr)->_typ == 358 /* v.ast.Ident */) { v__checker__Checker_fail_if_stack_struct_action_outside_unsafe(c, &/*mut*/(*r_expr->_v__ast__Ident), _S("returned")); } else if ((r_expr)->_typ == 376 /* v.ast.PrefixExpr */ && (*(v__ast__PrefixExpr*)__as_cast((r_expr)->_v__ast__PrefixExpr,(r_expr)->_typ, 376)).op == v__token__Kind__amp) { if (((*r_expr->_v__ast__PrefixExpr).right)._typ == 358 /* v.ast.Ident */) { v__checker__Checker_fail_if_stack_struct_action_outside_unsafe(c, (voidptr)&(*(*r_expr->_v__ast__PrefixExpr).right._v__ast__Ident), _S("returned")); } } } } if (exp_is_option && node->exprs.len > 0) { v__ast__Expr expr0 = (*(v__ast__Expr*)array_get(node->exprs, 0)); if ((expr0)._typ == 344 /* v.ast.CallExpr */) { if ((*expr0._v__ast__CallExpr).or_block.kind == v__ast__OrKind__propagate_option && node->exprs.len == 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`?` is not needed, use `return "), 0xfe10, {.d_s = (*expr0._v__ast__CallExpr).name}}, {_S("()`"), 0, { .d_c = 0 }}})), (*expr0._v__ast__CallExpr).pos); } } } // Defer begin if (v__checker__Checker_return_stmt_defer_0) { c->inside_return = prev_inside_return; } // Defer end } VV_LOC void v__checker__Checker_find_unreachable_statements_after_noreturn_calls(v__checker__Checker* c, Array_v__ast__Stmt stmts) { bool prev_stmt_was_noreturn_call = false; for (int _t1 = 0; _t1 < stmts.len; ++_t1) { v__ast__Stmt stmt = ((v__ast__Stmt*)stmts.data)[_t1]; if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { if (((*stmt._v__ast__ExprStmt).expr)._typ == 344 /* v.ast.CallExpr */) { if (prev_stmt_was_noreturn_call) { v__checker__Checker_error(c, _S("unreachable code after a @[noreturn] call"), (*stmt._v__ast__ExprStmt).pos); return; } prev_stmt_was_noreturn_call = (*(*stmt._v__ast__ExprStmt).expr._v__ast__CallExpr).is_noreturn; } } else { prev_stmt_was_noreturn_call = false; } } } VV_LOC bool v__checker__has_top_return(Array_v__ast__Stmt stmts) { for (int _t1 = 0; _t1 < stmts.len; ++_t1) { v__ast__Stmt stmt = ((v__ast__Stmt*)stmts.data)[_t1]; if (stmt._typ == 412 /* v.ast.Return */) { return true; } else if (stmt._typ == 393 /* v.ast.Block */) { if (v__checker__has_top_return((*stmt._v__ast__Block).stmts)) { return true; } } else if (stmt._typ == 401 /* v.ast.ExprStmt */) { if (((*stmt._v__ast__ExprStmt).expr)._typ == 344 /* v.ast.CallExpr */) { if ((*(*stmt._v__ast__ExprStmt).expr._v__ast__CallExpr).is_noreturn || ((*(*stmt._v__ast__ExprStmt).expr._v__ast__CallExpr).is_method == false && fast_string_eq((*(*stmt._v__ast__ExprStmt).expr._v__ast__CallExpr).name, _S("panic")))) { return true; } } else if (((*stmt._v__ast__ExprStmt).expr)._typ == 349 /* v.ast.ComptimeCall */) { if ((*(*stmt._v__ast__ExprStmt).expr._v__ast__ComptimeCall).kind == v__ast__ComptimeCallKind__compile_error) { return true; } } else if (((*stmt._v__ast__ExprStmt).expr)._typ == 367 /* v.ast.LockExpr */) { if (v__checker__has_top_return((*(*stmt._v__ast__ExprStmt).expr._v__ast__LockExpr).stmts)) { return true; } } } else { } } return false; } VV_LOC void v__checker__Checker_check_noreturn_fn_decl(v__checker__Checker* c, v__ast__FnDecl* node) { if (!node->is_noreturn) { return; } if (node->no_body) { return; } if (node->return_type != _const_v__ast__void_type) { v__checker__Checker_error(c, _S("[noreturn] functions cannot have return types"), node->pos); } if (v__checker__uses_return_stmt(node->stmts)) { v__checker__Checker_error(c, _S("[noreturn] functions cannot use return statements"), node->pos); } v__token__Pos pos = node->pos; bool is_valid_end_of_noreturn_fn = false; if (node->stmts.len != 0) { v__ast__Stmt last_stmt = (*(v__ast__Stmt*)array_last(node->stmts)); if (last_stmt._typ == 401 /* v.ast.ExprStmt */) { if (((*last_stmt._v__ast__ExprStmt).expr)._typ == 344 /* v.ast.CallExpr */) { if ((*(*last_stmt._v__ast__ExprStmt).expr._v__ast__CallExpr).should_be_skipped) { v__checker__Checker_error(c, _S("@[noreturn] functions cannot end with a skippable `@[if ..]` call"), (*last_stmt._v__ast__ExprStmt).pos); return; } if ((*(*last_stmt._v__ast__ExprStmt).expr._v__ast__CallExpr).is_noreturn) { is_valid_end_of_noreturn_fn = true; } } } else if (last_stmt._typ == 404 /* v.ast.ForStmt */) { if ((*last_stmt._v__ast__ForStmt).is_inf && (*last_stmt._v__ast__ForStmt).stmts.len == 0) { is_valid_end_of_noreturn_fn = true; } } else { } if (!is_valid_end_of_noreturn_fn) { pos = (*(last_stmt.pos)); } } if (!is_valid_end_of_noreturn_fn) { v__checker__Checker_error(c, _S("@[noreturn] functions should end with a call to another @[noreturn] function, or with an infinite `for {}` loop"), pos); } } VV_LOC bool v__checker__uses_return_stmt(Array_v__ast__Stmt stmts) { if (stmts.len == 0) { return false; } for (int _t2 = 0; _t2 < stmts.len; ++_t2) { v__ast__Stmt stmt = ((v__ast__Stmt*)stmts.data)[_t2]; if (stmt._typ == 412 /* v.ast.Return */) { return true; } else if (stmt._typ == 393 /* v.ast.Block */) { if (v__checker__uses_return_stmt((*stmt._v__ast__Block).stmts)) { return true; } } else if (stmt._typ == 401 /* v.ast.ExprStmt */) { if ((*stmt._v__ast__ExprStmt).expr._typ == 344 /* v.ast.CallExpr */) { if (v__checker__uses_return_stmt((*(*stmt._v__ast__ExprStmt).expr._v__ast__CallExpr).or_block.stmts)) { return true; } } else if ((*stmt._v__ast__ExprStmt).expr._typ == 369 /* v.ast.MatchExpr */) { for (int _t6 = 0; _t6 < (*(*stmt._v__ast__ExprStmt).expr._v__ast__MatchExpr).branches.len; ++_t6) { v__ast__MatchBranch b = ((v__ast__MatchBranch*)(*(*stmt._v__ast__ExprStmt).expr._v__ast__MatchExpr).branches.data)[_t6]; if (v__checker__uses_return_stmt(b.stmts)) { return true; } } } else if ((*stmt._v__ast__ExprStmt).expr._typ == 378 /* v.ast.SelectExpr */) { for (int _t8 = 0; _t8 < (*(*stmt._v__ast__ExprStmt).expr._v__ast__SelectExpr).branches.len; ++_t8) { v__ast__SelectBranch b = ((v__ast__SelectBranch*)(*(*stmt._v__ast__ExprStmt).expr._v__ast__SelectExpr).branches.data)[_t8]; if (v__checker__uses_return_stmt(b.stmts)) { return true; } } } else if ((*stmt._v__ast__ExprStmt).expr._typ == 359 /* v.ast.IfExpr */) { for (int _t10 = 0; _t10 < (*(*stmt._v__ast__ExprStmt).expr._v__ast__IfExpr).branches.len; ++_t10) { v__ast__IfBranch b = ((v__ast__IfBranch*)(*(*stmt._v__ast__ExprStmt).expr._v__ast__IfExpr).branches.data)[_t10]; if (v__checker__uses_return_stmt(b.stmts)) { return true; } } } else { } } else if (stmt._typ == 404 /* v.ast.ForStmt */) { if (v__checker__uses_return_stmt((*stmt._v__ast__ForStmt).stmts)) { return true; } } else if (stmt._typ == 402 /* v.ast.ForCStmt */) { if (v__checker__uses_return_stmt((*stmt._v__ast__ForCStmt).stmts)) { return true; } } else if (stmt._typ == 403 /* v.ast.ForInStmt */) { if (v__checker__uses_return_stmt((*stmt._v__ast__ForInStmt).stmts)) { return true; } } else { } } return false; } VV_LOC bool v__checker__is_noreturn_callexpr(v__ast__Expr expr) { if ((expr)._typ == 344 /* v.ast.CallExpr */) { return (*expr._v__ast__CallExpr).is_noreturn; } return false; } VV_LOC u8 v__checker__Checker_get_default_fmt(v__checker__Checker* c, v__ast__Type ftyp, v__ast__Type typ) { if (v__ast__Type_has_option_or_result(ftyp)) { return 's'; } else if (v__ast__Type_is_float(typ)) { return 'g'; } else if (v__ast__Type_is_signed(typ) || v__ast__Type_is_int_literal(typ)) { return 'd'; } else if (v__ast__Type_is_unsigned(typ)) { return 'u'; } else if (v__ast__Type_is_pointer(typ)) { return 'p'; } else { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, ftyp)); if (sym->kind == v__ast__Kind__alias) { v__ast__Alias info = *(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539); sym = v__ast__Table_sym(c->table, info.parent_type); if (info.parent_type == _const_v__ast__string_type) { return 's'; } } if (sym->kind == v__ast__Kind__function) { return 's'; } if ((ftyp == _const_v__ast__string_type || ftyp == _const_v__ast__bool_type) || (sym->kind == v__ast__Kind__enum || sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__array_fixed || sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__map || sym->kind == v__ast__Kind__multi_return || sym->kind == v__ast__Kind__sum_type || sym->kind == v__ast__Kind__interface || sym->kind == v__ast__Kind__aggregate || sym->kind == v__ast__Kind__none) || v__ast__Type_has_option_or_result(ftyp) || v__ast__TypeSymbol_has_method(sym, _S("str"))) { return 's'; } else { return '_'; } } return 0; } VV_LOC v__ast__Type v__checker__Checker_string_inter_lit(v__checker__Checker* c, v__ast__StringInterLiteral* node) { bool inside_interface_deref_save = c->inside_interface_deref; c->inside_interface_deref = true; for (int i = 0; i < node->exprs.len; ++i) { v__ast__Expr* expr = ((v__ast__Expr*)node->exprs.data) + i; v__ast__Type expected_type = c->expected_type; c->expected_type = _const_v__ast__string_type; v__ast__Type ftyp = v__checker__Checker_expr(c, expr); c->expected_type = expected_type; ftyp = v__type_resolver__TypeResolver_get_type_or_default(&c->type_resolver, *expr, v__checker__Checker_check_expr_option_or_result_call(c, *expr, ftyp)); if (ftyp == _const_v__ast__void_type || ftyp == 0) { v__checker__Checker_error(c, _S("expression does not return a value"), v__ast__Expr_pos(*expr)); } else if (ftyp == _const_v__ast__char_type && v__ast__Type_nr_muls(ftyp) == 0) { v__checker__Checker_error(c, _S("expression returning type `char` cannot be used in string interpolation directly, print its address or cast it to an integer instead"), v__ast__Expr_pos(*expr)); } if (ftyp == 0) { return _const_v__ast__void_type; } v__checker__Checker_markused_string_inter_lit(c, node, ftyp); v__checker__Checker_fail_if_unreadable(c, *expr, ftyp, _S("interpolation object")); array_push((array*)&node->expr_types, _MOV((v__ast__Type[]){ ftyp })); v__ast__TypeSymbol* ftyp_sym = v__ast__Table_sym(c->table, ftyp); v__ast__Type typ = (ftyp_sym->kind == v__ast__Kind__alias && !v__ast__TypeSymbol_has_method(ftyp_sym, _S("str")) ? (v__ast__Table_unalias_num_type(c->table, ftyp)) : (ftyp)); u8 fmt = (*(u8*)array_get(node->fmts, i)); if (!(fmt == 'E' || fmt == 'F' || fmt == 'G' || fmt == 'e' || fmt == 'f' || fmt == 'g' || fmt == 'd' || fmt == 'u' || fmt == 'x' || fmt == 'X' || fmt == 'o' || fmt == 'c' || fmt == 's' || fmt == 'S' || fmt == 'p' || fmt == 'b' || fmt == '_' || fmt == 'r' || fmt == 'R')) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown format specifier `"), 0xfe01, {.d_c = fmt}}, {_S("`"), 0, { .d_c = 0 }}})), (*(v__token__Pos*)array_get(node->fmt_poss, i))); } if (fmt == '_') { fmt = v__checker__Checker_get_default_fmt(c, ftyp, typ); if (fmt == '_') { if (typ != _const_v__ast__void_type && !(c->inside_lambda && v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("no known default format for type `"), 0xfe10, {.d_s = v__ast__Table_get_type_name(c->table, ftyp)}}, {_S("`"), 0, { .d_c = 0 }}})), (*(v__token__Pos*)array_get(node->fmt_poss, i))); } } else if (v__type_resolver__ResolverInfo_is_comptime(c->comptime, *expr) && v__type_resolver__TypeResolver_get_type_or_default(&c->type_resolver, *expr, _const_v__ast__void_type) != _const_v__ast__void_type) { array_set(&node->need_fmts, i, &(bool[]) { false }); } else { array_set(&node->fmts, i, &(u8[]) { fmt }); array_set(&node->need_fmts, i, &(bool[]) { false }); } } else { if ((*(int*)array_get(node->precisions, i)) != 987698 && !v__ast__Type_is_float(typ)) { v__checker__Checker_error(c, _S("precision specification only valid for float types"), (*(v__token__Pos*)array_get(node->fmt_poss, i))); } if ((*(bool*)array_get(node->pluss, i)) && !v__ast__Type_is_number(typ)) { v__checker__Checker_error(c, _S("plus prefix only allowed for numbers"), (*(v__token__Pos*)array_get(node->fmt_poss, i))); } if (((v__ast__Type_is_unsigned(typ) && !(fmt == 'u' || fmt == 'x' || fmt == 'X' || fmt == 'o' || fmt == 'c' || fmt == 'b')) || (v__ast__Type_is_signed(typ) && !(fmt == 'd' || fmt == 'x' || fmt == 'X' || fmt == 'o' || fmt == 'c' || fmt == 'b')) || (v__ast__Type_is_int_literal(typ) && !(fmt == 'd' || fmt == 'c' || fmt == 'x' || fmt == 'X' || fmt == 'o' || fmt == 'u' || fmt == 'b')) || (v__ast__Type_is_float(typ) && !(fmt == 'E' || fmt == 'F' || fmt == 'G' || fmt == 'e' || fmt == 'f' || fmt == 'g')) || (v__ast__Type_is_pointer(typ) && !(fmt == 'p' || fmt == 'x' || fmt == 'X')) || (v__ast__Type_is_string(typ) && !(fmt == 's' || fmt == 'S' || fmt == 'r' || fmt == 'R')) || ((Array_int_contains(new_array_from_c_array(2, 2, sizeof(int), _MOV((int[2]){_const_v__ast__i64_type_idx, _const_v__ast__f64_type_idx})), v__ast__Type_idx(typ))) && fmt == 'c')) && !(v__ast__Type_is_ptr(typ) && (fmt == 'p' || fmt == 'x' || fmt == 'X'))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("illegal format specifier `"), 0xfe01, {.d_c = fmt}}, {_S("` for type `"), 0xfe10, {.d_s = v__ast__Table_get_type_name(c->table, ftyp)}}, {_S("`"), 0, { .d_c = 0 }}})), (*(v__token__Pos*)array_get(node->fmt_poss, i))); } if ((v__ast__Table_final_sym(c->table, typ)->kind == v__ast__Kind__array || v__ast__Table_final_sym(c->table, typ)->kind == v__ast__Kind__array_fixed || v__ast__Table_final_sym(c->table, typ)->kind == v__ast__Kind__struct || v__ast__Table_final_sym(c->table, typ)->kind == v__ast__Kind__interface || v__ast__Table_final_sym(c->table, typ)->kind == v__ast__Kind__none || v__ast__Table_final_sym(c->table, typ)->kind == v__ast__Kind__map || v__ast__Table_final_sym(c->table, typ)->kind == v__ast__Kind__sum_type) && (fmt == 'E' || fmt == 'F' || fmt == 'G' || fmt == 'e' || fmt == 'f' || fmt == 'g' || fmt == 'd' || fmt == 'u' || fmt == 'x' || fmt == 'X' || fmt == 'o' || fmt == 'c' || fmt == 'p' || fmt == 'b' || fmt == 'r' || fmt == 'R') && !(v__ast__Type_is_ptr(typ) && (fmt == 'p' || fmt == 'x' || fmt == 'X'))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("illegal format specifier `"), 0xfe01, {.d_c = fmt}}, {_S("` for type `"), 0xfe10, {.d_s = v__ast__Table_get_type_name(c->table, ftyp)}}, {_S("`"), 0, { .d_c = 0 }}})), (*(v__token__Pos*)array_get(node->fmt_poss, i))); } array_set(&node->need_fmts, i, &(bool[]) { fmt != v__checker__Checker_get_default_fmt(c, ftyp, typ) }); } if (c->table->cur_fn != ((void*)0) && c->table->cur_fn->is_method && fast_string_eq(c->table->cur_fn->name, _S("str")) && string__eq(c->table->cur_fn->receiver.name, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(expr)}}, {_SLIT0, 0, { .d_c = 0 }}})))) { v__checker__Checker_error(c, _S("cannot call `str()` method recursively"), v__ast__Expr_pos(*expr)); } } c->inside_interface_deref = inside_interface_deref_save; if (c->pref->warn_about_allocs) { v__checker__Checker_warn_alloc(c, _S("string interpolation"), node->pos); } return _const_v__ast__string_type; } VV_LOC v__ast__Type v__checker__Checker_string_lit(v__checker__Checker* c, v__ast__StringLiteral* node) { bool valid_utf8 = encoding__utf8__validate__utf8_string(node->val); if (!valid_utf8) { v__checker__Checker_note(c, _S("invalid utf8 string, please check your file's encoding is utf8"), node->pos); } int idx = 0; for (;;) { if (!(idx < node->val.len)) break; u8 _t1 = node->val.str[ idx]; if (_t1 == ('\\')) { v__token__Pos start_pos = ((v__token__Pos){.len = (node->pos).len,.line_nr = (node->pos).line_nr,.pos = (node->pos).pos,.col = (int)((int)(node->pos.col + 1) + idx),.last_line = (node->pos).last_line,}); int start_idx = idx; idx++; _option_u8 _t2 = string_at_with_check(node->val, idx); ; if (_t2.state != 0) { IError err = _t2.err; return _const_v__ast__string_type; } u8 next_ch = *(byte*)&_t2.data; if (next_ch == '\\') { idx++; } else if (next_ch == 'u') { idx++; _option_u8 _t4 = string_at_with_check(node->val, idx); ; if (_t4.state != 0) { IError err = _t4.err; return _const_v__ast__string_type; } u8 ch = *(byte*)&_t4.data; int hex_char_count = 0; for (;;) { if (!(u8_is_hex_digit(ch))) break; hex_char_count++; v__token__Pos end_pos = ((v__token__Pos){.len = (int)((int)(idx + 1) - start_idx),.line_nr = (start_pos).line_nr,.pos = (start_pos).pos,.col = (start_pos).col,.last_line = (start_pos).last_line,}); if ((hex_char_count >= 1 && hex_char_count <= 5)) { } else if (hex_char_count == (6)) { u8 first_digit = (u8)(node->val.str[ (int)(idx - 5)] - 48); u8 second_digit = (u8)(node->val.str[ (int)(idx - 4)] - 48); if (first_digit > 1) { v__checker__Checker_error(c, _const_v__checker__unicode_lit_overflow_message, end_pos); } else if (first_digit == 1 && second_digit > 0) { v__checker__Checker_error(c, _const_v__checker__unicode_lit_overflow_message, end_pos); } } else { v__checker__Checker_error(c, _const_v__checker__unicode_lit_overflow_message, end_pos); } idx++; _option_u8 _t6 = string_at_with_check(node->val, idx); ; if (_t6.state != 0) { IError err = _t6.err; return _const_v__ast__string_type; } ch = *(byte*)&_t6.data; } } } else { idx++; } } return _const_v__ast__string_type; } VV_LOC v__ast__Type v__checker__Checker_int_lit(v__checker__Checker* c, v__ast__IntegerLiteral* node) { if (node->val.len < 17) { return _const_v__ast__int_literal_type; } string lit = string_to_upper_ascii(string_all_after(string_replace(node->val, _S("_"), _S("")), _S("-"))); bool is_neg = string_starts_with(node->val, _S("-")); if (lit.len > 2 && string_at(lit, 0) == '0' && (string_at(lit, 1) == 'B' || string_at(lit, 1) == 'X' || string_at(lit, 1) == 'O')) { v__checker__LoHiLimit* _t3 = (v__checker__LoHiLimit*)(map_get_check(ADDR(map, _const_v__checker__iencoding_map), &(rune[]){string_at(lit, 1)})); _option_v__checker__LoHiLimit _t2 = {0}; if (_t3) { *((v__checker__LoHiLimit*)&_t2.data) = *((v__checker__LoHiLimit*)_t3); } else { _t2.state = 2; _t2.err = _v_error(_S("map key does not exist")); } if (_t2.state == 0) { v__checker__LoHiLimit lohi = (*(v__checker__LoHiLimit*)_t2.data); _result_void _t4 = v__checker__Checker_check_num_literal(c, lohi, is_neg, string_substr(lit, 2, 2147483647)); if (_t4.is_error) { IError err = _t4.err; v__checker__Checker_num_lit_overflow_error(c, node); ; } ; } } else { v__checker__LoHiLimit lohi = (*(v__checker__LoHiLimit*)map_get(ADDR(map, _const_v__checker__iencoding_map), &(rune[]){'_'}, &(v__checker__LoHiLimit[]){ (v__checker__LoHiLimit){.lower = (string){.str=(byteptr)"", .is_lit=1},.higher = (string){.str=(byteptr)"", .is_lit=1},} })); _result_void _t5 = v__checker__Checker_check_num_literal(c, lohi, is_neg, lit); if (_t5.is_error) { IError err = _t5.err; v__checker__Checker_num_lit_overflow_error(c, node); ; } ; } return _const_v__ast__int_literal_type; } VV_LOC _result_void v__checker__Checker_check_num_literal(v__checker__Checker* c, v__checker__LoHiLimit lohi, bool is_neg, string lit) { string limit = (is_neg ? (lohi.lower) : (lohi.higher)); if (lit.len < limit.len) { return (_result_void){0}; } if (lit.len > limit.len) { return (_result_void){ .is_error=true, .err=_v_error(_S("length overflow")), .data={E_STRUCT} }; } if (lit.len == limit.len) { for (int i = 0; i < lit.len; ++i) { u8 digit = lit.str[i]; if (digit > limit.str[ i]) { return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("value overflow at i: "), 0xfe07, {.d_i32 = i}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } else if (digit < limit.str[ i]) { break; } } } return (_result_void){0}; } VV_LOC void v__checker__Checker_num_lit_overflow_error(v__checker__Checker* c, v__ast__IntegerLiteral* node) { if (c->inside_integer_literal_cast) { return; } v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("integer literal "), 0xfe10, {.d_s = node->val}}, {_S(" overflows int"), 0, { .d_c = 0 }}})), node->pos); } VV_LOC void v__checker__Checker_struct_decl(v__checker__Checker* c, v__ast__StructDecl* node) { bool v__checker__Checker_struct_decl_defer_0 = false; v__util__timing_start(_S("Checker.struct_decl")); v__checker__Checker_struct_decl_defer_0 = true; if ((node->language == v__ast__Language__c || node->language == v__ast__Language__js) && node->generic_types.len > 0) { string lang = (node->language == v__ast__Language__c ? (_S("C")) : (_S("JS"))); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = lang}}, {_S(" structs cannot be declared as generic"), 0, { .d_c = 0 }}})), node->pos); } string node_name = ((node->scoped_name).len != 0 ? (node->scoped_name) : (node->name)); multi_return_ref_v__ast__TypeSymbol_int mr_668 = v__ast__Table_find_sym_and_type_idx(c->table, node_name); v__ast__TypeSymbol* struct_sym = mr_668.arg0; int struct_typ_idx = mr_668.arg1; node->idx = struct_typ_idx; bool has_generic_types = false; if ((struct_sym->info)._typ == 518 /* v.ast.Struct */) { for (int _t1 = 0; _t1 < (*struct_sym->info._v__ast__Struct).fields.len; ++_t1) { v__ast__StructField* symfield = ((v__ast__StructField*)(*struct_sym->info._v__ast__Struct).fields.data) + _t1; symfield->container_typ = struct_typ_idx; if ((*struct_sym->info._v__ast__Struct).is_union) { symfield->is_part_of_union = true; } } if (node->language == v__ast__Language__v && !c->is_builtin_mod && !(*struct_sym->info._v__ast__Struct).is_anon) { v__checker__Checker_check_valid_pascal_case(c, node->name, _S("struct name"), node->pos); } for (int _t2 = 0; _t2 < node->embeds.len; ++_t2) { v__ast__Embed embed = ((v__ast__Embed*)node->embeds.data)[_t2]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(c->table, embed.typ); if ((embed_sym->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(c->table, (*embed_sym->info._v__ast__Alias).parent_type); if (parent_sym->kind != v__ast__Kind__struct) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = embed_sym->name}}, {_S("` (alias of `"), 0xfe10, {.d_s = parent_sym->name}}, {_S("`) is not a struct"), 0, { .d_c = 0 }}})), embed.pos); } } else if (embed_sym->kind != v__ast__Kind__struct) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = embed_sym->name}}, {_S("` is not a struct"), 0, { .d_c = 0 }}})), embed.pos); } else if ((*(v__ast__Struct*)__as_cast((embed_sym->info)._v__ast__Struct,(embed_sym->info)._typ, 518)).is_heap && !v__ast__Type_is_ptr(embed.typ)) { (*struct_sym->info._v__ast__Struct).is_heap = true; } bool embed_is_generic = v__ast__Type_has_flag(embed.typ, v__ast__TypeFlag__generic); if (embed_is_generic) { has_generic_types = true; } if (embed_is_generic && node->generic_types.len > 0) { Array_string embed_generic_names = v__ast__Table_generic_type_names(c->table, embed.typ); Array_string _t3 = {0}; Array_v__ast__Type _t3_orig = node->generic_types; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(string)); for (int _t5 = 0; _t5 < _t3_len; ++_t5) { v__ast__Type it = ((v__ast__Type*) _t3_orig.data)[_t5]; string _t4 = v__ast__Table_type_to_str(c->table, it); array_push((array*)&_t3, &_t4); } Array_string node_generic_names =_t3; for (int _t6 = 0; _t6 < embed_generic_names.len; ++_t6) { string name = ((string*)embed_generic_names.data)[_t6]; if (!(Array_string_contains(node_generic_names, name))) { string struct_generic_names = Array_string_join(node_generic_names, _S(", ")); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("generic type name `"), 0xfe10, {.d_s = name}}, {_S("` is not mentioned in struct `"), 0xfe10, {.d_s = node->name}}, {_S("["), 0xfe10, {.d_s = struct_generic_names}}, {_S("]`"), 0, { .d_c = 0 }}})), embed.pos); } } } } if ((*struct_sym->info._v__ast__Struct).is_minify && !c->pref->output_cross_c) { array_sort_with_compare(&node->fields, ((voidptr)(v__checker__minify_sort_fn))); array_sort_with_compare(&(*struct_sym->info._v__ast__Struct).fields, ((voidptr)(v__checker__minify_sort_fn))); } for (int _t7 = 0; _t7 < node->attrs.len; ++_t7) { v__ast__Attr attr = ((v__ast__Attr*)node->attrs.data)[_t7]; if (node->language != v__ast__Language__c && fast_string_eq(attr.name, _S("typedef"))) { v__checker__Checker_error(c, _S("`typedef` attribute can only be used with C structs"), node->pos); } } for (int _t8 = 0; _t8 < node->fields.len; ++_t8) { v__ast__StructField* field = ((v__ast__StructField*)node->fields.data) + _t8; v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, field->typ); if ((sym->info)._typ == 549 /* v.ast.ArrayFixed */ && v__checker__Checker_array_fixed_has_unresolved_size(c, (v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549))) { v__ast__Expr size_expr = (*sym->info._v__ast__ArrayFixed).size_expr; field->typ = v__checker__Checker_eval_array_fixed_sizes(c, &size_expr, 0, (*sym->info._v__ast__ArrayFixed).elem_type); for (int _t9 = 0; _t9 < (*struct_sym->info._v__ast__Struct).fields.len; ++_t9) { v__ast__StructField* symfield = ((v__ast__StructField*)(*struct_sym->info._v__ast__Struct).fields.data) + _t9; if (string__eq(symfield->name, field->name)) { symfield->typ = field->typ; } } } } v__util__timing_start(_S("Checker.struct setting default_expr_typ")); v__ast__Type old_expected_type = c->expected_type; for (int _t10 = 0; _t10 < node->fields.len; ++_t10) { v__ast__StructField* field = ((v__ast__StructField*)node->fields.data) + _t10; if (_us32_eq(v__ast__Type_set_nr_muls(v__ast__Type_clear_flag(field->typ, v__ast__TypeFlag__option), 0),struct_typ_idx)) { for (int _t11 = 0; _t11 < (*struct_sym->info._v__ast__Struct).fields.len; ++_t11) { v__ast__StructField* symfield = ((v__ast__StructField*)(*struct_sym->info._v__ast__Struct).fields.data) + _t11; if (string__eq(symfield->name, field->name)) { if (v__ast__Type_is_ptr(field->typ)) { symfield->is_recursive = true; } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("recursive struct is only possible with optional pointer (e.g. ?&"), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, v__ast__Type_clear_flag(field->typ, v__ast__TypeFlag__option))}}, {_S(")"), 0, { .d_c = 0 }}})), field->pos); } } } } if (!c->is_builtin_mod && node->language == v__ast__Language__v) { if (!(c->file->is_translated || c->pref->translated)) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, field->typ); bool _t12 = (sym->kind == v__ast__Kind__function && !v__ast__Type_has_flag(field->typ, v__ast__TypeFlag__option) && !field->has_default_expr); if ( _t12 && !Array_v__ast__Attr_contains(field->attrs, _S("required"))) { string error_msg = _S("uninitialized `fn` struct fields are not allowed, since they can result in segfaults; use `?fn` or `@[required]` or initialize the field with `=` (if you absolutely want to have unsafe function pointers, use `= unsafe { nil }`)"); v__checker__Checker_note(c, error_msg, field->pos); } } } if (field->has_default_expr) { c->expected_type = field->typ; field->default_expr_typ = v__checker__Checker_expr(c, &field->default_expr); if (v__ast__Type_is_ptr(field->typ) != v__ast__Type_is_ptr(field->default_expr_typ)) { if (field->default_expr._typ == 344 /* v.ast.CallExpr */) { string err_desc = (v__ast__Type_is_ptr(field->typ) ? (_S("is")) : (_S("is not"))); string val_desc = (v__ast__Type_is_ptr(field->default_expr_typ) ? (_S("is")) : (_S("is not"))); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("field "), 0xfe10, {.d_s = err_desc}}, {_S(" reference but default value "), 0xfe10, {.d_s = val_desc}}, {_S(" reference"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(field->default_expr)); } else if (field->default_expr._typ == 385 /* v.ast.StructInit */) { v__checker__Checker_error(c, _S("reference field must be initialized with reference"), v__ast__Expr_pos(field->default_expr)); } else { } } if (v__ast__Table_final_sym(c->table, field->typ)->kind == v__ast__Kind__voidptr && !(field->default_expr_typ == _const_v__ast__nil_type || field->default_expr_typ == _const_v__ast__voidptr_type || field->default_expr_typ == _const_v__ast__byteptr_type) && !v__ast__Type_is_ptr(field->default_expr_typ) && ((field->default_expr)._typ != 363 /* v.ast.IntegerLiteral */ || ((field->default_expr)._typ == 363 /* v.ast.IntegerLiteral */ && string_int((*(v__ast__IntegerLiteral*)__as_cast((field->default_expr)._v__ast__IntegerLiteral,(field->default_expr)._typ, 363)).val) != 0))) { v__checker__Checker_note(c, str_intp(2, _MOV((StrIntpData[]){{_S("voidptr variables may only be assigned voidptr values (e.g. unsafe { voidptr("), 0xfe10, {.d_s = v__ast__Expr_str(&field->default_expr)}}, {_S(") })"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(field->default_expr)); } v__ast__TypeSymbol* field_sym = v__ast__Table_sym(c->table, field->typ); v__ast__TypeSymbol* expr_sym = v__ast__Table_sym(c->table, field->default_expr_typ); if (field_sym->kind == v__ast__Kind__map && expr_sym->kind == v__ast__Kind__map && v__ast__Expr_is_lvalue(field->default_expr) && field->is_mut && (!v__ast__Type_is_ptr(field->default_expr_typ) || (field->default_expr)._typ == 358 /* v.ast.Ident */)) { v__checker__Checker_error(c, _S("cannot copy map: call `clone` method (or use a reference)"), v__ast__Expr_pos(field->default_expr)); } for (int _t13 = 0; _t13 < (*struct_sym->info._v__ast__Struct).fields.len; ++_t13) { v__ast__StructField* symfield = ((v__ast__StructField*)(*struct_sym->info._v__ast__Struct).fields.data) + _t13; if (string__eq(symfield->name, field->name)) { symfield->default_expr_typ = field->default_expr_typ; break; } } } if (field->anon_struct_decl.fields.len > 0) { v__checker__Checker_struct_decl(c, (voidptr)&field->anon_struct_decl); } } c->expected_type = old_expected_type; v__util__timing_measure_cumulative(_S("Checker.struct setting default_expr_typ")); for (int i = 0; i < node->fields.len; ++i) { v__ast__StructField field = ((v__ast__StructField*)node->fields.data)[i]; if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("struct field does not support storing Result"), field.option_pos); } if (!v__checker__Checker_ensure_type_exists(c, field.typ, field.type_pos)) { continue; } bool field_is_generic = v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__generic); if (v__ast__Table_type_kind(c->table, field.typ) != v__ast__Kind__alias && !v__checker__Checker_ensure_generic_type_specify_type_names(c, field.typ, field.type_pos, (v__ast__Table_final_sym(c->table, field.typ)->kind == v__ast__Kind__array || v__ast__Table_final_sym(c->table, field.typ)->kind == v__ast__Kind__array_fixed || v__ast__Table_final_sym(c->table, field.typ)->kind == v__ast__Kind__map), field_is_generic)) { continue; } if (field_is_generic) { has_generic_types = true; } if (node->language == v__ast__Language__v) { v__checker__Checker_check_valid_snake_case(c, field.name, _S("field name"), field.pos); } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, field.typ); string field_name = field.name; int field_name_len = field.name.len; for (int j = 0; j < i; ++j) { if (field_name_len == (*(v__ast__StructField*)array_get(node->fields, j)).name.len && string__eq(field_name, (*(v__ast__StructField*)array_get(node->fields, j)).name)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("field name `"), 0xfe10, {.d_s = field.name}}, {_S("` duplicate"), 0, { .d_c = 0 }}})), field.pos); } } if (field.typ != 0) { if (!v__ast__Type_is_ptr(field.typ)) { if (_us32_eq(v__ast__Table_unaliased_type(c->table, field.typ),struct_typ_idx)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = field.name}}, {_S("` is part of `"), 0xfe10, {.d_s = node->name}}, {_S("`, they can not both have the same type"), 0, { .d_c = 0 }}})), field.type_pos); } } } if (sym->kind == (v__ast__Kind__struct)) { v__ast__Struct info = *(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518); if (info.is_heap && !v__ast__Type_is_ptr(field.typ)) { (*struct_sym->info._v__ast__Struct).is_heap = true; } for (int _t14 = 0; _t14 < info.concrete_types.len; ++_t14) { v__ast__Type ct = ((v__ast__Type*)info.concrete_types.data)[_t14]; v__ast__TypeSymbol* ct_sym = v__ast__Table_sym(c->table, ct); if (ct_sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = ct_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), field.type_pos); } } } else if (sym->kind == (v__ast__Kind__multi_return)) { v__checker__Checker_error(c, _S("cannot use multi return as field type"), field.type_pos); } else if (sym->kind == (v__ast__Kind__none)) { v__checker__Checker_error(c, _S("cannot use `none` as field type"), field.type_pos); } else if (sym->kind == (v__ast__Kind__map)) { v__ast__Map info = v__ast__TypeSymbol_map_info(sym); if (v__ast__Type_has_flag(info.value_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("cannot use Result type as map value type"), field.type_pos); } } else if (sym->kind == (v__ast__Kind__alias)) { if (fast_string_eq(sym->name, _S("byte"))) { v__checker__Checker_error(c, _S("byte is deprecated, use u8 instead"), field.type_pos); } } else { v__checker__Checker_check_any_type(c, field.typ, sym, field.type_pos); } if (field.has_default_expr) { c->expected_type = field.typ; if (!v__ast__Type_has_option_or_result(field.typ)) { v__checker__Checker_check_expr_option_or_result_call(c, field.default_expr, field.default_expr_typ); } if ((sym->info)._typ == 549 /* v.ast.ArrayFixed */ && field.typ == field.default_expr_typ) { if (((*sym->info._v__ast__ArrayFixed).size_expr)._typ == 349 /* v.ast.ComptimeCall */) { if ((*(*sym->info._v__ast__ArrayFixed).size_expr._v__ast__ComptimeCall).kind == v__ast__ComptimeCallKind__d) { v__checker__Checker_error(c, _S("cannot initialize a fixed size array field that uses `$d()` as size quantifier since the size may change via -d"), v__ast__Expr_pos(field.default_expr)); } } } if ((field.default_expr)._typ == 338 /* v.ast.ArrayInit */) { if ((v__ast__Table_final_sym(c->table, field.default_expr_typ)->kind == v__ast__Kind__array || v__ast__Table_final_sym(c->table, field.default_expr_typ)->kind == v__ast__Kind__array_fixed) && _us32_eq(v__ast__Table_value_type(c->table, field.default_expr_typ),struct_typ_idx)) { v__checker__Checker_error(c, _S("cannot initialize array of same struct type that is being defined (recursion detected)"), field.pos); } } bool interface_implemented = sym->kind == v__ast__Kind__interface && v__checker__Checker_type_implements(c, field.default_expr_typ, field.typ, field.pos); _result_void _t15 = v__checker__Checker_check_expected(c, field.default_expr_typ, field.typ); if (_t15.is_error) { IError err = _t15.err; if (sym->kind == v__ast__Kind__interface && interface_implemented) { if (!c->inside_unsafe && !v__ast__Type_is_any_kind_of_pointer(field.default_expr_typ)) { if (v__ast__Table_sym(c->table, field.default_expr_typ)->kind != v__ast__Kind__interface) { v__checker__Checker_mark_as_referenced(c, &(*(v__ast__StructField*)array_get(node->fields, i)).default_expr, true); } } } else if (v__ast__Table_final_sym(c->table, field.typ)->kind == v__ast__Kind__function && v__ast__Type_is_pointer(field.default_expr_typ)) { continue; } else { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("incompatible initializer for field `"), 0xfe10, {.d_s = field.name}}, {_S("`: "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Expr_pos(field.default_expr)); } ; } ; if (v__ast__Expr_is_nil(field.default_expr)) { if (!v__ast__Type_is_any_kind_of_pointer(field.typ) && v__ast__Table_sym(c->table, field.typ)->kind != v__ast__Kind__function) { v__checker__Checker_error(c, _S("cannot assign `nil` to a non-pointer field"), field.type_pos); } } if (v__ast__Type_is_ptr(field.typ)) { if ((field.default_expr)._typ == 363 /* v.ast.IntegerLiteral */) { if (!c->inside_unsafe && !c->is_builtin_mod && fast_string_eq((*field.default_expr._v__ast__IntegerLiteral).val, _S("0"))) { v__checker__Checker_error(c, _S("default value of `0` for references can only be used inside `unsafe`"), (*field.default_expr._v__ast__IntegerLiteral).pos); } } bool field_is_option = v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option); if (field_is_option) { if ((field.default_expr)._typ == 371 /* v.ast.None */) { v__checker__Checker_warn(c, _S("unnecessary default value of `none`: struct fields are zeroed by default"), (*field.default_expr._v__ast__None).pos); } else if (v__ast__Expr_is_nil(field.default_expr)) { v__checker__Checker_error(c, _S("cannot assign `nil` to option value"), v__ast__Expr_pos(field.default_expr)); } } continue; } if ((Array_int_contains(_const_v__ast__unsigned_integer_type_idxs, field.typ))) { if ((field.default_expr)._typ == 363 /* v.ast.IntegerLiteral */) { if (string_at((*field.default_expr._v__ast__IntegerLiteral).val, 0) == '-') { v__checker__Checker_error(c, _S("cannot assign negative value to unsigned integer type"), (*field.default_expr._v__ast__IntegerLiteral).pos); } } } if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { if ((field.default_expr)._typ == 371 /* v.ast.None */) { v__checker__Checker_warn(c, _S("unnecessary default value of `none`: struct fields are zeroed by default"), (*field.default_expr._v__ast__None).pos); } } else if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__result)) { } else { if (field.default_expr._typ == 363 /* v.ast.IntegerLiteral */) { if (fast_string_eq((*field.default_expr._v__ast__IntegerLiteral).val, _S("0"))) { v__checker__Checker_warn(c, _S("unnecessary default value of `0`: struct fields are zeroed by default"), (*field.default_expr._v__ast__IntegerLiteral).pos); } } else if (field.default_expr._typ == 384 /* v.ast.StringLiteral */) { if (((*field.default_expr._v__ast__StringLiteral).val).len == 0) { v__checker__Checker_warn(c, _S("unnecessary default value of '': struct fields are zeroed by default"), (*field.default_expr._v__ast__StringLiteral).pos); } } else if (field.default_expr._typ == 342 /* v.ast.BoolLiteral */) { if ((*field.default_expr._v__ast__BoolLiteral).val == false) { v__checker__Checker_warn(c, _S("unnecessary default value `false`: struct fields are zeroed by default"), (*field.default_expr._v__ast__BoolLiteral).pos); } } else { } } } if (node->generic_types.len > 0 && v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__generic)) { Array_string field_generic_names = v__ast__Table_generic_type_names(c->table, field.typ); Array_string _t16 = {0}; Array_v__ast__Type _t16_orig = node->generic_types; int _t16_len = _t16_orig.len; _t16 = __new_array(0, _t16_len, sizeof(string)); for (int _t18 = 0; _t18 < _t16_len; ++_t18) { v__ast__Type it = ((v__ast__Type*) _t16_orig.data)[_t18]; string _t17 = v__ast__Table_type_to_str(c->table, it); array_push((array*)&_t16, &_t17); } Array_string node_generic_names =_t16; for (int _t19 = 0; _t19 < field_generic_names.len; ++_t19) { string name = ((string*)field_generic_names.data)[_t19]; if (!(Array_string_contains(node_generic_names, name))) { string struct_generic_names = Array_string_join(node_generic_names, _S(", ")); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("generic type name `"), 0xfe10, {.d_s = name}}, {_S("` is not mentioned in struct `"), 0xfe10, {.d_s = node->name}}, {_S("["), 0xfe10, {.d_s = struct_generic_names}}, {_S("]`"), 0, { .d_c = 0 }}})), field.type_pos); } } } } if (node->generic_types.len == 0 && has_generic_types) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic struct `"), 0xfe10, {.d_s = node->name}}, {_S("` declaration must specify the generic type names, e.g. "), 0xfe10, {.d_s = node->name}}, {_S("[T]"), 0, { .d_c = 0 }}})), node->pos); } } if (node->is_implements) { v__ast__Type struct_type = v__ast__Table_find_type(c->table, node->name); Array_string names_used = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t20 = 0; _t20 < node->implements_types.len; ++_t20) { v__ast__TypeNode t = ((v__ast__TypeNode*)node->implements_types.data)[_t20]; v__ast__TypeSymbol* t_sym = v__ast__Table_sym(c->table, t.typ); if ((t_sym->info)._typ == 542 /* v.ast.Interface */) { if ((*t_sym->info._v__ast__Interface).is_generic) { string itype_name = v__ast__Table_type_to_str(c->table, t.typ); if (!string_contains(itype_name, _S("["))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("missing generic type on "), 0xfe10, {.d_s = t_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}})), t.pos); } if (string_contains(itype_name, _S("<"))) { Array_string _t21 = {0}; Array_v__ast__Type _t21_orig = node->generic_types; int _t21_len = _t21_orig.len; _t21 = __new_array(0, _t21_len, sizeof(string)); for (int _t23 = 0; _t23 < _t21_len; ++_t23) { v__ast__Type it = ((v__ast__Type*) _t21_orig.data)[_t23]; string _t22 = v__ast__Table_type_to_str(c->table, it); array_push((array*)&_t21, &_t22); } Array_string struct_generic_letters =_t21; Array_string _t24 = {0}; Array_string _t24_orig = string_split(string_all_before(string_all_after(itype_name, _S("<")), _S(">")), _S(",")); int _t24_len = _t24_orig.len; _t24 = __new_array(0, _t24_len, sizeof(string)); for (int _t25 = 0; _t25 < _t24_len; ++_t25) { string it = ((string*) _t24_orig.data)[_t25]; if (!(Array_string_contains(struct_generic_letters, it))) { array_push((array*)&_t24, &it); } } Array_string unknown_letters =_t24; if (unknown_letters.len > 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown generic type "), 0xfe10, {.d_s = (*(string*)array_first(unknown_letters))}}, {_SLIT0, 0, { .d_c = 0 }}})), t.pos); } } } string variant_name = v__ast__Table_type_to_str(c->table, t.typ); if ((Array_string_contains(names_used, variant_name))) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("struct type "), 0xfe10, {.d_s = node->name}}, {_S(" cannot implement interface `"), 0xfe10, {.d_s = t_sym->name}}, {_S(" more than once`"), 0, { .d_c = 0 }}})), t.pos); } array_push((array*)&names_used, _MOV((string[]){ string_clone(variant_name) })); } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = t_sym->name}}, {_S("` is not an interface type"), 0, { .d_c = 0 }}})), t.pos); } v__checker__Checker_type_implements(c, struct_type, t.typ, node->pos); } } // Defer begin if (v__checker__Checker_struct_decl_defer_0) { v__util__timing_measure_cumulative(_S("Checker.struct_decl")); } // Defer end } VV_LOC int v__checker__minify_sort_fn(v__ast__StructField* a, v__ast__StructField* b) { if (a->typ == b->typ) { return 0; } if (a->typ == 19) { if (b->typ == 19) { return 0; } return 1; } else if (b->typ == 19) { return -1; } v__ast__Table* t = global_table; v__ast__TypeSymbol* a_sym = v__ast__Table_sym(t, a->typ); v__ast__TypeSymbol* b_sym = v__ast__Table_sym(t, b->typ); if ((a_sym->info)._typ == 548 /* v.ast.Enum */) { if (!(*a_sym->info._v__ast__Enum).is_flag && !(*a_sym->info._v__ast__Enum).uses_exprs) { int _t6; /* if prepend */ if ((b_sym->info)._typ == 548 /* v.ast.Enum */) { bool _t7 = true; _t6 = ((_t7 == ((*a_sym->info._v__ast__Enum).vals.len > (*b_sym->info._v__ast__Enum).vals.len))? (-1) : (_t7 == ((*a_sym->info._v__ast__Enum).vals.len < (*b_sym->info._v__ast__Enum).vals.len))? (1) : (0)) ; } else { _t6 = 1; } return _t6; } } else if ((b_sym->info)._typ == 548 /* v.ast.Enum */) { if (!(*b_sym->info._v__ast__Enum).is_flag && !(*b_sym->info._v__ast__Enum).uses_exprs) { return -1; } } multi_return_int_int mr_15569 = v__ast__Table_type_size(t, a->typ); int a_size = mr_15569.arg0; int a_align = mr_15569.arg1; multi_return_int_int mr_15608 = v__ast__Table_type_size(t, b->typ); int b_size = mr_15608.arg0; int b_align = mr_15608.arg1; bool _t10 = true; return ((_t10 == (a_align > b_align))? (-1) : (_t10 == (a_align < b_align))? (1) : (_t10 == (a_size > b_size))? (-1) : (_t10 == (a_size < b_size))? (1) : (0)); } VV_LOC v__ast__Type v__checker__Checker_struct_init(v__checker__Checker* c, v__ast__StructInit* node, bool is_field_zero_struct_init, Array_string* inited_fields) { bool v__checker__Checker_struct_init_defer_0 = false; bool v__checker__Checker_struct_init_defer_1 = false; bool old_inside_generic_struct_init; Array_v__ast__Type old_cur_struct_generic_types; Array_v__ast__Type old_cur_struct_concrete_types; v__util__timing_start(_S("Checker.struct_init")); v__checker__Checker_struct_init_defer_0 = true; if (node->typ == _const_v__ast__void_type) { if (c->expected_type == _const_v__ast__void_type) { v__checker__Checker_error(c, _S("unexpected short struct syntax"), node->pos); v__ast__Type _t1 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_struct_init_defer_0) { v__util__timing_measure_cumulative(_S("Checker.struct_init")); } // Defer end return _t1; } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, c->expected_type); if (sym->kind == v__ast__Kind__array) { node->typ = v__ast__Table_value_type(c->table, c->expected_type); } else { node->typ = c->expected_type; } } v__ast__TypeSymbol* struct_sym = v__ast__Table_sym(c->table, node->typ); old_inside_generic_struct_init = false; old_cur_struct_generic_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); old_cur_struct_concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); if ((struct_sym->info)._typ == 518 /* v.ast.Struct */) { for (int _t2 = 0; _t2 < (*struct_sym->info._v__ast__Struct).concrete_types.len; ++_t2) { v__ast__Type ct = ((v__ast__Type*)(*struct_sym->info._v__ast__Struct).concrete_types.data)[_t2]; v__ast__TypeSymbol* ct_sym = v__ast__Table_sym(c->table, ct); if (ct_sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = ct_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } if ((*struct_sym->info._v__ast__Struct).generic_types.len > 0 && (*struct_sym->info._v__ast__Struct).concrete_types.len == 0 && !node->is_short_syntax && c->table->cur_concrete_types.len != 0 && !is_field_zero_struct_init) { if (node->generic_types.len == 0) { v__checker__Checker_error(c, _S("generic struct init must specify type parameter, e.g. Foo[T]"), node->pos); } else if (node->generic_types.len > 0 && node->generic_types.len != (*struct_sym->info._v__ast__Struct).generic_types.len) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic struct init expects "), 0xfe07, {.d_i32 = (*struct_sym->info._v__ast__Struct).generic_types.len}}, {_S(" generic parameter, but got "), 0xfe07, {.d_i32 = node->generic_types.len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); } else if (node->generic_types.len > 0 && c->table->cur_fn != ((void*)0)) { for (int _t3 = 0; _t3 < node->generic_types.len; ++_t3) { v__ast__Type gtyp = ((v__ast__Type*)node->generic_types.data)[_t3]; if (!v__ast__Type_has_flag(gtyp, v__ast__TypeFlag__generic)) { continue; } string gtyp_name = v__ast__Table_sym(c->table, gtyp)->name; if (gtyp_name.len == 1 && !(Array_string_contains(c->table->cur_fn->generic_names, gtyp_name))) { string cur_generic_names = string__plus(string__plus(_S("("), Array_string_join(c->table->cur_fn->generic_names, _S(","))), _S(")")); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("generic struct init type parameter `"), 0xfe10, {.d_s = gtyp_name}}, {_S("` must be within the parameters `"), 0xfe10, {.d_s = cur_generic_names}}, {_S("` of the current generic function"), 0, { .d_c = 0 }}})), node->pos); break; } } } } if (node->generic_types.len > 0 && (*struct_sym->info._v__ast__Struct).generic_types.len == 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("a non generic struct `"), 0xfe10, {.d_s = node->typ_str}}, {_S("` used like a generic struct"), 0, { .d_c = 0 }}})), node->name_pos); } if ((*struct_sym->info._v__ast__Struct).generic_types.len > 0 && (*struct_sym->info._v__ast__Struct).generic_types.len == (*struct_sym->info._v__ast__Struct).concrete_types.len) { old_inside_generic_struct_init = c->inside_generic_struct_init; old_cur_struct_generic_types = array_clone_to_depth(&c->cur_struct_generic_types, 0); old_cur_struct_concrete_types = array_clone_to_depth(&c->cur_struct_concrete_types, 0); c->inside_generic_struct_init = true; c->cur_struct_generic_types = array_clone_to_depth(&(*struct_sym->info._v__ast__Struct).generic_types, 0); c->cur_struct_concrete_types = array_clone_to_depth(&(*struct_sym->info._v__ast__Struct).concrete_types, 0); v__checker__Checker_struct_init_defer_1 = true; } if ((*struct_sym->info._v__ast__Struct).is_union && node->init_fields.len > 1) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("union `"), 0xfe10, {.d_s = struct_sym->name}}, {_S("` can have only one field initialised"), 0, { .d_c = 0 }}})), node->pos); } } else if ((struct_sym->info)._typ == 553 /* v.ast.FnType */) { v__checker__Checker_error(c, _S("functions must be defined, not instantiated like structs"), node->pos); } if (c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len > 0) { v__ast__Table_unwrap_generic_type_ex(c->table, node->typ, c->table->cur_fn->generic_names, c->table->cur_concrete_types, true); if (c->pref->skip_unused && v__ast__Type_has_flag(node->typ, v__ast__TypeFlag__generic)) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){v__checker__Checker_unwrap_generic(c, node->typ)}, &(bool[]) { true }); map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){node->typ}, &(bool[]) { true }); } } if (!is_field_zero_struct_init) { v__checker__Checker_ensure_type_exists(c, node->typ, node->pos); } v__ast__TypeSymbol* type_sym = v__ast__Table_sym(c->table, node->typ); if (!c->is_builtin_mod && !c->inside_unsafe && type_sym->language == v__ast__Language__v && c->table->cur_concrete_types.len == 0) { int pos = string_last_index_u8(type_sym->name, '.'); u8 first_letter = string_at(type_sym->name, (int)(pos + 1)); if (!u8_is_capital(first_letter) && type_sym->kind != v__ast__Kind__none && (type_sym->kind != v__ast__Kind__struct || !((type_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((type_sym->info)._v__ast__Struct,(type_sym->info)._typ, 518)).is_anon)) && type_sym->kind != v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot initialize builtin type `"), 0xfe10, {.d_s = type_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } if (type_sym->kind == v__ast__Kind__enum && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, _S("cannot initialize enums"), node->pos); } } if (type_sym->kind == v__ast__Kind__sum_type && node->init_fields.len == 1) { string sexpr = v__ast__Expr_str(&(*(v__ast__StructInitField*)array_get(node->init_fields, 0)).expr); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("cast to sum type using `"), 0xfe10, {.d_s = type_sym->name}}, {_S("("), 0xfe10, {.d_s = sexpr}}, {_S(")` not `"), 0xfe10, {.d_s = type_sym->name}}, {_S("{"), 0xfe10, {.d_s = sexpr}}, {_S("}`"), 0, { .d_c = 0 }}})), node->pos); } if (type_sym->kind == v__ast__Kind__interface && type_sym->language != v__ast__Language__js) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot instantiate interface `"), 0xfe10, {.d_s = type_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } if ((type_sym->info)._typ == 539 /* v.ast.Alias */) { if (v__ast__Type_is_number((*type_sym->info._v__ast__Alias).parent_type)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("cannot instantiate number type alias `"), 0xfe10, {.d_s = type_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); v__ast__Type _t4 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_struct_init_defer_1) { c->inside_generic_struct_init = old_inside_generic_struct_init; c->cur_struct_generic_types = old_cur_struct_generic_types; c->cur_struct_concrete_types = old_cur_struct_concrete_types; } // Defer end // Defer begin if (v__checker__Checker_struct_init_defer_0) { v__util__timing_measure_cumulative(_S("Checker.struct_init")); } // Defer end return _t4; } } if (!node->has_update_expr && !type_sym->is_pub && type_sym->kind != v__ast__Kind__placeholder && type_sym->language != v__ast__Language__c && (!string__eq(type_sym->mod, c->mod) && !(v__ast__Type_has_flag(node->typ, v__ast__TypeFlag__generic) && !fast_string_eq(type_sym->mod, _S("builtin")))) && !is_field_zero_struct_init) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("type `"), 0xfe10, {.d_s = type_sym->name}}, {_S("` is private"), 0, { .d_c = 0 }}})), node->pos); } if ((type_sym->info)._typ == 518 /* v.ast.Struct */ && !string__eq(type_sym->mod, c->mod)) { for (int _t5 = 0; _t5 < (*type_sym->info._v__ast__Struct).attrs.len; ++_t5) { v__ast__Attr attr = ((v__ast__Attr*)(*type_sym->info._v__ast__Struct).attrs.data)[_t5]; if (_SLIT_EQ(attr.name.str, attr.name.len, "noinit")) { v__checker__Checker_error(c, string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("struct `"), 0xfe10, {.d_s = type_sym->name}}, {_S("` is declared with a `@[noinit]` attribute, so "), 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S("it cannot be initialized with `"), 0xfe10, {.d_s = type_sym->name}}, {_S("{}`"), 0, { .d_c = 0 }}}))), node->pos); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "deprecated")) { v__checker__Checker_deprecate(c, _S("struct"), type_sym->name, (*type_sym->info._v__ast__Struct).attrs, node->pos); } else { } } } if (type_sym->name.len == 1 && c->table->cur_fn != ((void*)0) && c->table->cur_fn->generic_names.len == 0) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown struct `"), 0xfe10, {.d_s = type_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); v__ast__Type _t6 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_struct_init_defer_1) { c->inside_generic_struct_init = old_inside_generic_struct_init; c->cur_struct_generic_types = old_cur_struct_generic_types; c->cur_struct_concrete_types = old_cur_struct_concrete_types; } // Defer end // Defer begin if (v__checker__Checker_struct_init_defer_0) { v__util__timing_measure_cumulative(_S("Checker.struct_init")); } // Defer end return _t6; } switch (type_sym->kind) { case v__ast__Kind__placeholder: { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown struct: "), 0xfe10, {.d_s = type_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); v__ast__Type _t7 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_struct_init_defer_1) { c->inside_generic_struct_init = old_inside_generic_struct_init; c->cur_struct_generic_types = old_cur_struct_generic_types; c->cur_struct_concrete_types = old_cur_struct_concrete_types; } // Defer end // Defer begin if (v__checker__Checker_struct_init_defer_0) { v__util__timing_measure_cumulative(_S("Checker.struct_init")); } // Defer end return _t7; } case v__ast__Kind__any: { for (int _t8 = 0; _t8 < node->init_fields.len; ++_t8) { v__ast__StructInitField* init_field = ((v__ast__StructInitField*)node->init_fields.data) + _t8; init_field->typ = v__checker__Checker_expr(c, &init_field->expr); init_field->expected_type = init_field->typ; } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, node->typ)); if ((sym->info)._typ == 518 /* v.ast.Struct */) { if (!string__eq(sym->mod, c->mod)) { for (int _t9 = 0; _t9 < (*sym->info._v__ast__Struct).attrs.len; ++_t9) { v__ast__Attr attr = ((v__ast__Attr*)(*sym->info._v__ast__Struct).attrs.data)[_t9]; if (_SLIT_EQ(attr.name.str, attr.name.len, "noinit")) { v__checker__Checker_error(c, string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("struct `"), 0xfe10, {.d_s = sym->name}}, {_S("` is declared with a `@[noinit]` attribute, so "), 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S("it cannot be initialized with `"), 0xfe10, {.d_s = sym->name}}, {_S("{}`"), 0, { .d_c = 0 }}}))), node->pos); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "deprecated")) { v__checker__Checker_deprecate(c, _S("struct"), sym->name, (*sym->info._v__ast__Struct).attrs, node->pos); } else { } } } if (node->no_keys && node->init_fields.len != (*sym->info._v__ast__Struct).fields.len) { string fname = ((*sym->info._v__ast__Struct).fields.len != 1 ? (_S("fields")) : (_S("field"))); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("initializing struct `"), 0xfe10, {.d_s = sym->name}}, {_S("` needs `"), 0xfe07, {.d_i32 = (*sym->info._v__ast__Struct).fields.len}}, {_S("` "), 0xfe10, {.d_s = fname}}, {_S(", but got `"), 0xfe07, {.d_i32 = node->init_fields.len}}, {_S("`"), 0, { .d_c = 0 }}})), node->pos); } } break; } case v__ast__Kind__struct: case v__ast__Kind__string: case v__ast__Kind__array: case v__ast__Kind__alias: { v__ast__Struct info = ((v__ast__Struct){.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.embeds = __new_array(0, 0, sizeof(v__ast__Type)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.is_typedef = 0,.is_union = 0,.is_heap = 0,.is_minify = 0,.is_anon = 0,.is_generic = 0,.is_shared = 0,.is_markused = 0,.has_option = 0,.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.parent_type = 0,}); if (type_sym->kind == v__ast__Kind__alias) { v__ast__Alias info_t = *(v__ast__Alias*)__as_cast((type_sym->info)._v__ast__Alias,(type_sym->info)._typ, 539); v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, info_t.parent_type); if (sym->kind == v__ast__Kind__placeholder) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("unknown struct: "), 0xfe10, {.d_s = type_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); v__ast__Type _t10 = _const_v__ast__void_type; // Defer begin if (v__checker__Checker_struct_init_defer_1) { c->inside_generic_struct_init = old_inside_generic_struct_init; c->cur_struct_generic_types = old_cur_struct_generic_types; c->cur_struct_concrete_types = old_cur_struct_concrete_types; } // Defer end // Defer begin if (v__checker__Checker_struct_init_defer_0) { v__util__timing_measure_cumulative(_S("Checker.struct_init")); } // Defer end return _t10; } if (sym->kind == (v__ast__Kind__struct)) { info = *(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518); } else if (sym->kind == (v__ast__Kind__array) || sym->kind == (v__ast__Kind__array_fixed) || sym->kind == (v__ast__Kind__map)) { } else { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("alias type name: "), 0xfe10, {.d_s = sym->name}}, {_S(" is not struct type"), 0, { .d_c = 0 }}})), node->pos); } } else { info = *(v__ast__Struct*)__as_cast((type_sym->info)._v__ast__Struct,(type_sym->info)._typ, 518); } if (node->no_keys) { int exp_len = info.fields.len; int got_len = node->init_fields.len; if (exp_len != got_len && !c->pref->translated) { string amount = (exp_len < got_len ? (_S("many")) : (_S("few"))); v__checker__Checker_error(c, str_intp(5, _MOV((StrIntpData[]){{_S("too "), 0xfe10, {.d_s = amount}}, {_S(" fields in `"), 0xfe10, {.d_s = type_sym->name}}, {_S("` literal (expecting "), 0xfe07, {.d_i32 = exp_len}}, {_S(", got "), 0xfe07, {.d_i32 = got_len}}, {_S(")"), 0, { .d_c = 0 }}})), node->pos); } } Array_v__ast__StructField info_fields_sorted = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); if (node->no_keys) { info_fields_sorted = array_clone_to_depth(&info.fields, 0); if (info_fields_sorted.len > 0) { qsort(info_fields_sorted.data, info_fields_sorted.len, info_fields_sorted.element_size, (voidptr)compare_12155997196440863451_v__ast__StructField_by_i); } ; } for (int i = 0; i < node->init_fields.len; ++i) { v__ast__StructInitField* init_field = ((v__ast__StructInitField*)node->init_fields.data) + i; v__ast__StructField field_info = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}); string field_name = _S(""); if (node->no_keys) { if (i >= info.fields.len) { break; } field_info = (*(v__ast__StructField*)array_get(info_fields_sorted, i)); field_name = field_info.name; (*(v__ast__StructInitField*)array_get(node->init_fields, i)).name = field_name; } else { field_name = init_field->name; bool exists = true; _result_v__ast__StructField _t11 = v__ast__Table_find_field_with_embeds(c->table, type_sym, field_name); if (_t11.is_error) { IError err = _t11.err; exists = false; *(v__ast__StructField*) _t11.data = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}); } field_info = (*(v__ast__StructField*)_t11.data); if (!exists) { Array_string _t12 = {0}; Array_v__ast__StructField _t12_orig = v__ast__Table_struct_fields(c->table, type_sym); int _t12_len = _t12_orig.len; _t12 = __new_array(0, _t12_len, sizeof(string)); for (int _t14 = 0; _t14 < _t12_len; ++_t14) { v__ast__StructField it = ((v__ast__StructField*) _t12_orig.data)[_t14]; string _t13 = it.name; array_push((array*)&_t12, &_t13); } Array_string existing_fields =_t12; v__checker__Checker_error(c, v__util__Suggestion_say(v__util__new_suggestion(init_field->name, existing_fields, ((v__util__SuggestionParams){.similarity_threshold = 0.5,.similarity_fn = strings__dice_coefficient,})), str_intp(3, _MOV((StrIntpData[]){{_S("unknown field `"), 0xfe10, {.d_s = init_field->name}}, {_S("` in struct literal of type `"), 0xfe10, {.d_s = type_sym->name}}, {_S("`"), 0, { .d_c = 0 }}}))), init_field->pos); continue; } if ((Array_string_contains(*inited_fields, field_name))) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate field name in struct literal: `"), 0xfe10, {.d_s = field_name}}, {_S("`"), 0, { .d_c = 0 }}})), init_field->pos); continue; } } v__ast__Type got_type = _const_v__ast__no_type; v__ast__Type exp_type = _const_v__ast__no_type; array_push((array*)inited_fields, _MOV((string[]){ string_clone(field_name) })); exp_type = field_info.typ; v__ast__TypeSymbol* exp_type_sym = v__ast__Table_sym(c->table, exp_type); c->expected_type = exp_type; got_type = v__checker__Checker_expr(c, &init_field->expr); v__ast__TypeSymbol* got_type_sym = v__ast__Table_sym(c->table, got_type); if (got_type == _const_v__ast__void_type) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__ast__Expr_str(&init_field->expr)}}, {_S("` (no value) used as value"), 0, { .d_c = 0 }}})), init_field->pos); } bool exp_type_is_option = v__ast__Type_has_flag(exp_type, v__ast__TypeFlag__option); if (!exp_type_is_option) { got_type = v__checker__Checker_check_expr_option_or_result_call(c, init_field->expr, got_type); if (v__ast__Type_has_flag(got_type, v__ast__TypeFlag__option)) { v__checker__Checker_error(c, _S("cannot assign an Option value to a non-option struct field"), init_field->pos); } else if (v__ast__Type_has_flag(got_type, v__ast__TypeFlag__result)) { v__checker__Checker_error(c, _S("cannot assign a Result value to a non-option struct field"), init_field->pos); } } if (v__ast__Type_has_flag(got_type, v__ast__TypeFlag__result)) { v__checker__Checker_check_expr_option_or_result_call(c, init_field->expr, init_field->typ); } if (exp_type_is_option && v__ast__Type_is_ptr(got_type) && !v__ast__Type_is_ptr(exp_type)) { v__checker__Checker_error(c, _S("cannot assign a pointer to option struct field"), init_field->pos); } if (exp_type_sym->kind == v__ast__Kind__voidptr) { if (got_type_sym->kind == v__ast__Kind__struct && !v__ast__Type_is_ptr(got_type)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("allocate `"), 0xfe10, {.d_s = got_type_sym->name}}, {_S("` on the heap for use in other functions"), 0, { .d_c = 0 }}})), init_field->pos); } else if (!(got_type == _const_v__ast__nil_type || got_type == _const_v__ast__voidptr_type || got_type == _const_v__ast__byteptr_type) && !v__ast__Type_is_ptr(got_type) && ((init_field->expr)._typ != 363 /* v.ast.IntegerLiteral */ || ((init_field->expr)._typ == 363 /* v.ast.IntegerLiteral */ && string_int((*(v__ast__IntegerLiteral*)__as_cast((init_field->expr)._v__ast__IntegerLiteral,(init_field->expr)._typ, 363)).val) != 0))) { v__checker__Checker_note(c, str_intp(2, _MOV((StrIntpData[]){{_S("voidptr variables may only be assigned voidptr values (e.g. unsafe { voidptr("), 0xfe10, {.d_s = v__ast__Expr_str(&init_field->expr)}}, {_S(") })"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(init_field->expr)); } } if (exp_type_sym->kind == v__ast__Kind__map && got_type_sym->kind == v__ast__Kind__map && !v__ast__Type_is_ptr(got_type) && field_info.is_mut && ((init_field->expr)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((init_field->expr)._v__ast__Ident,(init_field->expr)._typ, 358)).obj)._typ == 420 /* v.ast.ConstField */)) { v__checker__Checker_error(c, _S("cannot assign a const map to mut struct field, call `clone` method (or use a reference)"), v__ast__Expr_pos(init_field->expr)); } if (exp_type_sym->kind == v__ast__Kind__array && got_type_sym->kind == v__ast__Kind__array) { if ((init_field->expr)._typ == 361 /* v.ast.IndexExpr */ && ((*(v__ast__IndexExpr*)__as_cast((init_field->expr)._v__ast__IndexExpr,(init_field->expr)._typ, 361)).left)._typ == 358 /* v.ast.Ident */ && (v__ast__Ident_is_mut(((v__ast__Ident*)__as_cast((((v__ast__IndexExpr*)__as_cast((init_field->expr)._v__ast__IndexExpr,(init_field->expr)._typ, 361))->left)._v__ast__Ident,(((v__ast__IndexExpr*)__as_cast((init_field->expr)._v__ast__IndexExpr,(init_field->expr)._typ, 361))->left)._typ, 358))) || field_info.is_mut) && ((*(v__ast__IndexExpr*)__as_cast((init_field->expr)._v__ast__IndexExpr,(init_field->expr)._typ, 361)).index)._typ == 377 /* v.ast.RangeExpr */ && !c->inside_unsafe) { v__checker__Checker_add_error_detail_with_pos(c, _S("To silence this notice, use either an explicit `a[..].clone()`,\nor use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice."), v__ast__Expr_pos(init_field->expr)); v__checker__Checker_note(c, _S("an implicit clone of the slice was done here"), v__ast__Expr_pos(init_field->expr)); v__ast__CallExpr right = ((v__ast__CallExpr){ .pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .mod = (string){.str=(byteptr)"", .is_lit=1}, .name = _S("clone"), .is_method = true, .is_field = 0, .is_fn_var = 0, .is_fn_a_const = 0, .is_keep_alive = 0, .is_noreturn = 0, .is_ctor_new = 0, .is_file_translated = 0, .is_static_method = 0, .args = __new_array(0, 0, sizeof(v__ast__CallArg)), .expected_arg_types = __new_array(0, 0, sizeof(v__ast__Type)), .comptime_ret_val = 0, .language = 0, .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .left = init_field->expr, .left_type = got_type, .receiver_type = v__ast__Type_ref(got_type), .receiver_concrete_type = 0, .return_type = got_type, .return_type_generic = 0, .nr_ret_values = -1, .fn_var_type = 0, .const_name = (string){.str=(byteptr)"", .is_lit=1}, .should_be_skipped = 0, .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .concrete_list_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .raw_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .free_receiver = 0, .scope = c->fn_scope, .from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)), .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .is_return_used = true, .is_expand_simple_interpolation = 0, .is_unwrapped_fn_selector = 0, }); got_type = v__checker__Checker_expr(c, HEAP(v__ast__Expr, v__ast__CallExpr_to_sumtype_v__ast__Expr(&right))); (*(v__ast__StructInitField*)array_get(node->init_fields, i)).expr = v__ast__CallExpr_to_sumtype_v__ast__Expr(&right); } if (field_info.is_mut && ((init_field->expr)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((init_field->expr)._v__ast__Ident,(init_field->expr)._typ, 358)).obj)._typ == 420 /* v.ast.ConstField */) && !c->inside_unsafe) { v__checker__Checker_error(c, _S("cannot assign a const array to mut struct field, call `clone` method (or use `unsafe`)"), v__ast__Expr_pos(init_field->expr)); } } if (exp_type_sym->kind == v__ast__Kind__interface) { if (v__checker__Checker_type_implements(c, got_type, exp_type, init_field->pos)) { if (!c->inside_unsafe && got_type_sym->kind != v__ast__Kind__interface && !v__ast__Type_is_any_kind_of_pointer(got_type)) { v__checker__Checker_mark_as_referenced(c, &init_field->expr, true); } } } else if (got_type != _const_v__ast__void_type && got_type_sym->kind != v__ast__Kind__placeholder && !v__ast__Type_has_flag(exp_type, v__ast__TypeFlag__generic)) { _result_void _t16 = v__checker__Checker_check_expected(c, v__checker__Checker_unwrap_generic(c, got_type), v__checker__Checker_unwrap_generic(c, exp_type)); if (_t16.is_error) { IError err = _t16.err; v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot assign to field `"), 0xfe10, {.d_s = field_info.name}}, {_S("`: "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), init_field->pos); ; } ; } if (v__ast__Type_has_flag(exp_type, v__ast__TypeFlag__shared_f)) { if (!v__ast__Type_has_flag(got_type, v__ast__TypeFlag__shared_f) && v__ast__Type_is_ptr(got_type)) { v__checker__Checker_error(c, _S("`shared` field must be initialized with `shared` or value"), init_field->pos); } } else { if (!c->inside_unsafe && type_sym->language == v__ast__Language__v && !(c->file->is_translated || c->pref->translated) && v__ast__Type_is_ptr(exp_type) && !v__ast__Type_is_any_kind_of_pointer(got_type) && !exp_type_is_option && !((init_field->expr)._typ == 388 /* v.ast.UnsafeExpr */ && string__eq(v__ast__Expr_str(&((v__ast__UnsafeExpr*)__as_cast((init_field->expr)._v__ast__UnsafeExpr,(init_field->expr)._typ, 388))->expr), _S("0")))) { if (string__eq(v__ast__Expr_str(&init_field->expr), _S("0"))) { v__checker__Checker_error(c, _S("assigning `0` to a reference field is only allowed in `unsafe` blocks"), init_field->pos); } else { v__checker__Checker_error(c, _S("reference field must be initialized with reference"), init_field->pos); } } else if (v__ast__Type_is_any_kind_of_pointer(exp_type) && !v__ast__Type_is_any_kind_of_pointer(got_type) && !v__ast__Type_is_int(got_type) && (!exp_type_is_option || v__ast__Type_idx(got_type) != 20)) { string got_typ_str = v__ast__Table_type_to_str(c->table, got_type); string exp_typ_str = v__ast__Table_type_to_str(c->table, exp_type); v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("cannot assign to field `"), 0xfe10, {.d_s = field_info.name}}, {_S("`: expected a pointer `"), 0xfe10, {.d_s = exp_typ_str}}, {_S("`, but got `"), 0xfe10, {.d_s = got_typ_str}}, {_S("`"), 0, { .d_c = 0 }}})), init_field->pos); } } (*(v__ast__StructInitField*)array_get(node->init_fields, i)).typ = got_type; (*(v__ast__StructInitField*)array_get(node->init_fields, i)).expected_type = exp_type; if (v__ast__Type_is_ptr(got_type) && v__ast__Type_is_ptr(exp_type) && (init_field->expr)._typ == 358 /* v.ast.Ident */ && !info.is_heap) { v__checker__Checker_fail_if_stack_struct_action_outside_unsafe(c, (voidptr)&(*init_field->expr._v__ast__Ident), _S("assigned")); } if ((Array_int_contains(_const_v__ast__unsigned_integer_type_idxs, v__ast__Table_unaliased_type(c->table, exp_type))) && (init_field->expr)._typ == 363 /* v.ast.IntegerLiteral */ && string_at((*(v__ast__IntegerLiteral*)__as_cast((init_field->expr)._v__ast__IntegerLiteral,(init_field->expr)._typ, 363)).val, 0) == '-') { v__checker__Checker_error(c, _S("cannot assign negative value to unsigned integer type"), (*init_field->expr._v__ast__IntegerLiteral).pos); } if ((exp_type_sym->info)._typ == 518 /* v.ast.Struct */ && !(*(v__ast__Struct*)__as_cast((exp_type_sym->info)._v__ast__Struct,(exp_type_sym->info)._typ, 518)).is_anon && (init_field->expr)._typ == 385 /* v.ast.StructInit */ && (*(v__ast__StructInit*)__as_cast((init_field->expr)._v__ast__StructInit,(init_field->expr)._typ, 385)).is_anon) { v__checker__Checker_error(c, _S("cannot assign anonymous `struct` to a typed `struct`"), (*init_field->expr._v__ast__StructInit).pos); } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, init_field->typ); if (init_field->is_embed && sym->kind == v__ast__Kind__struct && sym->language == v__ast__Language__v) { Array_v__ast__StructField struct_fields = v__ast__Table_struct_fields(c->table, sym); for (int _t17 = 0; _t17 < struct_fields.len; ++_t17) { v__ast__StructField struct_field = ((v__ast__StructField*)struct_fields.data)[_t17]; array_push((array*)inited_fields, _MOV((string[]){ string_clone(struct_field.name) })); } } v__ast__TypeSymbol* expected_type_sym = v__ast__Table_final_sym(c->table, init_field->expected_type); if ((expected_type_sym->kind == v__ast__Kind__string || expected_type_sym->kind == v__ast__Kind__array || expected_type_sym->kind == v__ast__Kind__map || expected_type_sym->kind == v__ast__Kind__array_fixed || expected_type_sym->kind == v__ast__Kind__chan || expected_type_sym->kind == v__ast__Kind__struct) && v__ast__Expr_is_nil(init_field->expr) && !v__ast__Type_is_ptr(init_field->expected_type) && (init_field->expr)._typ == 388 /* v.ast.UnsafeExpr */) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot assign `nil` to struct field `"), 0xfe10, {.d_s = init_field->name}}, {_S("` with type `"), 0xfe10, {.d_s = expected_type_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__token__Pos_extend((*init_field->expr._v__ast__UnsafeExpr).pos, v__ast__Expr_pos((*init_field->expr._v__ast__UnsafeExpr).expr))); } } if (!node->has_update_expr) { v__checker__Checker_check_uninitialized_struct_fields_and_embeds(c, *node, *type_sym, (voidptr)&info, inited_fields); } break; } case v__ast__Kind__sum_type: { v__ast__Type first_typ = (*(v__ast__Type*)array_get((*(v__ast__SumType*)__as_cast((type_sym->info)._v__ast__SumType,(type_sym->info)._typ, 544)).variants, 0)); v__ast__TypeSymbol* first_sym = v__ast__Table_final_sym(c->table, first_typ); if (first_sym->kind == v__ast__Kind__struct) { v__ast__Struct info = *(v__ast__Struct*)__as_cast((first_sym->info)._v__ast__Struct,(first_sym->info)._typ, 518); v__checker__Checker_check_uninitialized_struct_fields_and_embeds(c, *node, *first_sym, (voidptr)&info, inited_fields); } break; } case v__ast__Kind__none: { Array_v__ast__StructField init_fields = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); for (int _t19 = 0; _t19 < node->init_fields.len; ++_t19) { v__ast__StructInitField* init_field = ((v__ast__StructInitField*)node->init_fields.data) + _t19; v__ast__StructInitField* expr = init_field; init_field->typ = v__checker__Checker_expr(c, &expr->expr); init_field->expected_type = init_field->typ; array_push((array*)&init_fields, _MOV((v__ast__StructField[]){ ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = c->anon_struct_should_be_mut,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = init_field->name,.typ = init_field->typ,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}) })); } c->table->anon_struct_counter++; string name = str_intp(2, _MOV((StrIntpData[]){{_S("_VAnonStruct"), 0xfe07, {.d_i32 = c->table->anon_struct_counter}}, {_SLIT0, 0, { .d_c = 0 }}})); v__ast__TypeSymbol sym_struct = ((v__ast__TypeSymbol){ .parent_idx = 0, .info = v__ast__Struct_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Struct, (((v__ast__Struct){.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.embeds = __new_array(0, 0, sizeof(v__ast__Type)),.fields = init_fields,.is_typedef = 0,.is_union = 0,.is_heap = 0,.is_minify = 0,.is_anon = true,.is_generic = 0,.is_shared = 0,.is_markused = 0,.has_option = 0,.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.parent_type = 0,})))), .kind = v__ast__Kind__struct, .name = name, .cname = v__util__no_dots(name), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = c->mod, .is_pub = true, .is_builtin = 0, .language = v__ast__Language__v, .idx = 0, .size = -1, .align = -1, }); int ret = v__ast__Table_register_sym(c->table, sym_struct); v__ast__Table_register_anon_struct(c->table, name, ret); node->typ = v__ast__Table_find_type_idx(c->table, name); break; } case v__ast__Kind__void: case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__i32: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__isize: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__usize: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__bool: case v__ast__Kind__array_fixed: case v__ast__Kind__map: case v__ast__Kind__chan: case v__ast__Kind__generic_inst: case v__ast__Kind__multi_return: case v__ast__Kind__enum: case v__ast__Kind__function: case v__ast__Kind__interface: case v__ast__Kind__float_literal: case v__ast__Kind__int_literal: case v__ast__Kind__aggregate: case v__ast__Kind__thread: default: { { break; } } } if (node->has_update_expr) { v__ast__Type update_type = v__checker__Checker_expr(c, &node->update_expr); node->update_expr_type = update_type; v__ast__TypeSymbol* expr_sym = v__ast__Table_final_sym(c->table, v__checker__Checker_unwrap_generic(c, update_type)); if ((node->update_expr)._typ == 350 /* v.ast.ComptimeSelector */) { v__checker__Checker_error(c, _S("cannot use struct update syntax in compile time expressions"), node->update_expr_pos); } else if (expr_sym->kind != v__ast__Kind__struct) { string s = v__ast__Table_type_to_str(c->table, update_type); v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("expected struct, found `"), 0xfe10, {.d_s = s}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->update_expr)); } else if (update_type != node->typ) { v__ast__TypeSymbol* from_sym = v__ast__Table_final_sym(c->table, update_type); v__ast__TypeSymbol* to_sym = v__ast__Table_final_sym(c->table, node->typ); v__ast__Struct from_info = *(v__ast__Struct*)__as_cast((from_sym->info)._v__ast__Struct,(from_sym->info)._typ, 518); v__ast__Struct to_info = *(v__ast__Struct*)__as_cast((to_sym->info)._v__ast__Struct,(to_sym->info)._typ, 518); if (!v__checker__Checker_check_struct_signature(c, from_info, to_info) || !v__checker__Checker_check_struct_signature_init_fields(c, from_info, to_info, *node)) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("struct `"), 0xfe10, {.d_s = from_sym->name}}, {_S("` is not compatible with struct `"), 0xfe10, {.d_s = to_sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->update_expr)); } } } if ((struct_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((struct_sym->info)._v__ast__Struct,(struct_sym->info)._typ, 518)).generic_types.len > 0 && c->table->cur_concrete_types.len == 0) { if ((*struct_sym->info._v__ast__Struct).concrete_types.len == 0) { Array_v__ast__Type concrete_types = v__checker__Checker_infer_struct_generic_types(c, node->typ, *node); if (concrete_types.len > 0) { Array_string _t21 = {0}; Array_v__ast__Type _t21_orig = (*struct_sym->info._v__ast__Struct).generic_types; int _t21_len = _t21_orig.len; _t21 = __new_array(0, _t21_len, sizeof(string)); for (int _t23 = 0; _t23 < _t21_len; ++_t23) { v__ast__Type it = ((v__ast__Type*) _t21_orig.data)[_t23]; string _t22 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t21, &_t22); } Array_string generic_names =_t21; node->typ = v__ast__Table_unwrap_generic_type(c->table, node->typ, generic_names, concrete_types); } } else if ((*struct_sym->info._v__ast__Struct).generic_types.len == (*struct_sym->info._v__ast__Struct).concrete_types.len) { v__ast__Type parent_type = (*struct_sym->info._v__ast__Struct).parent_type; v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(c->table, parent_type); if (c->inside_generic_struct_init) { v__ast__Struct st = (*struct_sym->info._v__ast__Struct); for (int _t24 = 0; _t24 < st.fields.len; ++_t24) { v__ast__StructField* field = ((v__ast__StructField*)st.fields.data) + _t24; v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, field->typ); if ((sym->info)._typ == 549 /* v.ast.ArrayFixed */ && v__checker__Checker_array_fixed_has_unresolved_size(c, (v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549))) { v__ast__Expr size_expr = (*sym->info._v__ast__ArrayFixed).size_expr; field->typ = v__checker__Checker_eval_array_fixed_sizes(c, &size_expr, 0, (*sym->info._v__ast__ArrayFixed).elem_type); } } } for (int _t25 = 0; _t25 < parent_sym->methods.len; ++_t25) { v__ast__Fn method = ((v__ast__Fn*)parent_sym->methods.data)[_t25]; Array_string _t26 = {0}; Array_v__ast__Type _t26_orig = (*struct_sym->info._v__ast__Struct).generic_types; int _t26_len = _t26_orig.len; _t26 = __new_array(0, _t26_len, sizeof(string)); for (int _t28 = 0; _t28 < _t26_len; ++_t28) { v__ast__Type it = ((v__ast__Type*) _t26_orig.data)[_t28]; string _t27 = v__ast__Table_sym(c->table, it)->name; array_push((array*)&_t26, &_t27); } Array_string generic_names =_t26; for (int i = 0; i < method.params.len; ++i) { v__ast__Param param = ((v__ast__Param*)method.params.data)[i]; if (i == 0 || !v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { continue; } v__ast__TypeSymbol* param_sym = v__ast__Table_sym(c->table, param.typ); if (param_sym->kind == v__ast__Kind__struct || param_sym->kind == v__ast__Kind__interface || param_sym->kind == v__ast__Kind__sum_type) { v__ast__Table_unwrap_generic_type(c->table, param.typ, generic_names, (*struct_sym->info._v__ast__Struct).concrete_types); } } } } } v__ast__Type _t29 = node->typ; // Defer begin if (v__checker__Checker_struct_init_defer_1) { c->inside_generic_struct_init = old_inside_generic_struct_init; c->cur_struct_generic_types = old_cur_struct_generic_types; c->cur_struct_concrete_types = old_cur_struct_concrete_types; } // Defer end // Defer begin if (v__checker__Checker_struct_init_defer_0) { v__util__timing_measure_cumulative(_S("Checker.struct_init")); } // Defer end return _t29; } VV_LOC void v__checker__Checker_check_uninitialized_struct_fields_and_embeds(v__checker__Checker* c, v__ast__StructInit node, v__ast__TypeSymbol type_sym, v__ast__Struct* info, Array_string* inited_fields) { Array_v__ast__StructField fields = v__ast__Table_struct_fields(c->table, (voidptr)&type_sym); Array_v__ast__Type checked_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int i = 0; i < fields.len; ++i) { v__ast__StructField* field = ((v__ast__StructField*)fields.data) + i; if ((Array_string_contains(*inited_fields, field->name))) { if (!string__eq(c->mod, type_sym.mod)) { if (!field->is_pub) { Array_string parts = string_split(type_sym.name, _S(".")); for (int _t1 = 0; _t1 < node.init_fields.len; ++_t1) { v__ast__StructInitField init_field = ((v__ast__StructInitField*)node.init_fields.data)[_t1]; if (string__eq(field->name, init_field.name)) { string _t2; /* if prepend */ if (parts.len > 1) { _t2 = Array_string_join(array_slice_ni(parts, -2, 2147483647), _S(".")); } else { _t2 = (*(string*)array_last(parts)); } string mod_type = _t2; if (!c->inside_unsafe) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("cannot access private field `"), 0xfe10, {.d_s = field->name}}, {_S("` on `"), 0xfe10, {.d_s = mod_type}}, {_S("`"), 0, { .d_c = 0 }}})), init_field.pos); break; } } } } if (field->is_deprecated) { for (int _t3 = 0; _t3 < node.init_fields.len; ++_t3) { v__ast__StructInitField init_field = ((v__ast__StructInitField*)node.init_fields.data)[_t3]; if (string__eq(field->name, init_field.name)) { v__checker__Checker_deprecate(c, _S("field"), field->name, field->attrs, init_field.pos); break; } } } } continue; } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, field->typ); if (field->is_embed && (sym->info)._typ == 518 /* v.ast.Struct */) { continue; } if (field->has_default_expr) { if (i < info->fields.len && field->default_expr_typ == 0) { if ((field->default_expr)._typ == 385 /* v.ast.StructInit */) { v__ast__Type idx = v__ast__Table_find_type(c->table, (*field->default_expr._v__ast__StructInit).typ_str); if (idx != 0) { (*(v__ast__StructField*)array_get(info->fields, i)).default_expr_typ = v__ast__new_type(((int)(idx))); } } else if (v__ast__Expr_is_nil(field->default_expr)) { if (v__ast__Type_is_any_kind_of_pointer(field->typ)) { (*(v__ast__StructField*)array_get(info->fields, i)).default_expr_typ = field->typ; } } else if ((field->default_expr)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((field->default_expr)._v__ast__Ident,(field->default_expr)._typ, 358)).info)._typ == 476 /* v.ast.IdentFn */) { v__checker__Checker_expr(c, &field->default_expr); } else { _option_v__ast__ConstField_ptr _t4; if (_t4 = v__ast__Scope_find_const(c->table->global_scope, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&field->default_expr)}}, {_SLIT0, 0, { .d_c = 0 }}}))), _t4.state == 0) { v__ast__ConstField* const_field = *(v__ast__ConstField**)_t4.data; (*(v__ast__StructField*)array_get(info->fields, i)).default_expr_typ = const_field->typ; } else if ((type_sym.info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((type_sym.info)._v__ast__Struct,(type_sym.info)._typ, 518)).is_anon) { c->expected_type = field->typ; field->default_expr_typ = v__checker__Checker_expr(c, &field->default_expr); (*(v__ast__StructField*)array_get(info->fields, i)).default_expr_typ = field->default_expr_typ; } } } continue; } bool field_is_option = v__ast__Type_has_flag(field->typ, v__ast__TypeFlag__option); if (v__ast__Type_is_ptr(field->typ) && !v__ast__Type_has_flag(field->typ, v__ast__TypeFlag__shared_f) && !field_is_option && !node.has_update_expr && !c->pref->translated && !c->file->is_translated) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("reference field `"), 0xfe10, {.d_s = type_sym.name}}, {_S("."), 0xfe10, {.d_s = field->name}}, {_S("` must be initialized"), 0, { .d_c = 0 }}})), node.pos); continue; } if (!field_is_option) { if (sym->kind == v__ast__Kind__struct) { v__checker__Checker_check_ref_fields_initialized(c, sym, &checked_types, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_sym.name}}, {_S("."), 0xfe10, {.d_s = field->name}}, {_SLIT0, 0, { .d_c = 0 }}})), (voidptr)&node.pos); } else if (sym->kind == v__ast__Kind__alias) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(c->table, (*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type); if (parent_sym->kind == v__ast__Kind__struct) { v__checker__Checker_check_ref_fields_initialized(c, parent_sym, &checked_types, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_sym.name}}, {_S("."), 0xfe10, {.d_s = field->name}}, {_SLIT0, 0, { .d_c = 0 }}})), (voidptr)&node.pos); } } } bool _t5 = (sym->kind == v__ast__Kind__interface && !node.has_update_expr && !field_is_option && sym->language != v__ast__Language__js); if ( _t5 && !Array_v__ast__Attr_contains(field->attrs, _S("noinit"))) { v__checker__Checker_note(c, str_intp(3, _MOV((StrIntpData[]){{_S("interface field `"), 0xfe10, {.d_s = type_sym.name}}, {_S("."), 0xfe10, {.d_s = field->name}}, {_S("` must be initialized"), 0, { .d_c = 0 }}})), node.pos); } bool _t7 = (!node.no_keys && !node.has_update_expr); bool _t6 = ( _t7 && Array_v__ast__Attr_contains(field->attrs, _S("required"))); bool _t8 = true; if (_t6) { Array_v__ast__StructInitField _t8_orig = node.init_fields; int _t8_len = _t8_orig.len; for (int _t9 = 0; _t9 < _t8_len; ++_t9) { v__ast__StructInitField it = ((v__ast__StructInitField*) _t8_orig.data)[_t9]; if (!(!string__eq(it.name, field->name))) { _t8 = false; break; } } } if ( _t6 &&_t8) { v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_S("field `"), 0xfe10, {.d_s = type_sym.name}}, {_S("."), 0xfe10, {.d_s = field->name}}, {_S("` must be initialized"), 0, { .d_c = 0 }}})), node.pos); } if (!node.has_update_expr && !field->has_default_expr && !v__ast__Type_is_ptr(field->typ) && !field_is_option) { v__ast__TypeSymbol* field_final_sym = v__ast__Table_final_sym(c->table, field->typ); if (field_final_sym->kind == v__ast__Kind__struct) { v__ast__StructInit zero_struct_init = ((v__ast__StructInit){.pos = node.pos,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.no_keys = 0,.is_short_syntax = 0,.is_anon = 0,.unresolved = 0,.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.typ_str = (string){.str=(byteptr)"", .is_lit=1},.typ = field->typ,.update_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_expr_type = 0,.update_expr_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.update_expr_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_update_embed = 0,.has_update_expr = 0,.init_fields = __new_array(0, 0, sizeof(v__ast__StructInitField)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.language = 0,}); if (field->is_part_of_union) { if ((Array_string_contains(*inited_fields, field->name))) { v__checker__Checker_struct_init(c, (voidptr)&zero_struct_init, true, inited_fields); } } else { v__checker__Checker_struct_init(c, (voidptr)&zero_struct_init, true, inited_fields); } } } } for (int _t10 = 0; _t10 < info->embeds.len; ++_t10) { v__ast__Type embed = ((v__ast__Type*)info->embeds.data)[_t10]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(c->table, embed); if ((embed_sym->info)._typ == 518 /* v.ast.Struct */) { if ((*embed_sym->info._v__ast__Struct).is_union) { Array_v__ast__StructField embed_union_fields = v__ast__Table_struct_fields(c->table, embed_sym); bool found = false; for (int _t11 = 0; _t11 < inited_fields->len; ++_t11) { string init_field = ((string*)inited_fields->data)[_t11]; for (int _t12 = 0; _t12 < embed_union_fields.len; ++_t12) { v__ast__StructField union_field = ((v__ast__StructField*)embed_union_fields.data)[_t12]; if (string__eq(init_field, union_field.name) && found) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_S("embed union `"), 0xfe10, {.d_s = embed_sym->name}}, {_S("` can have only one field initialised"), 0, { .d_c = 0 }}})), node.pos); } if (string__eq(init_field, union_field.name)) { found = true; } } } } } v__ast__StructInit zero_struct_init = ((v__ast__StructInit){.pos = node.pos,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.no_keys = 0,.is_short_syntax = 0,.is_anon = 0,.unresolved = 0,.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.typ_str = (string){.str=(byteptr)"", .is_lit=1},.typ = embed,.update_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_expr_type = 0,.update_expr_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.update_expr_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_update_embed = 0,.has_update_expr = 0,.init_fields = __new_array(0, 0, sizeof(v__ast__StructInitField)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.language = 0,}); v__checker__Checker_struct_init(c, (voidptr)&zero_struct_init, true, inited_fields); } } VV_LOC void v__checker__Checker_check_ref_fields_initialized(v__checker__Checker* c, v__ast__TypeSymbol* struct_sym, Array_v__ast__Type* checked_types, string linked_name, v__token__Pos* pos) { if ((c->pref->translated || c->file->is_translated) || struct_sym->language == v__ast__Language__c) { return; } Array_v__ast__StructField _t1 = v__ast__Table_struct_fields(c->table, struct_sym); for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__ast__StructField field = ((v__ast__StructField*)_t1.data)[_t2]; if ((Array_v__ast__Type_contains(*checked_types, field.typ))) { continue; } if (v__ast__Type_is_ptr(field.typ) && !v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__shared_f) && !v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option) && !field.has_default_expr) { v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_S("reference field `"), 0xfe10, {.d_s = linked_name}}, {_S("."), 0xfe10, {.d_s = field.name}}, {_S("` must be initialized (part of struct `"), 0xfe10, {.d_s = struct_sym->name}}, {_S("`)"), 0, { .d_c = 0 }}})), *pos); continue; } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, field.typ); if ((sym->info)._typ == 518 /* v.ast.Struct */) { if (sym->language == v__ast__Language__c) { continue; } if (field.is_embed && sym->language == v__ast__Language__v) { continue; } array_push((array*)checked_types, _MOV((v__ast__Type[]){ field.typ })); v__checker__Checker_check_ref_fields_initialized(c, sym, checked_types, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = linked_name}}, {_S("."), 0xfe10, {.d_s = field.name}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); } else if ((sym->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* psym = v__ast__Table_sym(c->table, (*sym->info._v__ast__Alias).parent_type); if (psym->kind == v__ast__Kind__struct) { array_push((array*)checked_types, _MOV((v__ast__Type[]){ field.typ })); v__checker__Checker_check_ref_fields_initialized(c, psym, checked_types, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = linked_name}}, {_S("."), 0xfe10, {.d_s = field.name}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); } } } } VV_LOC void v__checker__Checker_check_ref_fields_initialized_note(v__checker__Checker* c, v__ast__TypeSymbol* struct_sym, Array_v__ast__Type* checked_types, string linked_name, v__token__Pos* pos) { if ((c->pref->translated || c->file->is_translated) || struct_sym->language == v__ast__Language__c) { return; } Array_v__ast__StructField _t1 = v__ast__Table_struct_fields(c->table, struct_sym); for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__ast__StructField field = ((v__ast__StructField*)_t1.data)[_t2]; if ((Array_v__ast__Type_contains(*checked_types, field.typ))) { continue; } if (v__ast__Type_is_ptr(field.typ) && !v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__shared_f) && !v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option) && !field.has_default_expr) { v__checker__Checker_note(c, str_intp(4, _MOV((StrIntpData[]){{_S("reference field `"), 0xfe10, {.d_s = linked_name}}, {_S("."), 0xfe10, {.d_s = field.name}}, {_S("` must be initialized (part of struct `"), 0xfe10, {.d_s = struct_sym->name}}, {_S("`)"), 0, { .d_c = 0 }}})), *pos); continue; } v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, field.typ); if ((sym->info)._typ == 518 /* v.ast.Struct */) { if (sym->language == v__ast__Language__c) { continue; } if (field.is_embed && sym->language == v__ast__Language__v) { continue; } array_push((array*)checked_types, _MOV((v__ast__Type[]){ field.typ })); v__checker__Checker_check_ref_fields_initialized(c, sym, checked_types, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = linked_name}}, {_S("."), 0xfe10, {.d_s = field.name}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); } else if ((sym->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* psym = v__ast__Table_sym(c->table, (*sym->info._v__ast__Alias).parent_type); if (psym->kind == v__ast__Kind__struct) { array_push((array*)checked_types, _MOV((v__ast__Type[]){ field.typ })); v__checker__Checker_check_ref_fields_initialized(c, psym, checked_types, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = linked_name}}, {_S("."), 0xfe10, {.d_s = field.name}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); } } } } VV_LOC bool v__checker__Checker_is_anon_struct_compatible(v__checker__Checker* c, v__ast__Struct s1, v__ast__Struct s2) { if (!(s1.is_anon && s2.is_anon && s1.fields.len == s2.fields.len)) { return false; } bool is_compatible = true; for (int k = 0; k < s1.fields.len; ++k) { v__ast__StructField field = ((v__ast__StructField*)s1.fields.data)[k]; if (!v__checker__Checker_check_basic(c, field.typ, (*(v__ast__StructField*)array_get(s2.fields, k)).typ)) { is_compatible = false; break; } } return is_compatible; } inline VV_LOC void v__checker__Checker_markused_comptime_call(v__checker__Checker* c, bool check, string key) { if (check) { map_set(&c->table->used_features->comptime_calls, &(string[]){key}, &(bool[]) { true }); } } VV_LOC void v__checker__Checker_markused_assertstmt_auto_str(v__checker__Checker* c, v__ast__AssertStmt* node) { if (!c->table->used_features->auto_str && !c->is_builtin_mod && (node->expr)._typ == 362 /* v.ast.InfixExpr */) { if (!v__ast__TypeSymbol_has_method(v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, (*node->expr._v__ast__InfixExpr).left_type)), _S("str"))) { c->table->used_features->auto_str = true; return; } if (!v__ast__TypeSymbol_has_method(v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, (*node->expr._v__ast__InfixExpr).right_type)), _S("str"))) { c->table->used_features->auto_str = true; } } } VV_LOC void v__checker__Checker_markused_dumpexpr(v__checker__Checker* c, v__ast__DumpExpr* node) { if (c->is_builtin_mod) { return; } v__ast__Type unwrapped_type = v__checker__Checker_unwrap_generic(c, node->expr_type); if (v__ast__Type_has_flag(node->expr_type, v__ast__TypeFlag__generic)) { map_set(&c->table->used_features->comptime_syms, &(v__ast__Type[]){unwrapped_type}, &(bool[]) { true }); } if (!v__ast__TypeSymbol_has_method(v__ast__Table_sym(c->table, unwrapped_type), _S("str"))) { c->table->used_features->auto_str = true; if (v__ast__Type_is_ptr(node->expr_type)) { c->table->used_features->auto_str_ptr = true; } } else { map_set(&c->table->used_features->print_types, &(int[]){v__ast__Type_idx(node->expr_type)}, &(bool[]) { true }); } map_set(&c->table->used_features->print_types, &(int[]){_const_v__ast__int_type_idx}, &(bool[]) { true }); } inline VV_LOC void v__checker__Checker_markused_used_maps(v__checker__Checker* c, bool check) { if (check) { c->table->used_features->used_maps++; } } VV_LOC void v__checker__Checker_markused_castexpr(v__checker__Checker* c, v__ast__CastExpr* node, v__ast__Type to_type, v__ast__TypeSymbol* final_to_sym) { if (c->is_builtin_mod) { return; } if (c->table->used_features->used_maps == 0 && (final_to_sym->info)._typ == 544 /* v.ast.SumType */) { bool _t1 = false; Array_v__ast__Type _t1_orig = (*final_to_sym->info._v__ast__SumType).variants; int _t1_len = _t1_orig.len; for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t2]; if (v__ast__Table_final_sym(c->table, it)->kind == v__ast__Kind__map) { _t1 = true; break; } } if (_t1) { c->table->used_features->used_maps++; } } if (!(fast_string_eq(c->mod, _S("strings")) || fast_string_eq(c->mod, _S("math.bits"))) && v__ast__Type_is_ptr(to_type)) { c->table->used_features->cast_ptr = true; } } VV_LOC void v__checker__Checker_markused_comptimecall(v__checker__Checker* c, v__ast__ComptimeCall* node) { v__checker__Checker_markused_comptime_call(c, true, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(v__checker__Checker_unwrap_generic(c, c->comptime->comptime_for_method->receiver_type)))}}, {_S("."), 0xfe10, {.d_s = c->comptime->comptime_for_method->name}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (c->inside_anon_fn) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, node->left_type)); Array_v__ast__Fn _t1 = v__ast__TypeSymbol_get_methods(sym); for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__ast__Fn m = ((v__ast__Fn*)_t1.data)[_t2]; map_set(&c->table->used_features->comptime_calls, &(string[]){str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(v__checker__Checker_unwrap_generic(c, m.receiver_type)))}}, {_S("."), 0xfe10, {.d_s = m.name}}, {_SLIT0, 0, { .d_c = 0 }}}))}, &(bool[]) { true }); if (node->args.len > 0 && m.params.len > 0) { v__ast__Type last_param = (*(v__ast__Param*)array_last(m.params)).typ; bool _t3 = ((v__ast__Type_is_int(last_param) || v__ast__Type_is_bool(last_param))); if ( _t3 && v__ast__Table_final_sym(c->table, (*(v__ast__CallArg*)array_last(node->args)).typ)->kind == v__ast__Kind__array) { map_set(&c->table->used_features->comptime_calls, &(string[]){str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = _const_v__ast__string_type_idx}}, {_S("."), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, (*(v__ast__Param*)array_last(m.params)).typ)}}, {_SLIT0, 0, { .d_c = 0 }}}))}, &(bool[]) { true }); } } } } else { v__ast__Fn* m = c->comptime->comptime_for_method; if (node->args.len > 0 && m->params.len > 0) { v__ast__Type last_param = (*(v__ast__Param*)array_last(m->params)).typ; bool _t4 = ((v__ast__Type_is_int(last_param) || v__ast__Type_is_bool(last_param))); if ( _t4 && v__ast__Table_final_sym(c->table, (*(v__ast__CallArg*)array_last(node->args)).typ)->kind == v__ast__Kind__array) { map_set(&c->table->used_features->comptime_calls, &(string[]){str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = _const_v__ast__string_type_idx}}, {_S("."), 0xfe10, {.d_s = v__ast__Table_type_to_str(c->table, (*(v__ast__Param*)array_last(m->params)).typ)}}, {_SLIT0, 0, { .d_c = 0 }}}))}, &(bool[]) { true }); } } } } VV_LOC void v__checker__Checker_markused_comptimefor(v__checker__Checker* c, v__ast__ComptimeFor* node, v__ast__Type unwrapped_expr_type) { c->table->used_features->dump = true; if (c->table->used_features->used_maps == 0) { v__ast__TypeSymbol* final_sym = v__ast__Table_final_sym(c->table, unwrapped_expr_type); if ((final_sym->info)._typ == 514 /* v.ast.Map */) { c->table->used_features->used_maps++; } else if ((final_sym->info)._typ == 544 /* v.ast.SumType */) { bool _t1 = false; Array_v__ast__Type _t1_orig = (*final_sym->info._v__ast__SumType).variants; int _t1_len = _t1_orig.len; for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t2]; if (v__ast__Table_final_sym(c->table, it)->kind == v__ast__Kind__map) { _t1 = true; break; } } if (_t1) { c->table->used_features->used_maps++; } } } } VV_LOC void v__checker__Checker_markused_call_expr(v__checker__Checker* c, v__ast__Type left_type, v__ast__CallExpr* node) { if (left_type != 0 && v__ast__Type_is_ptr(left_type) && !c->table->used_features->auto_str_ptr && fast_string_eq(node->name, _S("str"))) { c->table->used_features->auto_str_ptr = true; } } VV_LOC void v__checker__Checker_markused_fn_call(v__checker__Checker* c, v__ast__CallExpr* node) { if (!c->is_builtin_mod && !fast_string_eq(c->mod, _S("math.bits")) && ((*(v__ast__CallArg*)array_get(node->args, 0)).expr)._typ != 384 /* v.ast.StringLiteral */) { if ((((*(v__ast__CallArg*)array_get(node->args, 0)).expr)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast(((*(v__ast__CallArg*)array_get(node->args, 0)).expr)._v__ast__CallExpr,((*(v__ast__CallArg*)array_get(node->args, 0)).expr)._typ, 344)).is_method && fast_string_eq((*(v__ast__CallExpr*)__as_cast(((*(v__ast__CallArg*)array_get(node->args, 0)).expr)._v__ast__CallExpr,((*(v__ast__CallArg*)array_get(node->args, 0)).expr)._typ, 344)).name, _S("str"))) || !v__ast__TypeSymbol_has_method(v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, (*(v__ast__CallArg*)array_get(node->args, 0)).typ)), _S("str"))) { c->table->used_features->auto_str = true; } else { if (v__ast__Type_has_option_or_result((*(v__ast__CallArg*)array_get(node->args, 0)).typ)) { c->table->used_features->print_options = true; } map_set(&c->table->used_features->print_types, &(int[]){v__ast__Type_idx((*(v__ast__CallArg*)array_get(node->args, 0)).typ)}, &(bool[]) { true }); if (!c->table->used_features->auto_str_ptr && ((*(v__ast__CallArg*)array_get(node->args, 0)).expr)._typ == 358 /* v.ast.Ident */) { v__ast__ScopeObject var_obj = (*(*(v__ast__CallArg*)array_get(node->args, 0)).expr._v__ast__Ident).obj; if ((var_obj)._typ == 422 /* v.ast.Var */) { if ((*var_obj._v__ast__Var).orig_type != 0 && v__ast__Table_final_sym(c->table, (*var_obj._v__ast__Var).orig_type)->kind == v__ast__Kind__interface) { c->table->used_features->auto_str_ptr = true; return; } } } } if (v__ast__Type_is_ptr((*(v__ast__CallArg*)array_get(node->args, 0)).typ)) { c->table->used_features->auto_str_ptr = true; } } } VV_LOC void v__checker__Checker_markused_method_call(v__checker__Checker* c, v__ast__CallExpr* node, v__ast__Expr* left_expr, v__ast__Type left_type) { if (!v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic) && (left_expr)->_typ == 358 /* v.ast.Ident */) { if (((*left_expr->_v__ast__Ident).obj)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast(((*left_expr->_v__ast__Ident).obj)._v__ast__Var,((*left_expr->_v__ast__Ident).obj)._typ, 422)).ct_type_var == v__ast__ComptimeVarKind__smartcast) { map_set(&c->table->used_features->comptime_calls, &(string[]){str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(left_type))}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}}))}, &(bool[]) { true }); } } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic)) { v__ast__Type unwrapped_left = v__checker__Checker_unwrap_generic(c, left_type); map_set(&c->table->used_features->comptime_calls, &(string[]){str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(unwrapped_left))}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}}))}, &(bool[]) { true }); if (!v__ast__Type_is_ptr(unwrapped_left) && (left_expr)->_typ == 358 /* v.ast.Ident */ && v__ast__Ident_is_mut(((v__ast__Ident*)__as_cast((left_expr)->_v__ast__Ident,(left_expr)->_typ, 358)))) { map_set(&c->table->used_features->comptime_calls, &(string[]){str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(v__ast__Type_ref(unwrapped_left)))}}, {_S("."), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}}))}, &(bool[]) { true }); } } } VV_LOC void v__checker__Checker_markused_string_inter_lit(v__checker__Checker* c, v__ast__StringInterLiteral* node, v__ast__Type ftyp) { if (c->is_builtin_mod) { return; } if (!v__ast__TypeSymbol_has_method(v__ast__Table_sym(c->table, ftyp), _S("str"))) { c->table->used_features->auto_str = true; } else { map_set(&c->table->used_features->print_types, &(int[]){v__ast__Type_idx(ftyp)}, &(bool[]) { true }); } if (v__ast__Type_is_ptr(ftyp)) { c->table->used_features->auto_str_ptr = true; } if (v__ast__Type_has_option_or_result(ftyp)) { c->table->used_features->print_options = true; } } VV_LOC void v__checker__Checker_markused_infixexpr(v__checker__Checker* c, bool check) { if (!check) { return; } c->table->used_features->index = true; } VV_LOC void v__checker__Checker_markused_array_method(v__checker__Checker* c, bool check, string method_name) { if (!check) { return; } if (_SLIT_EQ(method_name.str, method_name.len, "")) { } else if (_SLIT_EQ(method_name.str, method_name.len, "first")) { c->table->used_features->arr_first = true; } else if (_SLIT_EQ(method_name.str, method_name.len, "last")) { c->table->used_features->arr_last = true; } else if (_SLIT_EQ(method_name.str, method_name.len, "pop")) { c->table->used_features->arr_pop = true; } else if (_SLIT_EQ(method_name.str, method_name.len, "delete")) { c->table->used_features->arr_delete = true; } else if (_SLIT_EQ(method_name.str, method_name.len, "map")) { c->table->used_features->arr_map = true; } else { } } VV_LOC v__ast__AsmStmt v__parser__Parser_asm_stmt(v__parser__Parser* p, bool is_top_level) { bool v__parser__Parser_asm_stmt_defer_0 = false; p->inside_asm = true; p->inside_asm_template = true; v__parser__Parser_asm_stmt_defer_0 = true; p->n_asm = 0; if (is_top_level) { v__parser__Parser_top_level_statement_start(p); } v__ast__Scope* backup_scope = p->scope; v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__key_asm); _result_v__pref__Arch _t1 = v__pref__arch_from_string(p->tok.lit); if (_t1.is_error) { IError err = _t1.err; *(v__pref__Arch*) _t1.data = v__pref__Arch___auto; } v__pref__Arch arch = (*(v__pref__Arch*)_t1.data); if (is_top_level && arch == v__pref__Arch__wasm32) { v__parser__Parser_error(p, _S("wasm doesn't support toplevel assembly")); } bool is_volatile = false; bool is_goto = false; if (p->tok.kind == v__token__Kind__key_volatile) { _result_v__pref__Arch _t2 = v__pref__arch_from_string(p->peek_tok.lit); if (_t2.is_error) { IError err = _t2.err; *(v__pref__Arch*) _t2.data = v__pref__Arch___auto; } arch = (*(v__pref__Arch*)_t2.data); is_volatile = true; v__parser__Parser_next(p); } else if (p->tok.kind == v__token__Kind__key_goto) { _result_v__pref__Arch _t3 = v__pref__arch_from_string(p->peek_tok.lit); if (_t3.is_error) { IError err = _t3.err; *(v__pref__Arch*) _t3.data = v__pref__Arch___auto; } arch = (*(v__pref__Arch*)_t3.data); is_goto = true; v__parser__Parser_next(p); } if (arch == v__pref__Arch___auto && !p->pref->is_fmt) { if ((p->tok.lit).len == 0) { v__parser__Parser_error(p, _S("missing assembly architecture. Try i386, amd64, arm64, or wasm.")); } v__parser__Parser_error(p, _S("unknown assembly architecture")); } if (p->tok.kind != v__token__Kind__name) { v__parser__Parser_error(p, _S("must specify assembly architecture")); } else { v__parser__Parser_next(p); } v__parser__Parser_check_for_impure_v(p, v__ast__pref_arch_to_table_language(arch), v__token__Token_pos(&p->prev_tok)); v__parser__Parser_check(p, v__token__Kind__lcbr); p->scope = ((v__ast__Scope*)memdup(&(v__ast__Scope){.objects = v__ast__all_registers(p->table, arch),.struct_fields = new_map(sizeof(string), sizeof(v__ast__ScopeStructField), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.parent = ((void*)0),.detached_from_parent = true,.children = __new_array(0, 0, sizeof(v__ast__Scope*)),.start_pos = p->tok.pos,.end_pos = 0,}, sizeof(v__ast__Scope))); Array_string local_labels = __new_array_with_default(0, 0, sizeof(string), 0); Array_v__ast__AsmTemplate templates = __new_array_with_default(0, 0, sizeof(v__ast__AsmTemplate), 0); for (;;) { if (!(!(p->tok.kind == v__token__Kind__semicolon || p->tok.kind == v__token__Kind__rcbr || p->tok.kind == v__token__Kind__eof))) break; v__token__Pos template_pos = v__token__Token_pos(&p->tok); string name = _S(""); Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); if (p->tok.kind == v__token__Kind__name && arch == v__pref__Arch__amd64 && (fast_string_eq(p->tok.lit, _S("rex")) || fast_string_eq(p->tok.lit, _S("vex")) || fast_string_eq(p->tok.lit, _S("xop")))) { name = string__plus(name, p->tok.lit); v__parser__Parser_next(p); for (;;) { if (!(p->tok.kind == v__token__Kind__dot)) break; v__parser__Parser_next(p); name = string__plus(name, string__plus(_S("."), p->tok.lit)); v__parser__Parser_check(p, v__token__Kind__name); } name = string__plus(name, _S(" ")); } bool is_directive = p->tok.kind == v__token__Kind__dot; if (is_directive) { v__parser__Parser_next(p); } if (p->tok.kind == v__token__Kind__key_in || p->tok.kind == v__token__Kind__key_lock || p->tok.kind == v__token__Kind__key_orelse || p->tok.kind == v__token__Kind__key_select || p->tok.kind == v__token__Kind__key_return) { name = string__plus(name, v__token__Kind_str(p->tok.kind)); if (p->tok.kind == v__token__Kind__key_lock && (arch == v__pref__Arch__i386 || arch == v__pref__Arch__amd64)) { v__parser__Parser_next(p); bool has_suffix = (string_at(p->tok.lit, (int)(p->tok.lit.len - 1)) == 'b' || string_at(p->tok.lit, (int)(p->tok.lit.len - 1)) == 'w' || string_at(p->tok.lit, (int)(p->tok.lit.len - 1)) == 'l' || string_at(p->tok.lit, (int)(p->tok.lit.len - 1)) == 'q'); if (!((Array_string_contains(_const_v__parser__allowed_lock_prefix_ins, p->tok.lit)) || (has_suffix && (Array_string_contains(_const_v__parser__allowed_lock_prefix_ins, string_substr(p->tok.lit, 0, (int)(p->tok.lit.len - 1))))))) { v__parser__Parser_error(p, _S("The lock prefix cannot be used on this instruction")); } name = string__plus(name, _S(" ")); name = string__plus(name, p->tok.lit); } v__parser__Parser_next(p); } else if (p->tok.kind == v__token__Kind__number) { name = string__plus(name, p->tok.lit); v__parser__Parser_next(p); } else if (p->tok.kind == v__token__Kind__comment) { for (;;) { if (!(p->tok.kind == v__token__Kind__comment)) break; array_push((array*)&comments, _MOV((v__ast__Comment[]){ v__parser__Parser_comment(p) })); } } else { name = string__plus(name, p->tok.lit); v__parser__Parser_check(p, v__token__Kind__name); } if (arch == v__pref__Arch__rv32 || arch == v__pref__Arch__rv64 || arch == v__pref__Arch__wasm32 || arch == v__pref__Arch__arm64 || arch == v__pref__Arch__loongarch64) { for (;;) { if (!(p->tok.kind == v__token__Kind__dot)) break; name = string__plus(name, _S(".")); v__parser__Parser_next(p); if (arch == v__pref__Arch__wasm32 && p->tok.kind == v__token__Kind__key_const) { name = string__plus(name, _S("const")); v__parser__Parser_next(p); } else { name = string__plus(name, p->tok.lit); v__parser__Parser_check(p, v__token__Kind__name); } } } bool is_label = false; Array_v__ast__AsmArg args = __new_array_with_default(0, 0, sizeof(v__ast__AsmArg), 0); if (p->tok.line_nr == p->prev_tok.line_nr) { args_loop: for (;;) { if (v__token__Token_pos(&p->prev_tok).line_nr < v__token__Token_pos(&p->tok).line_nr) { break; } string segment = _S(""); if (p->tok.kind == v__token__Kind__name && p->peek_tok.kind == v__token__Kind__colon) { segment = p->tok.lit; v__parser__Parser_next(p); v__parser__Parser_next(p); } if (p->tok.kind == (v__token__Kind__name)) { array_push((array*)&args, _MOV((v__ast__AsmArg[]){ v__parser__Parser_reg_or_alias(p) })); } else if (p->tok.kind == (v__token__Kind__string)) { array_push((array*)&args, _MOV((v__ast__AsmArg[]){ string_to_sumtype_v__ast__AsmArg(&p->tok.lit) })); v__parser__Parser_next(p); } else if (p->tok.kind == (v__token__Kind__number)) { v__ast__Expr number_lit = v__parser__Parser_parse_number_literal(p); if (number_lit._typ == 356 /* v.ast.FloatLiteral */) { array_push((array*)&args, _MOV((v__ast__AsmArg[]){ v__ast__FloatLiteral_to_sumtype_v__ast__AsmArg(ADDR(v__ast__FloatLiteral, (((v__ast__FloatLiteral){.val = ((*number_lit._v__ast__FloatLiteral)).val,.pos = ((*number_lit._v__ast__FloatLiteral)).pos,})))) })); } else if (number_lit._typ == 363 /* v.ast.IntegerLiteral */) { if (is_directive) { array_push((array*)&args, _MOV((v__ast__AsmArg[]){ v__ast__AsmDisp_to_sumtype_v__ast__AsmArg(ADDR(v__ast__AsmDisp, (((v__ast__AsmDisp){.val = (*number_lit._v__ast__IntegerLiteral).val,.pos = (*number_lit._v__ast__IntegerLiteral).pos,})))) })); } else { array_push((array*)&args, _MOV((v__ast__AsmArg[]){ v__ast__IntegerLiteral_to_sumtype_v__ast__AsmArg(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = ((*number_lit._v__ast__IntegerLiteral)).val,.pos = ((*number_lit._v__ast__IntegerLiteral)).pos,})))) })); } } else { v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("p.parse_number_literal() invalid output: `"), 0xfe10, {.d_s = v__ast__Expr_str(&number_lit)}}, {_S("`"), 0, { .d_c = 0 }}}))); } } else if (p->tok.kind == (v__token__Kind__chartoken)) { array_push((array*)&args, _MOV((v__ast__AsmArg[]){ v__ast__CharLiteral_to_sumtype_v__ast__AsmArg(ADDR(v__ast__CharLiteral, (((v__ast__CharLiteral){.val = p->tok.lit,.pos = v__token__Token_pos(&p->tok),})))) })); v__parser__Parser_next(p); } else if (p->tok.kind == (v__token__Kind__colon)) { is_label = true; v__parser__Parser_next(p); array_push((array*)&local_labels, _MOV((string[]){ string_clone(name) })); break; } else if (p->tok.kind == (v__token__Kind__lsbr)) { if (arch == v__pref__Arch__wasm32) { v__parser__Parser_error(p, _S("wasm doesn't have addressing operands")); } v__ast__AsmAddressing addressing = v__parser__Parser_asm_addressing(p); addressing.segment = segment; array_push((array*)&args, _MOV((v__ast__AsmArg[]){ v__ast__AsmAddressing_to_sumtype_v__ast__AsmArg(&addressing) })); } else if (p->tok.kind == (v__token__Kind__rcbr)) { break; } else if (p->tok.kind == (v__token__Kind__semicolon)) { break; } else { v__parser__Parser_error(p, _S("invalid token in assembly block")); } if (p->tok.kind == v__token__Kind__comma) { v__parser__Parser_next(p); } else { break; } args_loop__continue: {} } args_loop__break: {} } for (;;) { if (!(p->tok.kind == v__token__Kind__comment)) break; array_push((array*)&comments, _MOV((v__ast__Comment[]){ v__parser__Parser_comment(p) })); } if (is_directive && (_SLIT_EQ(name.str, name.len, "globl") || _SLIT_EQ(name.str, name.len, "global"))) { for (int _t14 = 0; _t14 < args.len; ++_t14) { v__ast__AsmArg arg = ((v__ast__AsmArg*)args.data)[_t14]; array_push((array*)&p->global_labels, _MOV((string[]){ string_clone((*(v__ast__AsmAlias*)__as_cast((arg)._v__ast__AsmAlias,(arg)._typ, 497)).name) })); } } array_push((array*)&templates, _MOV((v__ast__AsmTemplate[]){ ((v__ast__AsmTemplate){ .name = name, .is_label = is_label, .is_directive = is_directive, .args = args, .comments = comments, .pos = v__token__Pos_extend(template_pos, v__token__Token_pos(&p->tok)), }) })); } v__ast__Scope* scope = p->scope; p->scope = backup_scope; p->inside_asm_template = false; Array_v__ast__AsmIO output = __new_array_with_default(0, 0, sizeof(v__ast__AsmIO), 0); Array_v__ast__AsmIO input = __new_array_with_default(0, 0, sizeof(v__ast__AsmIO), 0); Array_v__ast__AsmClobbered clobbered = __new_array_with_default(0, 0, sizeof(v__ast__AsmClobbered), 0); Array_string global_labels = __new_array_with_default(0, 0, sizeof(string), 0); if (!is_top_level) { if (p->tok.kind == v__token__Kind__semicolon) { output = v__parser__Parser_asm_ios(p, true); if (p->tok.kind == v__token__Kind__semicolon) { input = v__parser__Parser_asm_ios(p, false); } if (p->tok.kind == v__token__Kind__semicolon) { backup_scope = p->scope; p->scope = scope; v__parser__Parser_next(p); for (;;) { if (!(p->tok.kind == v__token__Kind__name)) break; v__ast__AsmRegister reg = ((v__ast__AsmRegister){.name = p->tok.lit,.typ = 0,.size = -1,}); v__parser__Parser_next(p); Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); for (;;) { if (!(p->tok.kind == v__token__Kind__comment)) break; array_push((array*)&comments, _MOV((v__ast__Comment[]){ v__parser__Parser_comment(p) })); } array_push((array*)&clobbered, _MOV((v__ast__AsmClobbered[]){ ((v__ast__AsmClobbered){.reg = reg,.comments = comments,}) })); if (p->tok.kind == v__token__Kind__rcbr || p->tok.kind == v__token__Kind__semicolon) { break; } } if (is_goto && p->tok.kind == v__token__Kind__semicolon) { v__parser__Parser_next(p); for (;;) { if (!(p->tok.kind == v__token__Kind__name)) break; array_push((array*)&global_labels, _MOV((string[]){ string_clone(p->tok.lit) })); v__parser__Parser_next(p); } } } } } else if (p->tok.kind == v__token__Kind__semicolon) { v__parser__Parser_error(p, _S("extended assembly is not allowed as a top level statement")); } p->scope = backup_scope; v__parser__Parser_check(p, v__token__Kind__rcbr); if (is_top_level) { v__parser__Parser_top_level_statement_end(p); } scope->end_pos = p->prev_tok.pos; v__ast__AsmStmt _t20 = ((v__ast__AsmStmt){ .arch = arch, .is_basic = is_top_level || (int)((int)(output.len + input.len) + clobbered.len) == 0, .is_volatile = is_volatile, .is_goto = is_goto, .clobbered = clobbered, .pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)), .templates = templates, .scope = scope, .output = output, .input = input, .global_labels = global_labels, .local_labels = local_labels, }); // Defer begin if (v__parser__Parser_asm_stmt_defer_0) { p->inside_asm = false; p->inside_asm_template = false; } // Defer end return _t20; } VV_LOC v__ast__AsmArg v__parser__Parser_reg_or_alias(v__parser__Parser* p) { v__parser__Parser_check(p, v__token__Kind__name); bool _t1 = _IN_MAP(ADDR(string, p->prev_tok.lit), ADDR(map, p->scope->objects)); bool _t4; if (!(_t1)) { bool _t5 = (p->prev_tok.len >= 2 && (string_at(p->prev_tok.lit, 0) == 'b' || string_at(p->prev_tok.lit, 0) == 'f')); bool _t6 = true; if (_t5) { Array_u8 _t6_orig = string_bytes(string_substr(p->prev_tok.lit, 1, 2147483647)); int _t6_len = _t6_orig.len; for (int _t7 = 0; _t7 < _t6_len; ++_t7) { u8 it = ((u8*) _t6_orig.data)[_t7]; if (!(u8_is_digit(it))) { _t6 = false; break; } } } _t4 = _t5 &&_t6; } if (_t1) { v__ast__ScopeObject x = (*(v__ast__ScopeObject*)map_get(ADDR(map, p->scope->objects), &(string[]){p->prev_tok.lit}, &(v__ast__ScopeObject[]){ (v__ast__ScopeObject){._v__ast__EmptyScopeObject=HEAP(v__ast__EmptyScopeObject, ((v__ast__EmptyScopeObject){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,})),._typ=418} })); if ((x)._typ == 419 /* v.ast.AsmRegister */) { return v__ast__AsmRegister_to_sumtype_v__ast__AsmArg(&(*x._v__ast__AsmRegister)); } else { v__parser__Parser_error(p, _S("non-register ast.ScopeObject found in scope")); return v__ast__AsmDisp_to_sumtype_v__ast__AsmArg(ADDR(v__ast__AsmDisp, (((v__ast__AsmDisp){.val = (string){.str=(byteptr)"", .is_lit=1},.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } } else if (_t4) { return v__ast__AsmDisp_to_sumtype_v__ast__AsmArg(ADDR(v__ast__AsmDisp, (((v__ast__AsmDisp){.val = string__plus(string_substr(p->prev_tok.lit, 1, 2147483647), u8_ascii_str(string_at(p->prev_tok.lit, 0))),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); } else { return v__ast__AsmAlias_to_sumtype_v__ast__AsmArg(ADDR(v__ast__AsmAlias, (((v__ast__AsmAlias){.pos = v__token__Token_pos(&p->prev_tok),.name = p->prev_tok.lit,})))); } return (v__ast__AsmArg){._v__ast__AsmAddressing=HEAP(v__ast__AsmAddressing, ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = {0},.base = {0},.index = {0},})),._typ=496}; } VV_LOC v__ast__AsmAddressing v__parser__Parser_asm_addressing(v__parser__Parser* p) { v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__lsbr); string unknown_addressing_mode = _S("unknown addressing mode. supported ones are [displacement],\011[base], [base + displacement], [index \342\210\227 scale + displacement], [base + index \342\210\227 scale + displacement], [base + index + displacement], [rip + displacement]"); if (p->peek_tok.kind == v__token__Kind__rsbr) { if (p->tok.kind == v__token__Kind__name) { v__ast__AsmArg base = v__parser__Parser_reg_or_alias(p); v__parser__Parser_check(p, v__token__Kind__rsbr); return ((v__ast__AsmAddressing){.scale = -1,.mode = v__ast__AddressingMode__base,.pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)),.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = (v__ast__AsmArg){._v__ast__AsmAddressing=HEAP(v__ast__AsmAddressing, ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = {0},.base = {0},.index = {0},})),._typ=496},.base = base,.index = (v__ast__AsmArg){._v__ast__AsmAddressing=HEAP(v__ast__AsmAddressing, ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = {0},.base = {0},.index = {0},})),._typ=496},}); } else if (p->tok.kind == v__token__Kind__number) { v__ast__AsmArg _t2; /* if prepend */ if (p->tok.kind == v__token__Kind__name) { _t2 = v__parser__Parser_reg_or_alias(p); } else { v__ast__AsmArg x = v__ast__AsmDisp_to_sumtype_v__ast__AsmArg(ADDR(v__ast__AsmDisp, (((v__ast__AsmDisp){.val = p->tok.lit,.pos = v__token__Token_pos(&p->tok),})))); v__parser__Parser_check(p, v__token__Kind__number); _t2 = x; } v__ast__AsmArg displacement = _t2; v__parser__Parser_check(p, v__token__Kind__rsbr); return ((v__ast__AsmAddressing){.scale = -1,.mode = v__ast__AddressingMode__displacement,.pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)),.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = displacement,.base = (v__ast__AsmArg){._v__ast__AsmAddressing=HEAP(v__ast__AsmAddressing, ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = {0},.base = {0},.index = {0},})),._typ=496},.index = (v__ast__AsmArg){._v__ast__AsmAddressing=HEAP(v__ast__AsmAddressing, ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = {0},.base = {0},.index = {0},})),._typ=496},}); } else { v__parser__Parser_error(p, unknown_addressing_mode); } } if (p->peek_tok.kind == v__token__Kind__plus && p->tok.kind == v__token__Kind__name) { if (fast_string_eq(p->tok.lit, _S("rip"))) { v__ast__AsmArg rip = v__parser__Parser_reg_or_alias(p); v__parser__Parser_next(p); v__ast__AsmArg _t4; /* if prepend */ if (p->tok.kind == v__token__Kind__name) { _t4 = v__parser__Parser_reg_or_alias(p); } else { v__ast__AsmArg x = v__ast__AsmDisp_to_sumtype_v__ast__AsmArg(ADDR(v__ast__AsmDisp, (((v__ast__AsmDisp){.val = p->tok.lit,.pos = v__token__Token_pos(&p->tok),})))); v__parser__Parser_check(p, v__token__Kind__number); _t4 = x; } v__ast__AsmArg displacement = _t4; v__parser__Parser_check(p, v__token__Kind__rsbr); return ((v__ast__AsmAddressing){.scale = -1,.mode = v__ast__AddressingMode__rip_plus_displacement,.pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)),.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = displacement,.base = rip,.index = (v__ast__AsmArg){._v__ast__AsmAddressing=HEAP(v__ast__AsmAddressing, ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = {0},.base = {0},.index = {0},})),._typ=496},}); } v__ast__AsmArg base = v__parser__Parser_reg_or_alias(p); v__parser__Parser_next(p); if (p->peek_tok.kind == v__token__Kind__rsbr) { if (p->tok.kind == v__token__Kind__number) { v__ast__AsmArg _t6; /* if prepend */ if (p->tok.kind == v__token__Kind__name) { _t6 = v__parser__Parser_reg_or_alias(p); } else { v__ast__AsmArg x = v__ast__AsmDisp_to_sumtype_v__ast__AsmArg(ADDR(v__ast__AsmDisp, (((v__ast__AsmDisp){.val = p->tok.lit,.pos = v__token__Token_pos(&p->tok),})))); v__parser__Parser_check(p, v__token__Kind__number); _t6 = x; } v__ast__AsmArg displacement = _t6; v__parser__Parser_check(p, v__token__Kind__rsbr); return ((v__ast__AsmAddressing){.scale = -1,.mode = v__ast__AddressingMode__base_plus_displacement,.pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)),.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = displacement,.base = base,.index = (v__ast__AsmArg){._v__ast__AsmAddressing=HEAP(v__ast__AsmAddressing, ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = {0},.base = {0},.index = {0},})),._typ=496},}); } else { v__parser__Parser_error(p, unknown_addressing_mode); } } v__ast__AsmArg index = v__parser__Parser_reg_or_alias(p); if (p->tok.kind == v__token__Kind__mul) { v__parser__Parser_next(p); int scale = string_int(p->tok.lit); v__parser__Parser_check(p, v__token__Kind__number); v__parser__Parser_check(p, v__token__Kind__plus); v__ast__AsmArg _t8; /* if prepend */ if (p->tok.kind == v__token__Kind__name) { _t8 = v__parser__Parser_reg_or_alias(p); } else { v__ast__AsmArg x = v__ast__AsmDisp_to_sumtype_v__ast__AsmArg(ADDR(v__ast__AsmDisp, (((v__ast__AsmDisp){.val = p->tok.lit,.pos = v__token__Token_pos(&p->tok),})))); v__parser__Parser_check(p, v__token__Kind__number); _t8 = x; } v__ast__AsmArg displacement = _t8; v__parser__Parser_check(p, v__token__Kind__rsbr); return ((v__ast__AsmAddressing){ .scale = scale, .mode = v__ast__AddressingMode__base_plus_index_times_scale_plus_displacement, .pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)), .segment = (string){.str=(byteptr)"", .is_lit=1}, .displacement = displacement, .base = base, .index = index, }); } else if (p->tok.kind == v__token__Kind__plus) { v__parser__Parser_next(p); v__ast__AsmArg _t10; /* if prepend */ if (p->tok.kind == v__token__Kind__name) { _t10 = v__parser__Parser_reg_or_alias(p); } else { v__ast__AsmArg x = v__ast__AsmDisp_to_sumtype_v__ast__AsmArg(ADDR(v__ast__AsmDisp, (((v__ast__AsmDisp){.val = p->tok.lit,.pos = v__token__Token_pos(&p->tok),})))); v__parser__Parser_check(p, v__token__Kind__number); _t10 = x; } v__ast__AsmArg displacement = _t10; v__parser__Parser_check(p, v__token__Kind__rsbr); return ((v__ast__AsmAddressing){.scale = -1,.mode = v__ast__AddressingMode__base_plus_index_plus_displacement,.pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)),.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = displacement,.base = base,.index = index,}); } } if (p->peek_tok.kind == v__token__Kind__mul) { v__ast__AsmArg index = v__parser__Parser_reg_or_alias(p); v__parser__Parser_next(p); int scale = string_int(p->tok.lit); v__parser__Parser_check(p, v__token__Kind__number); v__parser__Parser_check(p, v__token__Kind__plus); v__ast__AsmArg _t12; /* if prepend */ if (p->tok.kind == v__token__Kind__name) { _t12 = v__parser__Parser_reg_or_alias(p); } else { v__ast__AsmArg x = v__ast__AsmDisp_to_sumtype_v__ast__AsmArg(ADDR(v__ast__AsmDisp, (((v__ast__AsmDisp){.val = p->tok.lit,.pos = v__token__Token_pos(&p->tok),})))); v__parser__Parser_check(p, v__token__Kind__number); _t12 = x; } v__ast__AsmArg displacement = _t12; v__parser__Parser_check(p, v__token__Kind__rsbr); return ((v__ast__AsmAddressing){.scale = scale,.mode = v__ast__AddressingMode__index_times_scale_plus_displacement,.pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)),.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = displacement,.base = (v__ast__AsmArg){._v__ast__AsmAddressing=HEAP(v__ast__AsmAddressing, ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = {0},.base = {0},.index = {0},})),._typ=496},.index = index,}); } v__parser__Parser_error(p, unknown_addressing_mode); return ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = (v__ast__AsmArg){._v__ast__AsmAddressing=HEAP(v__ast__AsmAddressing, ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = {0},.base = {0},.index = {0},})),._typ=496},.base = (v__ast__AsmArg){._v__ast__AsmAddressing=HEAP(v__ast__AsmAddressing, ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = {0},.base = {0},.index = {0},})),._typ=496},.index = (v__ast__AsmArg){._v__ast__AsmAddressing=HEAP(v__ast__AsmAddressing, ((v__ast__AsmAddressing){.scale = -1,.mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.segment = (string){.str=(byteptr)"", .is_lit=1},.displacement = {0},.base = {0},.index = {0},})),._typ=496},}); } VV_LOC Array_v__ast__AsmIO v__parser__Parser_asm_ios(v__parser__Parser* p, bool output) { Array_v__ast__AsmIO res = __new_array_with_default(0, 0, sizeof(v__ast__AsmIO), 0); v__parser__Parser_check(p, v__token__Kind__semicolon); if (p->tok.kind == v__token__Kind__rcbr || p->tok.kind == v__token__Kind__semicolon) { return __new_array_with_default(0, 0, sizeof(v__ast__AsmIO), 0); } for (;;) { if (p->tok.kind == v__token__Kind__eof) { v__parser__Parser_error(p, _S("reached eof in asm_ios")); return __new_array_with_default(0, 0, sizeof(v__ast__AsmIO), 0); } v__token__Pos pos = v__token__Token_pos(&p->tok); string constraint = _S(""); if (p->tok.kind == v__token__Kind__lpar) { constraint = (output ? (_S("+r")) : (_S("r"))); } else { constraint = string__plus(constraint, ((p->tok.kind == (v__token__Kind__assign))? (_S("=")) : (p->tok.kind == (v__token__Kind__plus))? (_S("+")) : (p->tok.kind == (v__token__Kind__mod))? (_S("%")) : (p->tok.kind == (v__token__Kind__amp))? (_S("&")) : (_S("")))); if ((constraint).len != 0) { v__parser__Parser_next(p); } constraint = string__plus(constraint, p->tok.lit); if (p->tok.kind == v__token__Kind__at) { v__parser__Parser_next(p); } else { if (p->tok.kind == v__token__Kind__number) { if (string_int(p->tok.lit) >= 10) { v__parser__Parser_error_with_pos(p, _S("The digit must be between 0 and 9 only"), pos); return __new_array_with_default(0, 0, sizeof(v__ast__AsmIO), 0); } v__parser__Parser_check(p, v__token__Kind__number); } else { v__parser__Parser_check(p, v__token__Kind__name); } } } v__ast__Expr expr = v__parser__Parser_expr(p, 0); if ((expr)._typ == 374 /* v.ast.ParExpr */) { expr = (*expr._v__ast__ParExpr).expr; } else { v__parser__Parser_error(p, _S("asm in/output must be enclosed in brackets")); return __new_array_with_default(0, 0, sizeof(v__ast__AsmIO), 0); } string alias = _S(""); if (p->tok.kind == v__token__Kind__key_as) { v__parser__Parser_next(p); alias = p->tok.lit; v__parser__Parser_check(p, v__token__Kind__name); } else if ((expr)._typ == 358 /* v.ast.Ident */) { alias = (*expr._v__ast__Ident).name; } Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); for (;;) { if (!(p->tok.kind == v__token__Kind__comment)) break; array_push((array*)&comments, _MOV((v__ast__Comment[]){ v__parser__Parser_comment(p) })); } array_push((array*)&res, _MOV((v__ast__AsmIO[]){ ((v__ast__AsmIO){.alias = alias,.constraint = constraint,.comments = comments,.typ = 0,.pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)),.expr = expr,}) })); p->n_asm++; if (p->tok.kind == v__token__Kind__semicolon || p->tok.kind == v__token__Kind__rcbr) { break; } } return res; } VV_LOC v__ast__Stmt v__parser__Parser_assign_stmt(v__parser__Parser* p) { Array_v__ast__Ident defer_vars = array_clone_to_depth(&p->defer_vars, 0); p->defer_vars = __new_array_with_default(0, 0, sizeof(v__ast__Ident), 0); Array_v__ast__Expr exprs = v__parser__Parser_expr_list(p, true); if (!(p->inside_defer && p->tok.kind == v__token__Kind__decl_assign)) { _PUSH_MANY(&defer_vars, (p->defer_vars), _t1, Array_v__ast__Ident); } p->defer_vars = defer_vars; return v__parser__Parser_partial_assign_stmt(p, exprs); } VV_LOC _result_void v__parser__Parser_check_undefined_variables(v__parser__Parser* p, Array_string names, v__ast__Expr val) { bool v__parser__Parser_check_undefined_variables_defer_0 = false; p->expr_level++; v__parser__Parser_check_undefined_variables_defer_0 = true; _result_void _t1 = v__parser__Parser_check_expr_level(p); if (_t1.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } ; if (val._typ == 358 /* v.ast.Ident */) { for (int _t3 = 0; _t3 < names.len; ++_t3) { string name = ((string*)names.data)[_t3]; if (string__eq(name, (*val._v__ast__Ident).name) && (*val._v__ast__Ident).kind != v__ast__IdentKind__blank_ident) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("undefined variable: `"), 0xfe10, {.d_s = (*val._v__ast__Ident).name}}, {_S("`"), 0, { .d_c = 0 }}})), (*val._v__ast__Ident).pos); _result_void _t4 = (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("undefined variable: `"), 0xfe10, {.d_s = (*val._v__ast__Ident).name}}, {_S("`"), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end return _t4; } } } else if (val._typ == 338 /* v.ast.ArrayInit */) { if ((*val._v__ast__ArrayInit).has_cap) { _result_void _t5 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__ArrayInit).cap_expr); if (_t5.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t6 = {0}; _t6.is_error = true; _t6.err = _t5.err; return _t6; } ; } if ((*val._v__ast__ArrayInit).has_len) { _result_void _t7 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__ArrayInit).len_expr); if (_t7.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t8 = {0}; _t8.is_error = true; _t8.err = _t7.err; return _t8; } ; } if ((*val._v__ast__ArrayInit).has_init) { _result_void _t9 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__ArrayInit).init_expr); if (_t9.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t10 = {0}; _t10.is_error = true; _t10.err = _t9.err; return _t10; } ; } for (int _t11 = 0; _t11 < (*val._v__ast__ArrayInit).exprs.len; ++_t11) { v__ast__Expr expr = ((v__ast__Expr*)(*val._v__ast__ArrayInit).exprs.data)[_t11]; _result_void _t12 = v__parser__Parser_check_undefined_variables(p, names, expr); if (_t12.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t13 = {0}; _t13.is_error = true; _t13.err = _t12.err; return _t13; } ; } } else if (val._typ == 344 /* v.ast.CallExpr */) { _result_void _t14 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__CallExpr).left); if (_t14.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t15 = {0}; _t15.is_error = true; _t15.err = _t14.err; return _t15; } ; for (int _t16 = 0; _t16 < (*val._v__ast__CallExpr).args.len; ++_t16) { v__ast__CallArg arg = ((v__ast__CallArg*)(*val._v__ast__CallExpr).args.data)[_t16]; _result_void _t17 = v__parser__Parser_check_undefined_variables(p, names, arg.expr); if (_t17.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t18 = {0}; _t18.is_error = true; _t18.err = _t17.err; return _t18; } ; } } else if (val._typ == 345 /* v.ast.CastExpr */) { _result_void _t19 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__CastExpr).expr); if (_t19.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t20 = {0}; _t20.is_error = true; _t20.err = _t19.err; return _t20; } ; _result_void _t21 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__CastExpr).arg); if (_t21.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t22 = {0}; _t22.is_error = true; _t22.err = _t21.err; return _t22; } ; } else if (val._typ == 361 /* v.ast.IndexExpr */) { _result_void _t23 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__IndexExpr).left); if (_t23.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t24 = {0}; _t24.is_error = true; _t24.err = _t23.err; return _t24; } ; _result_void _t25 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__IndexExpr).index); if (_t25.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t26 = {0}; _t26.is_error = true; _t26.err = _t25.err; return _t26; } ; } else if (val._typ == 362 /* v.ast.InfixExpr */) { _result_void _t27 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__InfixExpr).left); if (_t27.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t28 = {0}; _t28.is_error = true; _t28.err = _t27.err; return _t28; } ; _result_void _t29 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__InfixExpr).right); if (_t29.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t30 = {0}; _t30.is_error = true; _t30.err = _t29.err; return _t30; } ; } else if (val._typ == 359 /* v.ast.IfExpr */) { _result_void _t31 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__IfExpr).left); if (_t31.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t32 = {0}; _t32.is_error = true; _t32.err = _t31.err; return _t32; } ; for (int _t33 = 0; _t33 < (*val._v__ast__IfExpr).branches.len; ++_t33) { v__ast__IfBranch branch = ((v__ast__IfBranch*)(*val._v__ast__IfExpr).branches.data)[_t33]; _result_void _t34 = v__parser__Parser_check_undefined_variables(p, names, branch.cond); if (_t34.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t35 = {0}; _t35.is_error = true; _t35.err = _t34.err; return _t35; } ; for (int _t36 = 0; _t36 < branch.stmts.len; ++_t36) { v__ast__Stmt stmt = ((v__ast__Stmt*)branch.stmts.data)[_t36]; if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { _result_void _t37 = v__parser__Parser_check_undefined_variables(p, names, (*stmt._v__ast__ExprStmt).expr); if (_t37.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t38 = {0}; _t38.is_error = true; _t38.err = _t37.err; return _t38; } ; } } } } else if (val._typ == 368 /* v.ast.MapInit */) { for (int _t39 = 0; _t39 < (*val._v__ast__MapInit).keys.len; ++_t39) { v__ast__Expr key = ((v__ast__Expr*)(*val._v__ast__MapInit).keys.data)[_t39]; _result_void _t40 = v__parser__Parser_check_undefined_variables(p, names, key); if (_t40.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t41 = {0}; _t41.is_error = true; _t41.err = _t40.err; return _t41; } ; } for (int _t42 = 0; _t42 < (*val._v__ast__MapInit).vals.len; ++_t42) { v__ast__Expr value = ((v__ast__Expr*)(*val._v__ast__MapInit).vals.data)[_t42]; _result_void _t43 = v__parser__Parser_check_undefined_variables(p, names, value); if (_t43.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t44 = {0}; _t44.is_error = true; _t44.err = _t43.err; return _t44; } ; } } else if (val._typ == 369 /* v.ast.MatchExpr */) { _result_void _t45 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__MatchExpr).cond); if (_t45.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t46 = {0}; _t46.is_error = true; _t46.err = _t45.err; return _t46; } ; for (int _t47 = 0; _t47 < (*val._v__ast__MatchExpr).branches.len; ++_t47) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)(*val._v__ast__MatchExpr).branches.data)[_t47]; for (int _t48 = 0; _t48 < branch.exprs.len; ++_t48) { v__ast__Expr expr = ((v__ast__Expr*)branch.exprs.data)[_t48]; _result_void _t49 = v__parser__Parser_check_undefined_variables(p, names, expr); if (_t49.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t50 = {0}; _t50.is_error = true; _t50.err = _t49.err; return _t50; } ; } for (int _t51 = 0; _t51 < branch.stmts.len; ++_t51) { v__ast__Stmt stmt = ((v__ast__Stmt*)branch.stmts.data)[_t51]; if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { _result_void _t52 = v__parser__Parser_check_undefined_variables(p, names, (*stmt._v__ast__ExprStmt).expr); if (_t52.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t53 = {0}; _t53.is_error = true; _t53.err = _t52.err; return _t53; } ; } } } } else if (val._typ == 374 /* v.ast.ParExpr */) { _result_void _t54 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__ParExpr).expr); if (_t54.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t55 = {0}; _t55.is_error = true; _t55.err = _t54.err; return _t55; } ; } else if (val._typ == 375 /* v.ast.PostfixExpr */) { _result_void _t56 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__PostfixExpr).expr); if (_t56.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t57 = {0}; _t57.is_error = true; _t57.err = _t56.err; return _t57; } ; } else if (val._typ == 376 /* v.ast.PrefixExpr */) { _result_void _t58 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__PrefixExpr).right); if (_t58.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t59 = {0}; _t59.is_error = true; _t59.err = _t58.err; return _t59; } ; } else if (val._typ == 379 /* v.ast.SelectorExpr */) { _result_void _t60 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__SelectorExpr).expr); if (_t60.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t61 = {0}; _t61.is_error = true; _t61.err = _t60.err; return _t61; } ; } else if (val._typ == 383 /* v.ast.StringInterLiteral */) { for (int _t62 = 0; _t62 < (*val._v__ast__StringInterLiteral).exprs.len; ++_t62) { v__ast__Expr expr_ = ((v__ast__Expr*)(*val._v__ast__StringInterLiteral).exprs.data)[_t62]; _result_void _t63 = v__parser__Parser_check_undefined_variables(p, names, expr_); if (_t63.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t64 = {0}; _t64.is_error = true; _t64.err = _t63.err; return _t64; } ; } } else if (val._typ == 385 /* v.ast.StructInit */) { for (int _t65 = 0; _t65 < (*val._v__ast__StructInit).init_fields.len; ++_t65) { v__ast__StructInitField init_field = ((v__ast__StructInitField*)(*val._v__ast__StructInit).init_fields.data)[_t65]; _result_void _t66 = v__parser__Parser_check_undefined_variables(p, names, init_field.expr); if (_t66.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t67 = {0}; _t67.is_error = true; _t67.err = _t66.err; return _t67; } ; } } else if (val._typ == 388 /* v.ast.UnsafeExpr */) { _result_void _t68 = v__parser__Parser_check_undefined_variables(p, names, (*val._v__ast__UnsafeExpr).expr); if (_t68.is_error) { // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end _result_void _t69 = {0}; _t69.is_error = true; _t69.err = _t68.err; return _t69; } ; } else { } // Defer begin if (v__parser__Parser_check_undefined_variables_defer_0) { p->expr_level--; } // Defer end return (_result_void){0}; } VV_LOC bool v__parser__Parser_check_cross_variables(v__parser__Parser* p, Array_v__ast__Expr exprs, v__ast__Expr val) { string val_str = v__ast__Expr_str(&val); if (val._typ == 358 /* v.ast.Ident */) { for (int _t1 = 0; _t1 < exprs.len; ++_t1) { v__ast__Expr expr = ((v__ast__Expr*)exprs.data)[_t1]; if ((expr)._typ == 358 /* v.ast.Ident */) { if (string__eq((*expr._v__ast__Ident).name, (*val._v__ast__Ident).name)) { return true; } } } } else if (val._typ == 361 /* v.ast.IndexExpr */) { for (int _t3 = 0; _t3 < exprs.len; ++_t3) { v__ast__Expr expr = ((v__ast__Expr*)exprs.data)[_t3]; if (string__eq(v__ast__Expr_str(&expr), val_str)) { return true; } } } else if (val._typ == 362 /* v.ast.InfixExpr */) { return v__parser__Parser_check_cross_variables(p, exprs, (*val._v__ast__InfixExpr).left) || v__parser__Parser_check_cross_variables(p, exprs, (*val._v__ast__InfixExpr).right); } else if (val._typ == 374 /* v.ast.ParExpr */) { return v__parser__Parser_check_cross_variables(p, exprs, (*val._v__ast__ParExpr).expr); } else if (val._typ == 344 /* v.ast.CallExpr */) { if (v__parser__Parser_check_cross_variables(p, exprs, (*val._v__ast__CallExpr).left)) { return true; } for (int _t8 = 0; _t8 < (*val._v__ast__CallExpr).args.len; ++_t8) { v__ast__CallArg arg = ((v__ast__CallArg*)(*val._v__ast__CallExpr).args.data)[_t8]; if (v__parser__Parser_check_cross_variables(p, exprs, arg.expr)) { return true; } } } else if (val._typ == 376 /* v.ast.PrefixExpr */) { return v__parser__Parser_check_cross_variables(p, exprs, (*val._v__ast__PrefixExpr).right); } else if (val._typ == 375 /* v.ast.PostfixExpr */) { return v__parser__Parser_check_cross_variables(p, exprs, (*val._v__ast__PostfixExpr).expr); } else if (val._typ == 379 /* v.ast.SelectorExpr */) { for (int _t12 = 0; _t12 < exprs.len; ++_t12) { v__ast__Expr expr = ((v__ast__Expr*)exprs.data)[_t12]; if (string__eq(v__ast__Expr_str(&expr), val_str)) { return true; } } } else { } return false; } VV_LOC v__ast__Stmt v__parser__Parser_partial_assign_stmt(v__parser__Parser* p, Array_v__ast__Expr left) { p->is_stmt_ident = false; v__token__Kind op = p->tok.kind; v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); Array_v__ast__Expr right = __new_array_with_default(0, left.len, sizeof(v__ast__Expr), 0); bool old_assign_rhs = p->inside_assign_rhs; p->inside_assign_rhs = true; right = v__parser__Parser_expr_list(p, true); p->inside_assign_rhs = old_assign_rhs; Array_v__ast__Comment end_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})); bool has_cross_var = false; bool is_static = false; bool is_volatile = false; for (int i = 0; i < left.len; ++i) { v__ast__Expr lx_ = ((v__ast__Expr*)left.data)[i]; v__ast__Expr lx = lx_; if (lx._typ == 358 /* v.ast.Ident */) { if (op == v__token__Kind__decl_assign) { if (v__ast__Scope_known_var(p->scope, (*lx._v__ast__Ident).name)) { if (!(p->pref->translated_go && (fast_string_eq((*lx._v__ast__Ident).name, _S("err")) || fast_string_eq((*lx._v__ast__Ident).name, _S("ok"))))) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("redefinition of `"), 0xfe10, {.d_s = (*lx._v__ast__Ident).name}}, {_S("`"), 0, { .d_c = 0 }}})), (*lx._v__ast__Ident).pos)))); } } v__ast__ShareType share = ((v__ast__ShareType)(0)); if (((*lx._v__ast__Ident).info)._typ == 477 /* v.ast.IdentVar */) { share = (*(*lx._v__ast__Ident).info._v__ast__IdentVar).share; if ((*(*lx._v__ast__Ident).info._v__ast__IdentVar).is_static) { if (!p->inside_unsafe && !p->pref->translated && !p->is_translated && !p->pref->is_fmt && !p->inside_unsafe_fn) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("static variables are supported only in -translated mode, `unsafe{}` blocks, or in `@[unsafe] fn`"), (*lx._v__ast__Ident).pos)))); } is_static = true; } if ((*(*lx._v__ast__Ident).info._v__ast__IdentVar).is_volatile) { is_volatile = true; } } v__ast__Var v = ((v__ast__Var){ .name = (*lx._v__ast__Ident).name, .share = share, .is_mut = (*lx._v__ast__Ident).is_mut || p->inside_for, .is_static = is_static, .is_volatile = is_volatile, .is_autofree_tmp = 0, .is_inherited = 0, .has_inherited = 0, .is_arg = 0, .is_auto_deref = 0, .is_unwrapped = 0, .is_index_var = 0, .expr = (left.len == right.len ? ((*(v__ast__Expr*)array_get(right, i))) : (_const_v__ast__empty_expr)), .typ = 0, .orig_type = 0, .smartcasts = __new_array(0, 0, sizeof(v__ast__Type)), .pos = (*lx._v__ast__Ident).pos, .is_used = 0, .is_changed = 0, .ct_type_var = 0, .ct_type_unwrapped = 0, .is_or = 0, .is_tmp = 0, .is_auto_heap = 0, .is_stack_obj = p->inside_for, }); if (p->prev_tok.kind == v__token__Kind__string) { v.typ = _const_v__ast__string_type_idx; } else if (p->prev_tok.kind == v__token__Kind__rsbr) { v.typ = _const_v__ast__array_type_idx; } if (p->pref->autofree) { v__ast__Expr r0 = (*(v__ast__Expr*)array_get(right, 0)); if ((r0)._typ == 344 /* v.ast.CallExpr */) { if ((*r0._v__ast__CallExpr).or_block.pos.pos > 0 && (*r0._v__ast__CallExpr).or_block.stmts.len > 0) { v.is_or = true; } } } v__ast__ScopeObject obj = v__ast__Var_to_sumtype_v__ast__ScopeObject(&v); (*lx._v__ast__Ident).obj = obj; v__ast__Scope_register(p->scope, obj); } } else if (lx._typ == 361 /* v.ast.IndexExpr */) { if (op == v__token__Kind__decl_assign) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("non-name `"), 0xfe10, {.d_s = v__ast__Expr_str(&(*lx._v__ast__IndexExpr).left)}}, {_S("["), 0xfe10, {.d_s = v__ast__Expr_str(&(*lx._v__ast__IndexExpr).index)}}, {_S("]` on left side of `:=`"), 0, { .d_c = 0 }}})), (*lx._v__ast__IndexExpr).pos)))); } (*lx._v__ast__IndexExpr).is_setter = true; } else if (lx._typ == 374 /* v.ast.ParExpr */) { } else if (lx._typ == 376 /* v.ast.PrefixExpr */) { } else if (lx._typ == 379 /* v.ast.SelectorExpr */) { if (op == v__token__Kind__decl_assign) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("use assignment `=` instead of declaration `:=` when modifying struct fields"), pos)))); } } else { } } if (op == v__token__Kind__decl_assign) { for (int _t5 = 0; _t5 < right.len; ++_t5) { v__ast__Expr r = ((v__ast__Expr*)right.data)[_t5]; Array_string _t7 = {0}; Array_v__ast__Expr _t7_orig = left; int _t7_len = _t7_orig.len; _t7 = __new_array(0, _t7_len, sizeof(string)); for (int _t9 = 0; _t9 < _t7_len; ++_t9) { v__ast__Expr it = ((v__ast__Expr*) _t7_orig.data)[_t9]; string _t8 = v__ast__Expr_str(&it); array_push((array*)&_t7, &_t8); } _result_void _t6 = v__parser__Parser_check_undefined_variables(p,_t7, r); if (_t6.is_error) { IError err = _t6.err; return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, IError_name_table[err._typ]._method_msg(err._object), pos)))); } ; } } else if (left.len > 1) { for (int _t11 = 0; _t11 < right.len; ++_t11) { v__ast__Expr r = ((v__ast__Expr*)right.data)[_t11]; has_cross_var = v__parser__Parser_check_cross_variables(p, left, r); if (!(op == v__token__Kind__assign || op == v__token__Kind__decl_assign)) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_unexpected_with_pos(p, pos, ((v__parser__ParamsForUnexpected){.got = v__token__Kind_str(op),.expecting = _S(":= or = or comma"),.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},}))))); } if (has_cross_var) { break; } } } v__ast__Attr attr = ((v__ast__Attr){.name = (string){.str=(byteptr)"", .is_lit=1},.has_arg = 0,.arg = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.ct_opt = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_at = 0,.ct_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.ct_evaled = 0,.ct_skip = 0,}); if (p->tok.kind == v__token__Kind__at && p->tok.line_nr == p->prev_tok.line_nr) { v__parser__Parser_check(p, v__token__Kind__at); v__parser__Parser_check(p, v__token__Kind__lsbr); attr = v__parser__Parser_parse_attr(p, true); v__parser__Parser_check(p, v__token__Kind__rsbr); } v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); p->expr_mod = _S(""); return v__ast__AssignStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__AssignStmt, (((v__ast__AssignStmt){ .op = op, .pos = pos, .end_comments = end_comments, .right = right, .left = left, .left_types = __new_array(0, 0, sizeof(v__ast__Type)), .right_types = __new_array(0, 0, sizeof(v__ast__Type)), .is_static = is_static, .is_volatile = is_volatile, .is_simple = p->inside_for && p->tok.kind == v__token__Kind__lcbr, .has_cross_var = has_cross_var, .attr = attr, })))); } VV_LOC v__ast__Attr v__parser__Parser_parse_attr(v__parser__Parser* p, bool is_at) { bool v__parser__Parser_parse_attr_defer_0 = false; v__ast__AttrKind kind = v__ast__AttrKind__plain; p->inside_attr_decl = true; v__parser__Parser_parse_attr_defer_0 = true; v__token__Pos apos = (is_at ? (v__token__Token_pos(ADDR(v__token__Token, v__parser__Parser_peek_token(p, -2)))) : (v__token__Token_pos(&p->prev_tok))); if (p->tok.kind == v__token__Kind__key_unsafe) { v__parser__Parser_next(p); v__ast__Attr _t1 = ((v__ast__Attr){.name = _S("unsafe"),.has_arg = 0,.arg = (string){.str=(byteptr)"", .is_lit=1},.kind = kind,.ct_opt = 0,.pos = v__token__Pos_extend(apos, v__token__Token_pos(&p->tok)),.has_at = is_at,.ct_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.ct_evaled = 0,.ct_skip = 0,}); // Defer begin if (v__parser__Parser_parse_attr_defer_0) { p->inside_attr_decl = false; } // Defer end return _t1; } string name = _S(""); bool has_arg = false; string arg = _S(""); v__ast__Expr comptime_cond = _const_v__ast__empty_expr; bool comptime_cond_opt = false; if (p->tok.kind == v__token__Kind__key_if) { kind = v__ast__AttrKind__comptime_define; v__parser__Parser_next(p); p->comptime_if_cond = true; p->inside_if_expr = true; p->inside_ct_if_expr = true; comptime_cond = v__parser__Parser_expr(p, 0); p->comptime_if_cond = false; p->inside_if_expr = false; p->inside_ct_if_expr = false; if ((comptime_cond)._typ == 375 /* v.ast.PostfixExpr */) { comptime_cond_opt = true; } name = v__ast__Expr_str(&comptime_cond); } else if (p->tok.kind == v__token__Kind__string) { name = p->tok.lit; kind = v__ast__AttrKind__string; v__parser__Parser_next(p); } else { name = v__parser__Parser_check_name(p); if (p->tok.kind == v__token__Kind__dot) { v__parser__Parser_next(p); name = string__plus(name, _S(".")); name = string__plus(name, v__parser__Parser_check_name(p)); } if (p->tok.kind == v__token__Kind__colon) { has_arg = true; v__parser__Parser_next(p); if (p->tok.kind == v__token__Kind__name) { kind = v__ast__AttrKind__plain; arg = v__parser__Parser_check_name(p); } else if (p->tok.kind == v__token__Kind__number) { kind = v__ast__AttrKind__number; arg = p->tok.lit; v__parser__Parser_next(p); } else if (p->tok.kind == v__token__Kind__string) { kind = v__ast__AttrKind__string; arg = p->tok.lit; v__parser__Parser_next(p); } else if (p->tok.kind == v__token__Kind__key_true || p->tok.kind == v__token__Kind__key_false) { kind = v__ast__AttrKind__bool; arg = v__token__Kind_str(p->tok.kind); v__parser__Parser_next(p); } else if (v__token__is_key(p->tok.lit)) { kind = v__ast__AttrKind__plain; arg = v__parser__Parser_check_name(p); } else { v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = _S("an argument is expected after `:`"),})); } } } v__ast__Attr _t2 = ((v__ast__Attr){ .name = name, .has_arg = has_arg, .arg = arg, .kind = kind, .ct_opt = comptime_cond_opt, .pos = v__token__Pos_extend(apos, v__token__Token_pos(&p->tok)), .has_at = is_at, .ct_expr = comptime_cond, .ct_evaled = 0, .ct_skip = 0, }); // Defer begin if (v__parser__Parser_parse_attr_defer_0) { p->inside_attr_decl = false; } // Defer end return _t2; } VV_LOC bool v__parser__Parser_is_attributes(v__parser__Parser* p) { if (p->tok.kind != v__token__Kind__lsbr) { return false; } int i = 0; for (;;) { v__token__Token tok = v__parser__Parser_peek_token(p, i); if (tok.kind == v__token__Kind__eof || tok.line_nr != p->tok.line_nr) { return false; } if (tok.kind == v__token__Kind__rsbr) { break; } i++; } v__token__Token peek_rsbr_tok = v__parser__Parser_peek_token(p, (int)(i + 1)); if (peek_rsbr_tok.line_nr == p->tok.line_nr && peek_rsbr_tok.kind != v__token__Kind__rcbr) { return false; } return true; } VV_LOC void v__parser__Parser_attributes(v__parser__Parser* p) { v__token__Pos start_pos = v__token__Token_pos(&p->tok); bool is_at = false; if (p->tok.kind == v__token__Kind__lsbr) { if (p->pref->is_fmt) { } else { v__parser__Parser_error(p, _S("`[attr]` has been deprecated, use `@[attr]` instead")); } v__parser__Parser_check(p, v__token__Kind__lsbr); } else if (p->tok.kind == v__token__Kind__at) { v__parser__Parser_check(p, v__token__Kind__at); v__parser__Parser_check(p, v__token__Kind__lsbr); is_at = true; } bool has_ctdefine = false; for (;;) { if (!(p->tok.kind != v__token__Kind__rsbr)) break; v__token__Pos attr_start_pos = v__token__Token_pos(&p->tok); v__ast__Attr attr = v__parser__Parser_parse_attr(p, is_at); if (Array_v__ast__Attr_contains(p->attrs, attr.name) && !fast_string_eq(attr.name, _S("wasm_export"))) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate attribute `"), 0xfe10, {.d_s = attr.name}}, {_S("`"), 0, { .d_c = 0 }}})), v__token__Pos_extend(attr_start_pos, v__token__Token_pos(&p->prev_tok))); return; } if (attr.kind == v__ast__AttrKind__comptime_define) { if (has_ctdefine) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("only one `[if flag]` may be applied at a time `"), 0xfe10, {.d_s = attr.name}}, {_S("`"), 0, { .d_c = 0 }}})), v__token__Pos_extend(attr_start_pos, v__token__Token_pos(&p->prev_tok))); return; } else { has_ctdefine = true; } } array_push((array*)&p->attrs, _MOV((v__ast__Attr[]){ attr })); if (p->tok.kind != v__token__Kind__semicolon) { if (p->tok.kind == v__token__Kind__rsbr) { v__parser__Parser_next(p); break; } v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = _S("`;`"),.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); return; } v__parser__Parser_next(p); } if (p->attrs.len == 0) { v__parser__Parser_error_with_pos(p, _S("attributes cannot be empty"), v__token__Pos_extend(start_pos, v__token__Token_pos(&p->tok))); return; } if (p->inside_struct_attr_decl && p->tok.kind == v__token__Kind__lsbr) { v__parser__Parser_error_with_pos(p, _S("multiple attributes should be in the same [], with ; separators"), v__token__Pos_extend(v__token__Token_pos(&p->prev_tok), v__token__Token_pos(&p->tok))); return; } else if (p->inside_struct_attr_decl && p->tok.kind == v__token__Kind__at) { v__parser__Parser_error_with_pos(p, _S("multiple attributes should be in the same @[], with ; separators"), v__token__Pos_extend(v__token__Token_pos(&p->prev_tok), v__token__Token_pos(&p->tok))); return; } } VV_LOC bool v__parser__Parser_is_fn_type_decl(v__parser__Parser* p) { int n = 1; v__token__Token tok = p->tok; v__token__Token prev_tok = p->tok; int cur_ln = p->tok.line_nr; for (;;) { tok = v__scanner__Scanner_peek_token(p->scanner, n); if (tok.kind == v__token__Kind__eof) { break; } if (tok.kind == v__token__Kind__lpar || tok.kind == v__token__Kind__rpar) { n++; prev_tok = tok; continue; } if (tok.kind == v__token__Kind__pipe) { if ((int)(tok.pos - prev_tok.pos) > prev_tok.len) { return false; } } if (tok.line_nr > cur_ln) { break; } prev_tok = tok; n++; } return true; } VV_LOC bool v__parser__Parser_has_prev_newline(v__parser__Parser* p) { v__token__Token tok = p->tok; v__token__Token prev_tok = p->prev_tok; int idx = -1; for (;;) { if ((int)((int)(tok.line_nr - prev_tok.line_nr) - string_count(prev_tok.lit, _S("\n"))) > 1) { return true; } if (prev_tok.kind == v__token__Kind__comment) { idx--; tok = prev_tok; prev_tok = v__parser__Parser_peek_token(p, idx); continue; } break; } return false; } VV_LOC bool v__parser__Parser_has_prev_line_comment_or_label(v__parser__Parser* p) { return p->prev_tok.kind == v__token__Kind__colon || (p->prev_tok.kind == v__token__Kind__comment && (int)(p->tok.line_nr - p->prev_tok.line_nr) == 1 && (int)(p->prev_tok.line_nr - v__parser__Parser_peek_token(p, -2).line_nr) > 0); } VV_LOC bool v__parser__Parser_is_array_type(v__parser__Parser* p) { int i = 1; v__token__Token tok = p->tok; int line_nr = p->tok.line_nr; for (;;) { tok = v__parser__Parser_peek_token(p, i); if (tok.line_nr != line_nr) { return false; } if (tok.kind == v__token__Kind__name || tok.kind == v__token__Kind__amp) { return true; } if (tok.kind == v__token__Kind__eof) { break; } i++; if (tok.kind == v__token__Kind__lsbr || tok.kind != v__token__Kind__rsbr) { continue; } } return false; } VV_LOC bool v__parser__Parser_is_following_concrete_types(v__parser__Parser* p) { if (!((p->tok.kind == v__token__Kind__lt || p->tok.kind == v__token__Kind__lsbr) && v__token__Token_is_next_to(p->tok, p->prev_tok))) { return false; } int i = 1; for (;;) { v__token__Token cur_tok = v__parser__Parser_peek_token(p, i); if (cur_tok.kind == v__token__Kind__eof) { return false; } else if (cur_tok.kind == v__token__Kind__rsbr) { break; } else if (cur_tok.kind == v__token__Kind__name) { if (v__parser__Parser_peek_token(p, (int)(i + 1)).kind == v__token__Kind__dot) { if (v__parser__Parser_is_typename(p, cur_tok)) { return false; } i++; } else if (!(v__parser__Parser_is_typename(p, cur_tok) && !(cur_tok.lit.len == 1 && !u8_is_capital(string_at(cur_tok.lit, 0))))) { return false; } } else if (cur_tok.kind != v__token__Kind__comma) { return false; } i++; } return true; } VV_LOC bool v__parser__Parser_is_generic_struct_init(v__parser__Parser* p) { bool lit0_is_capital = p->tok.kind != v__token__Kind__eof && p->tok.lit.len > 0 && u8_is_capital(p->tok.lit.str[ 0]); if (!lit0_is_capital || !(p->peek_tok.kind == v__token__Kind__lt || p->peek_tok.kind == v__token__Kind__lsbr)) { return false; } if (p->peek_tok.kind == v__token__Kind__lt) { return true; } else { int i = 2; int nested_sbr_count = 0; for (;;) { v__token__Token cur_tok = v__parser__Parser_peek_token(p, i); if (cur_tok.kind == v__token__Kind__eof || !(cur_tok.kind == v__token__Kind__amp || cur_tok.kind == v__token__Kind__dot || cur_tok.kind == v__token__Kind__comma || cur_tok.kind == v__token__Kind__name || cur_tok.kind == v__token__Kind__lpar || cur_tok.kind == v__token__Kind__rpar || cur_tok.kind == v__token__Kind__lsbr || cur_tok.kind == v__token__Kind__rsbr || cur_tok.kind == v__token__Kind__key_fn)) { break; } if (cur_tok.kind == v__token__Kind__lsbr) { nested_sbr_count++; } else if (cur_tok.kind == v__token__Kind__rsbr) { if (nested_sbr_count > 0) { nested_sbr_count--; } else { if (v__parser__Parser_peek_token(p, (int)(i + 1)).kind == v__token__Kind__lcbr) { return true; } break; } } i++; } } return false; } inline VV_LOC bool v__parser__Parser_is_typename(v__parser__Parser* p, v__token__Token t) { return t.kind == v__token__Kind__name && (u8_is_capital(t.lit.str[ 0]) || v__ast__Table_known_type(p->table, t.lit)); } VV_LOC bool v__parser__Parser_is_generic_call(v__parser__Parser* p) { bool lit0_is_capital = p->tok.kind != v__token__Kind__eof && p->tok.lit.len > 0 && u8_is_capital(p->tok.lit.str[ 0]); if (lit0_is_capital || !(p->peek_tok.kind == v__token__Kind__lt || p->peek_tok.kind == v__token__Kind__lsbr)) { return false; } v__token__Token tok2 = v__parser__Parser_peek_token(p, 2); v__token__Token tok3 = v__parser__Parser_peek_token(p, 3); v__token__Token tok4 = v__parser__Parser_peek_token(p, 4); v__token__Token tok5 = v__parser__Parser_peek_token(p, 5); v__token__Kind kind2 = tok2.kind; v__token__Kind kind3 = tok3.kind; v__token__Kind kind4 = tok4.kind; v__token__Kind kind5 = tok5.kind; if (kind2 == v__token__Kind__amp) { tok2 = tok3; kind2 = kind3; tok3 = tok4; kind3 = kind4; tok4 = tok5; kind4 = kind5; tok5 = v__parser__Parser_peek_token(p, 6); kind5 = tok5.kind; } if (kind2 == v__token__Kind__lsbr) { return tok3.kind == v__token__Kind__rsbr || (tok4.kind == v__token__Kind__rsbr && v__parser__Parser_is_typename(p, tok5)); } if (kind2 == v__token__Kind__name) { if (kind3 == v__token__Kind__lsbr && fast_string_eq(tok2.lit, _S("map"))) { return true; } if (p->peek_tok.kind == v__token__Kind__lt) { return ((kind3 == (v__token__Kind__gt))? (true) : (kind3 == (v__token__Kind__lt))? (!(tok4.lit.len == 1 && u8_is_capital(tok4.lit.str[ 0]))) : (kind3 == (v__token__Kind__comma))? (v__parser__Parser_is_typename(p, tok2)) : (kind3 == (v__token__Kind__dot))? (kind4 == v__token__Kind__name && (kind5 == v__token__Kind__gt || (kind5 == v__token__Kind__comma && v__parser__Parser_is_typename(p, tok4)))) : (false)); } else if (p->peek_tok.kind == v__token__Kind__lsbr) { int i = 3; int nested_sbr_count = 0; for (;;) { v__token__Token cur_tok = v__parser__Parser_peek_token(p, i); if (cur_tok.kind == v__token__Kind__eof || !(cur_tok.kind == v__token__Kind__amp || cur_tok.kind == v__token__Kind__dot || cur_tok.kind == v__token__Kind__comma || cur_tok.kind == v__token__Kind__name || cur_tok.kind == v__token__Kind__lpar || cur_tok.kind == v__token__Kind__rpar || cur_tok.kind == v__token__Kind__lsbr || cur_tok.kind == v__token__Kind__rsbr || cur_tok.kind == v__token__Kind__key_fn)) { break; } if (cur_tok.kind == v__token__Kind__lsbr) { nested_sbr_count++; } if (cur_tok.kind == v__token__Kind__rsbr) { if (nested_sbr_count > 0) { nested_sbr_count--; } else { v__token__Token prev_tok = v__parser__Parser_peek_token(p, (int)(i - 1)); if (!(v__parser__Parser_is_typename(p, prev_tok) || prev_tok.kind == v__token__Kind__rsbr)) { return false; } if (v__parser__Parser_peek_token(p, (int)(i + 1)).kind == v__token__Kind__lpar) { return true; } break; } } i++; } } } return false; } VV_LOC bool v__parser__Parser_is_generic_cast(v__parser__Parser* p) { if (!v__ast__type_can_start_with_token(&p->tok)) { return false; } int i = 0; int level = 0; int lt_count = 0; for (;;) { i++; v__token__Token tok = v__parser__Parser_peek_token(p, i); if (tok.kind == v__token__Kind__lt || tok.kind == v__token__Kind__lsbr) { lt_count++; level++; } else if (tok.kind == v__token__Kind__gt || tok.kind == v__token__Kind__rsbr) { level--; } if (lt_count > 0 && level == 0) { break; } if (i > 20 || !(Array_v__token__Kind_contains(_const_v__parser__valid_tokens_inside_types, tok.kind))) { return false; } } v__token__Token next_tok = v__parser__Parser_peek_token(p, (int)(i + 1)); if (next_tok.kind == v__token__Kind__lpar) { return true; } return false; } inline VV_LOC bool v__parser__Parser_is_generic_name(v__parser__Parser* p) { return p->tok.kind == v__token__Kind__name && v__util__is_generic_type_name(p->tok.lit); } void v__parser__Parser_codegen(v__parser__Parser* p, string code) { #if defined(CUSTOM_DEFINE_debug_codegen) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("parser.codegen: "), 0xfe10, {.d_s = code}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif p->codegen_text = string__plus(p->codegen_text, code); } VV_LOC void v__parser__Parser_handle_codegen_for_file(v__parser__Parser* p) { if (p->pref->is_fmt || (p->codegen_text).len == 0) { return; } string ptext = string__plus(string__plus(string__plus(_S("module "), string_all_after_last(p->mod, _S("."))), _S("\n")), p->codegen_text); array_push((array*)&codegen_files, _MOV((v__ast__File*[]){ v__parser__parse_text(ptext, p->file_path, p->table, p->scanner->comments_mode, p->pref) })); } VV_LOC void v__parser__handle_codegen_for_multiple_files(Array_v__ast__File_ptr* files) { if (codegen_files.len == 0) { return; } _PUSH_MANY(files, (codegen_files), _t1, Array_v__ast__File_ptr); array_clear(&codegen_files); } VV_LOC v__ast__ComptimeType v__parser__Parser_parse_comptime_type(v__parser__Parser* p) { v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__dollar); string name = v__parser__Parser_check_name(p); if (!(Array_string_contains(_const_v__parser__comptime_types, name))) { v__parser__Parser_error(p, str_intp(3, _MOV((StrIntpData[]){{_S("unsupported compile-time type `"), 0xfe10, {.d_s = name}}, {_S("`: only "), 0xfe10, {.d_s = Array_string_str(_const_v__parser__comptime_types)}}, {_S(" are supported"), 0, { .d_c = 0 }}}))); } v__ast__ComptimeTypeKind kind = v__ast__ComptimeTypeKind__unknown; kind = ((_SLIT_EQ(name.str, name.len, "map"))? (v__ast__ComptimeTypeKind__map) : (_SLIT_EQ(name.str, name.len, "struct"))? (v__ast__ComptimeTypeKind__struct) : (_SLIT_EQ(name.str, name.len, "interface"))? (v__ast__ComptimeTypeKind__iface) : (_SLIT_EQ(name.str, name.len, "int"))? (v__ast__ComptimeTypeKind__int) : (_SLIT_EQ(name.str, name.len, "float"))? (v__ast__ComptimeTypeKind__float) : (_SLIT_EQ(name.str, name.len, "alias"))? (v__ast__ComptimeTypeKind__alias) : (_SLIT_EQ(name.str, name.len, "function"))? (v__ast__ComptimeTypeKind__function) : (_SLIT_EQ(name.str, name.len, "array"))? (v__ast__ComptimeTypeKind__array) : (_SLIT_EQ(name.str, name.len, "array_fixed"))? (v__ast__ComptimeTypeKind__array_fixed) : (_SLIT_EQ(name.str, name.len, "array_dynamic"))? (v__ast__ComptimeTypeKind__array_dynamic) : (_SLIT_EQ(name.str, name.len, "enum"))? (v__ast__ComptimeTypeKind__enum) : (_SLIT_EQ(name.str, name.len, "sumtype"))? (v__ast__ComptimeTypeKind__sum_type) : (_SLIT_EQ(name.str, name.len, "option"))? (v__ast__ComptimeTypeKind__option) : (_SLIT_EQ(name.str, name.len, "string"))? (v__ast__ComptimeTypeKind__string) : (_SLIT_EQ(name.str, name.len, "pointer"))? (v__ast__ComptimeTypeKind__pointer) : (_SLIT_EQ(name.str, name.len, "voidptr"))? (v__ast__ComptimeTypeKind__voidptr) : (v__ast__ComptimeTypeKind__unknown)); return ((v__ast__ComptimeType){.kind = kind,.pos = pos,}); } VV_LOC v__ast__HashStmt v__parser__Parser_hash(v__parser__Parser* p) { v__token__Pos pos = v__token__Token_pos(&p->tok); string val = p->tok.lit; string kind = string_all_before(val, _S(" ")); Array_v__ast__Attr attrs = p->attrs; v__parser__Parser_next(p); string main_str = _S(""); string msg = _S(""); string content = string_all_before(string_all_after(val, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = kind}}, {_S(" "), 0, { .d_c = 0 }}}))), _S("//")); if (string_contains(content, _S(" #"))) { main_str = string_trim_space(string_all_before(content, _S(" #"))); msg = string_trim_space(string_all_after(content, _S(" #"))); } else { main_str = string_trim_space(content); msg = _S(""); } bool is_use_once = false; for (int _t1 = 0; _t1 < attrs.len; ++_t1) { v__ast__Attr fna = ((v__ast__Attr*)attrs.data)[_t1]; if (_SLIT_EQ(fna.name.str, fna.name.len, "use_once")) { is_use_once = true; } else { } } return ((v__ast__HashStmt){ .mod = p->mod, .pos = pos, .source_file = p->file_path, .is_use_once = is_use_once, .val = val, .kind = kind, .main = main_str, .msg = msg, .ct_conds = __new_array(0, 0, sizeof(v__ast__Expr)), .attrs = attrs, }); } VV_LOC v__ast__ComptimeCall v__parser__Parser_comptime_call(v__parser__Parser* p) { bool v__parser__Parser_comptime_call_defer_0 = false; v__ast__ComptimeCall *err_node = HEAP(v__ast__ComptimeCall, (((v__ast__ComptimeCall){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_parens = 0,.method_name = (string){.str=(byteptr)"", .is_lit=1},.kind = v__ast__ComptimeCallKind__unknown,.method_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.scope = ((void*)0),.is_vweb = 0,.is_veb = 0,.env_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_d_resolved = 0,.veb_tmpl = ((v__ast__File){.nr_lines = 0,.nr_bytes = 0,.nr_tokens = 0,.mod = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}),.global_scope = ((void*)0),.is_test = 0,.is_generated = 0,.is_translated = 0,.language = 0,.idx = 0,.path = (string){.str=(byteptr)"", .is_lit=1},.path_base = (string){.str=(byteptr)"", .is_lit=1},.scope = ((void*)0),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.imports = __new_array(0, 0, sizeof(v__ast__Import)),.auto_imports = __new_array(0, 0, sizeof(string)),.embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)),.imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.errors = __new_array(0, 0, sizeof(v__errors__Error)),.warnings = __new_array(0, 0, sizeof(v__errors__Warning)),.notices = __new_array(0, 0, sizeof(v__errors__Notice)),.generic_fns = __new_array(0, 0, sizeof(v__ast__FnDecl*)),.global_labels = __new_array(0, 0, sizeof(string)),.template_paths = __new_array(0, 0, sizeof(string)),.unique_prefix = (string){.str=(byteptr)"", .is_lit=1},.is_parse_text = 0,.is_template_text = 0,}),.left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.left_type = 0,.result_type = 0,.env_value = (string){.str=(byteptr)"", .is_lit=1},.compile_value = (string){.str=(byteptr)"", .is_lit=1},.args_var = (string){.str=(byteptr)"", .is_lit=1},.args = __new_array(0, 0, sizeof(v__ast__CallArg)),.embed_file = ((v__ast__EmbeddedFile){.compression_type = (string){.str=(byteptr)"", .is_lit=1},.rpath = (string){.str=(byteptr)"", .is_lit=1},.apath = (string){.str=(byteptr)"", .is_lit=1},.is_compressed = 0,.bytes = __new_array(0, 0, sizeof(u8)),.len = 0,}),.or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),}))); v__token__Pos start_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__dollar); bool is_veb = false; if (p->peek_tok.kind == v__token__Kind__dot) { string name = v__parser__Parser_check_name(p); if (_SLIT_NE(name.str, name.len, "vweb") && _SLIT_NE(name.str, name.len, "veb")) { v__parser__Parser_error(p, _const_v__parser__error_msg); return (*(err_node)); } Array_string _t2 = {0}; Array_v__ast__Import _t2_orig = p->ast_imports; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Import it = ((v__ast__Import*) _t2_orig.data)[_t4]; string _t3 = it.mod; array_push((array*)&_t2, &_t3); } Array_string import_mods =_t2; if (_SLIT_EQ(name.str, name.len, "vweb")) { if (!(Array_string_contains(import_mods, _S("vweb"))) && !(Array_string_contains(import_mods, _S("x.vweb")))) { v__parser__Parser_error_with_pos(p, _S("`$vweb` cannot be used without importing vweb"), v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok))); return (*(err_node)); } v__parser__Parser_register_used_import(p, _S("vweb")); } else if (_SLIT_EQ(name.str, name.len, "veb")) { if (!(Array_string_contains(import_mods, _S("veb")))) { v__parser__Parser_error_with_pos(p, _S("`$veb` cannot be used without importing veb"), v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok))); return (*(err_node)); } v__parser__Parser_register_used_import(p, _S("veb")); is_veb = true; } v__parser__Parser_check(p, v__token__Kind__dot); } string method_name = v__parser__Parser_check_name(p); if (!(Array_string_contains(_const_v__parser__supported_comptime_calls, method_name))) { v__parser__Parser_error(p, _const_v__parser__error_msg); return (*(err_node)); } bool is_embed_file = _SLIT_EQ(method_name.str, method_name.len, "embed_file"); bool is_html = _SLIT_EQ(method_name.str, method_name.len, "html"); v__parser__Parser_check(p, v__token__Kind__lpar); v__token__Pos arg_pos = v__token__Token_pos(&p->tok); if (_SLIT_EQ(method_name.str, method_name.len, "env") || _SLIT_EQ(method_name.str, method_name.len, "pkgconfig")) { string s = p->tok.lit; v__parser__Parser_check(p, v__token__Kind__string); v__parser__Parser_check(p, v__token__Kind__rpar); bool is_env = _SLIT_EQ(method_name.str, method_name.len, "env"); return ((v__ast__ComptimeCall){ .pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)), .has_parens = 0, .method_name = method_name, .kind = (is_env ? (v__ast__ComptimeCallKind__env) : (v__ast__ComptimeCallKind__pkgconfig)), .method_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .scope = ((void*)0), .is_vweb = 0, .is_veb = 0, .env_pos = start_pos, .is_d_resolved = 0, .veb_tmpl = ((v__ast__File){.nr_lines = 0,.nr_bytes = 0,.nr_tokens = 0,.mod = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}),.global_scope = ((void*)0),.is_test = 0,.is_generated = 0,.is_translated = 0,.language = 0,.idx = 0,.path = (string){.str=(byteptr)"", .is_lit=1},.path_base = (string){.str=(byteptr)"", .is_lit=1},.scope = ((void*)0),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.imports = __new_array(0, 0, sizeof(v__ast__Import)),.auto_imports = __new_array(0, 0, sizeof(string)),.embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)),.imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.errors = __new_array(0, 0, sizeof(v__errors__Error)),.warnings = __new_array(0, 0, sizeof(v__errors__Warning)),.notices = __new_array(0, 0, sizeof(v__errors__Notice)),.generic_fns = __new_array(0, 0, sizeof(v__ast__FnDecl*)),.global_labels = __new_array(0, 0, sizeof(string)),.template_paths = __new_array(0, 0, sizeof(string)),.unique_prefix = (string){.str=(byteptr)"", .is_lit=1},.is_parse_text = 0,.is_template_text = 0,}), .left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .left_type = 0, .result_type = 0, .env_value = (string){.str=(byteptr)"", .is_lit=1}, .compile_value = (string){.str=(byteptr)"", .is_lit=1}, .args_var = s, .args = __new_array(0, 0, sizeof(v__ast__CallArg)), .embed_file = ((v__ast__EmbeddedFile){.compression_type = (string){.str=(byteptr)"", .is_lit=1},.rpath = (string){.str=(byteptr)"", .is_lit=1},.apath = (string){.str=(byteptr)"", .is_lit=1},.is_compressed = 0,.bytes = __new_array(0, 0, sizeof(u8)),.len = 0,}), .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), }); } else if (_SLIT_EQ(method_name.str, method_name.len, "compile_error") || _SLIT_EQ(method_name.str, method_name.len, "compile_warn")) { string s = _S(""); Array_v__ast__CallArg args = __new_array_with_default(0, 0, sizeof(v__ast__CallArg), 0); if (p->tok.kind == v__token__Kind__string && p->peek_tok.kind == v__token__Kind__rpar) { s = p->tok.lit; v__parser__Parser_check(p, v__token__Kind__string); } else { array_push((array*)&args, _MOV((v__ast__CallArg[]){ ((v__ast__CallArg){.is_mut = 0,.share = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__parser__Parser_string_expr(p),.typ = _const_v__ast__string_type,.is_tmp_autofree = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.should_be_ptr = 0,.ct_expr = true,}) })); } v__parser__Parser_check(p, v__token__Kind__rpar); return ((v__ast__ComptimeCall){ .pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)), .has_parens = 0, .method_name = method_name, .kind = (_SLIT_EQ(method_name.str, method_name.len, "compile_error") ? (v__ast__ComptimeCallKind__compile_error) : (v__ast__ComptimeCallKind__compile_warn)), .method_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .scope = ((void*)0), .is_vweb = 0, .is_veb = 0, .env_pos = start_pos, .is_d_resolved = 0, .veb_tmpl = ((v__ast__File){.nr_lines = 0,.nr_bytes = 0,.nr_tokens = 0,.mod = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}),.global_scope = ((void*)0),.is_test = 0,.is_generated = 0,.is_translated = 0,.language = 0,.idx = 0,.path = (string){.str=(byteptr)"", .is_lit=1},.path_base = (string){.str=(byteptr)"", .is_lit=1},.scope = ((void*)0),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.imports = __new_array(0, 0, sizeof(v__ast__Import)),.auto_imports = __new_array(0, 0, sizeof(string)),.embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)),.imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.errors = __new_array(0, 0, sizeof(v__errors__Error)),.warnings = __new_array(0, 0, sizeof(v__errors__Warning)),.notices = __new_array(0, 0, sizeof(v__errors__Notice)),.generic_fns = __new_array(0, 0, sizeof(v__ast__FnDecl*)),.global_labels = __new_array(0, 0, sizeof(string)),.template_paths = __new_array(0, 0, sizeof(string)),.unique_prefix = (string){.str=(byteptr)"", .is_lit=1},.is_parse_text = 0,.is_template_text = 0,}), .left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .left_type = 0, .result_type = 0, .env_value = (string){.str=(byteptr)"", .is_lit=1}, .compile_value = (string){.str=(byteptr)"", .is_lit=1}, .args_var = s, .args = args, .embed_file = ((v__ast__EmbeddedFile){.compression_type = (string){.str=(byteptr)"", .is_lit=1},.rpath = (string){.str=(byteptr)"", .is_lit=1},.apath = (string){.str=(byteptr)"", .is_lit=1},.is_compressed = 0,.bytes = __new_array(0, 0, sizeof(u8)),.len = 0,}), .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), }); } else if (_SLIT_EQ(method_name.str, method_name.len, "res")) { bool has_args = false; string type_index = _S(""); if (p->tok.kind == v__token__Kind__number) { has_args = true; type_index = p->tok.lit; v__parser__Parser_check(p, v__token__Kind__number); } v__parser__Parser_check(p, v__token__Kind__rpar); if (has_args) { return ((v__ast__ComptimeCall){.pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)),.has_parens = 0,.method_name = method_name,.kind = v__ast__ComptimeCallKind__res,.method_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.scope = ((void*)0),.is_vweb = 0,.is_veb = 0,.env_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_d_resolved = 0,.veb_tmpl = ((v__ast__File){.nr_lines = 0,.nr_bytes = 0,.nr_tokens = 0,.mod = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}),.global_scope = ((void*)0),.is_test = 0,.is_generated = 0,.is_translated = 0,.language = 0,.idx = 0,.path = (string){.str=(byteptr)"", .is_lit=1},.path_base = (string){.str=(byteptr)"", .is_lit=1},.scope = ((void*)0),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.imports = __new_array(0, 0, sizeof(v__ast__Import)),.auto_imports = __new_array(0, 0, sizeof(string)),.embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)),.imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.errors = __new_array(0, 0, sizeof(v__errors__Error)),.warnings = __new_array(0, 0, sizeof(v__errors__Warning)),.notices = __new_array(0, 0, sizeof(v__errors__Notice)),.generic_fns = __new_array(0, 0, sizeof(v__ast__FnDecl*)),.global_labels = __new_array(0, 0, sizeof(string)),.template_paths = __new_array(0, 0, sizeof(string)),.unique_prefix = (string){.str=(byteptr)"", .is_lit=1},.is_parse_text = 0,.is_template_text = 0,}),.left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.left_type = 0,.result_type = 0,.env_value = (string){.str=(byteptr)"", .is_lit=1},.compile_value = (string){.str=(byteptr)"", .is_lit=1},.args_var = type_index,.args = __new_array(0, 0, sizeof(v__ast__CallArg)),.embed_file = ((v__ast__EmbeddedFile){.compression_type = (string){.str=(byteptr)"", .is_lit=1},.rpath = (string){.str=(byteptr)"", .is_lit=1},.apath = (string){.str=(byteptr)"", .is_lit=1},.is_compressed = 0,.bytes = __new_array(0, 0, sizeof(u8)),.len = 0,}),.or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),}); } return ((v__ast__ComptimeCall){.pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)),.has_parens = 0,.method_name = method_name,.kind = v__ast__ComptimeCallKind__res,.method_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.scope = ((void*)0),.is_vweb = 0,.is_veb = 0,.env_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_d_resolved = 0,.veb_tmpl = ((v__ast__File){.nr_lines = 0,.nr_bytes = 0,.nr_tokens = 0,.mod = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}),.global_scope = ((void*)0),.is_test = 0,.is_generated = 0,.is_translated = 0,.language = 0,.idx = 0,.path = (string){.str=(byteptr)"", .is_lit=1},.path_base = (string){.str=(byteptr)"", .is_lit=1},.scope = ((void*)0),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.imports = __new_array(0, 0, sizeof(v__ast__Import)),.auto_imports = __new_array(0, 0, sizeof(string)),.embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)),.imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.errors = __new_array(0, 0, sizeof(v__errors__Error)),.warnings = __new_array(0, 0, sizeof(v__errors__Warning)),.notices = __new_array(0, 0, sizeof(v__errors__Notice)),.generic_fns = __new_array(0, 0, sizeof(v__ast__FnDecl*)),.global_labels = __new_array(0, 0, sizeof(string)),.template_paths = __new_array(0, 0, sizeof(string)),.unique_prefix = (string){.str=(byteptr)"", .is_lit=1},.is_parse_text = 0,.is_template_text = 0,}),.left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.left_type = 0,.result_type = 0,.env_value = (string){.str=(byteptr)"", .is_lit=1},.compile_value = (string){.str=(byteptr)"", .is_lit=1},.args_var = (string){.str=(byteptr)"", .is_lit=1},.args = __new_array(0, 0, sizeof(v__ast__CallArg)),.embed_file = ((v__ast__EmbeddedFile){.compression_type = (string){.str=(byteptr)"", .is_lit=1},.rpath = (string){.str=(byteptr)"", .is_lit=1},.apath = (string){.str=(byteptr)"", .is_lit=1},.is_compressed = 0,.bytes = __new_array(0, 0, sizeof(u8)),.len = 0,}),.or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),}); } else if (_SLIT_EQ(method_name.str, method_name.len, "d")) { string const_string = p->tok.lit; v__parser__Parser_check(p, v__token__Kind__string); v__parser__Parser_check(p, v__token__Kind__comma); v__ast__Expr arg_expr = v__parser__Parser_expr(p, 0); Array_v__ast__CallArg args = new_array_from_c_array(1, 1, sizeof(v__ast__CallArg), _MOV((v__ast__CallArg[1]){((v__ast__CallArg){.is_mut = 0,.share = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = arg_expr,.typ = 0,.is_tmp_autofree = 0,.pos = v__token__Token_pos(&p->tok),.should_be_ptr = 0,.ct_expr = 0,})})); v__parser__Parser_check(p, v__token__Kind__rpar); return ((v__ast__ComptimeCall){ .pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)), .has_parens = 0, .method_name = method_name, .kind = v__ast__ComptimeCallKind__d, .method_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .scope = ((void*)0), .is_vweb = 0, .is_veb = 0, .env_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_d_resolved = 0, .veb_tmpl = ((v__ast__File){.nr_lines = 0,.nr_bytes = 0,.nr_tokens = 0,.mod = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}),.global_scope = ((void*)0),.is_test = 0,.is_generated = 0,.is_translated = 0,.language = 0,.idx = 0,.path = (string){.str=(byteptr)"", .is_lit=1},.path_base = (string){.str=(byteptr)"", .is_lit=1},.scope = ((void*)0),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.imports = __new_array(0, 0, sizeof(v__ast__Import)),.auto_imports = __new_array(0, 0, sizeof(string)),.embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)),.imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.errors = __new_array(0, 0, sizeof(v__errors__Error)),.warnings = __new_array(0, 0, sizeof(v__errors__Warning)),.notices = __new_array(0, 0, sizeof(v__errors__Notice)),.generic_fns = __new_array(0, 0, sizeof(v__ast__FnDecl*)),.global_labels = __new_array(0, 0, sizeof(string)),.template_paths = __new_array(0, 0, sizeof(string)),.unique_prefix = (string){.str=(byteptr)"", .is_lit=1},.is_parse_text = 0,.is_template_text = 0,}), .left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .left_type = 0, .result_type = 0, .env_value = (string){.str=(byteptr)"", .is_lit=1}, .compile_value = (string){.str=(byteptr)"", .is_lit=1}, .args_var = const_string, .args = args, .embed_file = ((v__ast__EmbeddedFile){.compression_type = (string){.str=(byteptr)"", .is_lit=1},.rpath = (string){.str=(byteptr)"", .is_lit=1},.apath = (string){.str=(byteptr)"", .is_lit=1},.is_compressed = 0,.bytes = __new_array(0, 0, sizeof(u8)),.len = 0,}), .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), }); } bool has_string_arg = p->tok.kind == v__token__Kind__string; string literal_string_param = (is_html && !has_string_arg ? (_S("")) : (p->tok.lit)); if (p->tok.kind == v__token__Kind__name) { _option_v__ast__Var_ptr _t14; _option_v__ast__ConstField_ptr _t15; if (_t14 = v__ast__Scope_find_var(p->scope, p->tok.lit), _t14.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t14.data; if ((var->expr)._typ == 384 /* v.ast.StringLiteral */) { literal_string_param = (*var->expr._v__ast__StringLiteral).val; } } else if (_t15 = v__ast__Scope_find_const(p->table->global_scope, string__plus(string__plus(p->mod, _S(".")), p->tok.lit)), _t15.state == 0) { v__ast__ConstField* var = *(v__ast__ConstField**)_t15.data; if ((var->expr)._typ == 384 /* v.ast.StringLiteral */) { literal_string_param = (*var->expr._v__ast__StringLiteral).val; } } } string path_of_literal_string_param = string_replace(literal_string_param, _S("/"), _const_os__path_separator); v__ast__CallArg arg = ((v__ast__CallArg){.is_mut = 0,.share = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = 0,.is_tmp_autofree = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.should_be_ptr = 0,.ct_expr = 0,}); if (is_html && !(has_string_arg || p->tok.kind == v__token__Kind__rpar)) { v__parser__Parser_error(p, _S("expecting `$vweb.html()` for a default template path or `$vweb.html(\"/path/to/template.html\")`")); } if (is_html && p->tok.kind != v__token__Kind__string) { } else { v__ast__Expr arg_expr = v__parser__Parser_expr(p, 0); arg = ((v__ast__CallArg){.is_mut = 0,.share = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = arg_expr,.typ = 0,.is_tmp_autofree = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.should_be_ptr = 0,.ct_expr = 0,}); } string embed_compression_type = _S("none"); if (is_embed_file) { if (p->tok.kind == v__token__Kind__comma) { v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__dot); embed_compression_type = v__parser__Parser_check_name(p); } } v__parser__Parser_check(p, v__token__Kind__rpar); if (is_embed_file) { v__parser__Parser_register_auto_import(p, _S("v.preludes.embed_file")); if (_SLIT_EQ(embed_compression_type.str, embed_compression_type.len, "zlib")) { v__parser__Parser_register_auto_import(p, _S("v.preludes.embed_file.zlib")); } return ((v__ast__ComptimeCall){ .pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)), .has_parens = 0, .method_name = method_name, .kind = v__ast__ComptimeCallKind__embed_file, .method_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .scope = ((void*)0), .is_vweb = 0, .is_veb = 0, .env_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_d_resolved = 0, .veb_tmpl = ((v__ast__File){.nr_lines = 0,.nr_bytes = 0,.nr_tokens = 0,.mod = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}),.global_scope = ((void*)0),.is_test = 0,.is_generated = 0,.is_translated = 0,.language = 0,.idx = 0,.path = (string){.str=(byteptr)"", .is_lit=1},.path_base = (string){.str=(byteptr)"", .is_lit=1},.scope = ((void*)0),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.imports = __new_array(0, 0, sizeof(v__ast__Import)),.auto_imports = __new_array(0, 0, sizeof(string)),.embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)),.imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.errors = __new_array(0, 0, sizeof(v__errors__Error)),.warnings = __new_array(0, 0, sizeof(v__errors__Warning)),.notices = __new_array(0, 0, sizeof(v__errors__Notice)),.generic_fns = __new_array(0, 0, sizeof(v__ast__FnDecl*)),.global_labels = __new_array(0, 0, sizeof(string)),.template_paths = __new_array(0, 0, sizeof(string)),.unique_prefix = (string){.str=(byteptr)"", .is_lit=1},.is_parse_text = 0,.is_template_text = 0,}), .left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .left_type = 0, .result_type = 0, .env_value = (string){.str=(byteptr)"", .is_lit=1}, .compile_value = (string){.str=(byteptr)"", .is_lit=1}, .args_var = (string){.str=(byteptr)"", .is_lit=1}, .args = new_array_from_c_array(1, 1, sizeof(v__ast__CallArg), _MOV((v__ast__CallArg[1]){arg})), .embed_file = ((v__ast__EmbeddedFile){.compression_type = embed_compression_type,.rpath = (string){.str=(byteptr)"", .is_lit=1},.apath = (string){.str=(byteptr)"", .is_lit=1},.is_compressed = 0,.bytes = __new_array(0, 0, sizeof(u8)),.len = 0,}), .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), }); } Array_string fn_path = string_split(p->cur_fn_name, _S("_")); string fn_path_joined = Array_string_join(fn_path, _const_os__path_separator); string compiled_vfile_path = os__real_path(string_replace(p->scanner->file_path, _S("/"), _const_os__path_separator)); string _t17; /* if prepend */ if (is_html && !has_string_arg) { _t17 = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*(string*)array_last(fn_path))}}, {_S(".html"), 0, { .d_c = 0 }}})); } else { _t17 = path_of_literal_string_param; } string tmpl_path = _t17; string dir = os__dir(compiled_vfile_path); string path = os__join_path_single(dir, fn_path_joined); path = string__plus(path, _S(".html")); path = os__real_path(path); if (!is_html || has_string_arg) { if (os__is_abs_path(tmpl_path)) { path = tmpl_path; } else { path = os__join_path_single(dir, tmpl_path); } } if (!os__exists(path)) { if (is_html) { path = os__join_path(dir, new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("templates"), fn_path_joined}))); path = string__plus(path, _S(".html")); } if (!os__exists(path)) { if (p->pref->is_fmt) { return ((v__ast__ComptimeCall){ .pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)), .has_parens = 0, .method_name = method_name, .kind = (is_html ? (v__ast__ComptimeCallKind__html) : (v__ast__ComptimeCallKind__tmpl)), .method_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .scope = ((void*)0), .is_vweb = true, .is_veb = is_veb, .env_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_d_resolved = 0, .veb_tmpl = ((v__ast__File){.nr_lines = 0,.nr_bytes = 0,.nr_tokens = 0,.mod = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}),.global_scope = ((void*)0),.is_test = 0,.is_generated = 0,.is_translated = 0,.language = 0,.idx = 0,.path = (string){.str=(byteptr)"", .is_lit=1},.path_base = (string){.str=(byteptr)"", .is_lit=1},.scope = ((void*)0),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.imports = __new_array(0, 0, sizeof(v__ast__Import)),.auto_imports = __new_array(0, 0, sizeof(string)),.embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)),.imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.errors = __new_array(0, 0, sizeof(v__errors__Error)),.warnings = __new_array(0, 0, sizeof(v__errors__Warning)),.notices = __new_array(0, 0, sizeof(v__errors__Notice)),.generic_fns = __new_array(0, 0, sizeof(v__ast__FnDecl*)),.global_labels = __new_array(0, 0, sizeof(string)),.template_paths = __new_array(0, 0, sizeof(string)),.unique_prefix = (string){.str=(byteptr)"", .is_lit=1},.is_parse_text = 0,.is_template_text = 0,}), .left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .left_type = 0, .result_type = 0, .env_value = (string){.str=(byteptr)"", .is_lit=1}, .compile_value = (string){.str=(byteptr)"", .is_lit=1}, .args_var = literal_string_param, .args = new_array_from_c_array(1, 1, sizeof(v__ast__CallArg), _MOV((v__ast__CallArg[1]){arg})), .embed_file = ((v__ast__EmbeddedFile){.compression_type = (string){.str=(byteptr)"", .is_lit=1},.rpath = (string){.str=(byteptr)"", .is_lit=1},.apath = (string){.str=(byteptr)"", .is_lit=1},.is_compressed = 0,.bytes = __new_array(0, 0, sizeof(u8)),.len = 0,}), .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), }); } if (is_html) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("veb HTML template \""), 0xfe10, {.d_s = tmpl_path}}, {_S("\" not found"), 0, { .d_c = 0 }}})), arg_pos); } else { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("template file \""), 0xfe10, {.d_s = tmpl_path}}, {_S("\" not found"), 0, { .d_c = 0 }}})), arg_pos); } return (*(err_node)); } } string tmp_fn_name = string__plus(string_replace(p->cur_fn_name, _S("."), _S("__")), int_str(start_pos.pos)); #if defined(CUSTOM_DEFINE_trace_comptime) { println(str_intp(3, _MOV((StrIntpData[]){{_S(">>> compiling comptime template file \""), 0xfe10, {.d_s = path}}, {_S("\" for "), 0xfe10, {.d_s = tmp_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif string v_code = v__parser__Parser_compile_template_file(p, path, tmp_fn_name); #if defined(CUSTOM_DEFINE_print_veb_template_expansions) { Array_string lines = string_split(v_code, _S("\n")); for (int i = 0; i < lines.len; ++i) { string line = ((string*)lines.data)[i]; println(str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = path}}, {_S(":"), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(": "), 0xfe10, {.d_s = line}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } #endif #if defined(CUSTOM_DEFINE_trace_comptime) { println(_S("")); println(str_intp(2, _MOV((StrIntpData[]){{_S(">>> template for "), 0xfe10, {.d_s = path}}, {_S(":"), 0, { .d_c = 0 }}}))); println(v_code); println(_S(">>> end of template END")); println(_S("")); } #endif v__parser__Parser_open_scope(p); v__parser__Parser_comptime_call_defer_0 = true; v__ast__File* file = v__parser__parse_comptime(tmpl_path, v_code, p->table, p->pref, p->scope); file->path = tmpl_path; v__ast__ComptimeCall _t23 = ((v__ast__ComptimeCall){ .pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)), .has_parens = 0, .method_name = method_name, .kind = (is_html ? (v__ast__ComptimeCallKind__html) : (v__ast__ComptimeCallKind__tmpl)), .method_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .scope = ((void*)0), .is_vweb = true, .is_veb = is_veb, .env_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_d_resolved = 0, .veb_tmpl = *file, .left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .left_type = 0, .result_type = 0, .env_value = (string){.str=(byteptr)"", .is_lit=1}, .compile_value = (string){.str=(byteptr)"", .is_lit=1}, .args_var = literal_string_param, .args = new_array_from_c_array(1, 1, sizeof(v__ast__CallArg), _MOV((v__ast__CallArg[1]){arg})), .embed_file = ((v__ast__EmbeddedFile){.compression_type = (string){.str=(byteptr)"", .is_lit=1},.rpath = (string){.str=(byteptr)"", .is_lit=1},.apath = (string){.str=(byteptr)"", .is_lit=1},.is_compressed = 0,.bytes = __new_array(0, 0, sizeof(u8)),.len = 0,}), .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), }); // Defer begin if (v__parser__Parser_comptime_call_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t23; } VV_LOC v__ast__ComptimeFor v__parser__Parser_comptime_for(v__parser__Parser* p) { bool v__parser__Parser_comptime_for_defer_0 = false; v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__key_for); v__token__Pos var_pos = v__token__Token_pos(&p->tok); string val_var = v__parser__Parser_check_name(p); v__parser__Parser_check(p, v__token__Kind__key_in); v__ast__Expr expr = _const_v__ast__empty_expr; v__token__Pos typ_pos = v__token__Token_pos(&p->tok); v__ast__Language lang = v__parser__Parser_parse_language(p); v__ast__Type typ = _const_v__ast__void_type; if (p->tok.lit.len == 0) { v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("invalid expr, use `"), 0xfe10, {.d_s = p->peek_tok.lit}}, {_S("` instead"), 0, { .d_c = 0 }}}))); return ((v__ast__ComptimeFor){.val_var = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.typ = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},}); } if (u8_is_capital(string_at(p->tok.lit, 0)) || _IN_MAP(ADDR(string, p->tok.lit), ADDR(map, p->imports))) { typ = v__parser__Parser_parse_any_type(p, lang, false, true, false); } else { expr = v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (v__parser__Parser_ident(p, lang)))); v__ast__Scope_mark_var_as_used(p->scope, (*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).name); } typ_pos = v__token__Pos_extend(typ_pos, v__token__Token_pos(&p->prev_tok)); v__parser__Parser_check(p, v__token__Kind__dot); string for_val = v__parser__Parser_check_name(p); v__ast__ComptimeForKind kind = v__ast__ComptimeForKind__methods; v__parser__Parser_open_scope(p); v__parser__Parser_comptime_for_defer_0 = true; if (_SLIT_EQ(for_val.str, for_val.len, "params")) { v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = val_var,.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = v__ast__Table_find_type(p->table, _S("MethodParam")),.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = var_pos,.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,}))))); kind = v__ast__ComptimeForKind__params; } else if (_SLIT_EQ(for_val.str, for_val.len, "methods")) { v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = val_var,.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = v__ast__Table_find_type(p->table, _S("FunctionData")),.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = var_pos,.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,}))))); } else if (_SLIT_EQ(for_val.str, for_val.len, "values")) { v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = val_var,.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = v__ast__Table_find_type(p->table, _S("EnumData")),.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = var_pos,.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,}))))); kind = v__ast__ComptimeForKind__values; } else if (_SLIT_EQ(for_val.str, for_val.len, "fields")) { v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = val_var,.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = v__ast__Table_find_type(p->table, _S("FieldData")),.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = var_pos,.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,}))))); kind = v__ast__ComptimeForKind__fields; } else if (_SLIT_EQ(for_val.str, for_val.len, "variants")) { v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = val_var,.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = v__ast__Table_find_type(p->table, _S("VariantData")),.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = var_pos,.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,}))))); kind = v__ast__ComptimeForKind__variants; } else if (_SLIT_EQ(for_val.str, for_val.len, "attributes")) { v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = val_var,.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = v__ast__Table_find_type(p->table, _S("VAttribute")),.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = var_pos,.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,}))))); kind = v__ast__ComptimeForKind__attributes; } else { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("unknown kind `"), 0xfe10, {.d_s = for_val}}, {_S("`, available are: `methods`, `fields`, `values`, `variants`, `attributes` or `params`"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->prev_tok)); v__ast__ComptimeFor _t2 = ((v__ast__ComptimeFor){.val_var = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.typ = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},}); // Defer begin if (v__parser__Parser_comptime_for_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t2; } v__token__Pos spos = v__token__Token_pos(&p->tok); Array_v__ast__Stmt stmts = v__parser__Parser_parse_block(p); v__ast__ComptimeFor _t3 = ((v__ast__ComptimeFor){ .val_var = val_var, .kind = kind, .pos = v__token__Pos_extend(spos, v__token__Token_pos(&p->tok)), .typ_pos = typ_pos, .stmts = stmts, .typ = typ, .expr = expr, }); // Defer begin if (v__parser__Parser_comptime_for_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t3; } VV_LOC v__ast__AtExpr v__parser__Parser_at(v__parser__Parser* p) { string name = p->tok.lit; v__token__AtKind kind = ((_SLIT_EQ(name.str, name.len, "@FN"))? (v__token__AtKind__fn_name) : (_SLIT_EQ(name.str, name.len, "@METHOD"))? (v__token__AtKind__method_name) : (_SLIT_EQ(name.str, name.len, "@MOD"))? (v__token__AtKind__mod_name) : (_SLIT_EQ(name.str, name.len, "@STRUCT"))? (v__token__AtKind__struct_name) : (_SLIT_EQ(name.str, name.len, "@FILE"))? (v__token__AtKind__file_path) : (_SLIT_EQ(name.str, name.len, "@DIR"))? (v__token__AtKind__file_dir) : (_SLIT_EQ(name.str, name.len, "@LINE"))? (v__token__AtKind__line_nr) : (_SLIT_EQ(name.str, name.len, "@FILE_LINE"))? (v__token__AtKind__file_path_line_nr) : (_SLIT_EQ(name.str, name.len, "@LOCATION"))? (v__token__AtKind__location) : (_SLIT_EQ(name.str, name.len, "@COLUMN"))? (v__token__AtKind__column_nr) : (_SLIT_EQ(name.str, name.len, "@VCURRENTHASH"))? (v__token__AtKind__v_current_hash) : (_SLIT_EQ(name.str, name.len, "@VHASH"))? (v__token__AtKind__vhash) : (_SLIT_EQ(name.str, name.len, "@VMOD_FILE"))? (v__token__AtKind__vmod_file) : (_SLIT_EQ(name.str, name.len, "@VEXE"))? (v__token__AtKind__vexe_path) : (_SLIT_EQ(name.str, name.len, "@VEXEROOT"))? (v__token__AtKind__vexeroot_path) : (_SLIT_EQ(name.str, name.len, "@VMODROOT"))? (v__token__AtKind__vmodroot_path) : (_SLIT_EQ(name.str, name.len, "@VMODHASH"))? (v__token__AtKind__vmod_hash) : (_SLIT_EQ(name.str, name.len, "@VROOT"))? (v__token__AtKind__vroot_path) : (_SLIT_EQ(name.str, name.len, "@BUILD_DATE"))? (v__token__AtKind__build_date) : (_SLIT_EQ(name.str, name.len, "@BUILD_TIME"))? (v__token__AtKind__build_time) : (_SLIT_EQ(name.str, name.len, "@BUILD_TIMESTAMP"))? (v__token__AtKind__build_timestamp) : (v__token__AtKind__unknown)); v__ast__AtExpr expr = ((v__ast__AtExpr){.name = name,.pos = v__token__Token_pos(&p->tok),.kind = kind,.val = (string){.str=(byteptr)"", .is_lit=1},}); v__parser__Parser_next(p); return expr; } VV_LOC v__ast__Expr v__parser__Parser_comptime_selector(v__parser__Parser* p, v__ast__Expr left) { v__parser__Parser_check(p, v__token__Kind__dollar); v__token__Pos start_pos = v__token__Token_pos(&p->prev_tok); if (p->peek_tok.kind == v__token__Kind__lpar) { v__token__Pos method_pos = v__token__Token_pos(&p->tok); string method_name = v__parser__Parser_check_name(p); v__ast__Scope_mark_var_as_used(p->scope, method_name); v__parser__Parser_check(p, v__token__Kind__lpar); Array_v__ast__CallArg args = v__parser__Parser_call_args(p); v__parser__Parser_check(p, v__token__Kind__rpar); v__ast__OrKind or_kind = v__ast__OrKind__absent; v__token__Pos or_pos = v__token__Token_pos(&p->tok); Array_v__ast__Stmt or_stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); if (p->tok.kind == v__token__Kind__key_orelse) { or_kind = v__ast__OrKind__block; multi_return_Array_v__ast__Stmt_v__token__Pos mr_13845 = v__parser__Parser_or_block(p, v__parser__OrBlockErrVarMode__with_err_var); or_stmts = mr_13845.arg0; or_pos = mr_13845.arg1; } return v__ast__ComptimeCall_to_sumtype_v__ast__Expr(ADDR(v__ast__ComptimeCall, (((v__ast__ComptimeCall){ .pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)), .has_parens = 0, .method_name = method_name, .kind = v__ast__ComptimeCallKind__method, .method_pos = method_pos, .scope = p->scope, .is_vweb = 0, .is_veb = 0, .env_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_d_resolved = 0, .veb_tmpl = ((v__ast__File){.nr_lines = 0,.nr_bytes = 0,.nr_tokens = 0,.mod = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}),.global_scope = ((void*)0),.is_test = 0,.is_generated = 0,.is_translated = 0,.language = 0,.idx = 0,.path = (string){.str=(byteptr)"", .is_lit=1},.path_base = (string){.str=(byteptr)"", .is_lit=1},.scope = ((void*)0),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.imports = __new_array(0, 0, sizeof(v__ast__Import)),.auto_imports = __new_array(0, 0, sizeof(string)),.embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)),.imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.errors = __new_array(0, 0, sizeof(v__errors__Error)),.warnings = __new_array(0, 0, sizeof(v__errors__Warning)),.notices = __new_array(0, 0, sizeof(v__errors__Notice)),.generic_fns = __new_array(0, 0, sizeof(v__ast__FnDecl*)),.global_labels = __new_array(0, 0, sizeof(string)),.template_paths = __new_array(0, 0, sizeof(string)),.unique_prefix = (string){.str=(byteptr)"", .is_lit=1},.is_parse_text = 0,.is_template_text = 0,}), .left = left, .left_type = 0, .result_type = 0, .env_value = (string){.str=(byteptr)"", .is_lit=1}, .compile_value = (string){.str=(byteptr)"", .is_lit=1}, .args_var = _S(""), .args = args, .embed_file = ((v__ast__EmbeddedFile){.compression_type = (string){.str=(byteptr)"", .is_lit=1},.rpath = (string){.str=(byteptr)"", .is_lit=1},.apath = (string){.str=(byteptr)"", .is_lit=1},.is_compressed = 0,.bytes = __new_array(0, 0, sizeof(u8)),.len = 0,}), .or_block = ((v__ast__OrExpr){.kind = or_kind,.pos = or_pos,.stmts = or_stmts,}), })))); } bool has_parens = false; if (p->tok.kind == v__token__Kind__lpar) { v__parser__Parser_next(p); has_parens = true; } else { v__parser__Parser_warn_with_pos(p, _S("use brackets instead e.g. `s.$(field.name)` - run vfmt"), v__token__Token_pos(&p->tok)); } v__ast__Expr expr = v__parser__Parser_expr(p, 0); if (has_parens) { v__parser__Parser_check(p, v__token__Kind__rpar); } return v__ast__ComptimeSelector_to_sumtype_v__ast__Expr(ADDR(v__ast__ComptimeSelector, (((v__ast__ComptimeSelector){.has_parens = has_parens,.pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)),.or_block = ((v__ast__OrExpr){.kind = (p->tok.kind == v__token__Kind__question ? (v__ast__OrKind__propagate_option) : (v__ast__OrKind__absent)),.pos = v__token__Token_pos(&p->tok),.stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0),}),.left = left,.left_type = 0,.field_expr = expr,.typ = 0,.is_name = 0,.typ_key = (string){.str=(byteptr)"", .is_lit=1},})))); } VV_LOC v__ast__ArrayInit v__parser__Parser_array_init(v__parser__Parser* p, bool is_option, v__ast__Type alias_array_type) { v__token__Pos first_pos = v__token__Token_pos(&p->tok); v__token__Pos last_pos = v__token__Token_pos(&p->tok); v__ast__Type array_type = _const_v__ast__void_type; v__ast__Type elem_type = _const_v__ast__void_type; v__token__Pos elem_type_pos = first_pos; Array_v__ast__Expr exprs = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); Array_Array_v__ast__Comment ecmnts = __new_array_with_default(0, 0, sizeof(Array_v__ast__Comment), 0); Array_v__ast__Comment pre_cmnts = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); bool is_fixed = false; bool has_val = false; bool has_type = false; bool has_init = false; bool has_index = false; v__ast__Expr init_expr = _const_v__ast__empty_expr; if (alias_array_type == _const_v__ast__void_type) { v__parser__Parser_check(p, v__token__Kind__lsbr); if (p->tok.kind == v__token__Kind__rsbr) { last_pos = v__token__Token_pos(&p->tok); int line_nr = p->tok.line_nr; v__parser__Parser_next(p); if ((p->tok.kind == v__token__Kind__name || p->tok.kind == v__token__Kind__amp || p->tok.kind == v__token__Kind__lsbr || p->tok.kind == v__token__Kind__question || p->tok.kind == v__token__Kind__key_shared || p->tok.kind == v__token__Kind__not) && p->tok.line_nr == line_nr) { elem_type_pos = v__token__Token_pos(&p->tok); elem_type = v__parser__Parser_parse_type(p); if (elem_type != 0) { if (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__result)) { v__parser__Parser_error_with_pos(p, _S("arrays do not support storing Result values"), elem_type_pos); } int idx = v__ast__Table_find_or_register_array(p->table, elem_type); if (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__generic)) { array_type = v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); } else { array_type = v__ast__new_type(idx); } if (is_option) { array_type = v__ast__Type_set_flag(array_type, v__ast__TypeFlag__option); } has_type = true; } } last_pos = v__token__Token_pos(&p->tok); } else { bool old_inside_array_lit = p->inside_array_lit; string old_last_enum_name = p->last_enum_name; string old_last_enum_mod = p->last_enum_mod; p->inside_array_lit = true; p->last_enum_name = _S(""); p->last_enum_mod = _S(""); pre_cmnts = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); for (int i = 0; !(p->tok.kind == v__token__Kind__rsbr || p->tok.kind == v__token__Kind__eof); i++) { array_push((array*)&exprs, _MOV((v__ast__Expr[]){ v__parser__Parser_expr(p, 0) })); array_push((array*)&ecmnts, _MOV((Array_v__ast__Comment[]){ v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})) })); if (p->tok.kind == v__token__Kind__comma) { v__parser__Parser_next(p); } _PUSH_MANY(&(*(Array_v__ast__Comment*)array_last(ecmnts)), (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t3, Array_v__ast__Comment); } p->inside_array_lit = old_inside_array_lit; p->last_enum_name = old_last_enum_name; p->last_enum_mod = old_last_enum_mod; int line_nr = p->tok.line_nr; last_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__rsbr); if (exprs.len == 1 && p->tok.line_nr == line_nr && ((p->tok.kind == v__token__Kind__name || p->tok.kind == v__token__Kind__amp || p->tok.kind == v__token__Kind__question || p->tok.kind == v__token__Kind__key_shared) || (p->tok.kind == v__token__Kind__lsbr && v__parser__Parser_is_array_type(p)))) { elem_type = v__parser__Parser_parse_type(p); if (elem_type != 0) { v__ast__TypeSymbol* s = v__ast__Table_sym(p->table, elem_type); if (fast_string_eq(s->name, _S("byte"))) { v__parser__Parser_error(p, _S("`byte` has been deprecated in favor of `u8`: use `[10]u8{}` instead of `[10]byte{}`")); } } last_pos = v__token__Token_pos(&p->tok); is_fixed = true; if (p->tok.kind == v__token__Kind__lcbr) { v__parser__Parser_next(p); if (p->tok.kind != v__token__Kind__rcbr) { v__token__Pos pos = v__token__Token_pos(&p->tok); string n = v__parser__Parser_check_name(p); if (_SLIT_NE(n.str, n.len, "init")) { if (is_fixed) { v__parser__Parser_error_with_pos(p, _S("`len` and `cap` are invalid attributes for fixed array dimension"), pos); } else { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("expected `init:`, not `"), 0xfe10, {.d_s = n}}, {_S("`"), 0, { .d_c = 0 }}})), pos); } return ((v__ast__ArrayInit){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.elem_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.ecmnts = __new_array(0, 0, sizeof(Array_v__ast__Comment)),.pre_cmnts = __new_array(0, 0, sizeof(v__ast__Comment)),.is_fixed = 0,.is_option = 0,.has_val = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.has_len = 0,.has_cap = 0,.has_init = 0,.has_index = 0,.exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.len_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.cap_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.init_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.expr_types = __new_array(0, 0, sizeof(v__ast__Type)),.elem_type = 0,.init_type = 0,.typ = 0,.alias_type = 0,.has_callexpr = 0,}); } v__parser__Parser_check(p, v__token__Kind__colon); has_init = true; has_index = v__parser__Parser_handle_index_variable(p, &init_expr); } last_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__rcbr); } else { string modifier = (is_option ? (_S("?")) : (_S(""))); v__parser__Parser_warn_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("use e.g. `x := "), 0xfe10, {.d_s = modifier}}, {_S("[1]Type{}` instead of `x := "), 0xfe10, {.d_s = modifier}}, {_S("[1]Type`"), 0, { .d_c = 0 }}})), v__token__Pos_extend(first_pos, last_pos)); } } else { if (p->tok.kind == v__token__Kind__not) { last_pos = v__token__Token_pos(&p->tok); is_fixed = true; has_val = true; v__parser__Parser_next(p); } if (p->tok.kind == v__token__Kind__not && p->tok.line_nr == p->prev_tok.line_nr) { last_pos = v__token__Token_pos(&p->tok); v__parser__Parser_error_with_pos(p, _S("use e.g. `[1, 2, 3]!` instead of `[1, 2, 3]!!`"), last_pos); v__parser__Parser_next(p); } } } if (exprs.len == 0 && p->tok.kind != v__token__Kind__lcbr && has_type) { if (!p->pref->is_fmt) { string modifier = (is_option ? (_S("?")) : (_S(""))); v__parser__Parser_warn_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("use `x := "), 0xfe10, {.d_s = modifier}}, {_S("[]Type{}` instead of `x := "), 0xfe10, {.d_s = modifier}}, {_S("[]Type`"), 0, { .d_c = 0 }}})), v__token__Pos_extend(first_pos, last_pos)); } } } else { array_type = (({ v__ast__TypeInfo _t5 = v__ast__Table_sym(p->table, alias_array_type)->info; *(v__ast__Alias*)__as_cast(_t5._v__ast__Alias,_t5._typ, 539); })).parent_type; elem_type = v__ast__TypeSymbol_array_info(v__ast__Table_sym(p->table, array_type)).elem_type; v__parser__Parser_next(p); } bool has_len = false; bool has_cap = false; v__ast__Expr len_expr = _const_v__ast__empty_expr; v__ast__Expr cap_expr = _const_v__ast__empty_expr; v__token__Pos attr_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (p->tok.kind == v__token__Kind__lcbr && exprs.len == 0 && array_type != _const_v__ast__void_type) { v__parser__Parser_next(p); for (;;) { if (!(p->tok.kind != v__token__Kind__rcbr)) break; attr_pos = v__token__Token_pos(&p->tok); string key = v__parser__Parser_check_name(p); v__parser__Parser_check(p, v__token__Kind__colon); if (is_option) { v__parser__Parser_error(p, _S("Option array cannot have initializers")); } if (_SLIT_EQ(key.str, key.len, "len")) { has_len = true; len_expr = v__parser__Parser_expr(p, 0); } else if (_SLIT_EQ(key.str, key.len, "cap")) { has_cap = true; cap_expr = v__parser__Parser_expr(p, 0); } else if (_SLIT_EQ(key.str, key.len, "init")) { has_init = true; has_index = v__parser__Parser_handle_index_variable(p, &init_expr); } else { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("wrong field `"), 0xfe10, {.d_s = key}}, {_S("`, expecting `len`, `cap`, or `init`"), 0, { .d_c = 0 }}})), attr_pos); return ((v__ast__ArrayInit){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.elem_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.ecmnts = __new_array(0, 0, sizeof(Array_v__ast__Comment)),.pre_cmnts = __new_array(0, 0, sizeof(v__ast__Comment)),.is_fixed = 0,.is_option = 0,.has_val = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.has_len = 0,.has_cap = 0,.has_init = 0,.has_index = 0,.exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.len_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.cap_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.init_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.expr_types = __new_array(0, 0, sizeof(v__ast__Type)),.elem_type = 0,.init_type = 0,.typ = 0,.alias_type = 0,.has_callexpr = 0,}); } if (p->tok.kind != v__token__Kind__rcbr) { v__parser__Parser_check(p, v__token__Kind__comma); } } v__parser__Parser_check(p, v__token__Kind__rcbr); if (has_init && !has_len) { v__parser__Parser_error_with_pos(p, _S("cannot use `init` attribute unless `len` attribute is also provided"), attr_pos); } } v__token__Pos pos = v__token__Pos_extend_with_last_line(first_pos, last_pos, p->prev_tok.line_nr); return ((v__ast__ArrayInit){ .pos = pos, .elem_type_pos = elem_type_pos, .ecmnts = ecmnts, .pre_cmnts = pre_cmnts, .is_fixed = is_fixed, .is_option = is_option, .has_val = has_val, .mod = p->mod, .has_len = has_len, .has_cap = has_cap, .has_init = has_init, .has_index = has_index, .exprs = exprs, .len_expr = len_expr, .cap_expr = cap_expr, .init_expr = init_expr, .expr_types = __new_array(0, 0, sizeof(v__ast__Type)), .elem_type = elem_type, .init_type = 0, .typ = array_type, .alias_type = alias_array_type, .has_callexpr = 0, }); } VV_LOC v__ast__MapInit v__parser__Parser_map_init(v__parser__Parser* p) { bool v__parser__Parser_map_init_defer_0 = false; bool old_inside_map_init; old_inside_map_init = p->inside_map_init; p->inside_map_init = true; v__parser__Parser_map_init_defer_0 = true; v__token__Pos first_pos = v__token__Token_pos(&p->prev_tok); Array_v__ast__Expr keys = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); Array_v__ast__Expr vals = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); Array_Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(Array_v__ast__Comment), 0); bool has_update_expr = false; v__ast__Expr update_expr = _const_v__ast__empty_expr; Array_v__ast__Comment update_expr_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); v__token__Pos update_expr_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); Array_v__ast__Comment pre_cmnts = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); if (p->tok.kind == v__token__Kind__ellipsis) { has_update_expr = true; v__parser__Parser_check(p, v__token__Kind__ellipsis); update_expr = v__parser__Parser_expr(p, 0); update_expr_pos = v__ast__Expr_pos(update_expr); if (p->tok.kind == v__token__Kind__comma) { v__parser__Parser_next(p); } _PUSH_MANY(&update_expr_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,}))), _t1, Array_v__ast__Comment); } for (;;) { if (!(!(p->tok.kind == v__token__Kind__rcbr || p->tok.kind == v__token__Kind__eof))) break; if (p->tok.kind == v__token__Kind__name && (fast_string_eq(p->tok.lit, _S("r")) || fast_string_eq(p->tok.lit, _S("c")) || fast_string_eq(p->tok.lit, _S("js")))) { v__ast__Expr key = v__parser__Parser_string_expr(p); array_push((array*)&keys, _MOV((v__ast__Expr[]){ key })); } else { v__ast__Expr key = v__parser__Parser_expr(p, 0); array_push((array*)&keys, _MOV((v__ast__Expr[]){ key })); } v__parser__Parser_check(p, v__token__Kind__colon); v__ast__Expr val = v__parser__Parser_expr(p, 0); array_push((array*)&vals, _MOV((v__ast__Expr[]){ val })); if (p->tok.kind == v__token__Kind__comma) { v__parser__Parser_next(p); } array_push((array*)&comments, _MOV((Array_v__ast__Comment[]){ v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})) })); } v__ast__MapInit _t6 = ((v__ast__MapInit){ .pos = v__token__Pos_extend_with_last_line(first_pos, v__token__Token_pos(&p->tok), p->tok.line_nr), .comments = comments, .pre_cmnts = pre_cmnts, .keys = keys, .vals = vals, .val_types = __new_array(0, 0, sizeof(v__ast__Type)), .typ = 0, .key_type = 0, .value_type = 0, .has_update_expr = has_update_expr, .update_expr = update_expr, .update_expr_pos = update_expr_pos, .update_expr_comments = update_expr_comments, }); // Defer begin if (v__parser__Parser_map_init_defer_0) { p->inside_map_init = old_inside_map_init; } // Defer end return _t6; } VV_LOC void v__parser__Parser_scope_register_index(v__parser__Parser* p) { map_set(&p->scope->objects, &(string[]){_S("index")}, &(v__ast__ScopeObject[]) { v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){ .name = _S("index"), .share = 0, .is_mut = false, .is_static = 0, .is_volatile = 0, .is_autofree_tmp = 0, .is_inherited = 0, .has_inherited = 0, .is_arg = 0, .is_auto_deref = 0, .is_unwrapped = 0, .is_index_var = true, .expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .typ = _const_v__ast__int_type, .orig_type = 0, .smartcasts = __new_array(0, 0, sizeof(v__ast__Type)), .pos = v__token__Token_pos(&p->tok), .is_used = false, .is_changed = 0, .ct_type_var = 0, .ct_type_unwrapped = 0, .is_or = 0, .is_tmp = 0, .is_auto_heap = 0, .is_stack_obj = 0, })))) }); map_set(&p->scope->objects, &(string[]){_S("it")}, &(v__ast__ScopeObject[]) { v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = _S("it"),.share = 0,.is_mut = false,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = _const_v__ast__int_type,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = v__token__Token_pos(&p->tok),.is_used = false,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,})))) }); } VV_LOC bool v__parser__Parser_handle_index_variable(v__parser__Parser* p, v__ast__Expr* default_expr) { bool v__parser__Parser_handle_index_variable_defer_0 = false; bool has_index = false; v__parser__Parser_open_scope(p); v__parser__Parser_handle_index_variable_defer_0 = true; v__parser__Parser_scope_register_index(p); *default_expr = v__parser__Parser_expr(p, 0); _option_v__ast__Var_ptr _t1; if (_t1 = v__ast__Scope_find_var(p->scope, _S("index")), _t1.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t1.data; v__ast__Var* variable = var; bool is_used = variable->is_used; variable->is_used = true; has_index = is_used; } _option_v__ast__Var_ptr _t2; if (_t2 = v__ast__Scope_find_var(p->scope, _S("it")), _t2.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t2.data; v__ast__Var* variable = var; bool is_used = variable->is_used; if (is_used) { v__parser__Parser_warn(p, _S("variable `it` in array initialization will soon be replaced with `index`")); } variable->is_used = true; if (!has_index) { has_index = is_used; } } bool _t3 = has_index; // Defer begin if (v__parser__Parser_handle_index_variable_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t3; } VV_LOC v__ast__EnumVal v__parser__Parser_enum_val_expr(v__parser__Parser* p, string mod) { string enum_name = v__parser__Parser_check_name(p); v__token__Pos enum_name_pos = v__token__Token_pos(&p->prev_tok); if ((mod).len != 0) { enum_name = string__plus(string__plus(mod, _S(".")), enum_name); } else { string* _t2 = (string*)(map_get_check(ADDR(map, p->imported_symbols), &(string[]){enum_name})); _option_string _t1 = {0}; if (_t2) { *((string*)&_t1.data) = *((string*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } ; if (_t1.state != 0) { IError err = _t1.err; *(string*) _t1.data = v__parser__Parser_prepend_mod(p, enum_name); } enum_name = (*(string*)_t1.data); } v__parser__Parser_check(p, v__token__Kind__dot); string val = v__parser__Parser_check_name(p); p->expr_mod = _S(""); p->last_enum_name = enum_name; p->last_enum_mod = mod; return ((v__ast__EnumVal){.enum_name = enum_name,.val = val,.mod = mod,.pos = v__token__Pos_extend(enum_name_pos, v__token__Token_pos(&p->prev_tok)),.typ = 0,}); } VV_LOC v__ast__EnumVal v__parser__Parser_enum_val(v__parser__Parser* p) { v__token__Pos start_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__dot); string val = v__parser__Parser_check_name(p); return ((v__ast__EnumVal){.enum_name = (string){.str=(byteptr)"", .is_lit=1},.val = val,.mod = (string){.str=(byteptr)"", .is_lit=1},.pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)),.typ = 0,}); } VV_LOC v__ast__EnumDecl v__parser__Parser_enum_decl(v__parser__Parser* p) { v__parser__Parser_top_level_statement_start(p); bool is_pub = p->tok.kind == v__token__Kind__key_pub; v__token__Pos start_pos = v__token__Token_pos(&p->tok); if (is_pub) { v__parser__Parser_next(p); } v__parser__Parser_check(p, v__token__Kind__key_enum); v__token__Pos end_pos = v__token__Token_pos(&p->tok); if (v__parser__Parser_disallow_declarations_in_script_mode(p)) { return ((v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); } string enum_name = v__parser__Parser_check_name(p); if (enum_name.len == 0) { v__parser__Parser_error_with_pos(p, _S("enum names can not be empty"), end_pos); return ((v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); } if (enum_name.len == 1) { v__parser__Parser_error_with_pos(p, _S("single letter capital names are reserved for generic template types."), end_pos); return ((v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); } if (_IN_MAP(ADDR(string, enum_name), ADDR(map, p->imported_symbols))) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot register enum `"), 0xfe10, {.d_s = enum_name}}, {_S("`, this type was already imported"), 0, { .d_c = 0 }}})), end_pos); return ((v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); } string name = v__parser__Parser_prepend_mod(p, enum_name); v__ast__EnumDecl* _t7 = (v__ast__EnumDecl*)(map_get_check(ADDR(map, p->table->enum_decls), &(string[]){name})); _option_v__ast__EnumDecl _t6 = {0}; if (_t7) { *((v__ast__EnumDecl*)&_t6.data) = *((v__ast__EnumDecl*)_t7); } else { _t6.state = 2; _t6.err = _v_error(_S("map key does not exist")); } bool _t5; /* if prepend */ if (_t6.state == 0) { v__ast__EnumDecl _dummy_6 = (*(v__ast__EnumDecl*)_t6.data); _t5 = true; } else { IError err = _t6.err; _t5 = false; } bool already_exists = _t5; v__ast__Type enum_type = _const_v__ast__int_type; v__token__Pos typ_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (p->tok.kind == v__token__Kind__key_as) { v__parser__Parser_next(p); typ_pos = v__token__Token_pos(&p->tok); enum_type = v__parser__Parser_parse_type(p); } Array_v__ast__Comment enum_decl_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); v__parser__Parser_check(p, v__token__Kind__lcbr); _PUSH_MANY(&enum_decl_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t8, Array_v__ast__Comment); string senum_type = v__ast__Table_get_type_name(p->table, enum_type); Array_string vals = __new_array_with_default(0, 0, sizeof(string), 0); Array_v__ast__EnumField fields = __new_array_with_default(0, 0, sizeof(v__ast__EnumField), 0); bool uses_exprs = false; Map_string_Array_v__ast__Attr enum_attrs = new_map(sizeof(string), sizeof(Array_v__ast__Attr), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (;;) { if (!(p->tok.kind != v__token__Kind__eof && p->tok.kind != v__token__Kind__rcbr)) break; Array_v__ast__Comment pre_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); v__token__Pos pos = v__token__Token_pos(&p->tok); bool has_prev_newline = v__parser__Parser_has_prev_newline(p); bool has_break_line = has_prev_newline || v__parser__Parser_has_prev_line_comment_or_label(p); string val = v__parser__Parser_check_name(p); array_push((array*)&vals, _MOV((string[]){ string_clone(val) })); v__ast__Expr expr = _const_v__ast__empty_expr; bool has_expr = false; if (p->tok.kind == v__token__Kind__assign) { v__parser__Parser_next(p); expr = v__parser__Parser_expr(p, 0); has_expr = true; uses_exprs = true; } Array_v__ast__Attr attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); if (p->tok.kind == v__token__Kind__lsbr || p->tok.kind == v__token__Kind__at) { v__parser__Parser_attributes(p); _PUSH_MANY(&attrs, (p->attrs), _t10, Array_v__ast__Attr); (*(Array_v__ast__Attr*)map_get_and_set((map*)&enum_attrs, &(string[]){val}, &(Array_v__ast__Attr[]){ __new_array(0, 0, sizeof(v__ast__Attr)) })) = attrs; p->attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); } Array_v__ast__Comment comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})); Array_v__ast__Comment next_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = true,})); array_push((array*)&fields, _MOV((v__ast__EnumField[]){ ((v__ast__EnumField){ .name = val, .source_name = v__parser__source_name(val), .pos = pos, .pre_comments = pre_comments, .comments = comments, .next_comments = next_comments, .has_expr = has_expr, .has_prev_newline = has_prev_newline, .has_break_line = has_break_line, .attrs = attrs, .expr = expr, }) })); } v__parser__Parser_top_level_statement_end(p); v__parser__Parser_check(p, v__token__Kind__rcbr); bool is_flag = Array_v__ast__Attr_contains(p->attrs, _S("flag")); bool is_multi_allowed = Array_v__ast__Attr_contains(p->attrs, _S("_allow_multiple_values")); string pubfn = (fast_string_eq(p->mod, _S("main")) ? (_S("@[flag_enum_fn] fn")) : (_S("@[flag_enum_fn] pub fn"))); if (is_flag) { if (fields.len > 64) { v__parser__Parser_error(p, _S("when an enum is used as bit field, it must have a max of 64 fields")); return ((v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); } for (int _t13 = 0; _t13 < fields.len; ++_t13) { v__ast__EnumField f = ((v__ast__EnumField*)fields.data)[_t13]; if (f.has_expr) { v__parser__Parser_error_with_pos(p, _S("when an enum is used as a bit field, you can not assign custom values"), f.pos); return ((v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); } } if (!already_exists) { string all_bits_set_value = string__plus(_S("0b"), string_repeat(_S("1"), fields.len)); v__parser__Parser_codegen(p, str_intp(40, _MOV((StrIntpData[]){{_S("\n//\n@[inline] "), 0xfe10, {.d_s = pubfn}}, {_S(" ( e &"), 0xfe10, {.d_s = enum_name}}, {_S(") is_empty() bool { return "), 0xfe10, {.d_s = senum_type}}, {_S("(*e) == 0 }\n@[inline] "), 0xfe10, {.d_s = pubfn}}, {_S(" ( e &"), 0xfe10, {.d_s = enum_name}}, {_S(") has(flag_ "), 0xfe10, {.d_s = enum_name}}, {_S(") bool { return ("), 0xfe10, {.d_s = senum_type}}, {_S("(*e) & ("), 0xfe10, {.d_s = senum_type}}, {_S("(flag_))) != 0 }\n@[inline] "), 0xfe10, {.d_s = pubfn}}, {_S(" ( e &"), 0xfe10, {.d_s = enum_name}}, {_S(") all(flag_ "), 0xfe10, {.d_s = enum_name}}, {_S(") bool { return ("), 0xfe10, {.d_s = senum_type}}, {_S("(*e) & ("), 0xfe10, {.d_s = senum_type}}, {_S("(flag_))) == "), 0xfe10, {.d_s = senum_type}}, {_S("(flag_) }\n@[inline] "), 0xfe10, {.d_s = pubfn}}, {_S(" (mut e "), 0xfe10, {.d_s = enum_name}}, {_S(") set(flag_ "), 0xfe10, {.d_s = enum_name}}, {_S(") { unsafe{ *e = "), 0xfe10, {.d_s = enum_name}}, {_S("("), 0xfe10, {.d_s = senum_type}}, {_S("(*e) | ("), 0xfe10, {.d_s = senum_type}}, {_S("(flag_))) } }\n@[inline] "), 0xfe10, {.d_s = pubfn}}, {_S(" (mut e "), 0xfe10, {.d_s = enum_name}}, {_S(") set_all() { unsafe{ *e = "), 0xfe10, {.d_s = enum_name}}, {_S("("), 0xfe10, {.d_s = all_bits_set_value}}, {_S(") } }\n@[inline] "), 0xfe10, {.d_s = pubfn}}, {_S(" (mut e "), 0xfe10, {.d_s = enum_name}}, {_S(") clear(flag_ "), 0xfe10, {.d_s = enum_name}}, {_S(") { unsafe{ *e = "), 0xfe10, {.d_s = enum_name}}, {_S("("), 0xfe10, {.d_s = senum_type}}, {_S("(*e) & ~("), 0xfe10, {.d_s = senum_type}}, {_S("(flag_))) } }\n@[inline] "), 0xfe10, {.d_s = pubfn}}, {_S(" (mut e "), 0xfe10, {.d_s = enum_name}}, {_S(") clear_all() { unsafe{ *e = "), 0xfe10, {.d_s = enum_name}}, {_S("(0) } }\n@[inline] "), 0xfe10, {.d_s = pubfn}}, {_S(" (mut e "), 0xfe10, {.d_s = enum_name}}, {_S(") toggle(flag_ "), 0xfe10, {.d_s = enum_name}}, {_S(") { unsafe{ *e = "), 0xfe10, {.d_s = enum_name}}, {_S("("), 0xfe10, {.d_s = senum_type}}, {_S("(*e) ^ ("), 0xfe10, {.d_s = senum_type}}, {_S("(flag_))) } }\n//\n"), 0, { .d_c = 0 }}}))); } } strings__Builder isb = strings__new_builder(1024); strings__Builder_write_string(&isb, _S("\n")); if (is_flag) { { strings__Builder_write_string(&isb, _S("@[inline] ")); strings__Builder_write_string(&isb, pubfn); strings__Builder_write_string(&isb, _S(" ")); strings__Builder_write_string(&isb, enum_name); strings__Builder_write_string(&isb, _S(".zero() ")); strings__Builder_write_string(&isb, enum_name); strings__Builder_write_string(&isb, _S(" {\n")); } { strings__Builder_write_string(&isb, _S("\011\011return unsafe{ ")); strings__Builder_write_string(&isb, enum_name); strings__Builder_write_string(&isb, _S("(0) }\n")); } strings__Builder_write_string(&isb, _S("}\n")); } { strings__Builder_write_string(&isb, pubfn); strings__Builder_write_string(&isb, _S(" ")); strings__Builder_write_string(&isb, enum_name); strings__Builder_write_string(&isb, _S(".from[W](input W) !")); strings__Builder_write_string(&isb, enum_name); strings__Builder_write_string(&isb, _S(" {\n")); } strings__Builder_write_string(&isb, _S("\011$if input is $int {\n")); { strings__Builder_write_string(&isb, _S("\011\011val := unsafe{ ")); strings__Builder_write_string(&isb, enum_name); strings__Builder_write_string(&isb, _S("(input) }\n")); } if (is_flag) { strings__Builder_write_string(&isb, _S("\011\011if input == 0 { return val }\n")); string all_bits_set_value = string__plus(_S("0b"), string_repeat(_S("1"), fields.len)); { strings__Builder_write_string(&isb, _S("\011\011if input & ~")); strings__Builder_write_string(&isb, all_bits_set_value); strings__Builder_write_string(&isb, _S(" == 0 { return val }\n")); } } else { strings__Builder_write_string(&isb, _S("\011\011match val {\n")); for (int _t15 = 0; _t15 < fields.len; ++_t15) { v__ast__EnumField f = ((v__ast__EnumField*)fields.data)[_t15]; { strings__Builder_write_string(&isb, _S("\011\011\011.")); strings__Builder_write_string(&isb, f.source_name); strings__Builder_write_string(&isb, _S(" { return ")); strings__Builder_write_string(&isb, enum_name); strings__Builder_write_string(&isb, _S(".")); strings__Builder_write_string(&isb, f.source_name); strings__Builder_write_string(&isb, _S(" }\n")); } } if (is_flag) { strings__Builder_write_string(&isb, _S("\011\011\011else{}\n")); } strings__Builder_write_string(&isb, _S("\011\011}\n")); } strings__Builder_write_string(&isb, _S("\011}\n")); strings__Builder_write_string(&isb, _S("\011$if input is $string {\n")); strings__Builder_write_string(&isb, _S("\011\011val := input.str()\n")); if (is_flag) { { strings__Builder_write_string(&isb, _S("\011\011if val == \'\' { return unsafe{ ")); strings__Builder_write_string(&isb, enum_name); strings__Builder_write_string(&isb, _S("(0) } }\n")); } } strings__Builder_write_string(&isb, _S("\011\011match val {\n")); for (int _t16 = 0; _t16 < fields.len; ++_t16) { v__ast__EnumField f = ((v__ast__EnumField*)fields.data)[_t16]; { strings__Builder_write_string(&isb, _S("\011\011\011\'")); strings__Builder_write_string(&isb, f.name); strings__Builder_write_string(&isb, _S("\' { return ")); strings__Builder_write_string(&isb, enum_name); strings__Builder_write_string(&isb, _S(".")); strings__Builder_write_string(&isb, f.source_name); strings__Builder_write_string(&isb, _S(" }\n")); } } strings__Builder_write_string(&isb, _S("\011\011\011else{}\n")); strings__Builder_write_string(&isb, _S("\011\011}\n")); strings__Builder_write_string(&isb, _S("\011}\n")); strings__Builder_write_string(&isb, _S("\011return error('invalid value')\n")); strings__Builder_write_string(&isb, _S("}\n")); strings__Builder_write_string(&isb, _S("\n")); string code_for_from_fn = strings__Builder_str(&isb); #if defined(CUSTOM_DEFINE_debug_enumcodegen) { if (fast_string_eq(p->mod, _S("main"))) { _v_dump_expr_string(_S("/home/runner/work/v/v/vlib/v/parser/enum.v"), 205, _S("code_for_from_fn"), code_for_from_fn); } } #endif if (u8_is_capital(string_at(enum_name, 0)) && fields.len > 0) { v__parser__Parser_codegen(p, code_for_from_fn); } int idx = v__ast__Table_register_sym(p->table, ((v__ast__TypeSymbol){ .parent_idx = 0, .info = v__ast__Enum_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Enum, (((v__ast__Enum){ .vals = vals, .is_flag = is_flag, .is_multi_allowed = is_multi_allowed, .uses_exprs = uses_exprs, .typ = enum_type, .attrs = enum_attrs, })))), .kind = v__ast__Kind__enum, .name = name, .cname = v__util__no_dots(name), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = p->mod, .is_pub = is_pub, .is_builtin = 0, .language = 0, .idx = 0, .size = -1, .align = -1, })); if (idx == _const_v__ast__string_type_idx || idx == _const_v__ast__rune_type_idx || idx == _const_v__ast__array_type_idx || idx == _const_v__ast__map_type_idx) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot register enum `"), 0xfe10, {.d_s = name}}, {_S("`, another type with this name exists"), 0, { .d_c = 0 }}})), end_pos); } if (idx == -1) { enum_type = idx; } v__ast__EnumDecl enum_decl = ((v__ast__EnumDecl){ .name = name, .is_pub = is_pub, .is_flag = is_flag, .is_multi_allowed = is_multi_allowed, .comments = enum_decl_comments, .fields = fields, .attrs = p->attrs, .typ = enum_type, .typ_pos = typ_pos, .pos = v__token__Pos_extend_with_last_line(start_pos, end_pos, p->prev_tok.line_nr), }); if (!already_exists) { v__ast__Table_register_enum_decl(p->table, enum_decl); } return enum_decl; } inline VV_LOC _result_void v__parser__Parser_check_expr_level(v__parser__Parser* p) { if (p->expr_level > 100) { return (_result_void){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("expr level > "), 0xfe07, {.d_i32 = _const_v__parser__max_expr_level}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } return (_result_void){0}; } VV_LOC v__ast__Expr v__parser__Parser_expr_no_value(v__parser__Parser* p, int precedence) { bool v__parser__Parser_expr_no_value_defer_0 = false; bool old_expecting_value; old_expecting_value = p->expecting_value; p->expecting_value = false; v__parser__Parser_expr_no_value_defer_0 = true; _result_v__ast__Expr _t2 = v__parser__Parser_check_expr(p, precedence); if (_t2.is_error) { IError err = _t2.err; if (v__token__is_decl(p->tok.kind) && v__parser__Parser_disallow_declarations_in_script_mode(p)) { v__ast__Expr _t3 = _const_v__ast__empty_expr; // Defer begin if (v__parser__Parser_expr_no_value_defer_0) { p->expecting_value = old_expecting_value; } // Defer end return _t3; } *(v__ast__Expr*) _t2.data = v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = _S("invalid expression:"),.additional_msg = (string){.str=(byteptr)"", .is_lit=1},}))))); } v__ast__Expr _t1 = (*(v__ast__Expr*)_t2.data); // Defer begin if (v__parser__Parser_expr_no_value_defer_0) { p->expecting_value = old_expecting_value; } // Defer end return _t1; } VV_LOC v__ast__Expr v__parser__Parser_expr(v__parser__Parser* p, int precedence) { bool v__parser__Parser_expr_defer_0 = false; bool old_expecting_value; old_expecting_value = p->expecting_value; p->expecting_value = true; v__parser__Parser_expr_defer_0 = true; _result_v__ast__Expr _t2 = v__parser__Parser_check_expr(p, precedence); if (_t2.is_error) { IError err = _t2.err; if (v__token__is_decl(p->tok.kind) && v__parser__Parser_disallow_declarations_in_script_mode(p)) { v__ast__Expr _t3 = _const_v__ast__empty_expr; // Defer begin if (v__parser__Parser_expr_defer_0) { p->expecting_value = old_expecting_value; } // Defer end return _t3; } *(v__ast__Expr*) _t2.data = v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = _S("invalid expression:"),.additional_msg = (string){.str=(byteptr)"", .is_lit=1},}))))); } v__ast__Expr _t1 = (*(v__ast__Expr*)_t2.data); // Defer begin if (v__parser__Parser_expr_defer_0) { p->expecting_value = old_expecting_value; } // Defer end return _t1; } VV_LOC _result_v__ast__Expr v__parser__Parser_check_expr(v__parser__Parser* p, int precedence) { bool v__parser__Parser_check_expr_defer_0 = false; ; p->expr_level++; v__parser__Parser_check_expr_defer_0 = true; _result_void _t1 = v__parser__Parser_check_expr_level(p); if (_t1.is_error) { // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end _result_v__ast__Expr _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } ; v__ast__Expr node = _const_v__ast__empty_expr; bool is_stmt_ident = p->is_stmt_ident; p->is_stmt_ident = false; if (!p->pref->is_fmt) { v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); } if (p->inside_if_cond) { _PUSH_MANY(&p->if_cond_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t3, Array_v__ast__Comment); } switch (p->tok.kind) { case v__token__Kind__key_mut: case v__token__Kind__key_shared: case v__token__Kind__key_atomic: case v__token__Kind__key_static: case v__token__Kind__key_volatile: { if ((p->peek_tok.kind == v__token__Kind__lpar || p->peek_tok.kind == v__token__Kind__lsbr) && v__token__Token_is_next_to(p->peek_tok, p->tok)) { node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (v__parser__Parser_call_expr(p, p->language, p->mod)))); } else { v__ast__Ident ident = v__parser__Parser_ident(p, v__ast__Language__v); node = v__ast__Ident_to_sumtype_v__ast__Expr(&ident); if (p->peek_tok.kind != v__token__Kind__assign && (p->inside_if_cond || p->inside_match)) { v__ast__Scope_mark_var_as_used(p->scope, ident.name); } v__parser__Parser_add_defer_var(p, ident); p->is_stmt_ident = is_stmt_ident; } break; } case v__token__Kind__name: case v__token__Kind__question: { if (p->peek_tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("sql"))) { node = v__parser__Parser_sql_expr(p); } else if (p->peek_tok.kind == v__token__Kind__lcbr && fast_string_eq(p->tok.lit, _S("map")) && !(p->builtin_mod && (fast_string_eq(p->file_base, _S("map.v")) || fast_string_eq(p->file_base, _S("map_d_gcboehm_opt.v"))))) { v__parser__Parser_error_with_pos(p, _S("deprecated map syntax, use syntax like `{'age': 20}`"), v__token__Token_pos(&p->tok)); } else if (p->tok.kind == v__token__Kind__question && p->peek_tok.kind == v__token__Kind__amp) { node = v__parser__Parser_prefix_expr(p); } else if (p->inside_for_expr && p->tok.kind == v__token__Kind__name && ((u8_is_capital(string_at(p->tok.lit, 0)) && p->peek_tok.kind == v__token__Kind__lcbr && (v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__rcbr || v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__name)) || (p->inside_array_lit && p->peek_tok.kind == v__token__Kind__dot && v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__name && u8_is_capital(string_at(v__parser__Parser_peek_token(p, 2).lit, 0)) && v__parser__Parser_peek_token(p, 3).kind == v__token__Kind__lcbr && (v__parser__Parser_peek_token(p, 4).kind == v__token__Kind__rcbr || v__parser__Parser_peek_token(p, 4).kind == v__token__Kind__name)))) { node = v__ast__StructInit_to_sumtype_v__ast__Expr(ADDR(v__ast__StructInit, (v__parser__Parser_struct_init(p, string__plus(string__plus(p->mod, _S(".")), p->tok.lit), v__ast__StructInitKind__normal, false)))); } else if (v__parser__Parser_is_generic_name(p) && p->peek_tok.kind == v__token__Kind__lcbr && v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__rcbr && v__parser__Parser_peek_token(p, 2).line_nr == p->tok.line_nr) { node = v__ast__StructInit_to_sumtype_v__ast__Expr(ADDR(v__ast__StructInit, (v__parser__Parser_struct_init(p, string__plus(string__plus(p->mod, _S(".")), p->tok.lit), v__ast__StructInitKind__normal, false)))); } else { if (p->inside_comptime_if && v__parser__Parser_is_generic_name(p) && p->peek_tok.kind != v__token__Kind__dot) { p->expecting_type = true; } node = v__parser__Parser_name_expr(p); p->is_stmt_ident = is_stmt_ident; } break; } case v__token__Kind__string: { node = v__parser__Parser_string_expr(p); break; } case v__token__Kind__comment: { node = v__ast__Comment_to_sumtype_v__ast__Expr(ADDR(v__ast__Comment, (v__parser__Parser_comment(p)))); _result_v__ast__Expr _t4 = {0}; _result_ok(&(v__ast__Expr[]) { node }, (_result*)(&_t4), sizeof(v__ast__Expr)); // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t4; } case v__token__Kind__dot: { node = v__ast__EnumVal_to_sumtype_v__ast__Expr(ADDR(v__ast__EnumVal, (v__parser__Parser_enum_val(p)))); break; } case v__token__Kind__at: { node = v__ast__AtExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__AtExpr, (v__parser__Parser_at(p)))); break; } case v__token__Kind__dollar: { if (p->peek_tok.kind == (v__token__Kind__name) || p->peek_tok.kind == (v__token__Kind__key_struct) || p->peek_tok.kind == (v__token__Kind__key_enum) || p->peek_tok.kind == (v__token__Kind__key_interface)) { if ((Array_string_contains(_const_v__parser__comptime_types, p->peek_tok.lit))) { node = v__ast__ComptimeType_to_sumtype_v__ast__Expr(ADDR(v__ast__ComptimeType, (v__parser__Parser_parse_comptime_type(p)))); } else { node = v__ast__ComptimeCall_to_sumtype_v__ast__Expr(ADDR(v__ast__ComptimeCall, (v__parser__Parser_comptime_call(p)))); } p->is_stmt_ident = is_stmt_ident; } else if (p->peek_tok.kind == (v__token__Kind__key_if)) { _result_v__ast__Expr _t5 = {0}; _result_ok(&(v__ast__Expr[]) { v__ast__IfExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__IfExpr, (v__parser__Parser_if_expr(p, true, false)))) }, (_result*)(&_t5), sizeof(v__ast__Expr)); // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t5; } else { _result_v__ast__Expr _t6 = {0}; _result_ok(&(v__ast__Expr[]) { v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_unexpected_with_pos(p, v__token__Token_pos(&p->peek_tok), ((v__parser__ParamsForUnexpected){.got = _S("`$`"),.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},}))))) }, (_result*)(&_t6), sizeof(v__ast__Expr)); // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t6; } break; } case v__token__Kind__chartoken: { node = v__ast__CharLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__CharLiteral, (((v__ast__CharLiteral){.val = p->tok.lit,.pos = v__token__Token_pos(&p->tok),})))); v__parser__Parser_next(p); break; } case v__token__Kind__amp: case v__token__Kind__mul: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__arrow: { node = v__parser__Parser_prefix_expr(p); break; } case v__token__Kind__minus: { if (p->peek_tok.kind == v__token__Kind__number) { node = v__parser__Parser_parse_number_literal(p); } else { node = v__parser__Parser_prefix_expr(p); } break; } case v__token__Kind__key_go: case v__token__Kind__key_spawn: { if ((p->peek_tok.kind == v__token__Kind__lpar || p->peek_tok.kind == v__token__Kind__lsbr) && v__token__Token_is_next_to(p->peek_tok, p->tok)) { node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (v__parser__Parser_call_expr(p, p->language, p->mod)))); } else { if ((p->pref->use_coroutines || p->pref->is_fmt) && p->tok.kind == v__token__Kind__key_go) { v__ast__GoExpr go_expr = v__parser__Parser_go_expr(p); go_expr.is_expr = true; node = v__ast__GoExpr_to_sumtype_v__ast__Expr(&go_expr); } else { v__ast__SpawnExpr spawn_expr = v__parser__Parser_spawn_expr(p); spawn_expr.is_expr = true; node = v__ast__SpawnExpr_to_sumtype_v__ast__Expr(&spawn_expr); } } break; } case v__token__Kind__key_true: case v__token__Kind__key_false: { if ((p->peek_tok.kind == v__token__Kind__lpar || p->peek_tok.kind == v__token__Kind__lsbr) && v__token__Token_is_next_to(p->peek_tok, p->tok)) { node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (v__parser__Parser_call_expr(p, p->language, p->mod)))); } else { node = v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = p->tok.kind == v__token__Kind__key_true,.pos = v__token__Token_pos(&p->tok),})))); v__parser__Parser_next(p); } break; } case v__token__Kind__key_match: { if ((p->peek_tok.kind == v__token__Kind__lpar || p->peek_tok.kind == v__token__Kind__lsbr) && v__token__Token_is_next_to(p->peek_tok, p->tok)) { node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (v__parser__Parser_call_expr(p, p->language, p->mod)))); } else { node = v__ast__MatchExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__MatchExpr, (v__parser__Parser_match_expr(p)))); } break; } case v__token__Kind__key_select: { if ((p->peek_tok.kind == v__token__Kind__lpar || p->peek_tok.kind == v__token__Kind__lsbr) && v__token__Token_is_next_to(p->peek_tok, p->tok)) { node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (v__parser__Parser_call_expr(p, p->language, p->mod)))); } else { node = v__ast__SelectExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__SelectExpr, (v__parser__Parser_select_expr(p)))); } break; } case v__token__Kind__key_nil: { node = v__ast__Nil_to_sumtype_v__ast__Expr(ADDR(v__ast__Nil, (((v__ast__Nil){.pos = v__token__Token_pos(&p->tok),})))); v__parser__Parser_next(p); break; } case v__token__Kind__number: { node = v__parser__Parser_parse_number_literal(p); break; } case v__token__Kind__lpar: { v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__lpar); Array_v__ast__Comment comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); node = v__parser__Parser_expr(p, 0); _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t7, Array_v__ast__Comment); v__parser__Parser_check(p, v__token__Kind__rpar); node = v__ast__ParExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__ParExpr, (((v__ast__ParExpr){.pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)),.expr = node,.comments = comments,})))); break; } case v__token__Kind__key_if: { if ((p->peek_tok.kind == v__token__Kind__lpar || p->peek_tok.kind == v__token__Kind__lsbr) && v__token__Token_is_next_to(p->peek_tok, p->tok)) { node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (v__parser__Parser_call_expr(p, p->language, p->mod)))); } else { bool is_expr = false; if (v__token__Kind_is_assign(p->prev_tok.kind)) { is_expr = true; } node = v__ast__IfExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__IfExpr, (v__parser__Parser_if_expr(p, false, is_expr)))); } break; } case v__token__Kind__key_unsafe: { v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); if (p->inside_unsafe) { _result_v__ast__Expr _t8 = {0}; _result_ok(&(v__ast__Expr[]) { v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("already inside `unsafe` block"), pos)))) }, (_result*)(&_t8), sizeof(v__ast__Expr)); // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t8; } p->inside_unsafe = true; v__parser__Parser_check(p, v__token__Kind__lcbr); v__ast__Expr e = v__parser__Parser_expr(p, 0); v__parser__Parser_check(p, v__token__Kind__rcbr); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); node = v__ast__UnsafeExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__UnsafeExpr, (((v__ast__UnsafeExpr){.pos = pos,.expr = e,})))); p->inside_unsafe = false; break; } case v__token__Kind__pipe: case v__token__Kind__logical_or: { _option_v__ast__LambdaExpr _t9; if (_t9 = v__parser__Parser_lambda_expr(p), _t9.state == 0) { v__ast__LambdaExpr nnn = *(v__ast__LambdaExpr*)_t9.data; node = v__ast__LambdaExpr_to_sumtype_v__ast__Expr(&nnn); } else { IError err = _t9.err; _result_v__ast__Expr _t10 = (_result_v__ast__Expr){ .is_error=true, .err=_v_error(_S("unexpected lambda expression")), .data={E_STRUCT} }; // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t10; } break; } case v__token__Kind__key_lock: case v__token__Kind__key_rlock: { if ((p->peek_tok.kind == v__token__Kind__lpar || p->peek_tok.kind == v__token__Kind__lsbr) && v__token__Token_is_next_to(p->peek_tok, p->tok)) { node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (v__parser__Parser_call_expr(p, p->language, p->mod)))); } else { node = v__ast__LockExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__LockExpr, (v__parser__Parser_lock_expr(p)))); } break; } case v__token__Kind__lsbr: { if (p->expecting_type) { node = v__parser__Parser_name_expr(p); } else if (p->is_amp && p->peek_tok.kind == v__token__Kind__rsbr) { int n = 2; v__token__Token peek_n_tok = v__parser__Parser_peek_token(p, n); for (;;) { if (!((peek_n_tok.kind == v__token__Kind__name || peek_n_tok.kind == v__token__Kind__dot))) break; n++; peek_n_tok = v__parser__Parser_peek_token(p, n); } if (peek_n_tok.kind != v__token__Kind__lcbr) { v__token__Pos pos = v__token__Token_pos(&p->tok); v__ast__Type typ = v__parser__Parser_parse_type(p); string typname = v__ast__Table_sym(p->table, typ)->name; v__parser__Parser_check(p, v__token__Kind__lpar); v__ast__Expr expr = v__parser__Parser_expr(p, 0); v__parser__Parser_check(p, v__token__Kind__rpar); node = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = typ,.expr = expr,.typname = typname,.expr_type = 0,.has_arg = 0,.pos = pos,})))); } else { node = v__ast__ArrayInit_to_sumtype_v__ast__Expr(ADDR(v__ast__ArrayInit, (v__parser__Parser_array_init(p, false, _const_v__ast__void_type)))); } } else { node = v__ast__ArrayInit_to_sumtype_v__ast__Expr(ADDR(v__ast__ArrayInit, (v__parser__Parser_array_init(p, false, _const_v__ast__void_type)))); } break; } case v__token__Kind__key_none: { v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); node = v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = pos,})))); break; } case v__token__Kind__key_typeof: { v__token__Pos spos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); if (p->tok.kind == v__token__Kind__lsbr) { v__parser__Parser_check(p, v__token__Kind__lsbr); v__token__Pos type_pos = v__token__Token_pos(&p->tok); v__ast__Type typ = v__parser__Parser_parse_type(p); v__parser__Parser_check(p, v__token__Kind__rsbr); v__parser__Parser_check(p, v__token__Kind__lpar); v__parser__Parser_check(p, v__token__Kind__rpar); node = v__ast__TypeOf_to_sumtype_v__ast__Expr(ADDR(v__ast__TypeOf, (((v__ast__TypeOf){.is_type = true,.pos = v__token__Pos_extend(type_pos, v__token__Token_pos(&p->tok)),.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = typ,})))); } else { v__parser__Parser_check(p, v__token__Kind__lpar); v__ast__Expr expr = v__parser__Parser_expr(p, 0); v__parser__Parser_check(p, v__token__Kind__rpar); if (p->tok.kind != v__token__Kind__dot && p->tok.line_nr == p->prev_tok.line_nr) { if (!p->inside_unsafe) { v__parser__Parser_warn_with_pos(p, _S("use e.g. `typeof(expr).name` or `sum_type_instance.type_name()` instead"), spos); } } node = v__ast__TypeOf_to_sumtype_v__ast__Expr(ADDR(v__ast__TypeOf, (((v__ast__TypeOf){.is_type = false,.pos = v__token__Pos_extend(spos, v__token__Token_pos(&p->tok)),.expr = expr,.typ = 0,})))); } break; } case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: { bool is_reftype = p->tok.kind == v__token__Kind__key_isreftype; v__parser__Parser_next(p); if (p->tok.kind == v__token__Kind__lsbr) { v__parser__Parser_check(p, v__token__Kind__lsbr); v__token__Pos type_pos = v__token__Token_pos(&p->tok); v__ast__Type typ = v__parser__Parser_parse_type(p); type_pos = v__token__Pos_extend(type_pos, v__token__Token_pos(&p->tok)); v__parser__Parser_check(p, v__token__Kind__rsbr); v__parser__Parser_check(p, v__token__Kind__lpar); v__parser__Parser_check(p, v__token__Kind__rpar); if (is_reftype) { node = v__ast__IsRefType_to_sumtype_v__ast__Expr(ADDR(v__ast__IsRefType, (((v__ast__IsRefType){.guessed_type = 0,.is_type = true,.pos = type_pos,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = typ,})))); } else { node = v__ast__SizeOf_to_sumtype_v__ast__Expr(ADDR(v__ast__SizeOf, (((v__ast__SizeOf){.guessed_type = 0,.is_type = true,.pos = type_pos,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = typ,})))); } } else { v__parser__Parser_check(p, v__token__Kind__lpar); v__token__Pos pos = v__token__Token_pos(&p->tok); bool is_known_var = v__ast__Scope_mark_var_as_used(p->scope, p->tok.lit) || v__ast__Scope_known_const(p->table->global_scope, string__plus(string__plus(p->mod, _S(".")), p->tok.lit)); bool is_type = v__parser__Parser_known_import(p, p->tok.lit) || v__token__Kind_is_start_of_type(p->tok.kind) || (p->tok.lit.len > 0 && u8_is_capital(string_at(p->tok.lit, 0))); if (p->peek_tok.kind == v__token__Kind__string && (fast_string_eq(p->tok.lit, _S("c")) || fast_string_eq(p->tok.lit, _S("r")))) { is_known_var = false; is_type = false; } if (is_known_var || !is_type) { v__ast__Expr expr = v__parser__Parser_expr(p, 0); if (is_reftype) { node = v__ast__IsRefType_to_sumtype_v__ast__Expr(ADDR(v__ast__IsRefType, (((v__ast__IsRefType){.guessed_type = 0,.is_type = false,.pos = pos,.expr = expr,.typ = 0,})))); } else { node = v__ast__SizeOf_to_sumtype_v__ast__Expr(ADDR(v__ast__SizeOf, (((v__ast__SizeOf){.guessed_type = 0,.is_type = false,.pos = pos,.expr = expr,.typ = 0,})))); } } else { if (p->tok.kind == v__token__Kind__name) { v__parser__Parser_register_used_import(p, p->tok.lit); } string save_expr_mod = p->expr_mod; p->expr_mod = _S(""); v__ast__Type arg_type = v__parser__Parser_parse_type(p); p->expr_mod = save_expr_mod; if (is_reftype) { node = v__ast__IsRefType_to_sumtype_v__ast__Expr(ADDR(v__ast__IsRefType, (((v__ast__IsRefType){.guessed_type = true,.is_type = true,.pos = pos,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = arg_type,})))); } else { node = v__ast__SizeOf_to_sumtype_v__ast__Expr(ADDR(v__ast__SizeOf, (((v__ast__SizeOf){.guessed_type = true,.is_type = true,.pos = pos,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = arg_type,})))); } } v__parser__Parser_check(p, v__token__Kind__rpar); } break; } case v__token__Kind__key_dump: { v__token__Pos spos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__lpar); v__ast__Expr expr = v__parser__Parser_expr(p, 0); if (p->tok.kind == v__token__Kind__comma && p->peek_tok.kind == v__token__Kind__rpar) { v__parser__Parser_next(p); } v__parser__Parser_check(p, v__token__Kind__rpar); v__token__Pos pos = v__token__Token_pos(&p->tok); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); node = v__ast__DumpExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__DumpExpr, (((v__ast__DumpExpr){.pos = v__token__Pos_extend(spos, pos),.expr = expr,.expr_type = 0,.cname = (string){.str=(byteptr)"", .is_lit=1},})))); break; } case v__token__Kind__key_offsetof: { v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__lpar); v__ast__Type st = v__parser__Parser_parse_type(p); v__parser__Parser_check(p, v__token__Kind__comma); if (p->tok.kind != v__token__Kind__name) { _result_v__ast__Expr _t11 = {0}; _result_ok(&(v__ast__Expr[]) { v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = p->tok.lit}}, {_S("`"), 0, { .d_c = 0 }}})),.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = _S("expecting struct field"),}))))) }, (_result*)(&_t11), sizeof(v__ast__Expr)); // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t11; } string field = p->tok.lit; v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__rpar); node = v__ast__OffsetOf_to_sumtype_v__ast__Expr(ADDR(v__ast__OffsetOf, (((v__ast__OffsetOf){.struct_type = st,.field = field,.pos = pos,})))); break; } case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: { bool is_likely = p->tok.kind == v__token__Kind__key_likely; v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__lpar); v__token__Pos lpos = v__token__Token_pos(&p->tok); v__ast__Expr expr = v__parser__Parser_expr(p, 0); v__parser__Parser_check(p, v__token__Kind__rpar); node = v__ast__Likely_to_sumtype_v__ast__Expr(ADDR(v__ast__Likely, (((v__ast__Likely){.pos = lpos,.is_likely = is_likely,.expr = expr,})))); break; } case v__token__Kind__lcbr: { v__parser__Parser_next(p); node = v__ast__MapInit_to_sumtype_v__ast__Expr(ADDR(v__ast__MapInit, (v__parser__Parser_map_init(p)))); v__parser__Parser_check(p, v__token__Kind__rcbr); break; } case v__token__Kind__key_fn: { if (p->expecting_type) { v__token__Pos start_pos = v__token__Token_pos(&p->tok); _result_v__ast__Expr _t12 = {0}; _result_ok(&(v__ast__Expr[]) { v__ast__TypeNode_to_sumtype_v__ast__Expr(ADDR(v__ast__TypeNode, (((v__ast__TypeNode){.pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)),.typ = v__parser__Parser_parse_type(p),.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),})))) }, (_result*)(&_t12), sizeof(v__ast__Expr)); // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t12; } else { node = v__ast__AnonFn_to_sumtype_v__ast__Expr(ADDR(v__ast__AnonFn, (v__parser__Parser_anon_fn(p)))); if (p->file_backend_mode == v__ast__Language__v || p->file_backend_mode == v__ast__Language__c) { v__parser__Parser_register_auto_import(p, _S("builtin.closure")); } if (p->tok.kind == v__token__Kind__lpar) { v__parser__Parser_next(p); v__token__Pos pos = v__token__Token_pos(&p->tok); Array_v__ast__CallArg args = v__parser__Parser_call_args(p); v__parser__Parser_check(p, v__token__Kind__rpar); v__ast__OrExpr or_block = v__parser__Parser_gen_or_block(p); node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (((v__ast__CallExpr){ .pos = pos, .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .mod = (string){.str=(byteptr)"", .is_lit=1}, .name = _S("anon"), .is_method = 0, .is_field = 0, .is_fn_var = 0, .is_fn_a_const = 0, .is_keep_alive = 0, .is_noreturn = 0, .is_ctor_new = 0, .is_file_translated = 0, .is_static_method = 0, .args = args, .expected_arg_types = __new_array(0, 0, sizeof(v__ast__Type)), .comptime_ret_val = 0, .language = 0, .or_block = or_block, .left = node, .left_type = 0, .receiver_type = 0, .receiver_concrete_type = 0, .return_type = 0, .return_type_generic = 0, .nr_ret_values = -1, .fn_var_type = 0, .const_name = (string){.str=(byteptr)"", .is_lit=1}, .should_be_skipped = 0, .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .concrete_list_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .raw_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .free_receiver = 0, .scope = p->scope, .from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)), .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .is_return_used = p->expecting_value, .is_expand_simple_interpolation = 0, .is_unwrapped_fn_selector = 0, })))); } _result_v__ast__Expr _t13 = {0}; _result_ok(&(v__ast__Expr[]) { node }, (_result*)(&_t13), sizeof(v__ast__Expr)); // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t13; } break; } case v__token__Kind__inc: case v__token__Kind__dec: { bool same_line_with_next = p->tok.line_nr == p->peek_tok.line_nr; bool next_tok_name = p->peek_tok.kind == v__token__Kind__name; if (next_tok_name && same_line_with_next) { v__parser__Parser_prefix_inc_dec_error(p); } break; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__str_inter: case v__token__Kind__plus: case v__token__Kind__div: case v__token__Kind__mod: case v__token__Kind__xor: case v__token__Kind__and: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__hash: case v__token__Kind__str_dollar: case v__token__Kind__left_shift: case v__token__Kind__right_shift: case v__token__Kind__unsigned_right_shift: case v__token__Kind__not_in: case v__token__Kind__not_is: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__rcbr: case v__token__Kind__rpar: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__eq: case v__token__Kind__ne: case v__token__Kind__gt: case v__token__Kind__lt: case v__token__Kind__ge: case v__token__Kind__le: case v__token__Kind__nl: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_for: case v__token__Kind__key_global: case v__token__Kind__key_goto: case v__token__Kind__key_import: case v__token__Kind__key_in: case v__token__Kind__key_interface: case v__token__Kind__key_is: case v__token__Kind__key_module: case v__token__Kind__key_return: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_struct: case v__token__Kind__key_type: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { if (p->tok.kind == v__token__Kind__key_struct && p->peek_tok.kind == v__token__Kind__lcbr) { if (p->expecting_type && p->inside_call_args) { v__token__Pos tok_pos = v__token__Token_pos(&p->tok); _result_v__ast__Expr _t14 = {0}; _result_ok(&(v__ast__Expr[]) { v__ast__TypeNode_to_sumtype_v__ast__Expr(ADDR(v__ast__TypeNode, (((v__ast__TypeNode){.pos = tok_pos,.typ = _const_v__ast__void_type,.stmt = v__ast__StructDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__StructDecl, (v__parser__Parser_struct_decl(p, true)))),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),})))) }, (_result*)(&_t14), sizeof(v__ast__Expr)); // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t14; } else { v__parser__Parser_next(p); _result_v__ast__Expr _t15 = {0}; _result_ok(&(v__ast__Expr[]) { v__ast__StructInit_to_sumtype_v__ast__Expr(ADDR(v__ast__StructInit, (v__parser__Parser_struct_init(p, _S(""), v__ast__StructInitKind__anon, false)))) }, (_result*)(&_t15), sizeof(v__ast__Expr)); // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t15; } } else if (p->tok.kind == v__token__Kind__key_type) { v__ast__Ident ident = v__parser__Parser_ident(p, v__ast__Language__v); node = v__ast__Ident_to_sumtype_v__ast__Expr(&ident); v__ast__Scope_mark_var_as_used(p->scope, ident.name); v__parser__Parser_add_defer_var(p, ident); p->is_stmt_ident = is_stmt_ident; } else if (p->tok.kind != v__token__Kind__eof && !(p->tok.kind == v__token__Kind__rsbr && p->inside_asm)) { _result_v__ast__Expr _t16 = (_result_v__ast__Expr){ .is_error=true, .err=_v_error(_S("none")), .data={E_STRUCT} }; // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t16; } break; } } } if (p->inside_array_lit) { if ((p->tok.kind == v__token__Kind__minus || p->tok.kind == v__token__Kind__mul || p->tok.kind == v__token__Kind__amp || p->tok.kind == v__token__Kind__arrow) && (int)(p->tok.pos + 1) == p->peek_tok.pos && (int)((int)(p->prev_tok.pos + p->prev_tok.len) + 1) != p->peek_tok.pos) { _result_v__ast__Expr _t17 = {0}; _result_ok(&(v__ast__Expr[]) { node }, (_result*)(&_t17), sizeof(v__ast__Expr)); // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t17; } } if (p->inside_if_cond) { _PUSH_MANY(&p->if_cond_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t18, Array_v__ast__Comment); } if (p->pref->is_fmt && p->tok.kind == v__token__Kind__comment && v__token__Kind_is_infix(p->peek_tok.kind) && !p->inside_infix && !p->inside_map_init && !(p->peek_tok.kind == v__token__Kind__mul && v__token__Token_pos(&p->peek_tok).line_nr != v__token__Token_pos(&p->tok).line_nr)) { p->left_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); } _result_v__ast__Expr _t19 = {0}; _result_ok(&(v__ast__Expr[]) { v__parser__Parser_expr_with_left(p, node, precedence, is_stmt_ident) }, (_result*)(&_t19), sizeof(v__ast__Expr)); // Defer begin if (v__parser__Parser_check_expr_defer_0) { p->expr_level--; } // Defer end return _t19; } VV_LOC v__ast__Expr v__parser__Parser_expr_with_left(v__parser__Parser* p, v__ast__Expr left, int precedence, bool is_stmt_ident) { v__ast__Expr node = left; if (p->inside_asm && v__token__Token_pos(&p->prev_tok).line_nr < v__token__Token_pos(&p->tok).line_nr) { return node; } v__parser__Parser_process_custom_orm_operators(p); for (;;) { if (!(precedence < v__token__Kind_precedence(p->tok.kind))) break; if (p->tok.kind == v__token__Kind__dot) { if ((p->inside_map_init || p->inside_array_lit) && (int)(p->tok.pos - p->prev_tok.pos) > p->prev_tok.len) { return node; } node = v__parser__Parser_dot_expr(p, node); if (p->name_error) { return node; } p->is_stmt_ident = is_stmt_ident; } else if ((left)._typ != 363 /* v.ast.IntegerLiteral */ && (p->tok.kind == v__token__Kind__lsbr || p->tok.kind == v__token__Kind__nilsbr) && (p->tok.line_nr == p->prev_tok.line_nr || (p->prev_tok.kind == v__token__Kind__string && p->tok.line_nr == (int)(p->prev_tok.line_nr + string_count(p->prev_tok.lit, _S("\n")))))) { if (p->peek_tok.kind == v__token__Kind__question && v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__name) { v__parser__Parser_next(p); v__parser__Parser_error_with_pos(p, _S("cannot use Option type name as concrete type"), v__token__Token_pos(&p->tok)); } else if (p->tok.kind == v__token__Kind__nilsbr) { node = v__ast__IndexExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__IndexExpr, (v__parser__Parser_index_expr(p, node, true)))); } else { node = v__ast__IndexExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__IndexExpr, (v__parser__Parser_index_expr(p, node, false)))); } p->is_stmt_ident = is_stmt_ident; if (p->tok.kind == v__token__Kind__lpar && p->tok.line_nr == p->prev_tok.line_nr && (node)._typ == 361 /* v.ast.IndexExpr */) { v__parser__Parser_next(p); v__token__Pos pos = v__token__Token_pos(&p->tok); Array_v__ast__CallArg args = v__parser__Parser_call_args(p); v__parser__Parser_check(p, v__token__Kind__rpar); v__ast__OrExpr or_block = v__parser__Parser_gen_or_block(p); node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (((v__ast__CallExpr){ .pos = pos, .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .mod = (string){.str=(byteptr)"", .is_lit=1}, .name = (string){.str=(byteptr)"", .is_lit=1}, .is_method = 0, .is_field = 0, .is_fn_var = 0, .is_fn_a_const = 0, .is_keep_alive = 0, .is_noreturn = 0, .is_ctor_new = 0, .is_file_translated = 0, .is_static_method = 0, .args = args, .expected_arg_types = __new_array(0, 0, sizeof(v__ast__Type)), .comptime_ret_val = 0, .language = 0, .or_block = or_block, .left = node, .left_type = 0, .receiver_type = 0, .receiver_concrete_type = 0, .return_type = 0, .return_type_generic = 0, .nr_ret_values = -1, .fn_var_type = 0, .const_name = (string){.str=(byteptr)"", .is_lit=1}, .should_be_skipped = 0, .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .concrete_list_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .raw_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .free_receiver = 0, .scope = p->scope, .from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)), .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .is_return_used = p->expecting_value, .is_expand_simple_interpolation = 0, .is_unwrapped_fn_selector = 0, })))); p->is_stmt_ident = is_stmt_ident; if (p->tok.kind == v__token__Kind__lpar && p->prev_tok.line_nr == p->tok.line_nr) { v__parser__Parser_next(p); v__token__Pos pos2 = v__token__Token_pos(&p->tok); Array_v__ast__CallArg args2 = v__parser__Parser_call_args(p); v__parser__Parser_check(p, v__token__Kind__rpar); v__ast__OrExpr or_block2 = v__parser__Parser_gen_or_block(p); node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (((v__ast__CallExpr){.pos = pos2,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mod = (string){.str=(byteptr)"", .is_lit=1},.name = (string){.str=(byteptr)"", .is_lit=1},.is_method = 0,.is_field = 0,.is_fn_var = 0,.is_fn_a_const = 0,.is_keep_alive = 0,.is_noreturn = 0,.is_ctor_new = 0,.is_file_translated = 0,.is_static_method = 0,.args = args2,.expected_arg_types = __new_array(0, 0, sizeof(v__ast__Type)),.comptime_ret_val = 0,.language = 0,.or_block = or_block2,.left = node,.left_type = 0,.receiver_type = 0,.receiver_concrete_type = 0,.return_type = 0,.return_type_generic = 0,.nr_ret_values = -1,.fn_var_type = 0,.const_name = (string){.str=(byteptr)"", .is_lit=1},.should_be_skipped = 0,.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.concrete_list_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.raw_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.free_receiver = 0,.scope = p->scope,.from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_return_used = 0,.is_expand_simple_interpolation = 0,.is_unwrapped_fn_selector = 0,})))); } } } else if (p->tok.kind == v__token__Kind__key_as && p->tok.line_nr == p->prev_tok.line_nr) { if (!p->inside_asm) { v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); v__ast__Type typ = v__parser__Parser_parse_type(p); node = v__ast__AsCast_to_sumtype_v__ast__Expr(ADDR(v__ast__AsCast, (((v__ast__AsCast){.typ = typ,.pos = pos,.expr = node,.expr_type = 0,})))); } else { return node; } } else if ((node)._typ != 345 /* v.ast.CastExpr */ && p->tok.kind == v__token__Kind__left_shift && p->is_stmt_ident) { v__token__Token tok = p->tok; v__token__Pos pos = v__token__Token_pos(&tok); v__parser__Parser_next(p); bool old_assign_rhs = p->inside_assign_rhs; p->inside_assign_rhs = true; v__ast__Expr right = v__parser__Parser_expr(p, (int)(precedence - 1)); p->inside_assign_rhs = old_assign_rhs; v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); if ((node)._typ == 361 /* v.ast.IndexExpr */) { v__ast__IndexExpr_recursive_arraymap_set_is_setter(&(*node._v__ast__IndexExpr)); } node = v__ast__InfixExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__InfixExpr, (((v__ast__InfixExpr){.op = tok.kind,.pos = pos,.is_stmt = true,.left = node,.right = right,.left_type = 0,.right_type = 0,.promoted_type = _const_v__ast__void_type,.auto_locked = (string){.str=(byteptr)"", .is_lit=1},.or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.ct_left_value_evaled = 0,.ct_left_value = _const_v__ast__empty_comptime_const_value,.left_ct_expr = 0,.ct_right_value_evaled = 0,.ct_right_value = _const_v__ast__empty_comptime_const_value,.right_ct_expr = 0,.before_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.after_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)),})))); } else if (v__token__Kind_is_infix(p->tok.kind) && !((p->tok.kind == v__token__Kind__minus || p->tok.kind == v__token__Kind__amp || p->tok.kind == v__token__Kind__mul || p->tok.kind == v__token__Kind__key_as || p->tok.kind == v__token__Kind__key_in || p->tok.kind == v__token__Kind__key_is) && p->tok.line_nr != p->prev_tok.line_nr)) { node = v__parser__Parser_infix_expr(p, node); if (p->tok.kind == v__token__Kind__key_as && p->inside_if) { return node; } } else if ((p->tok.kind == v__token__Kind__inc || p->tok.kind == v__token__Kind__dec) || (p->tok.kind == v__token__Kind__question && p->inside_ct_if_expr)) { if (p->peek_tok.kind == v__token__Kind__rpar || p->peek_tok.kind == v__token__Kind__rsbr) { if (!p->inside_ct_if_expr) { if (!p->pref->translated && !p->is_translated) { v__parser__Parser_warn_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__token__Kind_str(p->tok.kind)}}, {_S("` operator can only be used as a statement"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->tok)); } } } bool inc_dec_tok = (p->tok.kind == v__token__Kind__inc || p->tok.kind == v__token__Kind__dec); bool same_line_with_prev = p->tok.line_nr == p->prev_tok.line_nr; bool same_line_with_next = p->tok.line_nr == p->peek_tok.line_nr; bool next_tok_name = p->peek_tok.kind == v__token__Kind__name; if (inc_dec_tok && !same_line_with_prev && !next_tok_name) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__token__Token_str(p->tok)}}, {_S(" must be on the same line as the previous token"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->tok)); } bool prev_name_or_rsbr = (p->prev_tok.kind == v__token__Kind__name || p->prev_tok.kind == v__token__Kind__rsbr); if (inc_dec_tok && same_line_with_next && next_tok_name && (!prev_name_or_rsbr || !same_line_with_prev)) { v__parser__Parser_prefix_inc_dec_error(p); } if ((node)._typ == 361 /* v.ast.IndexExpr */) { v__ast__IndexExpr_recursive_mapset_is_setter(&(*node._v__ast__IndexExpr), true); } bool is_c2v_prefix = p->peek_tok.kind == v__token__Kind__dollar && v__token__Token_is_next_to(p->peek_tok, p->tok); node = v__ast__PostfixExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__PostfixExpr, (((v__ast__PostfixExpr){.op = p->tok.kind,.pos = v__token__Token_pos(&p->tok),.is_c2v_prefix = is_c2v_prefix,.expr = node,.typ = 0,.auto_locked = (string){.str=(byteptr)"", .is_lit=1},})))); if (is_c2v_prefix) { v__parser__Parser_next(p); } v__parser__Parser_next(p); } else { return node; } } return node; } VV_LOC v__ast__OrExpr v__parser__Parser_gen_or_block(v__parser__Parser* p) { if (p->tok.kind == v__token__Kind__key_orelse) { multi_return_Array_v__ast__Stmt_v__token__Pos mr_18794 = v__parser__Parser_or_block(p, v__parser__OrBlockErrVarMode__with_err_var); Array_v__ast__Stmt or_stmts = mr_18794.arg0; v__token__Pos or_pos = mr_18794.arg1; return ((v__ast__OrExpr){.kind = v__ast__OrKind__block,.pos = or_pos,.stmts = or_stmts,}); } else if (p->tok.kind == v__token__Kind__question || p->tok.kind == v__token__Kind__not) { v__token__Pos or_pos = v__token__Token_pos(&p->tok); bool is_not = p->tok.kind == v__token__Kind__not; v__parser__Parser_next(p); if (p->inside_defer) { v__parser__Parser_error_with_pos(p, _S("error propagation not allowed inside `defer` blocks"), v__token__Token_pos(&p->prev_tok)); } return ((v__ast__OrExpr){.kind = (is_not ? (v__ast__OrKind__propagate_result) : (v__ast__OrKind__propagate_option)),.pos = or_pos,.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}); } else { return ((v__ast__OrExpr){.kind = v__ast__OrKind__absent,.pos = v__token__Token_pos(&p->tok),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}); } return (v__ast__OrExpr){.kind = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}; } VV_LOC v__ast__Expr v__parser__Parser_infix_expr(v__parser__Parser* p, v__ast__Expr left) { bool v__parser__Parser_infix_expr_defer_0 = false; bool prev_inside_infix; prev_inside_infix = p->inside_infix; p->inside_infix = true; v__parser__Parser_infix_expr_defer_0 = true; v__token__Kind op = p->tok.kind; if (op == v__token__Kind__arrow) { p->or_is_handled = true; v__parser__Parser_register_auto_import(p, _S("sync")); } int precedence = v__token__Kind_precedence(p->tok.kind); v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); if (p->inside_if_cond) { _PUSH_MANY(&p->if_cond_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t1, Array_v__ast__Comment); } Array_v__ast__Comment before_op_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); if (p->pref->is_fmt && p->left_comments.len > 0) { before_op_comments = array_clone_to_depth(&p->left_comments, 0); p->left_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); } p->left_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); Array_v__ast__Comment after_op_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); v__ast__Expr right = _const_v__ast__empty_expr; bool prev_expecting_type = p->expecting_type; if (op == v__token__Kind__key_is || op == v__token__Kind__not_is) { p->expecting_type = true; } bool is_key_in = (op == v__token__Kind__key_in || op == v__token__Kind__not_in); if (is_key_in) { p->inside_in_array = true; } v__token__Pos right_op_pos = v__token__Token_pos(&p->tok); bool old_assign_rhs = p->inside_assign_rhs; if (op == v__token__Kind__decl_assign || op == v__token__Kind__assign) { p->inside_assign_rhs = true; } right = v__parser__Parser_expr(p, precedence); p->inside_assign_rhs = old_assign_rhs; if ((op == v__token__Kind__plus || op == v__token__Kind__minus || op == v__token__Kind__mul || op == v__token__Kind__div || op == v__token__Kind__mod || op == v__token__Kind__lt || op == v__token__Kind__eq) && (right)._typ == 376 /* v.ast.PrefixExpr */) { v__ast__Expr right_expr = (*right._v__ast__PrefixExpr).right; right_expr = v__ast__Expr_remove_par(&right_expr); if (((*right._v__ast__PrefixExpr).op == v__token__Kind__plus || (*right._v__ast__PrefixExpr).op == v__token__Kind__minus || (*right._v__ast__PrefixExpr).op == v__token__Kind__mul || (*right._v__ast__PrefixExpr).op == v__token__Kind__div || (*right._v__ast__PrefixExpr).op == v__token__Kind__mod || (*right._v__ast__PrefixExpr).op == v__token__Kind__lt || (*right._v__ast__PrefixExpr).op == v__token__Kind__eq) && v__ast__Expr_is_pure_literal(right_expr)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("invalid expression: unexpected token `"), 0xfe10, {.d_s = v__token__Kind_str(op)}}, {_S("`"), 0, { .d_c = 0 }}})), right_op_pos); } } if (is_key_in) { if (p->tok.kind == v__token__Kind__dotdot) { v__parser__Parser_check(p, v__token__Kind__dotdot); v__token__Pos pos_high = v__token__Token_pos(&p->tok); right = v__ast__RangeExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__RangeExpr, (((v__ast__RangeExpr){ .has_high = true, .has_low = true, .pos = pos_high, .is_gated = false, .low = right, .high = v__parser__Parser_expr(p, ((int)(v__token__Precedence__in_as))), .typ = 0, })))); } p->inside_in_array = false; } p->expecting_type = prev_expecting_type; Array_v__ast__Stmt or_stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); v__ast__OrKind or_kind = v__ast__OrKind__absent; v__token__Pos or_pos = v__token__Token_pos(&p->tok); if (op == v__token__Kind__arrow) { if (p->tok.kind == v__token__Kind__key_orelse) { or_kind = v__ast__OrKind__block; multi_return_Array_v__ast__Stmt_v__token__Pos mr_21347 = v__parser__Parser_or_block(p, v__parser__OrBlockErrVarMode__with_err_var); or_stmts = mr_21347.arg0; or_pos = mr_21347.arg1; } if (p->tok.kind == v__token__Kind__question) { v__parser__Parser_next(p); or_kind = v__ast__OrKind__propagate_option; } p->or_is_handled = false; } v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); v__ast__Expr _t2 = v__ast__InfixExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__InfixExpr, (((v__ast__InfixExpr){ .op = op, .pos = pos, .is_stmt = p->is_stmt_ident, .left = left, .right = right, .left_type = 0, .right_type = 0, .promoted_type = _const_v__ast__void_type, .auto_locked = (string){.str=(byteptr)"", .is_lit=1}, .or_block = ((v__ast__OrExpr){.kind = or_kind,.pos = or_pos,.stmts = or_stmts,}), .ct_left_value_evaled = 0, .ct_left_value = _const_v__ast__empty_comptime_const_value, .left_ct_expr = 0, .ct_right_value_evaled = 0, .ct_right_value = _const_v__ast__empty_comptime_const_value, .right_ct_expr = 0, .before_op_comments = before_op_comments, .after_op_comments = after_op_comments, })))); // Defer begin if (v__parser__Parser_infix_expr_defer_0) { p->inside_infix = prev_inside_infix; } // Defer end return _t2; } VV_LOC v__ast__Expr v__parser__Parser_prefix_expr(v__parser__Parser* p) { v__token__Pos pos = v__token__Token_pos(&p->tok); bool is_option = p->tok.kind == v__token__Kind__question; if (is_option) { v__parser__Parser_next(p); } v__token__Kind op = p->tok.kind; if (op == v__token__Kind__amp) { p->is_amp = true; } if (op == v__token__Kind__arrow) { p->or_is_handled = true; v__parser__Parser_register_auto_import(p, _S("sync")); } v__parser__Parser_next(p); v__ast__Expr right = v__parser__Parser_expr(p, ((int)(v__token__Precedence__prefix))); p->is_amp = false; if (op == v__token__Kind__amp) { if ((right)._typ == 345 /* v.ast.CastExpr */) { v__parser__Parser_recast_as_pointer(p, &/*mut*/(*right._v__ast__CastExpr), pos); if (is_option) { (*right._v__ast__CastExpr).typ = v__ast__Type_set_flag((*right._v__ast__CastExpr).typ, v__ast__TypeFlag__option); } return v__ast__CastExpr_to_sumtype_v__ast__Expr(&(*right._v__ast__CastExpr)); } if ((right)._typ == 379 /* v.ast.SelectorExpr */) { if (((*right._v__ast__SelectorExpr).expr)._typ == 345 /* v.ast.CastExpr */) { v__parser__Parser_recast_as_pointer(p, (voidptr)&(*(*right._v__ast__SelectorExpr).expr._v__ast__CastExpr), pos); return v__ast__SelectorExpr_to_sumtype_v__ast__Expr(&(*right._v__ast__SelectorExpr)); } } if ((right)._typ == 361 /* v.ast.IndexExpr */) { if (((*right._v__ast__IndexExpr).left)._typ == 345 /* v.ast.CastExpr */) { v__parser__Parser_recast_as_pointer(p, (voidptr)&(*(*right._v__ast__IndexExpr).left._v__ast__CastExpr), pos); return v__ast__IndexExpr_to_sumtype_v__ast__Expr(&(*right._v__ast__IndexExpr)); } } if ((right)._typ == 374 /* v.ast.ParExpr */) { if (((*right._v__ast__ParExpr).expr)._typ == 385 /* v.ast.StructInit */) { v__parser__Parser_note_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("unnecessary `()`, use `&"), 0xfe10, {.d_s = v__ast__Expr_str(&(*right._v__ast__ParExpr).expr)}}, {_S("` instead of `&("), 0xfe10, {.d_s = v__ast__Expr_str(&(*right._v__ast__ParExpr).expr)}}, {_S(")`"), 0, { .d_c = 0 }}})), (*right._v__ast__ParExpr).pos); right = (*right._v__ast__ParExpr).expr; } } if ((right)._typ == 386 /* v.ast.TypeNode */) { (*right._v__ast__TypeNode).typ = v__ast__Type_ref((*right._v__ast__TypeNode).typ); return v__ast__TypeNode_to_sumtype_v__ast__Expr(&(*right._v__ast__TypeNode)); } } Array_v__ast__Stmt or_stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); v__ast__OrKind or_kind = v__ast__OrKind__absent; v__token__Pos or_pos = v__token__Token_pos(&p->tok); if (op == v__token__Kind__arrow) { if ((right)._typ == 379 /* v.ast.SelectorExpr */) { or_kind = (*right._v__ast__SelectorExpr).or_block.kind; or_stmts = array_clone_to_depth(&(*right._v__ast__SelectorExpr).or_block.stmts, 0); (*right._v__ast__SelectorExpr).or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}); } else if (p->tok.kind == v__token__Kind__key_orelse) { or_kind = v__ast__OrKind__block; multi_return_Array_v__ast__Stmt_v__token__Pos mr_23626 = v__parser__Parser_or_block(p, v__parser__OrBlockErrVarMode__with_err_var); or_stmts = mr_23626.arg0; or_pos = mr_23626.arg1; } else if (p->tok.kind == v__token__Kind__question) { v__parser__Parser_next(p); or_kind = v__ast__OrKind__propagate_option; } p->or_is_handled = false; } v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); return v__ast__PrefixExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__PrefixExpr, (((v__ast__PrefixExpr){.op = op,.pos = pos,.right_type = 0,.right = right,.or_block = ((v__ast__OrExpr){.kind = or_kind,.pos = or_pos,.stmts = or_stmts,}),.is_option = 0,})))); } VV_LOC void v__parser__Parser_recast_as_pointer(v__parser__Parser* p, v__ast__CastExpr* cast_expr, v__token__Pos pos) { cast_expr->typ = v__ast__Type_ref(cast_expr->typ); cast_expr->typname = (cast_expr->typ == 0 ? (v__ast__Table_sym(p->table, cast_expr->typ)->name) : (_S("unknown type name"))); cast_expr->pos = v__token__Pos_extend(pos, cast_expr->pos); } VV_LOC void v__parser__Parser_prefix_inc_dec_error(v__parser__Parser* p) { string op = (p->tok.kind == v__token__Kind__inc ? (_S("++")) : (_S("--"))); v__token__Pos op_pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); v__ast__Expr expr = v__parser__Parser_expr(p, 0); v__token__Pos full_expr_pos = v__token__Pos_extend(op_pos, v__ast__Expr_pos(expr)); v__parser__Parser_error_with_pos(p, str_intp(5, _MOV((StrIntpData[]){{_S("prefix `"), 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&expr)}}, {_S("` is unsupported, use suffix form `"), 0xfe10, {.d_s = v__ast__Expr_str(&expr)}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_S("`"), 0, { .d_c = 0 }}})), full_expr_pos); } inline VV_LOC void v__parser__Parser_process_custom_orm_operators(v__parser__Parser* p) { if (!p->inside_orm) { return; } bool is_like_operator = p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("like")); bool is_ilike_operator = p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("ilike")); if (is_like_operator) { p->tok = ((v__token__Token){.kind = v__token__Kind__key_like,.lit = (p->tok).lit,.line_nr = (p->tok).line_nr,.col = (p->tok).col,.pos = (p->tok).pos,.len = (p->tok).len,.tidx = (p->tok).tidx,}); } else if (is_ilike_operator) { p->tok = ((v__token__Token){.kind = v__token__Kind__key_ilike,.lit = (p->tok).lit,.line_nr = (p->tok).line_nr,.col = (p->tok).col,.pos = (p->tok).pos,.len = (p->tok).len,.tidx = (p->tok).tidx,}); } } VV_LOC _option_v__ast__LambdaExpr v__parser__Parser_lambda_expr(v__parser__Parser* p) { bool v__parser__Parser_lambda_expr_defer_0 = false; if (!(p->tok.kind == v__token__Kind__logical_or || (v__parser__Parser_peek_token(p, 1).kind == v__token__Kind__name && v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__pipe) || (v__parser__Parser_peek_token(p, 1).kind == v__token__Kind__name && v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__comma))) { return (_option_v__ast__LambdaExpr){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } v__parser__Parser_open_scope(p); v__parser__Parser_lambda_expr_defer_0 = true; p->scope->detached_from_parent = true; v__token__Pos pos = v__token__Token_pos(&p->tok); Array_v__ast__Ident params = __new_array_with_default(0, 0, sizeof(v__ast__Ident), 0); if (p->tok.kind == v__token__Kind__logical_or) { v__parser__Parser_check(p, v__token__Kind__logical_or); } else { v__parser__Parser_check(p, v__token__Kind__pipe); for (;;) { if (p->tok.kind == v__token__Kind__eof) { break; } v__ast__Ident ident = v__parser__Parser_ident(p, v__ast__Language__v); if (v__ast__Scope_known_var(p->scope, ident.name)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("redefinition of parameter `"), 0xfe10, {.d_s = ident.name}}, {_S("`"), 0, { .d_c = 0 }}})), ident.pos); } array_push((array*)¶ms, _MOV((v__ast__Ident[]){ ident })); v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){ .name = ident.name, .share = 0, .is_mut = ident.is_mut, .is_static = 0, .is_volatile = 0, .is_autofree_tmp = 0, .is_inherited = 0, .has_inherited = 0, .is_arg = true, .is_auto_deref = 0, .is_unwrapped = 0, .is_index_var = 0, .expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .typ = 0, .orig_type = 0, .smartcasts = __new_array(0, 0, sizeof(v__ast__Type)), .pos = ident.pos, .is_used = true, .is_changed = 0, .ct_type_var = 0, .ct_type_unwrapped = 0, .is_or = 0, .is_tmp = 0, .is_auto_heap = 0, .is_stack_obj = true, }))))); if (p->tok.kind == v__token__Kind__pipe) { v__parser__Parser_next(p); break; } v__parser__Parser_check(p, v__token__Kind__comma); } } v__token__Pos pos_expr = v__token__Token_pos(&p->tok); v__ast__Expr e = v__parser__Parser_expr(p, 0); v__token__Pos pos_end = v__token__Token_pos(&p->tok); _option_v__ast__LambdaExpr _t3; _option_ok(&(v__ast__LambdaExpr[]) { ((v__ast__LambdaExpr){ .pos = v__token__Pos_extend(pos, v__ast__Expr_pos(e)), .params = params, .pos_expr = pos_expr, .expr = e, .pos_end = pos_end, .scope = p->scope, .func = ((void*)0), .is_checked = 0, .typ = 0, .call_ctx = ((void*)0), }) }, (_option*)(&_t3), sizeof(v__ast__LambdaExpr)); // Defer begin if (v__parser__Parser_lambda_expr_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t3; } VV_LOC v__ast__CallExpr v__parser__Parser_call_expr(v__parser__Parser* p, v__ast__Language language, string mod) { bool v__parser__Parser_call_expr_defer_0 = false; string old_expr_mod; v__token__Pos first_pos = v__token__Token_pos(&p->tok); string name = (language == v__ast__Language__js ? (v__parser__Parser_check_js_name(p)) : (v__parser__Parser_check_name(p))); bool is_static_type_method = language == v__ast__Language__v && (name).len != 0 && u8_is_capital(string_at(name, 0)) && p->tok.kind == v__token__Kind__dot; if (is_static_type_method) { v__parser__Parser_check(p, v__token__Kind__dot); name = string__plus(string__plus(name, _S("__static__")), v__parser__Parser_check_name(p)); } string fn_name = (language == v__ast__Language__c ? (str_intp(2, _MOV((StrIntpData[]){{_S("C."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : language == v__ast__Language__js ? (str_intp(2, _MOV((StrIntpData[]){{_S("JS."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : language == v__ast__Language__wasm ? (str_intp(2, _MOV((StrIntpData[]){{_S("WASM."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (mod).len != 0 ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mod}}, {_S("."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (name)); if (language != v__ast__Language__v) { v__parser__Parser_check_for_impure_v(p, language, first_pos); } v__ast__OrKind or_kind = v__ast__OrKind__absent; if (_SLIT_EQ(fn_name.str, fn_name.len, "json.decode") || _SLIT_EQ(fn_name.str, fn_name.len, "C.va_arg")) { p->expecting_type = true; } old_expr_mod = p->expr_mod; v__parser__Parser_call_expr_defer_0 = true; p->expr_mod = _S(""); Array_v__ast__Type concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); v__token__Pos concrete_list_pos = v__token__Token_pos(&p->tok); if (p->tok.kind == v__token__Kind__lt || p->tok.kind == v__token__Kind__lsbr) { p->expr_mod = _S(""); concrete_types = v__parser__Parser_parse_concrete_types(p); concrete_list_pos = v__token__Pos_extend(concrete_list_pos, v__token__Token_pos(&p->prev_tok)); } v__parser__Parser_check(p, v__token__Kind__lpar); Array_v__ast__CallArg args = v__parser__Parser_call_args(p); if (p->tok.kind != v__token__Kind__rpar) { v__ast__Fn* _t2 = (v__ast__Fn*)(map_get_check(ADDR(map, p->table->fns), &(string[]){fn_name})); _option_v__ast__Fn _t1 = {0}; if (_t2) { *((v__ast__Fn*)&_t1.data) = *((v__ast__Fn*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } ; if (_t1.state != 0) { IError err = _t1.err; *(v__ast__Fn*) _t1.data = (*(v__ast__Fn*)map_get(ADDR(map, p->table->fns), &(string[]){str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = p->mod}}, {_S("."), 0xfe10, {.d_s = fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })); } Array_v__ast__Param params = (*(v__ast__Fn*)_t1.data).params; if (args.len < params.len && p->prev_tok.kind != v__token__Kind__comma) { v__token__Pos pos = (p->tok.kind == v__token__Kind__eof ? (v__token__Token_pos(&p->prev_tok)) : (v__token__Token_pos(&p->tok))); v__parser__Parser_unexpected_with_pos(p, pos, ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = _S("`,`"),.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); } else if (args.len > params.len) { v__ast__CallArg* _t4 = (v__ast__CallArg*)(array_get_with_check(args, (int)(params.len - 1))); _option_v__ast__CallArg _t3 = {0}; if (_t4) { *((v__ast__CallArg*)&_t3.data) = *((v__ast__CallArg*)_t4); } else { _t3.state = 2; _t3.err = _v_error(_S("array index out of range")); } ; if (_t3.state != 0) { IError err = _t3.err; *(v__ast__CallArg*) _t3.data = (*(v__ast__CallArg*)array_get(args, 0)); } v__token__Pos ok_arg_pos = ((*(v__ast__CallArg*)_t3.data)).pos; v__token__Pos pos = ((v__token__Pos){.len = (ok_arg_pos).len,.line_nr = (ok_arg_pos).line_nr,.pos = (ok_arg_pos).pos,.col = (int)(ok_arg_pos.col + ok_arg_pos.len),.last_line = (ok_arg_pos).last_line,}); v__parser__Parser_unexpected_with_pos(p, v__token__Pos_extend(pos, v__token__Token_pos(&p->tok)), ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = _S("`)`"),.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); } else { v__token__Pos pos = (p->tok.kind == v__token__Kind__eof ? (v__token__Token_pos(&p->prev_tok)) : (v__token__Token_pos(&p->tok))); v__parser__Parser_unexpected_with_pos(p, pos, ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = _S("`)`"),.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); } } v__token__Pos last_pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); v__token__Pos pos = v__token__Pos_extend(first_pos, last_pos); Array_v__ast__Stmt or_stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); v__token__Pos or_pos = v__token__Token_pos(&p->tok); if (p->tok.kind == v__token__Kind__key_orelse) { or_kind = v__ast__OrKind__block; multi_return_Array_v__ast__Stmt_v__token__Pos mr_2435 = v__parser__Parser_or_block(p, v__parser__OrBlockErrVarMode__with_err_var); or_stmts = mr_2435.arg0; or_pos = mr_2435.arg1; } if (p->tok.kind == v__token__Kind__question || p->tok.kind == v__token__Kind__not) { bool is_not = p->tok.kind == v__token__Kind__not; v__parser__Parser_next(p); if (p->inside_defer) { v__parser__Parser_error_with_pos(p, _S("error propagation not allowed inside `defer` blocks"), v__token__Token_pos(&p->prev_tok)); } or_kind = (is_not ? (v__ast__OrKind__propagate_result) : (v__ast__OrKind__propagate_option)); } if (_IN_MAP(ADDR(string, fn_name), ADDR(map, p->imported_symbols))) { fn_name = (*(string*)map_get(ADDR(map, p->imported_symbols), &(string[]){fn_name}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })); v__parser__Parser_register_used_import_for_symbol_name(p, fn_name); } Array_v__ast__Comment comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); v__ast__CallExpr _t5 = ((v__ast__CallExpr){ .pos = pos, .name_pos = first_pos, .mod = p->mod, .name = fn_name, .is_method = 0, .is_field = 0, .is_fn_var = 0, .is_fn_a_const = 0, .is_keep_alive = 0, .is_noreturn = 0, .is_ctor_new = 0, .is_file_translated = 0, .is_static_method = is_static_type_method, .args = args, .expected_arg_types = __new_array(0, 0, sizeof(v__ast__Type)), .comptime_ret_val = 0, .language = language, .or_block = ((v__ast__OrExpr){.kind = or_kind,.pos = or_pos,.stmts = or_stmts,}), .left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .left_type = 0, .receiver_type = 0, .receiver_concrete_type = 0, .return_type = 0, .return_type_generic = 0, .nr_ret_values = -1, .fn_var_type = 0, .const_name = (string){.str=(byteptr)"", .is_lit=1}, .should_be_skipped = 0, .concrete_types = concrete_types, .concrete_list_pos = concrete_list_pos, .raw_concrete_types = concrete_types, .free_receiver = 0, .scope = p->scope, .from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)), .comments = comments, .is_return_used = p->expecting_value, .is_expand_simple_interpolation = 0, .is_unwrapped_fn_selector = 0, }); // Defer begin if (v__parser__Parser_call_expr_defer_0) { p->expr_mod = old_expr_mod; } // Defer end return _t5; } VV_LOC Array_v__ast__CallArg v__parser__Parser_call_args(v__parser__Parser* p) { bool v__parser__Parser_call_args_defer_0 = false; bool prev_inside_call_args; prev_inside_call_args = p->inside_call_args; p->inside_call_args = true; v__parser__Parser_call_args_defer_0 = true; Array_v__ast__CallArg args = __new_array_with_default(0, 0, sizeof(v__ast__CallArg), 0); for (;;) { if (!(p->tok.kind != v__token__Kind__rpar)) break; if (p->tok.kind == v__token__Kind__eof) { Array_v__ast__CallArg _t1 = args; // Defer begin if (v__parser__Parser_call_args_defer_0) { p->inside_call_args = prev_inside_call_args; } // Defer end return _t1; } bool is_shared = p->tok.kind == v__token__Kind__key_shared; bool is_atomic = p->tok.kind == v__token__Kind__key_atomic; bool is_mut = p->tok.kind == v__token__Kind__key_mut || is_shared || is_atomic; if (is_mut) { v__parser__Parser_next(p); } Array_v__ast__Comment comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); v__token__Pos arg_start_pos = v__token__Token_pos(&p->tok); bool array_decompose = false; if (p->tok.kind == v__token__Kind__ellipsis) { v__parser__Parser_next(p); array_decompose = true; } v__ast__Expr expr = _const_v__ast__empty_expr; if (p->peek_tok.kind == v__token__Kind__colon) { expr = v__ast__StructInit_to_sumtype_v__ast__Expr(ADDR(v__ast__StructInit, (v__parser__Parser_struct_init(p, _S("void_type"), v__ast__StructInitKind__short_syntax, false)))); } else { expr = v__parser__Parser_expr(p, 0); } if (array_decompose) { expr = v__ast__ArrayDecompose_to_sumtype_v__ast__Expr(ADDR(v__ast__ArrayDecompose, (((v__ast__ArrayDecompose){.pos = v__token__Token_pos(&p->tok),.expr = expr,.expr_type = 0,.arg_type = 0,})))); } if ((expr)._typ == 385 /* v.ast.StructInit */) { _PUSH_MANY(&(*expr._v__ast__StructInit).pre_comments, (comments), _t2, Array_v__ast__Comment); comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); } v__token__Pos pos = v__token__Pos_extend(arg_start_pos, v__token__Token_pos(&p->prev_tok)); _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t3, Array_v__ast__Comment); array_push((array*)&args, _MOV((v__ast__CallArg[]){ ((v__ast__CallArg){.is_mut = is_mut,.share = v__ast__sharetype_from_flags(is_shared, is_atomic),.comments = comments,.expr = expr,.typ = 0,.is_tmp_autofree = 0,.pos = pos,.should_be_ptr = 0,.ct_expr = 0,}) })); if (p->tok.kind != v__token__Kind__comma) { break; } v__parser__Parser_next(p); } Array_v__ast__CallArg _t5 = args; // Defer begin if (v__parser__Parser_call_args_defer_0) { p->inside_call_args = prev_inside_call_args; } // Defer end return _t5; } VV_LOC v__ast__FnDecl v__parser__Parser_fn_decl(v__parser__Parser* p) { bool v__parser__Parser_fn_decl_defer_0 = false; v__parser__Parser_top_level_statement_start(p); v__token__Pos start_pos = v__token__Token_pos(&p->tok); bool is_manualfree = p->is_manualfree; bool is_deprecated = false; bool is_direct_arr = false; bool is_keep_alive = false; bool is_exported = false; bool is_unsafe = false; bool is_must_use = false; bool is_trusted = false; bool is_noreturn = false; bool is_ctor_new = false; bool is_c2v_variadic = false; bool is_c_extern = false; bool is_markused = false; bool is_expand_simple_interpolation = false; Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); Array_v__ast__Attr fn_attrs = p->attrs; p->attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); for (int _t1 = 0; _t1 < fn_attrs.len; ++_t1) { v__ast__Attr fna = ((v__ast__Attr*)fn_attrs.data)[_t1]; if (_SLIT_EQ(fna.name.str, fna.name.len, "noreturn")) { is_noreturn = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "manualfree")) { is_manualfree = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "deprecated")) { is_deprecated = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "direct_array_access")) { if (!p->pref->force_bounds_checking) { is_direct_arr = true; } } else if (_SLIT_EQ(fna.name.str, fna.name.len, "keep_args_alive")) { is_keep_alive = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "export")) { is_exported = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "wasm_export")) { is_exported = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "unsafe")) { is_unsafe = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "must_use")) { is_must_use = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "trusted")) { is_trusted = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "c2v_variadic")) { is_c2v_variadic = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "use_new")) { is_ctor_new = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "markused")) { is_markused = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "c_extern")) { is_c_extern = true; } else if (_SLIT_EQ(fna.name.str, fna.name.len, "windows_stdcall")) { v__parser__Parser_note_with_pos(p, _S("the tag [windows_stdcall] has been deprecated, it will be an error after 2022-06-01, use `[callconv: stdcall]` instead"), v__token__Token_pos(&p->tok)); } else if (_SLIT_EQ(fna.name.str, fna.name.len, "_fastcall")) { v__parser__Parser_note_with_pos(p, _S("the tag [_fastcall] has been deprecated, it will be an error after 2022-06-01, use `[callconv: fastcall]` instead"), v__token__Token_pos(&p->tok)); } else if (_SLIT_EQ(fna.name.str, fna.name.len, "callconv")) { if (!fna.has_arg) { v__parser__Parser_error_with_pos(p, _S("callconv attribute is present but its value is missing"), v__token__Token_pos(&p->prev_tok)); } if (!(fast_string_eq(fna.arg, _S("stdcall")) || fast_string_eq(fna.arg, _S("fastcall")) || fast_string_eq(fna.arg, _S("cdecl")))) { v__parser__Parser_error_with_pos(p, _S("unsupported calling convention, supported are stdcall, fastcall and cdecl"), v__token__Token_pos(&p->prev_tok)); } } else if (_SLIT_EQ(fna.name.str, fna.name.len, "expand_simple_interpolation")) { is_expand_simple_interpolation = true; } else { } } _option_int _t2 = Array_v__ast__Attr_find_comptime_define(fn_attrs); if (_t2.state != 0) { IError err = _t2.err; *(int*) _t2.data = -1; } int conditional_ctdefine_idx = (*(int*)_t2.data); bool is_pub = p->tok.kind == v__token__Kind__key_pub; if (is_pub) { v__parser__Parser_next(p); } v__parser__Parser_check(p, v__token__Kind__key_fn); _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t3, Array_v__ast__Comment); v__parser__Parser_open_scope(p); v__parser__Parser_fn_decl_defer_0 = true; v__token__Pos language_tok_pos = v__token__Token_pos(&p->tok); v__ast__Language language = v__parser__Parser_parse_language(p); p->fn_language = language; if (language != v__ast__Language__v) { for (int _t4 = 0; _t4 < fn_attrs.len; ++_t4) { v__ast__Attr fna = ((v__ast__Attr*)fn_attrs.data)[_t4]; if (fast_string_eq(fna.name, _S("export"))) { v__parser__Parser_error_with_pos(p, _S("interop function cannot be exported"), fna.pos); break; } } } if (is_keep_alive && language != v__ast__Language__c) { v__parser__Parser_error_with_pos(p, _S("attribute [keep_args_alive] is only supported for C functions"), language_tok_pos); } if (language != v__ast__Language__v) { v__parser__Parser_check_for_impure_v(p, language, language_tok_pos); if (language == v__ast__Language__c) { is_unsafe = !is_trusted; } } v__parser__ReceiverParsingInfo rec = ((v__parser__ReceiverParsingInfo){.name = (string){.str=(byteptr)"", .is_lit=1},.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = _const_v__ast__void_type,.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_mut = 0,.language = language,}); bool is_method = false; bool is_static_type_method = false; Array_v__ast__Param params = __new_array_with_default(0, 0, sizeof(v__ast__Param), 0); if (p->tok.kind == v__token__Kind__lpar) { is_method = true; _result_void _t5 = v__parser__Parser_fn_receiver(p, ¶ms, (voidptr)&rec); if (_t5.is_error) { IError err = _t5.err; v__ast__FnDecl _t6 = ((v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_method = 0,.is_static_type_method = 0,.static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_expand_simple_interpolation = 0,}); // Defer begin if (v__parser__Parser_fn_decl_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t6; } ; language = rec.language; p->fn_language = language; } string name = _S(""); v__ast__TypeSymbol* type_sym = v__ast__Table_sym(p->table, rec.typ); v__token__Pos name_pos = v__token__Token_pos(&p->tok); v__token__Pos static_type_pos = v__token__Token_pos(&p->tok); if (p->tok.kind == v__token__Kind__name || v__parser__is_ident_name(p->tok.lit)) { string check_name = _S(""); is_static_type_method = p->tok.lit.len > 0 && u8_is_capital(string_at(p->tok.lit, 0)) && p->peek_tok.kind == v__token__Kind__dot && language == v__ast__Language__v; if (is_static_type_method) { string type_name = p->tok.lit; static_type_pos = v__token__Token_pos(&p->tok); rec.typ = v__parser__Parser_parse_type(p); v__parser__Parser_check(p, v__token__Kind__dot); check_name = v__parser__Parser_check_name(p); name = string__plus(string__plus(type_name, _S("__static__")), check_name); name_pos = v__token__Pos_extend(name_pos, v__token__Token_pos(&p->prev_tok)); } else { check_name = (language == v__ast__Language__js ? (v__parser__Parser_check_js_name(p)) : (v__parser__Parser_check_name(p))); name = check_name; } if (language == v__ast__Language__v && !p->pref->translated && !p->is_translated && v__util__contains_capital(check_name) && !p->builtin_mod) { v__parser__Parser_error_with_pos(p, _S("function names cannot contain uppercase letters, use snake_case instead"), name_pos); v__ast__FnDecl _t7 = ((v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_method = 0,.is_static_type_method = 0,.static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_expand_simple_interpolation = 0,}); // Defer begin if (v__parser__Parser_fn_decl_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t7; } if (is_method) { bool is_duplicate = v__ast__TypeSymbol_has_method(type_sym, name); if (type_sym->kind == v__ast__Kind__interface && is_duplicate) { if ((type_sym->info)._typ == 542 /* v.ast.Interface */) { is_duplicate = !v__ast__Interface_has_method(&(*type_sym->info._v__ast__Interface), name); } } if (is_duplicate) { if (type_sym->kind == v__ast__Kind__enum && (_SLIT_EQ(name.str, name.len, "is_empty") || _SLIT_EQ(name.str, name.len, "has") || _SLIT_EQ(name.str, name.len, "all") || _SLIT_EQ(name.str, name.len, "set") || _SLIT_EQ(name.str, name.len, "set_all") || _SLIT_EQ(name.str, name.len, "clear") || _SLIT_EQ(name.str, name.len, "clear_all") || _SLIT_EQ(name.str, name.len, "toggle") || _SLIT_EQ(name.str, name.len, "zero") || _SLIT_EQ(name.str, name.len, "from"))) { _option_v__ast__Fn _t8; if (_t8 = v__ast__TypeSymbol_find_method(type_sym, name), _t8.state == 0) { v__ast__Fn enum_fn = *(v__ast__Fn*)_t8.data; name_pos = enum_fn.name_pos; } v__parser__Parser_error_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("duplicate method `"), 0xfe10, {.d_s = name}}, {_S("`, `"), 0xfe10, {.d_s = name}}, {_S("` is an enum type built-in method"), 0, { .d_c = 0 }}})), name_pos); } else { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate method `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}})), name_pos); } v__ast__FnDecl _t9 = ((v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_method = 0,.is_static_type_method = 0,.static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_expand_simple_interpolation = 0,}); // Defer begin if (v__parser__Parser_fn_decl_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t9; } } if (!p->pref->is_fmt) { if (_IN_MAP(ADDR(string, name), ADDR(map, p->imported_symbols))) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot redefine imported function `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}})), name_pos); v__ast__FnDecl _t10 = ((v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_method = 0,.is_static_type_method = 0,.static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_expand_simple_interpolation = 0,}); // Defer begin if (v__parser__Parser_fn_decl_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t10; } } } else if ((p->tok.kind == v__token__Kind__plus || p->tok.kind == v__token__Kind__minus || p->tok.kind == v__token__Kind__mul || p->tok.kind == v__token__Kind__div || p->tok.kind == v__token__Kind__mod || p->tok.kind == v__token__Kind__lt || p->tok.kind == v__token__Kind__eq) && p->peek_tok.kind == v__token__Kind__lpar) { name = v__token__Kind_str(p->tok.kind); if (rec.typ == _const_v__ast__void_type) { v__parser__Parser_error_with_pos(p, _S("cannot use operator overloading with normal functions"), v__token__Token_pos(&p->tok)); } if (v__ast__TypeSymbol_has_method(type_sym, name)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot duplicate operator overload `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->tok)); } v__parser__Parser_next(p); } else if ((p->tok.kind == v__token__Kind__ne || p->tok.kind == v__token__Kind__gt || p->tok.kind == v__token__Kind__ge || p->tok.kind == v__token__Kind__le) && p->peek_tok.kind == v__token__Kind__lpar) { v__parser__Parser_error_with_pos(p, _S("cannot overload `!=`, `>`, `<=` and `>=` as they are auto generated from `==` and`<`"), v__token__Token_pos(&p->tok)); } else if (p->tok.kind == v__token__Kind__plus_assign || p->tok.kind == v__token__Kind__minus_assign || p->tok.kind == v__token__Kind__div_assign || p->tok.kind == v__token__Kind__mult_assign || p->tok.kind == v__token__Kind__mod_assign) { string _t11 = (string){.str=(byteptr)"", .is_lit=1}; switch (p->tok.kind) { case v__token__Kind__plus_assign: { _t11 = _S("+"); break; } case v__token__Kind__minus_assign: { _t11 = _S("-"); break; } case v__token__Kind__div_assign: { _t11 = _S("/"); break; } case v__token__Kind__mod_assign: { _t11 = _S("%"); break; } case v__token__Kind__mult_assign: { _t11 = _S("*"); break; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__plus: case v__token__Kind__minus: case v__token__Kind__mul: case v__token__Kind__div: case v__token__Kind__mod: case v__token__Kind__xor: case v__token__Kind__pipe: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__and: case v__token__Kind__logical_or: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__amp: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__left_shift: case v__token__Kind__right_shift: case v__token__Kind__unsigned_right_shift: case v__token__Kind__not_in: case v__token__Kind__not_is: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__xor_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__eq: case v__token__Kind__ne: case v__token__Kind__gt: case v__token__Kind__lt: case v__token__Kind__ge: case v__token__Kind__le: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_in: case v__token__Kind__key_interface: case v__token__Kind__key_is: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { _t11 = _S("unknown op"); break; } } } string extracted_op = _t11; if (v__ast__TypeSymbol_has_method(type_sym, extracted_op)) { v__parser__Parser_error(p, str_intp(3, _MOV((StrIntpData[]){{_S("cannot overload `"), 0xfe10, {.d_s = v__token__Kind_str(p->tok.kind)}}, {_S("`, operator is implicitly overloaded because the `"), 0xfe10, {.d_s = extracted_op}}, {_S("` operator is overloaded"), 0, { .d_c = 0 }}}))); } v__parser__Parser_error(p, str_intp(4, _MOV((StrIntpData[]){{_S("cannot overload `"), 0xfe10, {.d_s = v__token__Kind_str(p->tok.kind)}}, {_S("`, overload `"), 0xfe10, {.d_s = extracted_op}}, {_S("` and `"), 0xfe10, {.d_s = v__token__Kind_str(p->tok.kind)}}, {_S("` will be automatically generated"), 0, { .d_c = 0 }}}))); } else { v__parser__Parser_error_with_pos(p, _S("expecting method name"), v__token__Token_pos(&p->tok)); v__ast__FnDecl _t12 = ((v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_method = 0,.is_static_type_method = 0,.static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_expand_simple_interpolation = 0,}); // Defer begin if (v__parser__Parser_fn_decl_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t12; } multi_return_Array_v__ast__Type_Array_string mr_11817 = v__parser__Parser_parse_generic_types(p); Array_string generic_names = mr_11817.arg1; if (is_method && v__ast__Type_has_flag(rec.typ, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* sym = v__ast__Table_sym(p->table, rec.typ); if ((sym->info)._typ == 518 /* v.ast.Struct */) { _result_Array_string _t13 = v__parser__Parser_types_to_names(p, (*sym->info._v__ast__Struct).generic_types, v__token__Token_pos(&p->tok), _S("sym.info.generic_types")); if (_t13.is_error) { IError err = _t13.err; v__ast__FnDecl _t14 = ((v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_method = 0,.is_static_type_method = 0,.static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_expand_simple_interpolation = 0,}); // Defer begin if (v__parser__Parser_fn_decl_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t14; } Array_string decl_generic_names = (*(Array_string*)_t13.data); Array_string fn_generic_names = array_clone_to_depth(&generic_names, 0); generic_names = v__ast__Table_generic_type_names(p->table, rec.typ); if (decl_generic_names.len != generic_names.len) { string plural = (decl_generic_names.len == 1 ? (_S("")) : (_S("s"))); v__parser__Parser_error_with_pos(p, str_intp(4, _MOV((StrIntpData[]){{_S("expected "), 0xfe07, {.d_i32 = decl_generic_names.len}}, {_S(" generic parameter"), 0xfe10, {.d_s = plural}}, {_S(", got "), 0xfe07, {.d_i32 = generic_names.len}}, {_SLIT0, 0, { .d_c = 0 }}})), rec.type_pos); } for (int _t15 = 0; _t15 < fn_generic_names.len; ++_t15) { string gname = ((string*)fn_generic_names.data)[_t15]; if (!(Array_string_contains(generic_names, gname))) { array_push((array*)&generic_names, _MOV((string[]){ string_clone(gname) })); } } } } multi_return_Array_v__ast__Param_bool_bool_bool mr_12723 = v__parser__Parser_fn_params(p); Array_v__ast__Param params_t = mr_12723.arg0; bool are_params_type_only = mr_12723.arg1; bool is_variadic = mr_12723.arg2; bool is_c_variadic = mr_12723.arg3; if (is_c2v_variadic) { is_variadic = true; } _PUSH_MANY(¶ms, (params_t), _t17, Array_v__ast__Param); v__token__Pos return_type_pos = v__token__Token_pos(&p->tok); v__ast__Type return_type = _const_v__ast__void_type; bool same_line = p->tok.line_nr == p->prev_tok.line_nr; if ((v__token__Kind_is_start_of_type(p->tok.kind) && (same_line || p->tok.kind != v__token__Kind__lsbr)) || (same_line && p->tok.kind == v__token__Kind__key_fn)) { p->inside_fn_return = true; return_type = v__parser__Parser_parse_type(p); p->inside_fn_return = false; return_type_pos = v__token__Pos_extend(return_type_pos, v__token__Token_pos(&p->prev_tok)); if (p->tok.kind == v__token__Kind__question || p->tok.kind == v__token__Kind__not) { v__ast__TypeSymbol* ret_type_sym = v__ast__Table_sym(p->table, return_type); v__parser__Parser_error_with_pos(p, str_intp(5, _MOV((StrIntpData[]){{_S("wrong syntax, it must be "), 0xfe10, {.d_s = v__token__Kind_str(p->tok.kind)}}, {_SLIT0, 0xfe10, {.d_s = ret_type_sym->name}}, {_S(", not "), 0xfe10, {.d_s = ret_type_sym->name}}, {_SLIT0, 0xfe10, {.d_s = v__token__Kind_str(p->tok.kind)}}, {_SLIT0, 0, { .d_c = 0 }}})), return_type_pos); } } if (p->tok.kind == v__token__Kind__comma) { v__token__Pos mr_pos = v__token__Pos_extend(return_type_pos, v__token__Token_pos(&p->peek_tok)); v__parser__Parser_error_with_pos(p, _S("multiple return types in function declaration must use parentheses, e.g. (int, string)"), mr_pos); } int type_sym_method_idx = 0; bool no_body = p->tok.kind != v__token__Kind__lcbr; v__token__Pos end_pos = v__token__Token_pos(&p->prev_tok); string short_fn_name = name; bool is_main = _SLIT_EQ(short_fn_name.str, short_fn_name.len, "main") && fast_string_eq(p->mod, _S("main")); if (is_main) { p->main_already_defined = true; } bool is_test = (!is_method && params.len == 0) && p->inside_test_file && (string_starts_with(short_fn_name, _S("test_")) || string_starts_with(short_fn_name, _S("testsuite_"))); v__ast__Language file_mode = p->file_backend_mode; if (is_main) { _option_v__ast__Fn _t18; if (_t18 = v__ast__Table_find_fn(p->table, _S("main.main")), _t18.state == 0) { if ((Array_string_contains(_const_os__args, _S(".")))) { v__parser__Parser_error_with_pos(p, _S("multiple `main` functions detected, and you ran `v .`\nperhaps there are multiple V programs in this directory, and you need to\nrun them via `v file.v` instead"), name_pos); } } } if (is_method && is_static_type_method) { v__parser__Parser_error_with_pos(p, _S("cannot declare a static function as a receiver method"), name_pos); } if (!are_params_type_only) { for (int k = 0; k < params.len; ++k) { v__ast__Param param = ((v__ast__Param*)params.data)[k]; if (v__ast__Scope_known_var(p->scope, param.name)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("redefinition of parameter `"), 0xfe10, {.d_s = param.name}}, {_S("`"), 0, { .d_c = 0 }}})), param.pos); v__ast__FnDecl _t19 = ((v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_method = 0,.is_static_type_method = 0,.static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_expand_simple_interpolation = 0,}); // Defer begin if (v__parser__Parser_fn_decl_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t19; } bool is_stack_obj = !v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__shared_f) && (param.is_mut || v__ast__Type_is_ptr(param.typ)); v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){ .name = param.name, .share = 0, .is_mut = param.is_mut, .is_static = 0, .is_volatile = 0, .is_autofree_tmp = 0, .is_inherited = 0, .has_inherited = 0, .is_arg = true, .is_auto_deref = param.is_mut, .is_unwrapped = 0, .is_index_var = 0, .expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .typ = param.typ, .orig_type = 0, .smartcasts = __new_array(0, 0, sizeof(v__ast__Type)), .pos = param.pos, .is_used = is_pub || no_body || (is_method && k == 0) || p->builtin_mod, .is_changed = 0, .ct_type_var = ((!is_method || k >= 0) && v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic) && !v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__variadic) ? (v__ast__ComptimeVarKind__generic_param) : (v__ast__ComptimeVarKind__no_comptime)), .ct_type_unwrapped = 0, .is_or = 0, .is_tmp = 0, .is_auto_heap = 0, .is_stack_obj = is_stack_obj, }))))); } } if (is_method) { bool is_non_local = type_sym->mod.len > 0 && !string__eq(type_sym->mod, p->mod) && type_sym->language == v__ast__Language__v; if (!is_non_local && !(p->builtin_mod && p->pref->is_fmt) && (type_sym->kind == v__ast__Kind__array || type_sym->kind == v__ast__Kind__map)) { v__ast__TypeSymbol* elem_type_sym = v__ast__Table_sym(p->table, v__ast__Table_value_type(p->table, rec.typ)); is_non_local = elem_type_sym->mod.len > 0 && !string__eq(elem_type_sym->mod, p->mod) && elem_type_sym->language == v__ast__Language__v; } if (is_non_local) { v__parser__Parser_error_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("cannot define new methods on non-local type "), 0xfe10, {.d_s = type_sym->name}}, {_S(". Define an alias and use that instead like `type AliasName = "), 0xfe10, {.d_s = type_sym->name}}, {_S("` "), 0, { .d_c = 0 }}})), rec.type_pos); v__ast__FnDecl _t20 = ((v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_method = 0,.is_static_type_method = 0,.static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_expand_simple_interpolation = 0,}); // Defer begin if (v__parser__Parser_fn_decl_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t20; } type_sym_method_idx = v__ast__TypeSymbol_register_method(type_sym, ((v__ast__Fn){ .is_variadic = is_variadic, .is_c_variadic = 0, .language = language, .is_pub = is_pub, .is_ctor_new = 0, .is_deprecated = is_deprecated, .is_noreturn = is_noreturn, .is_unsafe = is_unsafe, .is_must_use = is_must_use, .is_placeholder = 0, .is_main = is_main, .is_test = is_test, .is_keep_alive = is_keep_alive, .is_method = true, .is_static_type_method = 0, .no_body = no_body, .is_file_translated = 0, .mod = p->mod, .file = p->file_path, .file_mode = file_mode, .pos = start_pos, .name_pos = name_pos, .return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .return_type = return_type, .receiver_type = rec.typ, .name = name, .params = params, .source_fn = 0, .usages = 0, .generic_names = generic_names, .dep_names = __new_array(0, 0, sizeof(string)), .attrs = fn_attrs, .is_conditional = conditional_ctdefine_idx != -1, .ctdefine_idx = conditional_ctdefine_idx, .from_embedded_type = 0, .is_expand_simple_interpolation = is_expand_simple_interpolation, })); } else { name = ((language == (v__ast__Language__c))? (str_intp(2, _MOV((StrIntpData[]){{_S("C."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (language == (v__ast__Language__js))? (str_intp(2, _MOV((StrIntpData[]){{_S("JS."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (language == (v__ast__Language__wasm))? (str_intp(2, _MOV((StrIntpData[]){{_S("WASM."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (v__parser__Parser_prepend_mod(p, name))); if (!p->pref->translated && language == v__ast__Language__v) { v__ast__Fn* _t22 = (v__ast__Fn*)(map_get_check(ADDR(map, p->table->fns), &(string[]){name})); _option_v__ast__Fn _t21 = {0}; if (_t22) { *((v__ast__Fn*)&_t21.data) = *((v__ast__Fn*)_t22); } else { _t21.state = 2; _t21.err = _v_error(_S("map key does not exist")); } if (_t21.state == 0) { v__ast__Fn existing = (*(v__ast__Fn*)_t21.data); if ((existing.name).len != 0) { if (file_mode == v__ast__Language__v && existing.file_mode != v__ast__Language__v) { if (!p->pref->is_fmt) { name = v__parser__Parser_prepend_mod(p, str_intp(3, _MOV((StrIntpData[]){{_S("pure_v_but_overridden_by_"), 0xfe10, {.d_s = v__ast__Language_str(existing.file_mode)}}, {_S("_"), 0xfe10, {.d_s = short_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } else { array_push((array*)&p->table->redefined_fns, _MOV((string[]){ string_clone(name) })); } } } } v__ast__Table_register_fn(p->table, ((v__ast__Fn){ .is_variadic = is_variadic, .is_c_variadic = is_c_variadic, .language = language, .is_pub = is_pub, .is_ctor_new = is_ctor_new, .is_deprecated = is_deprecated, .is_noreturn = is_noreturn, .is_unsafe = is_unsafe, .is_must_use = is_must_use, .is_placeholder = 0, .is_main = is_main, .is_test = is_test, .is_keep_alive = is_keep_alive, .is_method = false, .is_static_type_method = is_static_type_method, .no_body = no_body, .is_file_translated = p->is_translated, .mod = p->mod, .file = p->file_path, .file_mode = file_mode, .pos = start_pos, .name_pos = name_pos, .return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .return_type = return_type, .receiver_type = (is_static_type_method ? (rec.typ) : (0)), .name = name, .params = params, .source_fn = 0, .usages = 0, .generic_names = generic_names, .dep_names = __new_array(0, 0, sizeof(string)), .attrs = fn_attrs, .is_conditional = conditional_ctdefine_idx != -1, .ctdefine_idx = conditional_ctdefine_idx, .from_embedded_type = 0, .is_expand_simple_interpolation = is_expand_simple_interpolation, })); } p->cur_fn_name = name; Array_v__ast__Stmt stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); v__token__Pos body_start_pos = v__token__Token_pos(&p->tok); if (p->tok.kind == v__token__Kind__lcbr) { if (language != v__ast__Language__v && !(language == v__ast__Language__js && (type_sym->info)._typ == 542 /* v.ast.Interface */)) { v__parser__Parser_error_with_pos(p, _S("interop functions cannot have a body"), body_start_pos); } v__ast__Scope* last_fn_scope = p->scope; p->inside_fn = true; p->inside_unsafe_fn = is_unsafe; p->cur_fn_scope = p->scope; stmts = v__parser__Parser_parse_block_no_scope(p, true); p->cur_fn_scope = last_fn_scope; p->inside_unsafe_fn = false; p->inside_fn = false; } if (!no_body && are_params_type_only) { v__parser__Parser_error_with_pos(p, _S("functions with type only params can not have bodies"), body_start_pos); v__ast__FnDecl _t24 = ((v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_method = 0,.is_static_type_method = 0,.static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_expand_simple_interpolation = 0,}); // Defer begin if (v__parser__Parser_fn_decl_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t24; } v__ast__FnDecl fn_decl = ((v__ast__FnDecl){ .name = name, .short_name = short_fn_name, .mod = p->mod, .is_deprecated = is_deprecated, .is_pub = is_pub, .is_c_variadic = is_c_variadic, .is_c_extern = is_c_extern, .is_variadic = is_variadic, .is_anon = 0, .is_noreturn = is_noreturn, .is_manualfree = is_manualfree, .is_main = is_main, .is_test = is_test, .is_conditional = conditional_ctdefine_idx != -1, .is_exported = is_exported, .is_keep_alive = is_keep_alive, .is_unsafe = is_unsafe, .is_must_use = is_must_use, .is_markused = is_markused, .is_file_translated = p->is_translated, .receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = rec.name,.typ = rec.typ,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}), .receiver_pos = rec.pos, .is_method = is_method, .is_static_type_method = is_static_type_method, .static_type_pos = static_type_pos, .method_type_pos = rec.type_pos, .method_idx = type_sym_method_idx, .rec_mut = rec.is_mut, .has_prev_newline = 0, .has_break_line = 0, .rec_share = 0, .language = language, .file_mode = 0, .no_body = no_body, .is_builtin = p->builtin_mod || (Array_string_contains(_const_v__util__builtin_module_parts, p->mod)), .name_pos = name_pos, .body_pos = body_start_pos, .file = p->file_path, .generic_names = generic_names, .is_direct_arr = is_direct_arr, .attrs = fn_attrs, .ctdefine_idx = conditional_ctdefine_idx, .idx = 0, .params = params, .stmts = stmts, .defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)), .trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .return_type = return_type, .return_type_pos = return_type_pos, .has_return = 0, .should_be_skipped = 0, .ninstances = 0, .has_await = 0, .comments = comments, .end_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})), .next_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .source_file = ((void*)0), .scope = p->scope, .label_names = p->label_names, .pos = v__token__Pos_extend_with_last_line(start_pos, end_pos, p->prev_tok.line_nr), .end_pos = v__token__Token_pos(&p->tok), .is_expand_simple_interpolation = is_expand_simple_interpolation, }); if (generic_names.len > 0) { v__ast__Table_register_fn_generic_types(p->table, v__ast__FnDecl_fkey(&fn_decl)); } p->label_names = __new_array_with_default(0, 0, sizeof(string), 0); v__ast__FnDecl _t25 = fn_decl; // Defer begin if (v__parser__Parser_fn_decl_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t25; } VV_LOC _result_void v__parser__Parser_fn_receiver(v__parser__Parser* p, Array_v__ast__Param* params, v__parser__ReceiverParsingInfo* rec) { bool v__parser__Parser_fn_receiver_defer_0 = false; p->inside_receiver_param = true; v__parser__Parser_fn_receiver_defer_0 = true; v__token__Pos lpar_pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); bool is_shared = p->tok.kind == v__token__Kind__key_shared; bool is_atomic = p->tok.kind == v__token__Kind__key_atomic; rec->is_mut = p->tok.kind == v__token__Kind__key_mut || is_shared || is_atomic; if (rec->is_mut) { v__parser__Parser_next(p); } if (is_shared) { v__parser__Parser_register_auto_import(p, _S("sync")); } v__token__Pos rec_start_pos = v__token__Token_pos(&p->tok); rec->name = v__parser__Parser_check_name(p); if (!rec->is_mut) { rec->is_mut = p->tok.kind == v__token__Kind__key_mut; if (rec->is_mut) { v__token__Token ptoken2 = v__parser__Parser_peek_token(p, 2); v__parser__Parser_warn_with_pos(p, _S("use `(mut f Foo)` instead of `(f mut Foo)`"), v__token__Pos_extend(lpar_pos, v__token__Token_pos(&ptoken2))); } } if (p->tok.kind == v__token__Kind__key_shared) { v__token__Token ptoken2 = v__parser__Parser_peek_token(p, 2); v__parser__Parser_error_with_pos(p, _S("use `(shared f Foo)` instead of `(f shared Foo)`"), v__token__Pos_extend(lpar_pos, v__token__Token_pos(&ptoken2))); } rec->pos = v__token__Pos_extend(rec_start_pos, v__token__Token_pos(&p->tok)); bool is_amp = p->tok.kind == v__token__Kind__amp; if (p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("JS"))) { rec->language = v__ast__Language__js; } rec->type_pos = v__token__Token_pos(&p->tok); rec->typ = v__parser__Parser_parse_type_with_mut(p, rec->is_mut); if (v__ast__Type_idx(rec->typ) == 0) { _result_void _t1 = (_result_void){ .is_error=true, .err=_v_error(_S("void receiver type")), .data={E_STRUCT} }; // Defer begin if (v__parser__Parser_fn_receiver_defer_0) { p->inside_receiver_param = false; } // Defer end return _t1; } rec->type_pos = v__token__Pos_extend(rec->type_pos, v__token__Token_pos(&p->prev_tok)); if (is_amp && rec->is_mut) { v__parser__Parser_error_with_pos(p, _S("use `(mut f Foo)` or `(f &Foo)` instead of `(mut f &Foo)`"), v__token__Pos_extend(lpar_pos, v__token__Token_pos(&p->tok))); _result_void _t2 = (_result_void){ .is_error=true, .err=_v_error(_S("invalid `mut f &Foo`")), .data={E_STRUCT} }; // Defer begin if (v__parser__Parser_fn_receiver_defer_0) { p->inside_receiver_param = false; } // Defer end return _t2; } if (is_shared) { rec->typ = v__ast__Type_set_flag(rec->typ, v__ast__TypeFlag__shared_f); } if (is_atomic) { rec->typ = v__ast__Type_set_flag(rec->typ, v__ast__TypeFlag__atomic_f); } if (rec->language != v__ast__Language__v) { v__parser__Parser_check_for_impure_v(p, rec->language, rec->type_pos); } v__parser__Parser_check(p, v__token__Kind__rpar); array_push((array*)params, _MOV((v__ast__Param[]){ ((v__ast__Param){ .pos = rec_start_pos, .name = rec->name, .is_mut = rec->is_mut, .is_shared = is_shared, .is_atomic = is_atomic, .type_pos = rec->type_pos, .is_hidden = 0, .on_newline = 0, .typ = rec->typ, }) })); // Defer begin if (v__parser__Parser_fn_receiver_defer_0) { p->inside_receiver_param = false; } // Defer end return (_result_void){0}; } VV_LOC v__ast__AnonFn v__parser__Parser_anon_fn(v__parser__Parser* p) { bool v__parser__Parser_anon_fn_defer_0 = false; v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__key_fn); if (p->tok.kind == v__token__Kind__name) { if (v__parser__Parser_disallow_declarations_in_script_mode(p)) { return ((v__ast__AnonFn){.decl = ((v__ast__FnDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.is_deprecated = 0,.is_pub = 0,.is_c_variadic = 0,.is_c_extern = 0,.is_variadic = 0,.is_anon = 0,.is_noreturn = 0,.is_manualfree = 0,.is_main = 0,.is_test = 0,.is_conditional = 0,.is_exported = 0,.is_keep_alive = 0,.is_unsafe = 0,.is_must_use = 0,.is_markused = 0,.is_file_translated = 0,.receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_method = 0,.is_static_type_method = 0,.static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.method_idx = 0,.rec_mut = 0,.has_prev_newline = 0,.has_break_line = 0,.rec_share = 0,.language = 0,.file_mode = 0,.no_body = 0,.is_builtin = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.file = (string){.str=(byteptr)"", .is_lit=1},.generic_names = __new_array(0, 0, sizeof(string)),.is_direct_arr = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.ctdefine_idx = -1,.idx = 0,.params = __new_array(0, 0, sizeof(v__ast__Param)),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)),.trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.return_type = 0,.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_return = 0,.should_be_skipped = 0,.ninstances = 0,.has_await = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.source_file = ((void*)0),.scope = ((void*)0),.label_names = __new_array(0, 0, sizeof(string)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_expand_simple_interpolation = 0,}),.inherited_vars = __new_array(0, 0, sizeof(v__ast__Param)),.typ = 0,.has_gen = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}); } } bool old_inside_defer = p->inside_defer; p->inside_defer = false; v__parser__Parser_open_scope(p); v__parser__Parser_anon_fn_defer_0 = true; p->scope->detached_from_parent = true; Array_v__ast__Param inherited_vars = (p->tok.kind == v__token__Kind__lsbr && !(p->peek_tok.kind == v__token__Kind__name && p->peek_tok.lit.len == 1 && u8_is_capital(string_at(p->peek_tok.lit, 0))) ? (v__parser__Parser_closure_vars(p)) : (__new_array_with_default(0, 0, sizeof(v__ast__Param), 0))); Array_string _t2 = {0}; Array_v__ast__Param _t2_orig = inherited_vars; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Param it = ((v__ast__Param*) _t2_orig.data)[_t4]; string _t3 = it.name; array_push((array*)&_t2, &_t3); } Array_string inherited_vars_name =_t2; multi_return_Array_v__ast__Type_Array_string mr_24806 = v__parser__Parser_parse_generic_types(p); Array_string generic_names = mr_24806.arg1; multi_return_Array_v__ast__Param_bool_bool_bool mr_24860 = v__parser__Parser_fn_params(p); Array_v__ast__Param params = mr_24860.arg0; bool is_variadic = mr_24860.arg2; for (int _t5 = 0; _t5 < params.len; ++_t5) { v__ast__Param param = ((v__ast__Param*)params.data)[_t5]; if ((param.name).len == 0 && v__ast__Table_sym(p->table, param.typ)->kind != v__ast__Kind__placeholder) { v__parser__Parser_error_with_pos(p, _S("use `_` to name an unused parameter"), param.pos); } if ((Array_string_contains(inherited_vars_name, param.name))) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("the parameter name `"), 0xfe10, {.d_s = param.name}}, {_S("` conflicts with the captured value name"), 0, { .d_c = 0 }}})), param.pos); } else if (v__ast__Scope_known_var(p->scope, param.name)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("redefinition of parameter `"), 0xfe10, {.d_s = param.name}}, {_S("`"), 0, { .d_c = 0 }}})), param.pos); } bool is_stack_obj = !v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__shared_f) && (param.is_mut || v__ast__Type_is_ptr(param.typ)); v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){ .name = param.name, .share = 0, .is_mut = param.is_mut, .is_static = 0, .is_volatile = 0, .is_autofree_tmp = 0, .is_inherited = 0, .has_inherited = 0, .is_arg = true, .is_auto_deref = param.is_mut, .is_unwrapped = 0, .is_index_var = 0, .expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .typ = param.typ, .orig_type = 0, .smartcasts = __new_array(0, 0, sizeof(v__ast__Type)), .pos = param.pos, .is_used = true, .is_changed = 0, .ct_type_var = 0, .ct_type_unwrapped = 0, .is_or = 0, .is_tmp = 0, .is_auto_heap = 0, .is_stack_obj = is_stack_obj, }))))); } bool same_line = p->tok.line_nr == p->prev_tok.line_nr; v__ast__Type return_type = _const_v__ast__void_type; v__token__Pos return_type_pos = v__token__Token_pos(&p->tok); if (same_line) { if ((v__token__Kind_is_start_of_type(p->tok.kind) && (same_line || p->tok.kind != v__token__Kind__lsbr)) || (same_line && p->tok.kind == v__token__Kind__key_fn)) { p->inside_fn_return = true; return_type = v__parser__Parser_parse_type(p); p->inside_fn_return = false; return_type_pos = v__token__Pos_extend(return_type_pos, v__token__Token_pos(&p->tok)); } else if (p->tok.kind != v__token__Kind__lcbr) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("expected return type, not "), 0xfe10, {.d_s = v__token__Token_str(p->tok)}}, {_S(" for anonymous function"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->tok)); } } Array_v__ast__Stmt stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); bool no_body = p->tok.kind != v__token__Kind__lcbr; same_line = p->tok.line_nr == p->prev_tok.line_nr; if (no_body && same_line) { v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__token__Token_str(p->tok)}}, {_S(" after anonymous function signature"), 0, { .d_c = 0 }}})),.expecting = _S("`{`"),.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); } Array_string label_names = __new_array_with_default(0, 0, sizeof(string), 0); v__ast__Fn func = ((v__ast__Fn){.is_variadic = is_variadic,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = false,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = return_type,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = params,.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); string name = v__ast__Table_get_anon_fn_name(p->table, p->unique_prefix, (voidptr)&func, p->tok.pos); string keep_fn_name = p->cur_fn_name; p->cur_fn_name = name; if (p->tok.kind == v__token__Kind__lcbr) { Array_string tmp = p->label_names; p->label_names = __new_array_with_default(0, 0, sizeof(string), 0); bool old_assign_rhs = p->inside_assign_rhs; p->inside_assign_rhs = false; stmts = v__parser__Parser_parse_block_no_scope(p, false); p->inside_assign_rhs = old_assign_rhs; label_names = array_clone_to_depth(&p->label_names, 0); p->label_names = tmp; } p->cur_fn_name = keep_fn_name; func.name = name; int idx = v__ast__Table_find_or_register_fn_type(p->table, func, true, false); v__ast__Type typ = (generic_names.len > 0 ? (v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic)) : (v__ast__new_type(idx))); p->inside_defer = old_inside_defer; v__ast__AnonFn _t6 = ((v__ast__AnonFn){.decl = ((v__ast__FnDecl){ .name = name, .short_name = _S(""), .mod = p->mod, .is_deprecated = 0, .is_pub = 0, .is_c_variadic = 0, .is_c_extern = 0, .is_variadic = is_variadic, .is_anon = true, .is_noreturn = 0, .is_manualfree = 0, .is_main = 0, .is_test = 0, .is_conditional = 0, .is_exported = 0, .is_keep_alive = 0, .is_unsafe = 0, .is_must_use = 0, .is_markused = 0, .is_file_translated = 0, .receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}), .receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_method = false, .is_static_type_method = 0, .static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .method_idx = 0, .rec_mut = 0, .has_prev_newline = 0, .has_break_line = 0, .rec_share = 0, .language = 0, .file_mode = 0, .no_body = no_body, .is_builtin = 0, .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .file = p->file_path, .generic_names = generic_names, .is_direct_arr = 0, .attrs = __new_array(0, 0, sizeof(v__ast__Attr)), .ctdefine_idx = -1, .idx = 0, .params = params, .stmts = stmts, .defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)), .trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .return_type = return_type, .return_type_pos = return_type_pos, .has_return = 0, .should_be_skipped = 0, .ninstances = 0, .has_await = 0, .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .end_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .next_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .source_file = ((void*)0), .scope = p->scope, .label_names = label_names, .pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)), .end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_expand_simple_interpolation = 0, }),.inherited_vars = inherited_vars,.typ = typ,.has_gen = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}); // Defer begin if (v__parser__Parser_anon_fn_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t6; } VV_LOC multi_return_Array_v__ast__Param_bool_bool_bool v__parser__Parser_fn_params(v__parser__Parser* p) { v__parser__Parser_check(p, v__token__Kind__lpar); Array_v__ast__Param params = __new_array_with_default(0, 0, sizeof(v__ast__Param), 0); bool is_variadic = false; bool is_c_variadic = false; string param_name = (p->tok.kind == v__token__Kind__name && p->tok.lit.len > 0 && u8_is_capital(string_at(p->tok.lit, 0)) ? (v__parser__Parser_prepend_mod(p, p->tok.lit)) : (p->tok.lit)); bool is_generic_type = p->tok.kind == v__token__Kind__name && p->tok.lit.len == 1 && u8_is_capital(string_at(p->tok.lit, 0)); bool types_only = (p->tok.kind == v__token__Kind__question || p->tok.kind == v__token__Kind__not || p->tok.kind == v__token__Kind__amp || p->tok.kind == v__token__Kind__ellipsis || p->tok.kind == v__token__Kind__key_fn || p->tok.kind == v__token__Kind__lsbr) || (p->peek_tok.kind == v__token__Kind__comma && (v__ast__Table_known_type(p->table, param_name) || is_generic_type)) || p->peek_tok.kind == v__token__Kind__dot || p->peek_tok.kind == v__token__Kind__rpar || p->fn_language == v__ast__Language__c || (p->tok.kind == v__token__Kind__key_mut && ((p->peek_tok.kind == v__token__Kind__amp || p->peek_tok.kind == v__token__Kind__ellipsis || p->peek_tok.kind == v__token__Kind__key_fn || p->peek_tok.kind == v__token__Kind__lsbr) || (v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__comma && (p->tok.kind != v__token__Kind__key_mut || u8_is_capital(string_at(p->peek_tok.lit, 0)))) || v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__rpar || (p->peek_tok.kind == v__token__Kind__name && v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__dot))); int prev_param_newline = v__token__Token_pos(&p->tok).line_nr; if (types_only) { int param_no = 1; for (;;) { if (!(p->tok.kind != v__token__Kind__rpar)) break; if (p->tok.kind == v__token__Kind__eof) { v__parser__Parser_error_with_pos(p, _S("expecting `)`"), v__token__Token_pos(&p->tok)); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=__new_array_with_default(0, 0, sizeof(v__ast__Param), 0), .arg1=false, .arg2=false, .arg3=false}; } bool is_shared = p->tok.kind == v__token__Kind__key_shared; bool is_atomic = p->tok.kind == v__token__Kind__key_atomic; bool is_mut = p->tok.kind == v__token__Kind__key_mut || is_shared || is_atomic; string name = _S(""); if (is_mut) { v__parser__Parser_next(p); } if (p->fn_language == v__ast__Language__c && p->tok.kind == v__token__Kind__name && !(p->peek_tok.kind == v__token__Kind__comma || p->peek_tok.kind == v__token__Kind__rpar || p->peek_tok.kind == v__token__Kind__dot)) { name = p->tok.lit; v__parser__Parser_next(p); } if (p->tok.kind == v__token__Kind__ellipsis) { v__parser__Parser_next(p); is_variadic = true; is_c_variadic = p->tok.kind == v__token__Kind__rpar; if (is_c_variadic) { v__parser__Parser_check(p, v__token__Kind__rpar); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=params, .arg1=types_only, .arg2=is_variadic, .arg3=is_c_variadic}; } } v__token__Pos pos = v__token__Token_pos(&p->tok); v__ast__Type param_type = v__parser__Parser_parse_type(p); v__token__Pos type_pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)); if (param_type == 0) { return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=__new_array_with_default(0, 0, sizeof(v__ast__Param), 0), .arg1=false, .arg2=false, .arg3=false}; } if (is_mut) { if (!v__ast__Type_has_flag(param_type, v__ast__TypeFlag__generic)) { if (is_variadic) { v__parser__Parser_error_with_pos(p, _S("variadic arguments cannot be `mut`, `shared` or `atomic`"), pos); } if (is_shared) { v__parser__Parser_check_fn_shared_arguments(p, param_type, pos); } else if (is_atomic) { v__parser__Parser_check_fn_atomic_arguments(p, param_type, pos); } else { v__parser__Parser_check_fn_mutable_arguments(p, param_type, pos); } } else if (is_shared || is_atomic) { v__parser__Parser_error_with_pos(p, _S("generic object cannot be `atomic`or `shared`"), pos); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=__new_array_with_default(0, 0, sizeof(v__ast__Param), 0), .arg1=false, .arg2=false, .arg3=false}; } if (v__ast__Type_is_ptr(param_type) && v__ast__Table_sym(p->table, param_type)->kind == v__ast__Kind__struct) { param_type = v__ast__Type_ref(param_type); } else { param_type = v__ast__Type_set_nr_muls(param_type, 1); } if (v__ast__Type_has_flag(param_type, v__ast__TypeFlag__option)) { param_type = v__ast__Type_set_flag(param_type, v__ast__TypeFlag__option_mut_param_t); } if (is_shared) { param_type = v__ast__Type_set_flag(param_type, v__ast__TypeFlag__shared_f); } if (is_atomic) { param_type = v__ast__Type_set_flag(param_type, v__ast__TypeFlag__atomic_f); } } if (is_variadic) { param_type = v__ast__Type_set_flag(v__ast__new_type(v__ast__Table_find_or_register_array(p->table, param_type)), v__ast__TypeFlag__variadic); } if (p->tok.kind == v__token__Kind__eof) { v__parser__Parser_error_with_pos(p, _S("expecting `)`"), v__token__Token_pos(&p->prev_tok)); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=__new_array_with_default(0, 0, sizeof(v__ast__Param), 0), .arg1=false, .arg2=false, .arg3=false}; } if (p->tok.kind == v__token__Kind__comma) { if (is_variadic) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use ...(variadic) with non-final parameter no "), 0xfe07, {.d_i32 = param_no}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=__new_array_with_default(0, 0, sizeof(v__ast__Param), 0), .arg1=false, .arg2=false, .arg3=false}; } v__parser__Parser_next(p); } v__ast__Language alanguage = v__ast__Table_sym(p->table, param_type)->language; if (alanguage != v__ast__Language__v) { v__parser__Parser_check_for_impure_v(p, alanguage, pos); } array_push((array*)¶ms, _MOV((v__ast__Param[]){ ((v__ast__Param){ .pos = pos, .name = name, .is_mut = is_mut, .is_shared = 0, .is_atomic = 0, .type_pos = type_pos, .is_hidden = 0, .on_newline = prev_param_newline != pos.line_nr, .typ = param_type, }) })); prev_param_newline = pos.line_nr; param_no++; if (param_no > 1024) { v__parser__Parser_error_with_pos(p, _S("too many parameters"), pos); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=__new_array_with_default(0, 0, sizeof(v__ast__Param), 0), .arg1=false, .arg2=false, .arg3=false}; } } } else { for (;;) { if (!(p->tok.kind != v__token__Kind__rpar)) break; if (p->tok.kind == v__token__Kind__eof) { v__parser__Parser_error_with_pos(p, _S("expecting `)`"), v__token__Token_pos(&p->tok)); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=__new_array_with_default(0, 0, sizeof(v__ast__Param), 0), .arg1=false, .arg2=false, .arg3=false}; } bool is_shared = p->tok.kind == v__token__Kind__key_shared; bool is_atomic = p->tok.kind == v__token__Kind__key_atomic; bool is_mut = p->tok.kind == v__token__Kind__key_mut || is_shared || is_atomic; if (is_mut) { v__parser__Parser_next(p); } if (p->tok.kind == v__token__Kind__ellipsis && p->peek_tok.kind == v__token__Kind__rpar) { v__parser__Parser_check(p, v__token__Kind__ellipsis); v__parser__Parser_check(p, v__token__Kind__rpar); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=params, .arg1=types_only, .arg2=true, .arg3=true}; } Array_v__token__Pos param_pos = new_array_from_c_array(1, 1, sizeof(v__token__Pos), _MOV((v__token__Pos[1]){v__token__Token_pos(&p->tok)})); string name = v__parser__Parser_check_name(p); Array_string param_names = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){string_clone(name)})); if ((name).len != 0 && p->fn_language == v__ast__Language__v && u8_is_capital(string_at(name, 0))) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("parameter name must not begin with upper case letter (`"), 0xfe10, {.d_s = (*(string*)array_get(param_names, 0))}}, {_S("`)"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->prev_tok)); } Array_v__token__Pos type_pos = new_array_from_c_array(1, 1, sizeof(v__token__Pos), _MOV((v__token__Pos[1]){v__token__Token_pos(&p->tok)})); for (;;) { if (!(p->tok.kind == v__token__Kind__comma)) break; if (!p->pref->is_fmt) { v__parser__Parser_error(p, string__plus(_S("`fn f(x, y Type)` syntax has been deprecated. "), str_intp(2, _MOV((StrIntpData[]){{_S("Use `fn f(x Type, y Type)` instead. You can run `v fmt -w \""), 0xfe10, {.d_s = p->scanner->file_path}}, {_S("\"` to automatically fix your code."), 0, { .d_c = 0 }}})))); } v__parser__Parser_next(p); array_push((array*)¶m_pos, _MOV((v__token__Pos[]){ v__token__Token_pos(&p->tok) })); array_push((array*)¶m_names, _MOV((string[]){ v__parser__Parser_check_name(p) })); array_push((array*)&type_pos, _MOV((v__token__Pos[]){ v__token__Token_pos(&p->tok) })); } if (p->tok.kind == v__token__Kind__key_mut) { if (!p->pref->is_fmt) { v__parser__Parser_warn_with_pos(p, _S("use `mut f Foo` instead of `f mut Foo`"), v__token__Token_pos(&p->tok)); } is_mut = true; } if (p->tok.kind == v__token__Kind__key_shared) { v__parser__Parser_error_with_pos(p, _S("use `shared f Foo` instead of `f shared Foo`"), v__token__Token_pos(&p->tok)); } if (p->tok.kind == v__token__Kind__ellipsis) { v__parser__Parser_next(p); is_variadic = true; is_c_variadic = p->tok.kind == v__token__Kind__rpar; if (is_c_variadic) { v__parser__Parser_check(p, v__token__Kind__rpar); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=params, .arg1=types_only, .arg2=is_variadic, .arg3=is_c_variadic}; } } v__token__Pos pos = v__token__Token_pos(&p->tok); v__ast__Type typ = v__parser__Parser_parse_type(p); array_set(&type_pos, 0, &(v__token__Pos[]) { v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)) }); if (typ == 0) { return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=__new_array_with_default(0, 0, sizeof(v__ast__Param), 0), .arg1=false, .arg2=false, .arg3=false}; } if (is_mut) { if (!v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { if (is_variadic) { v__parser__Parser_error_with_pos(p, _S("variadic arguments cannot be `mut`, `shared` or `atomic`"), pos); } if (is_shared) { v__parser__Parser_check_fn_shared_arguments(p, typ, pos); } else if (is_atomic) { v__parser__Parser_check_fn_atomic_arguments(p, typ, pos); } else { v__parser__Parser_check_fn_mutable_arguments(p, typ, pos); } } else if (is_shared || is_atomic) { v__parser__Parser_error_with_pos(p, _S("generic object cannot be `atomic` or `shared`"), pos); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=__new_array_with_default(0, 0, sizeof(v__ast__Param), 0), .arg1=false, .arg2=false, .arg3=false}; } if (v__ast__Type_is_ptr(typ) && v__ast__Table_sym(p->table, typ)->kind == v__ast__Kind__struct) { typ = v__ast__Type_ref(typ); } else { typ = v__ast__Type_set_nr_muls(typ, 1); } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__option_mut_param_t); } if (is_shared) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__shared_f); } if (is_atomic) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__atomic_f); } } if (is_variadic) { typ = v__ast__Type_set_flag(v__ast__Type_set_nr_muls(v__ast__Type_derive(v__ast__new_type(v__ast__Table_find_or_register_array(p->table, typ)), typ), 0), v__ast__TypeFlag__variadic); } for (int i = 0; i < param_names.len; ++i) { string para_name = ((string*)param_names.data)[i]; v__ast__Language alanguage = v__ast__Table_sym(p->table, typ)->language; if (alanguage != v__ast__Language__v) { v__parser__Parser_check_for_impure_v(p, alanguage, (*(v__token__Pos*)array_get(type_pos, i))); } array_push((array*)¶ms, _MOV((v__ast__Param[]){ ((v__ast__Param){ .pos = (*(v__token__Pos*)array_get(param_pos, i)), .name = para_name, .is_mut = is_mut, .is_shared = is_shared, .is_atomic = is_atomic, .type_pos = (*(v__token__Pos*)array_get(type_pos, i)), .is_hidden = 0, .on_newline = prev_param_newline != (*(v__token__Pos*)array_get(param_pos, i)).line_nr, .typ = typ, }) })); prev_param_newline = (*(v__token__Pos*)array_get(param_pos, i)).line_nr; if (is_variadic && p->tok.kind == v__token__Kind__comma && p->peek_tok.kind != v__token__Kind__rpar) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use ...(variadic) with non-final parameter "), 0xfe10, {.d_s = para_name}}, {_SLIT0, 0, { .d_c = 0 }}})), (*(v__token__Pos*)array_get(param_pos, i))); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=__new_array_with_default(0, 0, sizeof(v__ast__Param), 0), .arg1=false, .arg2=false, .arg3=false}; } } if (p->tok.kind == v__token__Kind__eof) { v__parser__Parser_error_with_pos(p, _S("expecting `)`"), v__token__Token_pos(&p->prev_tok)); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=__new_array_with_default(0, 0, sizeof(v__ast__Param), 0), .arg1=false, .arg2=false, .arg3=false}; } if (p->tok.kind != v__token__Kind__rpar) { v__parser__Parser_check(p, v__token__Kind__comma); } } } v__parser__Parser_check(p, v__token__Kind__rpar); return (multi_return_Array_v__ast__Param_bool_bool_bool){.arg0=params, .arg1=types_only, .arg2=is_variadic, .arg3=is_c_variadic}; } VV_LOC v__ast__SpawnExpr v__parser__Parser_spawn_expr(v__parser__Parser* p) { v__parser__Parser_next(p); v__token__Pos spos = v__token__Token_pos(&p->tok); bool old_inside_assign_rhs = p->inside_assign_rhs; p->inside_assign_rhs = false; v__ast__Expr expr = v__parser__Parser_expr(p, 0); p->inside_assign_rhs = old_inside_assign_rhs; v__ast__CallExpr _t1; /* if prepend */ if ((expr)._typ == 344 /* v.ast.CallExpr */) { _t1 = (*expr._v__ast__CallExpr); } else { v__parser__Parser_error_with_pos(p, _S("expression in `spawn` must be a function call"), v__ast__Expr_pos(expr)); _t1 = ((v__ast__CallExpr){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mod = (string){.str=(byteptr)"", .is_lit=1},.name = (string){.str=(byteptr)"", .is_lit=1},.is_method = 0,.is_field = 0,.is_fn_var = 0,.is_fn_a_const = 0,.is_keep_alive = 0,.is_noreturn = 0,.is_ctor_new = 0,.is_file_translated = 0,.is_static_method = 0,.args = __new_array(0, 0, sizeof(v__ast__CallArg)),.expected_arg_types = __new_array(0, 0, sizeof(v__ast__Type)),.comptime_ret_val = 0,.language = 0,.or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.left_type = 0,.receiver_type = 0,.receiver_concrete_type = 0,.return_type = 0,.return_type_generic = 0,.nr_ret_values = -1,.fn_var_type = 0,.const_name = (string){.str=(byteptr)"", .is_lit=1},.should_be_skipped = 0,.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.concrete_list_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.raw_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.free_receiver = 0,.scope = p->scope,.from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_return_used = 0,.is_expand_simple_interpolation = 0,.is_unwrapped_fn_selector = 0,}); } v__ast__CallExpr call_expr = _t1; call_expr.is_return_used = true; v__token__Pos pos = v__token__Pos_extend(spos, v__token__Token_pos(&p->prev_tok)); v__parser__Parser_register_auto_import(p, _S("sync.threads")); p->table->gostmts++; return ((v__ast__SpawnExpr){.pos = pos,.call_expr = call_expr,.is_expr = 0,}); } VV_LOC v__ast__GoExpr v__parser__Parser_go_expr(v__parser__Parser* p) { v__parser__Parser_next(p); v__token__Pos spos = v__token__Token_pos(&p->tok); bool old_inside_assign_rhs = p->inside_assign_rhs; p->inside_assign_rhs = false; v__ast__Expr expr = v__parser__Parser_expr(p, 0); p->inside_assign_rhs = old_inside_assign_rhs; v__ast__CallExpr _t1; /* if prepend */ if ((expr)._typ == 344 /* v.ast.CallExpr */) { _t1 = (*expr._v__ast__CallExpr); } else { v__parser__Parser_error_with_pos(p, _S("expression in `go` must be a function call"), v__ast__Expr_pos(expr)); _t1 = ((v__ast__CallExpr){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mod = (string){.str=(byteptr)"", .is_lit=1},.name = (string){.str=(byteptr)"", .is_lit=1},.is_method = 0,.is_field = 0,.is_fn_var = 0,.is_fn_a_const = 0,.is_keep_alive = 0,.is_noreturn = 0,.is_ctor_new = 0,.is_file_translated = 0,.is_static_method = 0,.args = __new_array(0, 0, sizeof(v__ast__CallArg)),.expected_arg_types = __new_array(0, 0, sizeof(v__ast__Type)),.comptime_ret_val = 0,.language = 0,.or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.left_type = 0,.receiver_type = 0,.receiver_concrete_type = 0,.return_type = 0,.return_type_generic = 0,.nr_ret_values = -1,.fn_var_type = 0,.const_name = (string){.str=(byteptr)"", .is_lit=1},.should_be_skipped = 0,.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.concrete_list_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.raw_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.free_receiver = 0,.scope = p->scope,.from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_return_used = 0,.is_expand_simple_interpolation = 0,.is_unwrapped_fn_selector = 0,}); } v__ast__CallExpr call_expr = _t1; call_expr.is_return_used = true; v__token__Pos pos = v__token__Pos_extend(spos, v__token__Token_pos(&p->prev_tok)); p->table->gostmts++; return ((v__ast__GoExpr){.pos = pos,.call_expr = call_expr,.is_expr = 0,}); } VV_LOC Array_v__ast__Param v__parser__Parser_closure_vars(v__parser__Parser* p) { v__parser__Parser_check(p, v__token__Kind__lsbr); Array_v__ast__Param vars = __new_array_with_default(0, 5, sizeof(v__ast__Param), 0); for (;;) { bool is_shared = p->tok.kind == v__token__Kind__key_shared; bool is_atomic = p->tok.kind == v__token__Kind__key_atomic; bool is_mut = p->tok.kind == v__token__Kind__key_mut || is_shared || is_atomic; if (is_mut) { v__parser__Parser_next(p); } v__token__Pos var_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__name); string var_name = p->prev_tok.lit; _option_v__ast__Var_ptr _t1 = v__ast__Scope_find_var(p->scope->parent, var_name); if (_t1.state != 0) { IError err = _t1.err; if (v__ast__Scope_known_global(p->table->global_scope, var_name)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("no need to capture global variable `"), 0xfe10, {.d_s = var_name}}, {_S("` in closure"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->prev_tok)); return __new_array_with_default(0, 0, sizeof(v__ast__Param), 0); } v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("undefined ident: `"), 0xfe10, {.d_s = var_name}}, {_S("`"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->prev_tok)); return __new_array_with_default(0, 0, sizeof(v__ast__Param), 0); } v__ast__Var* var = (*(v__ast__Var**)_t1.data); var->is_used = true; if (is_mut) { var->is_changed = true; } v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){ .name = ((*var)).name, .share = ((*var)).share, .is_mut = is_mut, .is_static = ((*var)).is_static, .is_volatile = ((*var)).is_volatile, .is_autofree_tmp = ((*var)).is_autofree_tmp, .is_inherited = true, .has_inherited = var->is_inherited, .is_arg = ((*var)).is_arg, .is_auto_deref = ((*var)).is_auto_deref, .is_unwrapped = ((*var)).is_unwrapped, .is_index_var = ((*var)).is_index_var, .expr = ((*var)).expr, .typ = ((*var)).typ, .orig_type = ((*var)).orig_type, .smartcasts = ((*var)).smartcasts, .pos = var_pos, .is_used = false, .is_changed = false, .ct_type_var = ((*var)).ct_type_var, .ct_type_unwrapped = ((*var)).ct_type_unwrapped, .is_or = ((*var)).is_or, .is_tmp = ((*var)).is_tmp, .is_auto_heap = ((*var)).is_auto_heap, .is_stack_obj = ((*var)).is_stack_obj, }))))); array_push((array*)&vars, _MOV((v__ast__Param[]){ ((v__ast__Param){.pos = var_pos,.name = var_name,.is_mut = is_mut,.is_shared = is_shared,.is_atomic = is_atomic,.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_hidden = 0,.on_newline = 0,.typ = 0,}) })); if (p->tok.kind != v__token__Kind__comma) { break; } v__parser__Parser_next(p); } v__parser__Parser_check(p, v__token__Kind__rsbr); return vars; } VV_LOC void v__parser__Parser_check_fn_mutable_arguments(v__parser__Parser* p, v__ast__Type typ, v__token__Pos pos) { v__ast__TypeSymbol* sym = v__ast__Table_sym(p->table, typ); if (sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__array_fixed || sym->kind == v__ast__Kind__interface || sym->kind == v__ast__Kind__map || sym->kind == v__ast__Kind__placeholder || sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__generic_inst || sym->kind == v__ast__Kind__sum_type) { return; } if (v__ast__Type_is_any_kind_of_pointer(typ)) { return; } if (sym->kind == v__ast__Kind__alias) { v__ast__Type atyp = (*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type; v__parser__Parser_check_fn_mutable_arguments(p, atyp, pos); return; } if (p->fn_language == v__ast__Language__c) { return; } v__parser__Parser_error_with_pos(p, string__plus(_S("mutable arguments are only allowed for arrays, interfaces, maps, pointers, structs or their aliases\n"), str_intp(4, _MOV((StrIntpData[]){{_S("return values instead: `fn foo(mut n "), 0xfe10, {.d_s = sym->name}}, {_S(") {` => `fn foo(n "), 0xfe10, {.d_s = sym->name}}, {_S(") "), 0xfe10, {.d_s = sym->name}}, {_S(" {`"), 0, { .d_c = 0 }}}))), pos); } VV_LOC void v__parser__Parser_check_fn_shared_arguments(v__parser__Parser* p, v__ast__Type typ, v__token__Pos pos) { v__ast__TypeSymbol* sym = v__ast__Table_sym(p->table, typ); if (sym->kind == v__ast__Kind__generic_inst) { sym = (*(v__ast__TypeSymbol**)array_get(p->table->type_symbols, (*(v__ast__GenericInst*)__as_cast((sym->info)._v__ast__GenericInst,(sym->info)._typ, 555)).parent_idx)); } if (!(sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__map || sym->kind == v__ast__Kind__placeholder) && !v__ast__Type_is_ptr(typ)) { v__parser__Parser_error_with_pos(p, _S("shared arguments are only allowed for arrays, maps, and structs\n"), pos); } } VV_LOC void v__parser__Parser_check_fn_atomic_arguments(v__parser__Parser* p, v__ast__Type typ, v__token__Pos pos) { v__ast__TypeSymbol* sym = v__ast__Table_sym(p->table, typ); if (!(sym->kind == v__ast__Kind__u32 || sym->kind == v__ast__Kind__int || sym->kind == v__ast__Kind__u64)) { v__parser__Parser_error_with_pos(p, string__plus(_S("atomic arguments are only allowed for 32/64 bit integers\n"), str_intp(3, _MOV((StrIntpData[]){{_S("use shared arguments instead: `fn foo(atomic n "), 0xfe10, {.d_s = sym->name}}, {_S(") {` => `fn foo(shared n "), 0xfe10, {.d_s = sym->name}}, {_S(") {`"), 0, { .d_c = 0 }}}))), pos); } } VV_LOC v__ast__Stmt v__parser__Parser_for_stmt(v__parser__Parser* p) { v__parser__Parser_check(p, v__token__Kind__key_for); v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_open_scope(p); p->inside_for = true; if (p->tok.kind == v__token__Kind__key_match) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, _S("cannot use `match` in `for` loop"))))); } Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t2, Array_v__ast__Comment); if (p->tok.kind == v__token__Kind__lcbr) { p->inside_for = false; Array_v__ast__Stmt stmts = v__parser__Parser_parse_block_no_scope(p, false); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); v__ast__ForStmt for_stmt = ((v__ast__ForStmt){.is_inf = true,.pos = pos,.comments = comments,.cond = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.stmts = stmts,.label = (string){.str=(byteptr)"", .is_lit=1},.scope = p->scope,}); v__parser__Parser_close_scope(p); return v__ast__ForStmt_to_sumtype_v__ast__Stmt(&for_stmt); } else if (p->peek_tok.kind == v__token__Kind__semicolon || ((p->peek_tok.kind == v__token__Kind__inc || p->peek_tok.kind == v__token__Kind__dec) && (v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__semicolon || v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__comma)) || v__token__Kind_is_assign(p->peek_tok.kind) || p->tok.kind == v__token__Kind__semicolon || (p->peek_tok.kind == v__token__Kind__comma && v__parser__Parser_peek_token(p, 2).kind != v__token__Kind__key_mut && v__parser__Parser_peek_token(p, 3).kind != v__token__Kind__key_in)) { if (p->tok.kind == v__token__Kind__key_mut) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, _S("`mut` is not needed in `for ;;` loops: use `for i := 0; i < n; i ++ {`"))))); } v__ast__Stmt init = _const_v__ast__empty_stmt; v__ast__Expr cond = v__parser__Parser_new_true_expr(p); v__ast__Stmt inc = _const_v__ast__empty_stmt; bool has_init = false; bool has_cond = false; bool has_inc = false; bool is_multi = p->peek_tok.kind == v__token__Kind__comma && v__parser__Parser_peek_token(p, 2).kind != v__token__Kind__key_mut && v__parser__Parser_peek_token(p, 3).kind != v__token__Kind__key_in; if (v__token__Kind_is_assign(p->peek_tok.kind) || is_multi) { init = v__parser__Parser_assign_stmt(p); has_init = true; } else if (p->peek_tok.kind == v__token__Kind__inc || p->peek_tok.kind == v__token__Kind__dec) { init = v__parser__Parser_stmt(p, false); has_init = true; } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t5, Array_v__ast__Comment); v__parser__Parser_check(p, v__token__Kind__semicolon); if (p->tok.kind != v__token__Kind__semicolon) { if (p->tok.kind == v__token__Kind__name && (p->peek_tok.kind == v__token__Kind__inc || p->peek_tok.kind == v__token__Kind__dec)) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, str_intp(3, _MOV((StrIntpData[]){{_S("cannot use "), 0xfe10, {.d_s = p->tok.lit}}, {_SLIT0, 0xfe10, {.d_s = v__token__Kind_str(p->peek_tok.kind)}}, {_S(" as value"), 0, { .d_c = 0 }}})))))); } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t7, Array_v__ast__Comment); cond = v__parser__Parser_expr(p, 0); has_cond = true; } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t8, Array_v__ast__Comment); v__parser__Parser_check(p, v__token__Kind__semicolon); if (!is_multi) { is_multi = p->peek_tok.kind == v__token__Kind__comma; } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t9, Array_v__ast__Comment); if (p->tok.kind != v__token__Kind__lcbr) { inc = v__parser__Parser_stmt(p, false); has_inc = true; } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t10, Array_v__ast__Comment); p->inside_for = false; Array_v__ast__Stmt stmts = v__parser__Parser_parse_block_no_scope(p, false); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); v__ast__ForCStmt for_c_stmt = ((v__ast__ForCStmt){ .has_init = has_init, .has_cond = has_cond, .has_inc = has_inc, .is_multi = is_multi, .pos = pos, .comments = comments, .init = init, .cond = cond, .inc = inc, .stmts = stmts, .label = (string){.str=(byteptr)"", .is_lit=1}, .scope = p->scope, }); v__parser__Parser_close_scope(p); return v__ast__ForCStmt_to_sumtype_v__ast__Stmt(&for_c_stmt); } else if ((p->peek_tok.kind == v__token__Kind__key_in || p->peek_tok.kind == v__token__Kind__comma) || (p->tok.kind == v__token__Kind__key_mut && (v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__key_in || v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__comma))) { bool val_is_mut = p->tok.kind == v__token__Kind__key_mut; v__token__Pos mut_pos = v__token__Token_pos(&p->tok); if (val_is_mut) { v__parser__Parser_next(p); } v__token__Pos key_var_pos = v__token__Token_pos(&p->tok); v__token__Pos val_var_pos = v__token__Token_pos(&p->tok); string key_var_name = _S(""); string val_var_name = v__parser__Parser_check_name(p); if (p->tok.kind == v__token__Kind__comma) { if (val_is_mut) { v__parser__Parser_error_with_pos(p, _S("index of array or key of map cannot be mutated"), mut_pos); } v__parser__Parser_next(p); if (p->tok.kind == v__token__Kind__key_mut) { v__parser__Parser_next(p); val_is_mut = true; } key_var_name = val_var_name; val_var_pos = v__token__Token_pos(&p->tok); val_var_name = v__parser__Parser_check_name(p); if (string__eq(key_var_name, val_var_name) && _SLIT_NE(key_var_name.str, key_var_name.len, "_")) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("key and value in a for loop cannot be the same"), val_var_pos)))); } if (v__ast__Scope_known_var(p->scope, key_var_name)) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("redefinition of key iteration variable `"), 0xfe10, {.d_s = key_var_name}}, {_S("`"), 0, { .d_c = 0 }}})), key_var_pos)))); } if (v__ast__Scope_known_var(p->scope, val_var_name)) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("redefinition of value iteration variable `"), 0xfe10, {.d_s = val_var_name}}, {_S("`"), 0, { .d_c = 0 }}})), val_var_pos)))); } v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = key_var_name,.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = _const_v__ast__int_type,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = key_var_pos,.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = true,.is_auto_heap = 0,.is_stack_obj = true,}))))); } else if (v__ast__Scope_known_var(p->scope, val_var_name)) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("redefinition of value iteration variable `"), 0xfe10, {.d_s = val_var_name}}, {_S("`, use `for ("), 0xfe10, {.d_s = val_var_name}}, {_S(" in array) {` if you want to check for a condition instead"), 0, { .d_c = 0 }}})), val_var_pos)))); } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t16, Array_v__ast__Comment); v__parser__Parser_check(p, v__token__Kind__key_in); _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t17, Array_v__ast__Comment); p->inside_for_expr = true; v__ast__Expr cond = v__parser__Parser_expr(p, 0); p->inside_for_expr = false; v__ast__Expr high_expr = _const_v__ast__empty_expr; bool is_range = false; if (p->tok.kind == v__token__Kind__ellipsis) { v__parser__Parser_error_with_pos(p, _S("for loop only supports exclusive (`..`) ranges, not inclusive (`...`)"), v__token__Token_pos(&p->tok)); } else if (p->tok.kind == v__token__Kind__dotdot) { is_range = true; v__parser__Parser_next(p); high_expr = v__parser__Parser_expr(p, 0); v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = val_var_name,.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = _const_v__ast__int_type,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = val_var_pos,.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = true,.is_auto_heap = 0,.is_stack_obj = true,}))))); if ((key_var_name).len != 0) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("cannot declare index variable with range `for`"), key_var_pos)))); } if (val_is_mut) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("variable in range `for` cannot be mut"), mut_pos)))); } } else { v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){ .name = val_var_name, .share = 0, .is_mut = val_is_mut, .is_static = 0, .is_volatile = 0, .is_autofree_tmp = 0, .is_inherited = 0, .has_inherited = 0, .is_arg = 0, .is_auto_deref = val_is_mut, .is_unwrapped = 0, .is_index_var = 0, .expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .typ = 0, .orig_type = 0, .smartcasts = __new_array(0, 0, sizeof(v__ast__Type)), .pos = val_var_pos, .is_used = 0, .is_changed = 0, .ct_type_var = 0, .ct_type_unwrapped = 0, .is_or = 0, .is_tmp = true, .is_auto_heap = 0, .is_stack_obj = true, }))))); } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t20, Array_v__ast__Comment); p->inside_for = false; Array_v__ast__Stmt stmts = v__parser__Parser_parse_block_no_scope(p, false); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); v__ast__ForInStmt for_in_stmt = ((v__ast__ForInStmt){ .key_var = key_var_name, .val_var = val_var_name, .is_range = is_range, .pos = pos, .kv_pos = key_var_pos, .vv_pos = val_var_pos, .comments = comments, .val_is_mut = val_is_mut, .val_is_ref = 0, .cond = cond, .key_type = 0, .val_type = 0, .cond_type = 0, .high = high_expr, .high_type = 0, .kind = 0, .label = (string){.str=(byteptr)"", .is_lit=1}, .scope = p->scope, .stmts = stmts, }); v__parser__Parser_close_scope(p); return v__ast__ForInStmt_to_sumtype_v__ast__Stmt(&for_in_stmt); } v__ast__Expr cond = v__parser__Parser_expr(p, 0); p->inside_for = false; v__parser__Parser_open_scope(p); Array_v__ast__Stmt stmts = v__parser__Parser_parse_block_no_scope(p, false); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); v__ast__ForStmt for_stmt = ((v__ast__ForStmt){.is_inf = 0,.pos = pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.cond = cond,.stmts = stmts,.label = (string){.str=(byteptr)"", .is_lit=1},.scope = p->scope,}); v__parser__Parser_close_scope(p); v__parser__Parser_close_scope(p); return v__ast__ForStmt_to_sumtype_v__ast__Stmt(&for_stmt); } VV_LOC v__ast__IfExpr v__parser__Parser_if_expr(v__parser__Parser* p, bool is_comptime, bool is_expr) { bool v__parser__Parser_if_expr_defer_0 = false; bool was_inside_if_expr; bool was_inside_ct_if_expr; was_inside_if_expr = p->inside_if_expr; was_inside_ct_if_expr = p->inside_ct_if_expr; v__parser__Parser_if_expr_defer_0 = true; p->inside_if_expr = true; bool is_expr_ = p->prev_tok.kind == v__token__Kind__key_return || is_expr; v__token__Pos pos = v__token__Token_pos(&p->tok); if (is_comptime) { p->inside_ct_if_expr = true; v__parser__Parser_next(p); pos = v__token__Pos_extend(v__token__Token_pos(&p->prev_tok), v__token__Token_pos(&p->tok)); } Array_v__ast__IfBranch branches = __new_array_with_default(0, 0, sizeof(v__ast__IfBranch), 0); bool has_else = false; Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); bool prev_guard = false; for (;;) { if (!((p->tok.kind == v__token__Kind__key_if || p->tok.kind == v__token__Kind__key_else))) break; p->inside_if = true; if (is_comptime) { p->inside_comptime_if = true; } v__token__Pos start_pos = (is_comptime ? (v__token__Pos_extend(v__token__Token_pos(&p->prev_tok), v__token__Token_pos(&p->tok))) : (v__token__Token_pos(&p->tok))); if (p->tok.kind == v__token__Kind__key_else) { _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t1, Array_v__ast__Comment); v__parser__Parser_check(p, v__token__Kind__key_else); _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t2, Array_v__ast__Comment); if (p->tok.kind == v__token__Kind__key_match) { v__parser__Parser_error(p, _S("cannot use `match` with `if` statements")); v__ast__IfExpr _t3 = ((v__ast__IfExpr){.is_comptime = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.post_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.branches = __new_array(0, 0, sizeof(v__ast__IfBranch)),.is_expr = 0,.typ = 0,.has_else = 0,}); // Defer begin if (v__parser__Parser_if_expr_defer_0) { p->inside_if_expr = was_inside_if_expr; p->inside_ct_if_expr = was_inside_ct_if_expr; } // Defer end return _t3; } if (p->tok.kind == v__token__Kind__lcbr) { has_else = true; p->inside_if = false; p->inside_comptime_if = false; v__token__Pos end_pos = v__token__Token_pos(&p->prev_tok); v__token__Pos body_pos = v__token__Token_pos(&p->tok); v__parser__Parser_open_scope(p); if (prev_guard) { v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = _S("err"),.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = _const_v__ast__error_type,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = v__token__Token_pos(&p->tok),.is_used = true,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = true,}))))); } array_push((array*)&branches, _MOV((v__ast__IfBranch[]){ ((v__ast__IfBranch){.pos = v__token__Pos_extend(start_pos, end_pos),.body_pos = v__token__Pos_extend(body_pos, v__token__Token_pos(&p->tok)),.comments = comments,.cond = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.pkg_exist = 0,.stmts = v__parser__Parser_parse_block_no_scope(p, false),.scope = p->scope,}) })); v__parser__Parser_close_scope(p); comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); break; } if (is_comptime) { v__parser__Parser_check(p, v__token__Kind__dollar); } } v__token__Pos if_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__key_if); if (p->tok.kind == v__token__Kind__key_match) { v__parser__Parser_error(p, _S("cannot use `match` with `if` statements")); v__ast__IfExpr _t5 = ((v__ast__IfExpr){.is_comptime = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.post_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.branches = __new_array(0, 0, sizeof(v__ast__IfBranch)),.is_expr = 0,.typ = 0,.has_else = 0,}); // Defer begin if (v__parser__Parser_if_expr_defer_0) { p->inside_if_expr = was_inside_if_expr; p->inside_ct_if_expr = was_inside_ct_if_expr; } // Defer end return _t5; } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t6, Array_v__ast__Comment); v__ast__Expr cond = _const_v__ast__empty_expr; bool is_guard = false; if (!is_comptime && v__parser__Parser_peek_token_after_var_list(p).kind == v__token__Kind__decl_assign) { v__parser__Parser_open_scope(p); is_guard = true; Array_v__ast__IfGuardVar vars = __new_array_with_default(0, 0, sizeof(v__ast__IfGuardVar), 0); Array_string var_names = __new_array_with_default(0, 0, sizeof(string), 0); for (;;) { v__ast__IfGuardVar var = ((v__ast__IfGuardVar){.name = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); bool is_mut = false; if (p->tok.kind == v__token__Kind__key_mut) { is_mut = true; v__parser__Parser_next(p); } var.is_mut = is_mut; var.pos = v__token__Token_pos(&p->tok); var.name = v__parser__Parser_check_name(p); array_push((array*)&var_names, _MOV((string[]){ string_clone(var.name) })); if (v__ast__Scope_known_var(p->scope, var.name)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("redefinition of `"), 0xfe10, {.d_s = var.name}}, {_S("`"), 0, { .d_c = 0 }}})), var.pos); } array_push((array*)&vars, _MOV((v__ast__IfGuardVar[]){ var })); if (p->tok.kind != v__token__Kind__comma) { break; } v__parser__Parser_next(p); } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t9, Array_v__ast__Comment); v__parser__Parser_check(p, v__token__Kind__decl_assign); _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t10, Array_v__ast__Comment); v__ast__Expr expr = v__parser__Parser_expr(p, 0); if (!((expr)._typ == 344 /* v.ast.CallExpr */ || (expr)._typ == 361 /* v.ast.IndexExpr */ || (expr)._typ == 376 /* v.ast.PrefixExpr */ || (expr)._typ == 379 /* v.ast.SelectorExpr */ || (expr)._typ == 358 /* v.ast.Ident */)) { v__parser__Parser_error_with_pos(p, _S("if guard condition expression is illegal, it should return an Option"), v__ast__Expr_pos(expr)); } _result_void _t11 = v__parser__Parser_check_undefined_variables(p, var_names, expr); if (_t11.is_error) { IError err = _t11.err; v__parser__Parser_error_with_pos(p, IError_name_table[err._typ]._method_msg(err._object), pos); break; } ; cond = v__ast__IfGuardExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__IfGuardExpr, (((v__ast__IfGuardExpr){.vars = vars,.expr = expr,.expr_type = 0,})))); for (int _t12 = 0; _t12 < vars.len; ++_t12) { v__ast__IfGuardVar var = ((v__ast__IfGuardVar*)vars.data)[_t12]; v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = var.name,.share = 0,.is_mut = var.is_mut,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = cond,.typ = 0,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = var.pos,.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,}))))); } prev_guard = true; } else { prev_guard = false; p->comptime_if_cond = true; p->inside_if_cond = true; cond = v__parser__Parser_expr(p, 0); if ((cond)._typ == 362 /* v.ast.InfixExpr */ && !is_comptime) { if ((*cond._v__ast__InfixExpr).op == v__token__Kind__key_is || (*cond._v__ast__InfixExpr).op == v__token__Kind__not_is) { if (((*cond._v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */) { if ((*(*cond._v__ast__InfixExpr).left._v__ast__Ident).name.len == 1 && string_is_capital((*(*cond._v__ast__InfixExpr).left._v__ast__Ident).name) && ((*cond._v__ast__InfixExpr).right)._typ == 386 /* v.ast.TypeNode */) { v__parser__Parser_error_with_pos(p, _S("use `$if` instead of `if`"), if_pos); v__ast__IfExpr _t13 = ((v__ast__IfExpr){.is_comptime = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.post_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.branches = __new_array(0, 0, sizeof(v__ast__IfBranch)),.is_expr = 0,.typ = 0,.has_else = 0,}); // Defer begin if (v__parser__Parser_if_expr_defer_0) { p->inside_if_expr = was_inside_if_expr; p->inside_ct_if_expr = was_inside_ct_if_expr; } // Defer end return _t13; } } } } p->inside_if_cond = false; if (p->if_cond_comments.len > 0) { _PUSH_MANY(&comments, (p->if_cond_comments), _t14, Array_v__ast__Comment); p->if_cond_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); } p->comptime_if_cond = false; } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t15, Array_v__ast__Comment); v__token__Pos end_pos = v__token__Token_pos(&p->prev_tok); v__token__Pos body_pos = v__token__Token_pos(&p->tok); p->inside_if = false; p->inside_comptime_if = false; if (p->opened_scopes > p->max_opened_scopes) { p->should_abort = true; v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("too many nested conditionals, scopes: "), 0xfe07, {.d_i32 = p->opened_scopes}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__ast__IfExpr _t16 = ((v__ast__IfExpr){.is_comptime = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.post_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.branches = __new_array(0, 0, sizeof(v__ast__IfBranch)),.is_expr = 0,.typ = 0,.has_else = 0,}); // Defer begin if (v__parser__Parser_if_expr_defer_0) { p->inside_if_expr = was_inside_if_expr; p->inside_ct_if_expr = was_inside_ct_if_expr; } // Defer end return _t16; } v__parser__Parser_open_scope(p); Array_v__ast__Stmt stmts = v__parser__Parser_parse_block_no_scope(p, false); array_push((array*)&branches, _MOV((v__ast__IfBranch[]){ ((v__ast__IfBranch){ .pos = v__token__Pos_extend(start_pos, end_pos), .body_pos = v__token__Pos_extend(body_pos, v__token__Token_pos(&p->prev_tok)), .comments = comments, .cond = cond, .pkg_exist = 0, .stmts = stmts, .scope = p->scope, }) })); v__parser__Parser_close_scope(p); if (is_guard) { v__parser__Parser_close_scope(p); } comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); if (is_comptime) { if (p->tok.kind == v__token__Kind__key_else) { v__parser__Parser_error(p, _S("use `$else` instead of `else` in compile-time `if` branches")); v__ast__IfExpr _t18 = ((v__ast__IfExpr){.is_comptime = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.post_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.branches = __new_array(0, 0, sizeof(v__ast__IfBranch)),.is_expr = 0,.typ = 0,.has_else = 0,}); // Defer begin if (v__parser__Parser_if_expr_defer_0) { p->inside_if_expr = was_inside_if_expr; p->inside_ct_if_expr = was_inside_ct_if_expr; } // Defer end return _t18; } if (p->tok.kind != v__token__Kind__rcbr && p->peek_tok.kind == v__token__Kind__key_else) { v__parser__Parser_check(p, v__token__Kind__dollar); } } if (p->tok.kind != v__token__Kind__key_else) { break; } } v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); if (comments.len > 0) { pos.last_line = (*(v__ast__Comment*)array_last(comments)).pos.last_line; } v__ast__IfExpr _t19 = ((v__ast__IfExpr){ .is_comptime = is_comptime, .tok_kind = 0, .pos = pos, .post_comments = comments, .left = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .branches = branches, .is_expr = is_expr_, .typ = 0, .has_else = has_else, }); // Defer begin if (v__parser__Parser_if_expr_defer_0) { p->inside_if_expr = was_inside_if_expr; p->inside_ct_if_expr = was_inside_ct_if_expr; } // Defer end return _t19; } VV_LOC bool v__parser__Parser_is_only_array_type(v__parser__Parser* p) { if (p->tok.kind == v__token__Kind__lsbr) { for (int i = 1; i < 20; ++i) { if (v__parser__Parser_peek_token(p, i).kind == v__token__Kind__rsbr) { v__token__Kind next_kind = v__parser__Parser_peek_token(p, (int_literal)(i + 1)).kind; if (next_kind == v__token__Kind__name) { return true; } else if (next_kind == v__token__Kind__question && v__parser__Parser_peek_token(p, (int_literal)(i + 2)).kind == v__token__Kind__name) { return true; } else if (next_kind == v__token__Kind__lsbr) { continue; } else { return false; } } } } return false; } VV_LOC bool v__parser__Parser_is_match_sumtype_type(v__parser__Parser* p) { bool is_option = p->tok.kind == v__token__Kind__question; v__token__Token name_tok = (is_option ? (p->peek_tok) : (p->tok)); v__token__Kind next_tok_kind = (is_option ? (v__parser__Parser_peek_token(p, 2).kind) : (p->peek_tok.kind)); int next_next_idx = (is_option ? (3) : (2)); v__token__Token next_next_tok = v__parser__Parser_peek_token(p, next_next_idx); return name_tok.kind == v__token__Kind__name && !(fast_string_eq(name_tok.lit, _S("C")) && next_tok_kind == v__token__Kind__dot) && (((v__token__KeywordsMatcherTrie_matches(&_const_v__ast__builtin_type_names_matcher, name_tok.lit) || u8_is_capital(string_at(name_tok.lit, 0))) && next_tok_kind != v__token__Kind__lpar && !(next_tok_kind == v__token__Kind__dot && next_next_tok.kind == v__token__Kind__name && v__parser__Parser_peek_token(p, (int)(next_next_idx + 1)).kind == v__token__Kind__lpar)) || (next_tok_kind == v__token__Kind__dot && next_next_tok.lit.len > 0 && u8_is_capital(string_at(next_next_tok.lit, 0)))); } VV_LOC v__ast__MatchExpr v__parser__Parser_match_expr(v__parser__Parser* p) { v__token__Pos match_first_pos = v__token__Token_pos(&p->tok); bool old_inside_match = p->inside_match; p->inside_match = true; v__parser__Parser_check(p, v__token__Kind__key_match); bool is_sum_type = false; v__ast__Expr cond = v__parser__Parser_expr(p, 0); p->inside_match = old_inside_match; bool no_lcbr = p->tok.kind != v__token__Kind__lcbr; if (!no_lcbr) { v__parser__Parser_check(p, v__token__Kind__lcbr); } Array_v__ast__Comment comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); Array_v__ast__MatchBranch branches = __new_array_with_default(0, 0, sizeof(v__ast__MatchBranch), 0); for (;;) { if (!(p->tok.kind != v__token__Kind__eof)) break; v__token__Pos branch_first_pos = v__token__Token_pos(&p->tok); Array_v__ast__Expr exprs = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); Array_Array_v__ast__Comment ecmnts = __new_array_with_default(0, 0, sizeof(Array_v__ast__Comment), 0); v__parser__Parser_open_scope(p); bool is_else = false; if (p->tok.kind == v__token__Kind__key_else) { is_else = true; v__parser__Parser_next(p); } else if (v__parser__Parser_is_match_sumtype_type(p) || v__parser__Parser_is_only_array_type(p) || p->tok.kind == v__token__Kind__key_fn || (p->tok.kind == v__token__Kind__lsbr && v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__amp)) { Array_v__ast__Type types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (;;) { v__ast__Type parsed_type = v__parser__Parser_parse_type(p); array_push((array*)&types, _MOV((v__ast__Type[]){ parsed_type })); array_push((array*)&exprs, _MOV((v__ast__Expr[]){ v__ast__TypeNode_to_sumtype_v__ast__Expr(ADDR(v__ast__TypeNode, (((v__ast__TypeNode){.pos = v__token__Token_pos(&p->prev_tok),.typ = parsed_type,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),})))) })); if (p->tok.kind != v__token__Kind__comma) { array_push((array*)&ecmnts, _MOV((Array_v__ast__Comment[]){ v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})) })); break; } v__parser__Parser_check(p, v__token__Kind__comma); if (p->pref->is_fmt) { if (p->tok.kind == v__token__Kind__lcbr) { break; } for (;;) { if (!(p->tok.kind == v__token__Kind__comma)) break; v__parser__Parser_next(p); } array_push((array*)&ecmnts, _MOV((Array_v__ast__Comment[]){ v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})) })); } } is_sum_type = true; } else { if (p->tok.kind == v__token__Kind__rcbr) { v__parser__Parser_next(p); return ((v__ast__MatchExpr){.tok_kind = 0,.pos = match_first_pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.cond = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.branches = __new_array(0, 0, sizeof(v__ast__MatchBranch)),.is_expr = 0,.return_type = 0,.cond_type = 0,.expected_type = 0,.is_sum_type = 0,}); } for (;;) { p->inside_match_case = true; v__token__Pos range_pos = v__token__Token_pos(&p->tok); v__ast__Expr expr = v__parser__Parser_expr(p, 0); p->inside_match_case = false; if (p->tok.kind == v__token__Kind__dotdot) { v__parser__Parser_error_with_pos(p, _S("match only supports inclusive (`...`) ranges, not exclusive (`..`)"), v__token__Token_pos(&p->tok)); return ((v__ast__MatchExpr){.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.cond = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.branches = __new_array(0, 0, sizeof(v__ast__MatchBranch)),.is_expr = 0,.return_type = 0,.cond_type = 0,.expected_type = 0,.is_sum_type = 0,}); } else if (p->tok.kind == v__token__Kind__ellipsis) { v__parser__Parser_next(p); p->inside_match_case = true; v__ast__Expr expr2 = v__parser__Parser_expr(p, 0); p->inside_match_case = false; array_push((array*)&exprs, _MOV((v__ast__Expr[]){ v__ast__RangeExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__RangeExpr, (((v__ast__RangeExpr){.has_high = true,.has_low = true,.pos = v__token__Pos_extend(range_pos, v__token__Token_pos(&p->prev_tok)),.is_gated = 0,.low = expr,.high = expr2,.typ = 0,})))) })); } else { array_push((array*)&exprs, _MOV((v__ast__Expr[]){ expr })); } if (p->tok.kind != v__token__Kind__comma) { array_push((array*)&ecmnts, _MOV((Array_v__ast__Comment[]){ v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})) })); break; } v__parser__Parser_check(p, v__token__Kind__comma); if (p->pref->is_fmt) { if (p->tok.kind == v__token__Kind__lcbr) { break; } for (;;) { if (!(p->tok.kind == v__token__Kind__comma)) break; v__parser__Parser_next(p); } array_push((array*)&ecmnts, _MOV((Array_v__ast__Comment[]){ v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})) })); } } } v__token__Pos branch_last_pos = v__token__Token_pos(&p->prev_tok); p->inside_match_body = true; Array_v__ast__Stmt stmts = v__parser__Parser_parse_block_no_scope(p, false); v__ast__Scope* branch_scope = p->scope; v__parser__Parser_close_scope(p); p->inside_match_body = false; v__token__Pos pos = v__token__Pos_extend_with_last_line(branch_first_pos, branch_last_pos, p->prev_tok.line_nr); v__token__Pos branch_pos = v__token__Pos_extend_with_last_line(branch_first_pos, v__token__Token_pos(&p->tok), p->tok.line_nr); Array_v__ast__Comment post_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); array_push((array*)&branches, _MOV((v__ast__MatchBranch[]){ ((v__ast__MatchBranch){ .ecmnts = ecmnts, .pos = pos, .is_else = is_else, .post_comments = post_comments, .branch_pos = branch_pos, .stmts = stmts, .exprs = exprs, .scope = branch_scope, }) })); if (p->tok.kind == v__token__Kind__rcbr || (is_else && no_lcbr)) { break; } } v__token__Pos match_last_pos = v__token__Token_pos(&p->tok); v__token__Pos pos = ((v__token__Pos){.len = (int)((int)(match_last_pos.pos - match_first_pos.pos) + match_last_pos.len),.line_nr = match_first_pos.line_nr,.pos = match_first_pos.pos,.col = match_first_pos.col,.last_line = 0,}); if (p->tok.kind == v__token__Kind__rcbr) { v__parser__Parser_check(p, v__token__Kind__rcbr); } v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); return ((v__ast__MatchExpr){.tok_kind = 0,.pos = pos,.comments = comments,.cond = cond,.branches = branches,.is_expr = 0,.return_type = 0,.cond_type = 0,.expected_type = 0,.is_sum_type = is_sum_type,}); } VV_LOC v__ast__SelectExpr v__parser__Parser_select_expr(v__parser__Parser* p) { v__token__Pos match_first_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__key_select); bool no_lcbr = p->tok.kind != v__token__Kind__lcbr; if (!no_lcbr) { v__parser__Parser_check(p, v__token__Kind__lcbr); } Array_v__ast__SelectBranch branches = __new_array_with_default(0, 0, sizeof(v__ast__SelectBranch), 0); bool has_else = false; bool has_timeout = false; for (;;) { v__token__Pos branch_first_pos = v__token__Token_pos(&p->tok); v__ast__Comment comment = v__parser__Parser_check_comment(p); v__parser__Parser_open_scope(p); bool is_else = false; bool is_timeout = false; v__ast__Stmt stmt = _const_v__ast__empty_stmt; if (p->tok.kind == v__token__Kind__key_else) { if (has_timeout) { v__parser__Parser_error_with_pos(p, _S("timeout `> t` and `else` are mutually exclusive `select` keys"), v__token__Token_pos(&p->tok)); return ((v__ast__SelectExpr){.branches = __new_array(0, 0, sizeof(v__ast__SelectBranch)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_exception = 0,.is_expr = 0,.expected_type = 0,}); } if (has_else) { v__parser__Parser_error_with_pos(p, _S("at most one `else` branch allowed in `select` block"), v__token__Token_pos(&p->tok)); return ((v__ast__SelectExpr){.branches = __new_array(0, 0, sizeof(v__ast__SelectBranch)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_exception = 0,.is_expr = 0,.expected_type = 0,}); } is_else = true; has_else = true; v__parser__Parser_next(p); } else { bool is_gt = false; if (p->tok.kind == v__token__Kind__gt) { is_gt = true; v__parser__Parser_note_with_pos(p, _S("`>` is deprecated and will soon be forbidden - just state the timeout in nanoseconds"), v__token__Token_pos(&p->tok)); v__parser__Parser_next(p); } p->inside_match = true; p->inside_select = true; Array_v__ast__Expr exprs = v__parser__Parser_expr_list(p, true); if (exprs.len != 1) { v__parser__Parser_error(p, _S("only one expression allowed as `select` key")); return ((v__ast__SelectExpr){.branches = __new_array(0, 0, sizeof(v__ast__SelectBranch)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_exception = 0,.is_expr = 0,.expected_type = 0,}); } if (p->tok.kind == v__token__Kind__assign || p->tok.kind == v__token__Kind__decl_assign) { stmt = v__parser__Parser_partial_assign_stmt(p, exprs); } else { stmt = v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (((v__ast__ExprStmt){.pos = v__ast__Expr_pos((*(v__ast__Expr*)array_get(exprs, 0))),.comments = new_array_from_c_array(1, 1, sizeof(v__ast__Comment), _MOV((v__ast__Comment[1]){comment})),.expr = (*(v__ast__Expr*)array_get(exprs, 0)),.is_expr = true,.typ = 0,})))); } p->inside_match = false; p->inside_select = false; if (stmt._typ == 401 /* v.ast.ExprStmt */) { bool check_timeout = false; if (!(*stmt._v__ast__ExprStmt).is_expr) { v__parser__Parser_error_with_pos(p, _S("select: invalid expression"), (*stmt._v__ast__ExprStmt).pos); return ((v__ast__SelectExpr){.branches = __new_array(0, 0, sizeof(v__ast__SelectBranch)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_exception = 0,.is_expr = 0,.expected_type = 0,}); } else { if ((*stmt._v__ast__ExprStmt).expr._typ == 362 /* v.ast.InfixExpr */) { if ((*(*stmt._v__ast__ExprStmt).expr._v__ast__InfixExpr).op != v__token__Kind__arrow) { check_timeout = true; } else if (is_gt) { v__parser__Parser_error_with_pos(p, _S("send expression cannot be used as timeout"), (*stmt._v__ast__ExprStmt).pos); } } else { check_timeout = true; } } if (check_timeout) { if (has_else) { v__parser__Parser_error_with_pos(p, _S("`else` and timeout value are mutually exclusive `select` keys"), (*stmt._v__ast__ExprStmt).pos); return ((v__ast__SelectExpr){.branches = __new_array(0, 0, sizeof(v__ast__SelectBranch)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_exception = 0,.is_expr = 0,.expected_type = 0,}); } if (has_timeout) { v__parser__Parser_error_with_pos(p, _S("at most one timeout branch allowed in `select` block"), (*stmt._v__ast__ExprStmt).pos); return ((v__ast__SelectExpr){.branches = __new_array(0, 0, sizeof(v__ast__SelectBranch)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_exception = 0,.is_expr = 0,.expected_type = 0,}); } is_timeout = true; has_timeout = true; } } else if (stmt._typ == 392 /* v.ast.AssignStmt */) { v__ast__Expr expr = (*(v__ast__Expr*)array_get((*stmt._v__ast__AssignStmt).right, 0)); if (expr._typ == 376 /* v.ast.PrefixExpr */) { if ((*expr._v__ast__PrefixExpr).op != v__token__Kind__arrow) { v__parser__Parser_error_with_pos(p, _S("select key: `<-` operator expected"), (*expr._v__ast__PrefixExpr).pos); return ((v__ast__SelectExpr){.branches = __new_array(0, 0, sizeof(v__ast__SelectBranch)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_exception = 0,.is_expr = 0,.expected_type = 0,}); } } else { v__parser__Parser_error_with_pos(p, _S("select key: receive expression expected"), v__ast__Expr_pos((*(v__ast__Expr*)array_get((*stmt._v__ast__AssignStmt).right, 0)))); return ((v__ast__SelectExpr){.branches = __new_array(0, 0, sizeof(v__ast__SelectBranch)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_exception = 0,.is_expr = 0,.expected_type = 0,}); } } else { v__parser__Parser_error_with_pos(p, _S("select: transmission statement, timeout (in ns) or `else` expected"), (*(stmt.pos))); return ((v__ast__SelectExpr){.branches = __new_array(0, 0, sizeof(v__ast__SelectBranch)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_exception = 0,.is_expr = 0,.expected_type = 0,}); } } v__token__Pos branch_last_pos = v__token__Token_pos(&p->tok); p->inside_match_body = true; p->inside_for = false; Array_v__ast__Stmt stmts = v__parser__Parser_parse_block_no_scope(p, false); v__parser__Parser_close_scope(p); p->inside_match_body = false; v__token__Pos pos = ((v__token__Pos){.len = (int)((int)(branch_last_pos.pos - branch_first_pos.pos) + branch_last_pos.len),.line_nr = branch_first_pos.line_nr,.pos = branch_first_pos.pos,.col = branch_first_pos.col,.last_line = 0,}); Array_v__ast__Comment post_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); if (post_comments.len > 0) { pos.last_line = (*(v__ast__Comment*)array_last(post_comments)).pos.last_line; } array_push((array*)&branches, _MOV((v__ast__SelectBranch[]){ ((v__ast__SelectBranch){ .pos = pos, .comment = comment, .is_else = is_else, .is_timeout = is_timeout, .post_comments = post_comments, .stmt = stmt, .stmts = stmts, }) })); if (p->tok.kind == v__token__Kind__rcbr || ((is_else || is_timeout) && no_lcbr)) { break; } } v__token__Pos match_last_pos = v__token__Token_pos(&p->tok); v__token__Pos pos = ((v__token__Pos){.len = (int)((int)(match_last_pos.pos - match_first_pos.pos) + match_last_pos.len),.line_nr = match_first_pos.line_nr,.pos = match_first_pos.pos,.col = match_first_pos.col,.last_line = 0,}); if (p->tok.kind == v__token__Kind__rcbr) { v__parser__Parser_check(p, v__token__Kind__rcbr); } v__parser__Parser_register_auto_import(p, _S("sync")); return ((v__ast__SelectExpr){.branches = branches,.pos = v__token__Pos_extend_with_last_line(pos, v__token__Token_pos(&p->prev_tok), p->prev_tok.line_nr),.has_exception = has_else || has_timeout,.is_expr = 0,.expected_type = 0,}); } VV_LOC v__ast__Expr v__parser__Parser_lockable(v__parser__Parser* p) { Array_string names = __new_array_with_default(0, 0, sizeof(string), 0); Array_v__token__Pos positions = __new_array_with_default(0, 0, sizeof(v__token__Pos), 0); v__token__Pos pos = v__token__Token_pos(&p->tok); for (;;) { if (p->tok.kind != v__token__Kind__name) { v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = p->tok.lit}}, {_S("`"), 0, { .d_c = 0 }}})),.expecting = _S("field or variable name"),.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); } array_push((array*)&names, _MOV((string[]){ string_clone(p->tok.lit) })); array_push((array*)&positions, _MOV((v__token__Pos[]){ pos })); v__parser__Parser_next(p); if (p->tok.kind != v__token__Kind__dot) { break; } v__parser__Parser_next(p); v__token__Pos_extend(pos, v__token__Token_pos(&p->tok)); } v__ast__Expr expr = v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (((v__ast__Ident){ .language = v__ast__Language__v, .tok_kind = 0, .pos = (*(v__token__Pos*)array_get(positions, 0)), .mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .comptime = 0, .scope = p->scope, .obj = _const_v__ast__empty_scope_object, .mod = p->mod, .name = (*(string*)array_get(names, 0)), .full_name = (string){.str=(byteptr)"", .is_lit=1}, .cached_name = (string){.str=(byteptr)"", .is_lit=1}, .kind = 0, .info = v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentVar, (((v__ast__IdentVar){.typ = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_option = 0,.share = 0,})))), .is_mut = true, .or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .ct_expr = 0, })))); for (int i = 1; i < names.len; i++) { expr = v__ast__SelectorExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__SelectorExpr, (((v__ast__SelectorExpr){ .pos = (*(v__token__Pos*)array_get(positions, i)), .field_name = (*(string*)array_get(names, i)), .is_mut = true, .mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .next_token = (i < (int)(names.len - 1) ? (v__token__Kind__dot) : (p->tok.kind)), .expr = expr, .expr_type = 0, .typ = 0, .name_type = 0, .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .gkind_field = 0, .scope = p->scope, .from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)), .generic_from_embed_types = __new_array(0, 0, sizeof(Array_v__ast__Type)), .has_hidden_receiver = 0, .is_field_typ = 0, })))); } return expr; } VV_LOC Array_v__ast__Expr v__parser__Parser_lockable_list(v__parser__Parser* p) { Array_v__ast__Expr exprs = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); for (;;) { v__ast__Expr expr = v__parser__Parser_lockable(p); if ((expr)._typ != 348 /* v.ast.Comment */) { array_push((array*)&exprs, _MOV((v__ast__Expr[]){ expr })); if (p->tok.kind != v__token__Kind__comma) { break; } v__parser__Parser_next(p); } } return exprs; } VV_LOC v__ast__LockExpr v__parser__Parser_lock_expr(v__parser__Parser* p) { bool v__parser__Parser_lock_expr_defer_0 = false; v__parser__Parser_register_auto_import(p, _S("sync")); v__parser__Parser_open_scope(p); v__parser__Parser_lock_expr_defer_0 = true; v__token__Pos pos = v__token__Token_pos(&p->tok); Array_v__ast__Expr lockeds = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); Array_bool is_rlocked = __new_array_with_default(0, 0, sizeof(bool), 0); for (;;) { bool is_rlock = p->tok.kind == v__token__Kind__key_rlock; if (!is_rlock && p->tok.kind != v__token__Kind__key_lock) { v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = _S("one or more shared variable names"),.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); } v__parser__Parser_next(p); if (p->tok.kind == v__token__Kind__lcbr) { break; } if (p->tok.kind == v__token__Kind__name) { Array_v__ast__Expr exprs = v__parser__Parser_lockable_list(p); for (int _t1 = 0; _t1 < exprs.len; ++_t1) { v__ast__Expr e = ((v__ast__Expr*)exprs.data)[_t1]; if (!v__ast__Expr_is_lockable(&e)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__ast__Expr_str(&e)}}, {_S("` cannot be locked - only `x` or `x.y` are supported"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(e)); } array_push((array*)&lockeds, _MOV((v__ast__Expr[]){ e })); array_push((array*)&is_rlocked, _MOV((bool[]){ is_rlock })); } } if (p->tok.kind == v__token__Kind__lcbr) { break; } if (p->tok.kind == v__token__Kind__semicolon) { v__parser__Parser_next(p); } } Array_v__ast__Stmt stmts = v__parser__Parser_parse_block_no_scope(p, false); v__ast__Scope* scope = p->scope; v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); v__ast__LockExpr _t4 = ((v__ast__LockExpr){.is_rlock = is_rlocked,.pos = pos,.stmts = stmts,.lockeds = lockeds,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_expr = 0,.typ = 0,.scope = scope,}); // Defer begin if (v__parser__Parser_lock_expr_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t4; } VV_LOC void v__parser__Parser_language_not_allowed_error(v__parser__Parser* p, v__ast__Language language, v__token__Pos pos) { string upcase_language = string_to_upper_ascii(v__ast__Language_str(language)); v__parser__Parser_error_with_pos(p, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = upcase_language}}, {_S(" code is not allowed in ."), 0xfe10, {.d_s = v__ast__Language_str(p->file_backend_mode)}}, {_S(".v files, please move it to a ."), 0xfe10, {.d_s = v__ast__Language_str(language)}}, {_S(".v file"), 0, { .d_c = 0 }}})), pos); } VV_LOC void v__parser__Parser_language_not_allowed_warning(v__parser__Parser* p, v__ast__Language language, v__token__Pos pos) { string upcase_language = string_to_upper_ascii(v__ast__Language_str(language)); v__parser__Parser_warn_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = upcase_language}}, {_S(" code will not be allowed in pure .v files, please move it to a ."), 0xfe10, {.d_s = v__ast__Language_str(language)}}, {_S(".v file instead"), 0, { .d_c = 0 }}})), pos); } VV_LOC void v__parser__Parser_check_for_impure_v(v__parser__Parser* p, v__ast__Language language, v__token__Pos pos) { if (language == v__ast__Language__v) { return; } else { if (p->file_backend_mode == (v__ast__Language__c)) { if (language != v__ast__Language__c) { v__parser__Parser_language_not_allowed_error(p, language, pos); return; } } else if (p->file_backend_mode == (v__ast__Language__js)) { if (language != v__ast__Language__js) { v__parser__Parser_language_not_allowed_error(p, language, pos); return; } } else { } } if (!p->pref->warn_impure_v) { return; } if (p->file_backend_mode != language) { if (p->file_backend_mode == v__ast__Language__v) { if (p->pref->is_bare) { return; } v__parser__Parser_language_not_allowed_warning(p, language, pos); return; } } } VV_LOC v__ast__NodeError v__parser__Parser_error(v__parser__Parser* p, string s) { return v__parser__Parser_error_with_pos(p, s, v__token__Token_pos(&p->tok)); } VV_LOC void v__parser__Parser_warn(v__parser__Parser* p, string s) { v__parser__Parser_warn_with_pos(p, s, v__token__Token_pos(&p->tok)); } VV_LOC v__ast__NodeError v__parser__Parser_error_with_pos(v__parser__Parser* p, string s, v__token__Pos pos) { string kind = _S("error:"); if (p->pref->fatal_errors) { v__util__show_compiler_message(kind, ((v__errors__CompilerMessage){.message = s,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = p->file_path,.pos = pos,.reporter = 0,})); _v_exit(1); VUNREACHABLE(); } if (p->pref->output_mode == v__pref__OutputMode__stdout && !p->pref->check_only && !p->is_vls) { if (p->pref->is_verbose) { print_backtrace(); kind = _S("parser error:"); } v__util__show_compiler_message(kind, ((v__errors__CompilerMessage){.message = s,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = p->file_path,.pos = pos,.reporter = 0,})); _v_exit(1); VUNREACHABLE(); } else { array_push((array*)&p->errors, _MOV((v__errors__Error[]){ ((v__errors__Error){.CompilerMessage = ((v__errors__CompilerMessage){.message = s,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = p->file_path,.pos = pos,.reporter = v__errors__Reporter__parser,}),}) })); if (p->pref->check_only || p->pref->only_check_syntax) { if (p->tok.kind != v__token__Kind__eof) { v__parser__Parser_next(p); } } } if (p->pref->output_mode == v__pref__OutputMode__silent && p->tok.kind != v__token__Kind__eof) { v__parser__Parser_next(p); } return ((v__ast__NodeError){.idx = (int)(p->errors.len - 1),.pos = pos,}); } VV_LOC void v__parser__Parser_error_with_error(v__parser__Parser* p, v__errors__Error __v_error) { string kind = _S("error:"); if (p->pref->fatal_errors) { v__util__show_compiler_message(kind, __v_error.CompilerMessage); _v_exit(1); VUNREACHABLE(); } if (p->pref->output_mode == v__pref__OutputMode__stdout && !p->pref->check_only) { if (p->pref->is_verbose) { print_backtrace(); kind = _S("parser error:"); } v__util__show_compiler_message(kind, __v_error.CompilerMessage); _v_exit(1); VUNREACHABLE(); } else { if (p->pref->message_limit >= 0 && p->errors.len >= p->pref->message_limit) { p->should_abort = true; return; } array_push((array*)&p->errors, _MOV((v__errors__Error[]){ __v_error })); } if (p->pref->output_mode == v__pref__OutputMode__silent) { v__parser__Parser_next(p); } } VV_LOC void v__parser__Parser_warn_with_pos(v__parser__Parser* p, string s, v__token__Pos pos) { if (p->pref->warns_are_errors) { v__parser__Parser_error_with_pos(p, s, pos); return; } if (p->pref->skip_warnings) { return; } if (p->pref->output_mode == v__pref__OutputMode__stdout && !p->pref->check_only) { v__util__show_compiler_message(_S("warning:"), ((v__errors__CompilerMessage){.message = s,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = p->file_path,.pos = pos,.reporter = 0,})); } else { if (p->pref->message_limit >= 0 && p->warnings.len >= p->pref->message_limit) { p->should_abort = true; return; } array_push((array*)&p->warnings, _MOV((v__errors__Warning[]){ ((v__errors__Warning){.CompilerMessage = ((v__errors__CompilerMessage){.message = s,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = p->file_path,.pos = pos,.reporter = v__errors__Reporter__parser,}),}) })); } } VV_LOC void v__parser__Parser_note_with_pos(v__parser__Parser* p, string s, v__token__Pos pos) { if (p->pref->skip_warnings) { return; } if (p->pref->skip_notes) { return; } if (p->is_generated) { return; } if (p->pref->notes_are_errors) { v__parser__Parser_error_with_pos(p, s, pos); return; } if (p->pref->output_mode == v__pref__OutputMode__stdout && !p->pref->check_only) { v__util__show_compiler_message(_S("notice:"), ((v__errors__CompilerMessage){.message = s,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = p->file_path,.pos = pos,.reporter = 0,})); } else { array_push((array*)&p->notices, _MOV((v__errors__Notice[]){ ((v__errors__Notice){.CompilerMessage = ((v__errors__CompilerMessage){.message = s,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = p->file_path,.pos = pos,.reporter = v__errors__Reporter__parser,}),}) })); } } VV_LOC v__ast__NodeError v__parser__Parser_unexpected(v__parser__Parser* p, v__parser__ParamsForUnexpected params) { return v__parser__Parser_unexpected_with_pos(p, v__token__Token_pos(&p->tok), params); } VV_LOC v__ast__NodeError v__parser__Parser_unexpected_with_pos(v__parser__Parser* p, v__token__Pos pos, v__parser__ParamsForUnexpected params) { string msg = ((params.got).len != 0 ? (str_intp(2, _MOV((StrIntpData[]){{_S("unexpected "), 0xfe10, {.d_s = params.got}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("unexpected "), 0xfe10, {.d_s = v__token__Token_str(p->tok)}}, {_SLIT0, 0, { .d_c = 0 }}})))); if ((params.expecting).len != 0) { msg = string__plus(msg, str_intp(2, _MOV((StrIntpData[]){{_S(", expecting "), 0xfe10, {.d_s = params.expecting}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if ((params.prepend_msg).len != 0) { msg = string__plus(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = params.prepend_msg}}, {_S(" "), 0, { .d_c = 0 }}})), msg); } if ((params.additional_msg).len != 0) { msg = string__plus(msg, str_intp(2, _MOV((StrIntpData[]){{_S(", "), 0xfe10, {.d_s = params.additional_msg}}, {_SLIT0, 0, { .d_c = 0 }}}))); } return v__parser__Parser_error_with_pos(p, msg, pos); } VV_LOC bool v__parser__Parser_known_import(v__parser__Parser* p, string mod) { return _IN_MAP(ADDR(string, mod), ADDR(map, p->imports)); } VV_LOC string v__parser__Parser_prepend_mod(v__parser__Parser* p, string name) { if ((p->expr_mod).len != 0) { return string__plus(string__plus(p->expr_mod, _S(".")), name); } if (p->builtin_mod) { return name; } return string__plus(string__plus(p->mod, _S(".")), name); } VV_LOC bool v__parser__Parser_is_used_import(v__parser__Parser* p, string alias) { return (Array_string_contains(p->used_imports, alias)); } VV_LOC void v__parser__Parser_register_used_import(v__parser__Parser* p, string alias) { if (!v__parser__Parser_is_used_import(p, alias)) { array_push((array*)&p->used_imports, _MOV((string[]){ string_clone(alias) })); } } VV_LOC void v__parser__Parser_register_used_import_for_symbol_name(v__parser__Parser* p, string sym_name) { string short_import_name = string_all_after_last(string_all_before_last(sym_name, _S(".")), _S(".")); Map_string_string _t1 = p->imports; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string alias = *(string*)DenseArray_key(&_t1.key_values, _t2); alias = string_clone(alias); string mod = (*(string*)DenseArray_value(&_t1.key_values, _t2)); if (string__eq(mod, short_import_name)) { v__parser__Parser_register_used_import(p, alias); return; } } v__parser__Parser_register_used_import(p, short_import_name); } VV_LOC void v__parser__Parser_register_auto_import(v__parser__Parser* p, string alias) { if (string__eq(p->mod, alias)) { return; } if (!_IN_MAP(ADDR(string, alias), ADDR(map, p->imports))) { map_set(&p->imports, &(string[]){alias}, &(string[]) { alias }); array_push((array*)&p->table->imports, _MOV((string[]){ string_clone(alias) })); v__ast__Import node = ((v__ast__Import){.source_name = alias,.mod = alias,.alias = alias,.pos = v__token__Token_pos(&p->tok),.mod_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.alias_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.syms_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.syms = __new_array(0, 0, sizeof(v__ast__ImportSymbol)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); array_push((array*)&p->ast_imports, _MOV((v__ast__Import[]){ node })); } if (!(Array_string_contains(p->auto_imports, alias))) { array_push((array*)&p->auto_imports, _MOV((string[]){ string_clone(alias) })); } v__parser__Parser_register_used_import(p, alias); } VV_LOC void v__parser__Parser_check_unused_imports(v__parser__Parser* p) { if (p->pref->is_repl || p->pref->is_fmt) { return; } for (int _t1 = 0; _t1 < p->ast_imports.len; ++_t1) { v__ast__Import import_m = ((v__ast__Import*)p->ast_imports.data)[_t1]; string alias = import_m.alias; string mod = import_m.mod; if (!(alias.len == 1 && string_at(alias, 0) == '_') && !v__parser__Parser_is_used_import(p, alias)) { string mod_alias = (string__eq(alias, mod) ? (alias) : (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = alias}}, {_S(" ("), 0xfe10, {.d_s = mod}}, {_S(")"), 0, { .d_c = 0 }}})))); v__parser__Parser_warn_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("module '"), 0xfe10, {.d_s = mod_alias}}, {_S("' is imported but never used"), 0, { .d_c = 0 }}})), import_m.mod_pos); } } } VV_LOC v__ast__Module v__parser__Parser_module_decl(v__parser__Parser* p) { Array_v__ast__Attr module_attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); v__token__Pos attrs_pos = v__token__Token_pos(&p->tok); for (;;) { if (!(p->tok.kind == v__token__Kind__lsbr || p->tok.kind == v__token__Kind__at)) break; v__parser__Parser_attributes(p); } _PUSH_MANY(&module_attrs, (p->attrs), _t1, Array_v__ast__Attr); string name = _S("main"); v__token__Pos module_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); v__token__Pos name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); v__ast__Module mod_node = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}); bool is_skipped = p->tok.kind != v__token__Kind__key_module; if (is_skipped) { module_attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); } else { p->attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); module_pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); name_pos = v__token__Token_pos(&p->tok); name = v__parser__Parser_check_name(p); mod_node = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = module_pos,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}); if (module_pos.line_nr != name_pos.line_nr) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("`module` and `"), 0xfe10, {.d_s = name}}, {_S("` must be at same line"), 0, { .d_c = 0 }}})), name_pos); return mod_node; } v__token__Pos n_pos = v__token__Token_pos(&p->tok); if (module_pos.line_nr == n_pos.line_nr && !(p->tok.kind == v__token__Kind__comment || p->tok.kind == v__token__Kind__eof || p->tok.kind == v__token__Kind__semicolon)) { if (p->tok.kind == v__token__Kind__name) { v__parser__Parser_unexpected_with_pos(p, n_pos, ((v__parser__ParamsForUnexpected){.got = str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = p->tok.lit}}, {_S("`"), 0, { .d_c = 0 }}})),.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = str_intp(2, _MOV((StrIntpData[]){{_S("`module "), 0xfe10, {.d_s = name}}, {_S("`, you can only declare one module,"), 0, { .d_c = 0 }}})),.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); return mod_node; } else { v__parser__Parser_unexpected_with_pos(p, n_pos, ((v__parser__ParamsForUnexpected){.got = str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = v__token__Kind_str(p->tok.kind)}}, {_S("` after module name"), 0, { .d_c = 0 }}})),.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = str_intp(2, _MOV((StrIntpData[]){{_S("`module "), 0xfe10, {.d_s = name}}, {_S("`,"), 0, { .d_c = 0 }}})),.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); return mod_node; } } module_pos = v__token__Pos_extend(attrs_pos, name_pos); } string full_name = v__util__qualify_module(p->pref, name, p->file_path); p->mod = full_name; p->builtin_mod = fast_string_eq(p->mod, _S("builtin")); mod_node = ((v__ast__Module){ .name = full_name, .short_name = name, .attrs = module_attrs, .pos = module_pos, .name_pos = name_pos, .is_skipped = is_skipped, }); if (p->tok.kind == v__token__Kind__semicolon) { v__parser__Parser_check(p, v__token__Kind__semicolon); } if (!is_skipped) { (*(Array_v__ast__Attr*)map_get_and_set((map*)&p->table->module_attrs, &(string[]){p->mod}, &(Array_v__ast__Attr[]){ __new_array(0, 0, sizeof(v__ast__Attr)) })) = module_attrs; for (int _t5 = 0; _t5 < module_attrs.len; ++_t5) { v__ast__Attr ma = ((v__ast__Attr*)module_attrs.data)[_t5]; if (_SLIT_EQ(ma.name.str, ma.name.len, "deprecated") || _SLIT_EQ(ma.name.str, ma.name.len, "deprecated_after")) { map_set(&p->table->module_deprecated, &(string[]){p->mod}, &(bool[]) { true }); } else if (_SLIT_EQ(ma.name.str, ma.name.len, "manualfree")) { p->is_manualfree = true; } else if (_SLIT_EQ(ma.name.str, ma.name.len, "generated")) { p->is_generated = true; } else if (_SLIT_EQ(ma.name.str, ma.name.len, "has_globals")) { p->has_globals = true; } else if (_SLIT_EQ(ma.name.str, ma.name.len, "translated")) { p->is_translated = true; } else if (_SLIT_EQ(ma.name.str, ma.name.len, "wasm_import_namespace")) { if (!p->pref->is_fmt && p->pref->backend != v__pref__Backend__wasm) { v__parser__Parser_note_with_pos(p, _S("@[wasm_import_namespace] is only supported by the wasm backend"), ma.pos); } } else { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("unknown module attribute `["), 0xfe10, {.d_s = ma.name}}, {_S("]`"), 0, { .d_c = 0 }}})), ma.pos); return mod_node; } } } return mod_node; } VV_LOC v__ast__Import v__parser__Parser_import_stmt(v__parser__Parser* p) { v__token__Pos import_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__key_import); v__token__Pos pos = v__token__Token_pos(&p->tok); v__ast__Import import_node = ((v__ast__Import){.source_name = (string){.str=(byteptr)"", .is_lit=1},.mod = (string){.str=(byteptr)"", .is_lit=1},.alias = (string){.str=(byteptr)"", .is_lit=1},.pos = v__token__Pos_extend(import_pos, pos),.mod_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.alias_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.syms_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.syms = __new_array(0, 0, sizeof(v__ast__ImportSymbol)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); if (p->tok.kind == v__token__Kind__lpar) { v__parser__Parser_error_with_pos(p, _S("`import()` has been deprecated, use `import x` instead"), pos); return import_node; } string source_name = v__parser__Parser_check_name(p); if ((source_name).len == 0) { v__parser__Parser_error_with_pos(p, _S("import name can not be empty"), pos); return import_node; } Array_string mod_name_arr = __new_array_with_default(0, 0, sizeof(string), 0); array_push((array*)&mod_name_arr, _MOV((string[]){ string_clone(source_name) })); if (import_pos.line_nr != pos.line_nr) { v__parser__Parser_error_with_pos(p, _S("`import` statements must be a single line"), pos); return import_node; } string mod_alias = (*(string*)array_get(mod_name_arr, 0)); import_node = ((v__ast__Import){.source_name = source_name,.mod = (string){.str=(byteptr)"", .is_lit=1},.alias = (string){.str=(byteptr)"", .is_lit=1},.pos = v__token__Pos_extend(import_pos, pos),.mod_pos = pos,.alias_pos = pos,.syms_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.syms = __new_array(0, 0, sizeof(v__ast__ImportSymbol)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); for (;;) { if (!(p->tok.kind == v__token__Kind__dot)) break; v__parser__Parser_next(p); v__token__Pos submod_pos = v__token__Token_pos(&p->tok); if (p->tok.kind != v__token__Kind__name) { v__parser__Parser_error_with_pos(p, _S("module syntax error, please use `x.y.z`"), submod_pos); return import_node; } if (import_pos.line_nr != submod_pos.line_nr) { v__parser__Parser_error_with_pos(p, _S("`import` and `submodule` must be at same line"), submod_pos); return import_node; } string submod_name = v__parser__Parser_check_name(p); array_push((array*)&mod_name_arr, _MOV((string[]){ string_clone(submod_name) })); mod_alias = submod_name; pos = v__token__Pos_extend(pos, submod_pos); source_name = Array_string_join(mod_name_arr, _S(".")); import_node = ((v__ast__Import){ .source_name = source_name, .mod = v__util__qualify_import(p->pref, source_name, p->file_path), .alias = mod_alias, .pos = v__token__Pos_extend(import_pos, pos), .mod_pos = pos, .alias_pos = submod_pos, .syms_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .syms = __new_array(0, 0, sizeof(v__ast__ImportSymbol)), .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .next_comments = __new_array(0, 0, sizeof(v__ast__Comment)), }); } if (mod_name_arr.len == 1) { import_node = ((v__ast__Import){ .source_name = source_name, .mod = v__util__qualify_import(p->pref, (*(string*)array_get(mod_name_arr, 0)), p->file_path), .alias = mod_alias, .pos = import_node.pos, .mod_pos = import_node.mod_pos, .alias_pos = import_node.alias_pos, .syms_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .syms = __new_array(0, 0, sizeof(v__ast__ImportSymbol)), .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .next_comments = __new_array(0, 0, sizeof(v__ast__Comment)), }); } string mod_name = import_node.mod; if (p->tok.kind == v__token__Kind__key_as) { v__parser__Parser_next(p); v__token__Pos alias_pos = v__token__Token_pos(&p->tok); mod_alias = v__parser__Parser_check_name(p); if (string__eq(mod_alias, (*(string*)array_last(mod_name_arr)))) { v__parser__Parser_error_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("import alias `"), 0xfe10, {.d_s = mod_name}}, {_S(" as "), 0xfe10, {.d_s = mod_alias}}, {_S("` is redundant"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->prev_tok)); return import_node; } import_node = ((v__ast__Import){ .source_name = source_name, .mod = import_node.mod, .alias = mod_alias, .pos = v__token__Pos_extend(import_node.pos, alias_pos), .mod_pos = import_node.mod_pos, .alias_pos = alias_pos, .syms_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .syms = __new_array(0, 0, sizeof(v__ast__ImportSymbol)), .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .next_comments = __new_array(0, 0, sizeof(v__ast__Comment)), }); } if (p->tok.kind == v__token__Kind__lcbr) { v__token__Pos initial_syms_pos = v__token__Token_pos(&p->tok); v__parser__Parser_import_syms(p, (voidptr)&import_node); initial_syms_pos = v__token__Pos_extend(initial_syms_pos, v__token__Token_pos(&p->tok)); import_node = ((v__ast__Import){.source_name = source_name,.mod = (import_node).mod,.alias = (import_node).alias,.pos = v__token__Pos_extend(import_node.pos, initial_syms_pos),.mod_pos = (import_node).mod_pos,.alias_pos = (import_node).alias_pos,.syms_pos = initial_syms_pos,.syms = (import_node).syms,.comments = (import_node).comments,.next_comments = (import_node).next_comments,}); } v__token__Pos pos_t = v__token__Token_pos(&p->tok); if (import_pos.line_nr == pos_t.line_nr) { if (!(p->tok.kind == v__token__Kind__lcbr || p->tok.kind == v__token__Kind__eof || p->tok.kind == v__token__Kind__comment || p->tok.kind == v__token__Kind__semicolon || p->tok.kind == v__token__Kind__key_import)) { v__parser__Parser_error_with_pos(p, _S("cannot import multiple modules at a time"), pos_t); return import_node; } } import_node.comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})); import_node.next_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = true,})); map_set(&p->imports, &(string[]){mod_alias}, &(string[]) { mod_name }); if (p->tok.kind == v__token__Kind__semicolon) { v__parser__Parser_check(p, v__token__Kind__semicolon); } array_push((array*)&p->table->imports, _MOV((string[]){ string_clone(mod_name) })); array_push((array*)&p->ast_imports, _MOV((v__ast__Import[]){ import_node })); return import_node; } VV_LOC void v__parser__Parser_import_syms(v__parser__Parser* p, v__ast__Import* parent) { v__parser__Parser_next(p); v__token__Pos pos_t = v__token__Token_pos(&p->tok); if (p->tok.kind == v__token__Kind__rcbr) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("empty `"), 0xfe10, {.d_s = parent->mod}}, {_S("` import set, remove `{}`"), 0, { .d_c = 0 }}})), pos_t); return; } if (p->tok.kind != v__token__Kind__name) { v__parser__Parser_error_with_pos(p, _S("import syntax error, please specify a valid fn or type name"), pos_t); return; } for (;;) { if (!(p->tok.kind == v__token__Kind__name)) break; v__token__Pos pos = v__token__Token_pos(&p->tok); string alias = v__parser__Parser_check_name(p); map_set(&p->imported_symbols, &(string[]){alias}, &(string[]) { string__plus(string__plus(parent->mod, _S(".")), alias) }); array_push((array*)&parent->syms, _MOV((v__ast__ImportSymbol[]){ ((v__ast__ImportSymbol){.pos = pos,.name = alias,}) })); if (p->tok.kind == v__token__Kind__comma) { v__parser__Parser_next(p); continue; } if (p->tok.kind == v__token__Kind__rcbr) { break; } } if (p->tok.kind != v__token__Kind__rcbr) { v__parser__Parser_error_with_pos(p, _S("import syntax error, no closing `}`"), v__token__Token_pos(&p->tok)); return; } v__parser__Parser_next(p); } VV_LOC v__ast__Expr v__parser__Parser_sql_expr(v__parser__Parser* p) { bool tmp_inside_match = p->inside_match; p->inside_orm = true; p->inside_match = true; v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_check_name(p); _result_v__ast__Expr _t1 = v__parser__Parser_check_expr(p, 0); if (_t1.is_error) { IError err = _t1.err; *(v__ast__Expr*) _t1.data = v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = _S("database"),.prepend_msg = _S("invalid expression:"),.additional_msg = (string){.str=(byteptr)"", .is_lit=1},}))))); } v__ast__Expr db_expr = (*(v__ast__Expr*)_t1.data); v__parser__Parser_check(p, v__token__Kind__lcbr); bool is_select = p->tok.kind == v__token__Kind__key_select; bool is_insert = fast_string_eq(p->tok.lit, _S("insert")); if (!is_select && !is_insert) { v__parser__Parser_error(p, _S("expected \"select\" or \"insert\" in an ORM expression")); } v__parser__Parser_next(p); string inserted_var = _S(""); bool is_count = false; if (is_insert) { inserted_var = v__parser__Parser_check_name(p); v__ast__Scope_mark_var_as_used(p->scope, inserted_var); string into = v__parser__Parser_check_name(p); if (_SLIT_NE(into.str, into.len, "into")) { v__parser__Parser_error(p, _S("expecting `into`")); } } else if (is_select) { is_count = string__eq(v__parser__Parser_check_name(p), _S("count")); } v__ast__Type typ = _const_v__ast__void_type; if (is_count) { string n = v__parser__Parser_check_name(p); if (_SLIT_NE(n.str, n.len, "from")) { v__parser__Parser_error(p, _S("expecting \"from\" in a \"select count\" ORM statement")); } } v__token__Pos table_pos = v__token__Token_pos(&p->tok); v__ast__Type table_type = v__parser__Parser_parse_type(p); v__ast__Expr where_expr = _const_v__ast__empty_expr; bool has_where = p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("where")); if (has_where) { v__parser__Parser_next(p); where_expr = v__parser__Parser_expr(p, 0); v__ast__Expr where_check_result = v__parser__Parser_check_sql_where_expr_has_no_undefined_variables(p, &where_expr, __new_array_with_default(0, 0, sizeof(string), 0)); if ((where_check_result)._typ == 335 /* v.ast.NodeError */) { return v__ast__NodeError_to_sumtype_v__ast__Expr(&(*where_check_result._v__ast__NodeError)); } } bool has_limit = false; v__ast__Expr limit_expr = _const_v__ast__empty_expr; bool has_offset = false; v__ast__Expr offset_expr = _const_v__ast__empty_expr; bool has_order = false; v__ast__Expr order_expr = _const_v__ast__empty_expr; bool has_desc = false; if (p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("order"))) { v__parser__Parser_check_name(p); v__token__Pos order_pos = v__token__Token_pos(&p->tok); if (p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("by"))) { v__parser__Parser_check_name(p); } else { return v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("use `order by` in ORM queries"), order_pos)))); } has_order = true; order_expr = v__parser__Parser_expr(p, 0); if (p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("desc"))) { v__parser__Parser_check_name(p); has_desc = true; } } if (p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("limit"))) { v__parser__Parser_check_name(p); has_limit = true; limit_expr = v__parser__Parser_expr(p, 0); } if (p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("offset"))) { v__parser__Parser_check_name(p); has_offset = true; offset_expr = v__parser__Parser_expr(p, 0); } if (is_count) { typ = _const_v__ast__int_type; } else if (v__ast__Type_has_flag(table_type, v__ast__TypeFlag__generic)) { typ = v__ast__Type_set_flag(v__ast__new_type(v__ast__Table_find_or_register_array(p->table, table_type)), v__ast__TypeFlag__generic); } else { typ = v__ast__new_type(v__ast__Table_find_or_register_array(p->table, table_type)); } v__parser__Parser_check(p, v__token__Kind__rcbr); p->inside_match = false; p->inside_orm = false; v__ast__OrExpr or_expr = v__parser__Parser_parse_sql_or_block(p); p->inside_match = tmp_inside_match; return v__ast__SqlExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__SqlExpr, (((v__ast__SqlExpr){ .is_count = is_count, .is_insert = is_insert, .inserted_var = inserted_var, .has_where = has_where, .has_order = has_order, .has_limit = has_limit, .has_offset = has_offset, .has_desc = has_desc, .is_array = (is_count ? (false) : (true)), .is_generated = false, .pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)), .typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__result), .db_expr = db_expr, .where_expr = where_expr, .order_expr = order_expr, .limit_expr = limit_expr, .offset_expr = offset_expr, .table_expr = ((v__ast__TypeNode){.pos = table_pos,.typ = table_type,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}), .fields = __new_array(0, 0, sizeof(v__ast__StructField)), .sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlExpr), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .or_expr = or_expr, })))); } VV_LOC v__ast__SqlStmt v__parser__Parser_sql_stmt(v__parser__Parser* p) { bool v__parser__Parser_sql_stmt_defer_0 = false; v__token__Pos pos = v__token__Token_pos(&p->tok); p->inside_orm = true; p->inside_match = true; v__parser__Parser_sql_stmt_defer_0 = true; v__parser__Parser_check_name(p); _result_v__ast__Expr _t1 = v__parser__Parser_check_expr(p, 0); if (_t1.is_error) { IError err = _t1.err; *(v__ast__Expr*) _t1.data = v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = _S("database"),.prepend_msg = _S("invalid expression:"),.additional_msg = (string){.str=(byteptr)"", .is_lit=1},}))))); } v__ast__Expr db_expr = (*(v__ast__Expr*)_t1.data); v__parser__Parser_check(p, v__token__Kind__lcbr); Array_v__ast__SqlStmtLine lines = __new_array_with_default(0, 0, sizeof(v__ast__SqlStmtLine), 0); for (;;) { if (!(p->tok.kind != v__token__Kind__rcbr)) break; if (p->tok.kind == v__token__Kind__eof) { v__parser__Parser_unexpected_with_pos(p, pos, ((v__parser__ParamsForUnexpected){.got = _S("eof, while parsing an SQL statement"),.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); v__ast__SqlStmt _t2 = ((v__ast__SqlStmt){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.lines = __new_array(0, 0, sizeof(v__ast__SqlStmtLine)),.db_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.db_expr_type = 0,}); // Defer begin if (v__parser__Parser_sql_stmt_defer_0) { p->inside_orm = false; p->inside_match = false; } // Defer end return _t2; } array_push((array*)&lines, _MOV((v__ast__SqlStmtLine[]){ v__parser__Parser_parse_sql_stmt_line(p) })); } v__parser__Parser_next(p); v__ast__OrExpr or_expr = v__parser__Parser_parse_sql_or_block(p); pos.last_line = p->prev_tok.line_nr; v__ast__SqlStmt _t4 = ((v__ast__SqlStmt){.pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)),.lines = lines,.db_expr = db_expr,.or_expr = or_expr,.db_expr_type = 0,}); // Defer begin if (v__parser__Parser_sql_stmt_defer_0) { p->inside_orm = false; p->inside_match = false; } // Defer end return _t4; } VV_LOC v__ast__OrExpr v__parser__Parser_parse_sql_or_block(v__parser__Parser* p) { Array_v__ast__Stmt stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); v__ast__OrKind kind = v__ast__OrKind__absent; v__token__Pos pos = v__token__Token_pos(&p->tok); if (p->tok.kind == v__token__Kind__key_orelse) { kind = v__ast__OrKind__block; multi_return_Array_v__ast__Stmt_v__token__Pos mr_4635 = v__parser__Parser_or_block(p, v__parser__OrBlockErrVarMode__with_err_var); stmts = mr_4635.arg0; pos = mr_4635.arg1; } else if (p->tok.kind == v__token__Kind__not) { kind = v__ast__OrKind__propagate_result; v__parser__Parser_next(p); } return ((v__ast__OrExpr){.kind = kind,.pos = pos,.stmts = stmts,}); } VV_LOC v__ast__SqlStmtLine v__parser__Parser_parse_sql_stmt_line(v__parser__Parser* p) { Array_v__ast__Comment pre_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); string n = v__parser__Parser_check_name(p); v__token__Pos pos = v__token__Token_pos(&p->tok); v__ast__SqlStmtKind kind = v__ast__SqlStmtKind__insert; if (_SLIT_EQ(n.str, n.len, "delete")) { kind = v__ast__SqlStmtKind__delete; } else if (_SLIT_EQ(n.str, n.len, "update")) { kind = v__ast__SqlStmtKind__update; } else if (_SLIT_EQ(n.str, n.len, "create")) { kind = v__ast__SqlStmtKind__create; string table = v__parser__Parser_check_name(p); if (_SLIT_NE(table.str, table.len, "table")) { v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("expected `table` got `"), 0xfe10, {.d_s = table}}, {_S("`"), 0, { .d_c = 0 }}}))); return ((v__ast__SqlStmtLine){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = ((v__ast__TypeNode){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } v__ast__Type typ = v__parser__Parser_parse_type(p); v__token__Pos typ_pos = v__token__Token_pos(&p->tok); Array_v__ast__Comment end_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); return ((v__ast__SqlStmtLine){ .kind = kind, .pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)), .is_generated = false, .scope = p->scope, .object_var = (string){.str=(byteptr)"", .is_lit=1}, .updated_columns = __new_array(0, 0, sizeof(string)), .table_expr = ((v__ast__TypeNode){.pos = typ_pos,.typ = typ,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}), .fields = __new_array(0, 0, sizeof(v__ast__StructField)), .sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)), .pre_comments = pre_comments, .end_comments = end_comments, }); } else if (_SLIT_EQ(n.str, n.len, "drop")) { kind = v__ast__SqlStmtKind__drop; string table = v__parser__Parser_check_name(p); if (_SLIT_NE(table.str, table.len, "table")) { v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("expected `table` got `"), 0xfe10, {.d_s = table}}, {_S("`"), 0, { .d_c = 0 }}}))); return ((v__ast__SqlStmtLine){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = ((v__ast__TypeNode){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } v__ast__Type typ = v__parser__Parser_parse_type(p); v__token__Pos typ_pos = v__token__Token_pos(&p->tok); Array_v__ast__Comment end_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); return ((v__ast__SqlStmtLine){ .kind = kind, .pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)), .is_generated = false, .scope = p->scope, .object_var = (string){.str=(byteptr)"", .is_lit=1}, .updated_columns = __new_array(0, 0, sizeof(string)), .table_expr = ((v__ast__TypeNode){.pos = typ_pos,.typ = typ,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}), .fields = __new_array(0, 0, sizeof(v__ast__StructField)), .sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)), .pre_comments = pre_comments, .end_comments = end_comments, }); } string inserted_var = _S(""); v__ast__Type table_type = _const_v__ast__no_type; if (kind != v__ast__SqlStmtKind__delete) { if (kind == v__ast__SqlStmtKind__update) { table_type = v__parser__Parser_parse_type(p); } else if (kind == v__ast__SqlStmtKind__insert) { v__ast__Expr expr = v__parser__Parser_expr(p, 0); if ((expr)._typ == 358 /* v.ast.Ident */) { inserted_var = (*expr._v__ast__Ident).name; } else { v__parser__Parser_error(p, _S("can only insert variables")); return ((v__ast__SqlStmtLine){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = ((v__ast__TypeNode){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } } } n = v__parser__Parser_check_name(p); Array_string updated_columns = __new_array_with_default(0, 0, sizeof(string), 0); Array_v__ast__Expr update_exprs = __new_array_with_default(0, 5, sizeof(v__ast__Expr), 0); if (kind == v__ast__SqlStmtKind__insert && _SLIT_NE(n.str, n.len, "into")) { v__parser__Parser_error(p, _S("expecting `into`")); return ((v__ast__SqlStmtLine){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = ((v__ast__TypeNode){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } else if (kind == v__ast__SqlStmtKind__update) { if (_SLIT_NE(n.str, n.len, "set")) { v__parser__Parser_error(p, _S("expecting `set`")); return ((v__ast__SqlStmtLine){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = ((v__ast__TypeNode){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } for (;;) { string column = v__parser__Parser_check_name(p); array_push((array*)&updated_columns, _MOV((string[]){ string_clone(column) })); v__parser__Parser_check(p, v__token__Kind__assign); array_push((array*)&update_exprs, _MOV((v__ast__Expr[]){ v__parser__Parser_expr(p, 0) })); if (p->tok.kind == v__token__Kind__comma) { v__parser__Parser_check(p, v__token__Kind__comma); } else { break; } } } else if (kind == v__ast__SqlStmtKind__delete && _SLIT_NE(n.str, n.len, "from")) { v__parser__Parser_error(p, _S("expecting `from`")); return ((v__ast__SqlStmtLine){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = ((v__ast__TypeNode){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } v__token__Pos table_pos = v__token__Token_pos(&p->tok); v__ast__Expr where_expr = _const_v__ast__empty_expr; if (kind == v__ast__SqlStmtKind__insert) { table_pos = v__token__Token_pos(&p->tok); table_type = v__parser__Parser_parse_type(p); } else if (kind == v__ast__SqlStmtKind__update) { _option_bool _t11 = v__parser__Parser_check_sql_keyword(p, _S("where")); if (_t11.state != 0) { IError err = _t11.err; return ((v__ast__SqlStmtLine){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = ((v__ast__TypeNode){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } ; where_expr = v__parser__Parser_expr(p, 0); v__ast__Expr where_expr_result = v__parser__Parser_check_sql_where_expr_has_no_undefined_variables(p, &where_expr, __new_array_with_default(0, 0, sizeof(string), 0)); if ((where_expr_result)._typ == 335 /* v.ast.NodeError */) { return ((v__ast__SqlStmtLine){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = ((v__ast__TypeNode){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } } else if (kind == v__ast__SqlStmtKind__delete) { table_pos = v__token__Token_pos(&p->tok); table_type = v__parser__Parser_parse_type(p); _option_bool _t14 = v__parser__Parser_check_sql_keyword(p, _S("where")); if (_t14.state != 0) { IError err = _t14.err; return ((v__ast__SqlStmtLine){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = ((v__ast__TypeNode){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } ; where_expr = v__parser__Parser_expr(p, 0); v__ast__Expr where_expr_result = v__parser__Parser_check_sql_where_expr_has_no_undefined_variables(p, &where_expr, __new_array_with_default(0, 0, sizeof(string), 0)); if ((where_expr_result)._typ == 335 /* v.ast.NodeError */) { return ((v__ast__SqlStmtLine){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = ((v__ast__TypeNode){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } } Array_v__ast__Comment end_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); return ((v__ast__SqlStmtLine){ .kind = kind, .pos = pos, .is_generated = false, .scope = p->scope, .object_var = inserted_var, .updated_columns = updated_columns, .table_expr = ((v__ast__TypeNode){.pos = table_pos,.typ = table_type,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}), .fields = __new_array(0, 0, sizeof(v__ast__StructField)), .sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .where_expr = where_expr, .update_exprs = update_exprs, .pre_comments = pre_comments, .end_comments = end_comments, }); } VV_LOC _option_bool v__parser__Parser_check_sql_keyword(v__parser__Parser* p, string name) { if (!string__eq(v__parser__Parser_check_name(p), name)) { v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("ORM: expecting `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}}))); return (_option_bool){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } _option_bool _t2; _option_ok(&(bool[]) { true }, (_option*)(&_t2), sizeof(bool)); return _t2; } VV_LOC v__ast__Expr v__parser__Parser_check_sql_where_expr_has_no_undefined_variables(v__parser__Parser* p, v__ast__Expr* expr, Array_string unacceptable_variable_names) { if ((expr)->_typ == 358 /* v.ast.Ident */) { if (!v__ast__Scope_known_var(p->scope, (*expr->_v__ast__Ident).name)) { _result_void _t1 = v__parser__Parser_check_undefined_variables(p, unacceptable_variable_names, v__ast__Ident_to_sumtype_v__ast__Expr(&(*expr->_v__ast__Ident))); if (_t1.is_error) { IError err = _t1.err; return v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, IError_name_table[err._typ]._method_msg(err._object), (*expr->_v__ast__Ident).pos)))); } ; } } else if ((expr)->_typ == 362 /* v.ast.InfixExpr */) { if (((*expr->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */) { if (((*expr->_v__ast__InfixExpr).right)._typ == 358 /* v.ast.Ident */) { return v__parser__Parser_check_sql_where_expr_has_no_undefined_variables(p, HEAP(v__ast__Expr, v__ast__Ident_to_sumtype_v__ast__Expr(&(*(*expr->_v__ast__InfixExpr).right._v__ast__Ident))), new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){string_clone((*(*expr->_v__ast__InfixExpr).left._v__ast__Ident).name)}))); } } v__ast__Expr left_check_result = v__parser__Parser_check_sql_where_expr_has_no_undefined_variables(p, &(*expr->_v__ast__InfixExpr).left, __new_array_with_default(0, 0, sizeof(string), 0)); if ((left_check_result)._typ == 335 /* v.ast.NodeError */) { return v__ast__NodeError_to_sumtype_v__ast__Expr(&(*left_check_result._v__ast__NodeError)); } Array_string variable_names = (((*expr->_v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ ? (new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){v__ast__Ident_str((*(*expr->_v__ast__InfixExpr).left._v__ast__Ident))}))) : (__new_array_with_default(0, 0, sizeof(string), 0))); v__ast__Expr right_check_result = v__parser__Parser_check_sql_where_expr_has_no_undefined_variables(p, &(*expr->_v__ast__InfixExpr).right, variable_names); if ((right_check_result)._typ == 335 /* v.ast.NodeError */) { return v__ast__NodeError_to_sumtype_v__ast__Expr(&(*right_check_result._v__ast__NodeError)); } } else if ((expr)->_typ == 374 /* v.ast.ParExpr */) { return v__parser__Parser_check_sql_where_expr_has_no_undefined_variables(p, &(*expr->_v__ast__ParExpr).expr, __new_array_with_default(0, 0, sizeof(string), 0)); } return _const_v__ast__empty_expr; } VV_LOC v__ast__Type v__parser__Parser_parse_array_type(v__parser__Parser* p, v__token__Kind expecting, bool is_option) { bool v__parser__Parser_parse_array_type_defer_0 = false; v__parser__Parser_check(p, expecting); if (p->tok.kind == v__token__Kind__number || p->tok.kind == v__token__Kind__name || p->tok.kind == v__token__Kind__dollar) { int fixed_size = 0; v__ast__Expr size_expr = v__parser__Parser_expr(p, 0); bool size_unresolved = true; if (p->pref->is_fmt) { fixed_size = 987654321; } else { if (size_expr._typ == 363 /* v.ast.IntegerLiteral */) { fixed_size = string_int((*size_expr._v__ast__IntegerLiteral).val); size_unresolved = false; } else if (size_expr._typ == 349 /* v.ast.ComptimeCall */) { if ((*size_expr._v__ast__ComptimeCall).kind == v__ast__ComptimeCallKind__d) { _result_void _t1 = v__ast__ComptimeCall_resolve_compile_value(&(*size_expr._v__ast__ComptimeCall), p->pref->compile_values); if (_t1.is_error) { IError err = _t1.err; v__parser__Parser_error_with_pos(p, IError_name_table[err._typ]._method_msg(err._object), (*size_expr._v__ast__ComptimeCall).pos); } ; if ((*size_expr._v__ast__ComptimeCall).result_type != _const_v__ast__i64_type) { v__parser__Parser_error_with_pos(p, _S("value from $d() can only be positive integers when used as fixed size"), (*size_expr._v__ast__ComptimeCall).pos); } fixed_size = string_int((*size_expr._v__ast__ComptimeCall).compile_value); size_unresolved = false; } else { v__parser__Parser_error_with_pos(p, _S("only $d() is supported as fixed array size quantifier at compile time"), (*size_expr._v__ast__ComptimeCall).pos); } } else if (size_expr._typ == 358 /* v.ast.Ident */) { _option_v__ast__ConstField_ptr _t2; if (_t2 = v__ast__Scope_find_const(p->table->global_scope, v__ast__Ident_full_name(&(*size_expr._v__ast__Ident))), _t2.state == 0) { v__ast__ConstField* const_field = *(v__ast__ConstField**)_t2.data; if ((const_field->expr)._typ == 363 /* v.ast.IntegerLiteral */) { fixed_size = string_int((*const_field->expr._v__ast__IntegerLiteral).val); size_unresolved = false; } else if ((const_field->expr)._typ == 362 /* v.ast.InfixExpr */) { v__transformer__Transformer* t = v__transformer__new_transformer_with_table(p->table, p->pref); v__ast__Expr folded_expr = v__transformer__Transformer_infix_expr(t, (voidptr)&(*const_field->expr._v__ast__InfixExpr)); if ((folded_expr)._typ == 363 /* v.ast.IntegerLiteral */) { fixed_size = string_int((*folded_expr._v__ast__IntegerLiteral).val); size_unresolved = false; } } } else { IError err = _t2.err; if (p->pref->is_fmt) { fixed_size = 1; size_unresolved = false; } } } else if (size_expr._typ == 362 /* v.ast.InfixExpr */) { v__transformer__Transformer* t = v__transformer__new_transformer_with_table(p->table, p->pref); v__ast__Expr folded_expr = v__transformer__Transformer_infix_expr(t, &/*mut*/(*size_expr._v__ast__InfixExpr)); if ((folded_expr)._typ == 363 /* v.ast.IntegerLiteral */) { fixed_size = string_int((*folded_expr._v__ast__IntegerLiteral).val); size_unresolved = false; } } else { v__parser__Parser_error_with_pos(p, _S("fixed array size cannot use non-constant value"), v__ast__Expr_pos(size_expr)); } } v__parser__Parser_check(p, v__token__Kind__rsbr); p->fixed_array_dim++; v__parser__Parser_parse_array_type_defer_0 = true; v__ast__Type elem_type = v__parser__Parser_parse_type(p); if (v__ast__Type_idx(elem_type) == 0) { v__ast__Type _t3 = 0; // Defer begin if (v__parser__Parser_parse_array_type_defer_0) { p->fixed_array_dim--; } // Defer end return _t3; } if (fixed_size <= 0 && !size_unresolved) { v__parser__Parser_error_with_pos(p, _S("fixed size cannot be zero or negative"), v__ast__Expr_pos(size_expr)); } int idx = v__ast__Table_find_or_register_array_fixed(p->table, elem_type, fixed_size, size_expr, p->array_dim == 1 && p->fixed_array_dim == 1 && !is_option && p->inside_fn_return); if (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__generic)) { v__ast__Type _t4 = v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); // Defer begin if (v__parser__Parser_parse_array_type_defer_0) { p->fixed_array_dim--; } // Defer end return _t4; } v__ast__Type _t5 = v__ast__new_type(idx); // Defer begin if (v__parser__Parser_parse_array_type_defer_0) { p->fixed_array_dim--; } // Defer end return _t5; } v__parser__Parser_check(p, v__token__Kind__rsbr); v__ast__Type elem_type = v__parser__Parser_parse_type(p); if (v__ast__Type_idx(elem_type) == 0) { v__ast__Type _t6 = 0; // Defer begin if (v__parser__Parser_parse_array_type_defer_0) { p->fixed_array_dim--; } // Defer end return _t6; } if (v__ast__Type_idx(elem_type) == 29) { v__parser__Parser_register_auto_import(p, _S("sync.threads")); } int nr_dims = 1; bool not_attr = p->peek_tok.kind != v__token__Kind__name && !(v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__semicolon || v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__rsbr); for (;;) { if (!(p->tok.kind == expecting && not_attr)) break; v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__rsbr); nr_dims++; } int idx = v__ast__Table_find_or_register_array_with_dims(p->table, elem_type, nr_dims); if (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__generic)) { v__ast__Type _t7 = v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); // Defer begin if (v__parser__Parser_parse_array_type_defer_0) { p->fixed_array_dim--; } // Defer end return _t7; } v__ast__Type _t8 = v__ast__new_type(idx); // Defer begin if (v__parser__Parser_parse_array_type_defer_0) { p->fixed_array_dim--; } // Defer end return _t8; } VV_LOC v__ast__Type v__parser__Parser_parse_map_type(v__parser__Parser* p) { bool is_option = p->tok.kind == v__token__Kind__question && p->peek_tok.kind == v__token__Kind__name; if (is_option) { v__parser__Parser_next(p); } v__parser__Parser_next(p); if (p->tok.kind != v__token__Kind__lsbr) { if (p->inside_struct_field_decl) { v__parser__Parser_error_with_pos(p, _S("cannot use the map type without key and value definition"), v__token__Token_pos(&p->prev_tok)); return 0; } return _const_v__ast__map_type; } v__parser__Parser_check(p, v__token__Kind__lsbr); v__ast__Type key_type = v__parser__Parser_parse_type(p); if (v__ast__Type_idx(key_type) == 0) { return 0; } v__ast__TypeSymbol* key_sym = v__ast__Table_sym(p->table, key_type); bool is_alias = key_sym->kind == v__ast__Kind__alias; bool key_type_supported = (key_type == _const_v__ast__string_type_idx || key_type == _const_v__ast__voidptr_type_idx) || (key_sym->kind == v__ast__Kind__enum || key_sym->kind == v__ast__Kind__placeholder || key_sym->kind == v__ast__Kind__any) || ((v__ast__Type_is_int(key_type) || v__ast__Type_is_float(key_type) || is_alias) && !v__ast__Type_is_ptr(key_type)); if (!key_type_supported) { if (is_alias) { v__parser__Parser_error(p, _S("cannot use the alias type as the parent type is unsupported")); return 0; } string s = v__ast__Table_type_to_str(p->table, key_type); v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("maps only support string, integer, float, rune, enum or voidptr keys for now (not `"), 0xfe10, {.d_s = s}}, {_S("`)"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->tok)); return 0; } v__parser__Parser_check(p, v__token__Kind__rsbr); if (p->tok.kind == v__token__Kind__lsbr) { if (!(p->peek_tok.kind == v__token__Kind__rsbr || p->peek_tok.kind == v__token__Kind__number)) { string s = v__ast__Table_type_to_str(p->table, key_type); v__parser__Parser_error_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("maps can only have a single key. To declare a map use `map["), 0xfe10, {.d_s = s}}, {_S("]"), 0xfe10, {.d_s = p->peek_tok.lit}}, {_S("{}` instead"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->peek_tok)); return 0; } } v__ast__Type value_type = v__parser__Parser_parse_type(p); if (v__ast__Type_idx(value_type) == 0) { return 0; } if (v__ast__Type_idx(value_type) == 1) { v__parser__Parser_error_with_pos(p, _S("map value type is missing: use `map[KeyType]ValueType`"), v__token__Token_pos(&p->tok)); return 0; } int idx = v__ast__Table_find_or_register_map(p->table, key_type, value_type); if (v__ast__Type_has_flag(key_type, v__ast__TypeFlag__generic) || v__ast__Type_has_flag(value_type, v__ast__TypeFlag__generic)) { return v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); } if (is_option) { return v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__option); } else { return v__ast__new_type(idx); } return 0; } VV_LOC v__ast__Type v__parser__Parser_parse_chan_type(v__parser__Parser* p) { if (!(p->peek_tok.kind == v__token__Kind__name || p->peek_tok.kind == v__token__Kind__key_mut || p->peek_tok.kind == v__token__Kind__amp || p->peek_tok.kind == v__token__Kind__lsbr)) { v__parser__Parser_next(p); return _const_v__ast__chan_type; } v__parser__Parser_register_auto_import(p, _S("sync")); v__parser__Parser_next(p); p->inside_chan_decl = true; bool is_mut = p->tok.kind == v__token__Kind__key_mut; v__ast__Type elem_type = v__parser__Parser_parse_type(p); p->inside_chan_decl = false; int idx = v__ast__Table_find_or_register_chan(p->table, elem_type, is_mut); if (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__generic)) { return v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); } return v__ast__new_type(idx); } VV_LOC v__ast__Type v__parser__Parser_parse_thread_type(v__parser__Parser* p) { if (p->peek_tok.kind == v__token__Kind__lpar) { v__parser__Parser_next(p); v__ast__Type ret_type = v__parser__Parser_parse_multi_return_type(p); int idx = v__ast__Table_find_or_register_thread(p->table, ret_type); return v__ast__new_type(idx); } bool is_opt = p->peek_tok.kind == v__token__Kind__question; bool is_result = p->peek_tok.kind == v__token__Kind__not; if (is_opt || is_result) { v__parser__Parser_next(p); } if (!(p->peek_tok.kind == v__token__Kind__name || p->peek_tok.kind == v__token__Kind__key_pub || p->peek_tok.kind == v__token__Kind__key_mut || p->peek_tok.kind == v__token__Kind__amp || p->peek_tok.kind == v__token__Kind__lsbr)) { v__parser__Parser_next(p); if (is_opt) { v__ast__Type ret_type = _const_v__ast__void_type; ret_type = v__ast__Type_set_flag(ret_type, v__ast__TypeFlag__option); int idx = v__ast__Table_find_or_register_thread(p->table, ret_type); return v__ast__new_type(idx); } else if (is_result) { v__ast__Type ret_type = _const_v__ast__void_type; ret_type = v__ast__Type_set_flag(ret_type, v__ast__TypeFlag__result); int idx = v__ast__Table_find_or_register_thread(p->table, ret_type); return v__ast__new_type(idx); } else { return _const_v__ast__thread_type; } } if (!is_opt && !is_result) { v__parser__Parser_next(p); } if (is_opt || is_result || (p->tok.kind == v__token__Kind__amp || p->tok.kind == v__token__Kind__lsbr) || (p->tok.lit.len > 0 && u8_is_capital(string_at(p->tok.lit, 0))) || v__token__KeywordsMatcherTrie_matches(&_const_v__ast__builtin_type_names_matcher, p->tok.lit) || p->peek_tok.kind == v__token__Kind__dot) { v__ast__Type ret_type = v__parser__Parser_parse_type(p); if (is_opt) { ret_type = v__ast__Type_set_flag(ret_type, v__ast__TypeFlag__option); } else if (is_result) { ret_type = v__ast__Type_set_flag(ret_type, v__ast__TypeFlag__result); } int idx = v__ast__Table_find_or_register_thread(p->table, ret_type); if (v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__generic)) { return v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); } return v__ast__new_type(idx); } return _const_v__ast__thread_type; } VV_LOC v__ast__Type v__parser__Parser_parse_multi_return_type(v__parser__Parser* p) { v__parser__Parser_check(p, v__token__Kind__lpar); Array_v__ast__Type mr_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); bool has_generic = false; for (;;) { if (!(!(p->tok.kind == v__token__Kind__eof || p->tok.kind == v__token__Kind__rpar))) break; v__ast__Type mr_type = v__parser__Parser_parse_type(p); if (v__ast__Type_idx(mr_type) == 0) { break; } if (v__ast__Type_has_flag(mr_type, v__ast__TypeFlag__generic)) { has_generic = true; } array_push((array*)&mr_types, _MOV((v__ast__Type[]){ mr_type })); if (p->tok.kind == v__token__Kind__comma) { v__parser__Parser_next(p); } else { break; } } v__parser__Parser_check(p, v__token__Kind__rpar); if (mr_types.len == 1) { return (*(v__ast__Type*)array_get(mr_types, 0)); } int idx = v__ast__Table_find_or_register_multi_return(p->table, mr_types); if (has_generic) { return v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); } return v__ast__new_type(idx); } VV_LOC v__ast__Type v__parser__Parser_parse_fn_type(v__parser__Parser* p, string name, Array_v__ast__Type generic_types) { v__token__Pos fn_type_pos = v__token__Token_pos(ADDR(v__token__Token, v__parser__Parser_peek_token(p, -2))); v__parser__Parser_check(p, v__token__Kind__key_fn); for (int _t1 = 0; _t1 < p->attrs.len; ++_t1) { v__ast__Attr attr = ((v__ast__Attr*)p->attrs.data)[_t1]; if (_SLIT_EQ(attr.name.str, attr.name.len, "callconv")) { if (!attr.has_arg) { v__parser__Parser_error_with_pos(p, _S("callconv attribute is present but its value is missing"), v__token__Token_pos(&p->prev_tok)); } if (!(fast_string_eq(attr.arg, _S("stdcall")) || fast_string_eq(attr.arg, _S("fastcall")) || fast_string_eq(attr.arg, _S("cdecl")))) { v__parser__Parser_error_with_pos(p, _S("unsupported calling convention, supported are stdcall, fastcall and cdecl"), v__token__Token_pos(&p->prev_tok)); } } else { } } bool has_generic = false; int line_nr = p->tok.line_nr; multi_return_Array_v__ast__Param_bool_bool_bool mr_8877 = v__parser__Parser_fn_params(p); Array_v__ast__Param params = mr_8877.arg0; bool is_variadic = mr_8877.arg2; bool is_c_variadic = mr_8877.arg3; for (int _t2 = 0; _t2 < params.len; ++_t2) { v__ast__Param param = ((v__ast__Param*)params.data)[_t2]; if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { has_generic = true; break; } if (string__eq(v__ast__Table_sym(p->table, param.typ)->name, name)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = name}}, {_S("` cannot be a parameter as it references the fntype"), 0, { .d_c = 0 }}})), param.type_pos); } } v__ast__Type return_type = _const_v__ast__void_type; v__token__Pos return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (p->tok.line_nr == line_nr && v__token__Kind_is_start_of_type(p->tok.kind) && !v__parser__Parser_is_attributes(p)) { return_type_pos = v__token__Token_pos(&p->tok); return_type = v__parser__Parser_parse_type(p); if (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__generic)) { has_generic = true; } return_type_pos = v__token__Pos_extend(return_type_pos, v__token__Token_pos(&p->prev_tok)); } _result_Array_string _t3 = v__parser__Parser_types_to_names(p, generic_types, fn_type_pos, _S("generic_types")); if (_t3.is_error) { IError err = _t3.err; return _const_v__ast__no_type; } Array_string generic_names = (*(Array_string*)_t3.data); v__ast__Fn func = ((v__ast__Fn){ .is_variadic = is_variadic, .is_c_variadic = is_c_variadic, .language = 0, .is_pub = 0, .is_ctor_new = 0, .is_deprecated = 0, .is_noreturn = 0, .is_unsafe = 0, .is_must_use = 0, .is_placeholder = 0, .is_main = 0, .is_test = 0, .is_keep_alive = 0, .is_method = false, .is_static_type_method = 0, .no_body = 0, .is_file_translated = 0, .mod = (string){.str=(byteptr)"", .is_lit=1}, .file = (string){.str=(byteptr)"", .is_lit=1}, .file_mode = 0, .pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .return_type_pos = return_type_pos, .return_type = return_type, .receiver_type = 0, .name = name, .params = params, .source_fn = 0, .usages = 0, .generic_names = generic_names, .dep_names = __new_array(0, 0, sizeof(string)), .attrs = p->attrs, .is_conditional = 0, .ctdefine_idx = 0, .from_embedded_type = 0, .is_expand_simple_interpolation = 0, }); if (has_generic && generic_types.len == 0 && (name).len != 0) { v__parser__Parser_error_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = name}}, {_S("` type is generic fntype, must specify the generic type names, e.g. "), 0xfe10, {.d_s = name}}, {_S("[T]"), 0, { .d_c = 0 }}})), fn_type_pos); } if (string__eq(v__ast__Table_sym(p->table, return_type)->name, name)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = name}}, {_S("` cannot be a return type as it references the fntype"), 0, { .d_c = 0 }}})), return_type_pos); } bool has_decl = p->builtin_mod && string_starts_with(name, _S("Map")) && string_ends_with(name, _S("Fn")); bool already_exists = v__ast__Table_find_type_idx(p->table, name) != 0; int idx = v__ast__Table_find_or_register_fn_type(p->table, func, false, has_decl); if (already_exists && v__ast__Table_sym_by_idx(p->table, idx)->kind != v__ast__Kind__function) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot register fn `"), 0xfe10, {.d_s = name}}, {_S("`, another type with this name exists"), 0, { .d_c = 0 }}})), fn_type_pos); } if (has_generic) { return v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); } return v__ast__new_type(idx); } VV_LOC v__ast__Type v__parser__Parser_parse_type_with_mut(v__parser__Parser* p, bool is_mut) { v__ast__Type typ = v__parser__Parser_parse_type(p); if (is_mut) { return v__ast__Type_set_nr_muls(typ, 1); } return typ; } VV_LOC v__ast__Language v__parser__Parser_parse_language(v__parser__Parser* p) { bool _t1 = true; v__ast__Language language = ((_t1 == (p->tok.lit.len == 1 && p->tok.lit.str[ 0] == 'C'))? (v__ast__Language__c) : (_t1 == (p->tok.lit.len == 2 && p->tok.lit.str[ 0] == 'J' && p->tok.lit.str[ 1] == 'S'))? (v__ast__Language__js) : (_t1 == (p->tok.lit.len == 4 && p->tok.lit.str[ 0] == 'W' && p->tok.lit.str[ 1] == 'A' && p->tok.lit.str[ 2] == 'S' && p->tok.lit.str[ 3] == 'M'))? (v__ast__Language__wasm) : (v__ast__Language__v)); if (language != v__ast__Language__v) { v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__dot); } return language; } VV_LOC v__ast__Type v__parser__Parser_parse_inline_sum_type(v__parser__Parser* p) { v__parser__Parser_error(p, _S("inline sum types have been deprecated and will be removed on January 1, 2023 due to complicating the language and the compiler too much; define named sum types with `type Foo = Bar | Baz` instead")); return _const_v__ast__void_type; } VV_LOC Array_v__ast__TypeNode v__parser__Parser_parse_sum_type_variants(v__parser__Parser* p) { bool v__parser__Parser_parse_sum_type_variants_defer_0 = false; p->inside_sum_type = true; v__parser__Parser_parse_sum_type_variants_defer_0 = true; Array_v__ast__TypeNode types = __new_array_with_default(0, 0, sizeof(v__ast__TypeNode), 0); for (;;) { v__token__Pos type_start_pos = v__token__Token_pos(&p->tok); v__ast__Type typ = v__parser__Parser_parse_type(p); Array_v__ast__Comment end_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})); v__token__Token prev_tok = p->prev_tok; v__token__Pos type_end_pos = v__token__Token_pos(&prev_tok); v__token__Pos type_pos = v__token__Pos_extend(type_start_pos, type_end_pos); array_push((array*)&types, _MOV((v__ast__TypeNode[]){ ((v__ast__TypeNode){.pos = type_pos,.typ = typ,.stmt = _const_v__ast__empty_stmt,.end_comments = end_comments,}) })); if (p->tok.kind != v__token__Kind__pipe) { break; } v__parser__Parser_check(p, v__token__Kind__pipe); } Array_v__ast__TypeNode _t2 = types; // Defer begin if (v__parser__Parser_parse_sum_type_variants_defer_0) { p->inside_sum_type = false; } // Defer end return _t2; } VV_LOC v__ast__Type v__parser__Parser_parse_type(v__parser__Parser* p) { bool is_option = false; bool is_result = false; int line_nr = p->tok.line_nr; v__token__Pos option_pos = v__token__Token_pos(&p->tok); if (p->tok.kind == v__token__Kind__question) { v__parser__Parser_next(p); is_option = true; if (p->tok.kind == v__token__Kind__not) { v__parser__Parser_next(p); is_result = true; } } else if (p->tok.kind == v__token__Kind__not) { v__parser__Parser_next(p); is_result = true; if (p->tok.kind == v__token__Kind__question) { v__parser__Parser_next(p); is_option = true; } } if (is_option && is_result) { v__parser__Parser_error_with_pos(p, _S("the type must be Option or Result"), v__token__Token_pos(&p->prev_tok)); return 0; } if (is_option || is_result) { bool is_required_field = p->inside_struct_field_decl && p->tok.kind == v__token__Kind__lsbr && p->peek_tok.kind == v__token__Kind__name && fast_string_eq(p->peek_tok.lit, _S("required")); bool is_attr = p->tok.kind == v__token__Kind__at; if (p->tok.line_nr > line_nr || (p->tok.kind == v__token__Kind__comma || p->tok.kind == v__token__Kind__rpar || p->tok.kind == v__token__Kind__assign) || (is_attr || is_required_field) || p->tok.kind == v__token__Kind__comment) { v__ast__Type typ = _const_v__ast__void_type; if (is_option) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__option); } else if (is_result) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__result); } return typ; } } bool is_shared = p->tok.kind == v__token__Kind__key_shared; bool is_atomic = p->tok.kind == v__token__Kind__key_atomic; if (is_shared) { v__parser__Parser_register_auto_import(p, _S("sync")); } int nr_muls = 0; if (p->tok.kind == v__token__Kind__key_mut) { if (p->inside_fn_return) { v__parser__Parser_error_with_pos(p, _S("cannot use `mut` on fn return type"), v__token__Token_pos(&p->tok)); } else if (p->inside_struct_field_decl) { v__parser__Parser_error_with_pos(p, _S("cannot use `mut` on struct field type"), v__token__Token_pos(&p->tok)); } } if (p->tok.kind == v__token__Kind__key_mut || is_shared) { nr_muls++; v__parser__Parser_next(p); } if (is_atomic) { v__parser__Parser_next(p); } if (p->tok.kind == v__token__Kind__mul) { v__parser__Parser_error(p, _S("use `&Type` instead of `*Type` when declaring references")); return 0; } int nr_amps = 0; for (;;) { if (!(p->tok.kind == v__token__Kind__amp)) break; nr_amps++; nr_muls++; v__parser__Parser_next(p); } if (p->tok.kind == v__token__Kind__key_struct) { p->anon_struct_decl = v__parser__Parser_struct_decl(p, true); int typ = v__ast__Table_find_type_idx(p->table, p->anon_struct_decl.name); if (is_option) { typ = v__ast__Type_set_flag(v__ast__new_type(typ), v__ast__TypeFlag__option); } return typ; } v__ast__Language language = v__parser__Parser_parse_language(p); v__ast__Type typ = _const_v__ast__void_type; bool is_array = p->tok.kind == v__token__Kind__lsbr; v__token__Pos pos = v__token__Token_pos(&p->tok); if (p->tok.kind != v__token__Kind__lcbr) { typ = v__parser__Parser_parse_any_type(p, language, nr_muls > 0, true, is_option); if (v__ast__Type_idx(typ) == 0) { return 0; } if (typ == _const_v__ast__void_type) { v__parser__Parser_error_with_pos(p, _S("use `?` instead of `?void`"), pos); return 0; } v__ast__TypeSymbol* sym = v__ast__Table_sym(p->table, typ); if (p->inside_fn_concrete_type && (sym->info)._typ == 518 /* v.ast.Struct */) { if (!v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic) && (*sym->info._v__ast__Struct).generic_types.len > 0) { v__parser__Parser_error_with_pos(p, _S("missing concrete type on generic type"), v__token__Pos_extend(option_pos, v__token__Token_pos(&p->prev_tok))); } } if (is_option && (sym->info)._typ == 539 /* v.ast.Alias */ && v__ast__Type_has_flag((*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type, v__ast__TypeFlag__option)) { string alias_type_str = v__ast__Table_type_to_str(p->table, typ); string parent_type_str = v__ast__Table_type_to_str(p->table, (*sym->info._v__ast__Alias).parent_type); v__parser__Parser_error_with_pos(p, str_intp(4, _MOV((StrIntpData[]){{_S("cannot use double options like `?"), 0xfe10, {.d_s = parent_type_str}}, {_S("`, `?"), 0xfe10, {.d_s = alias_type_str}}, {_S("` is a double option. use `"), 0xfe10, {.d_s = alias_type_str}}, {_S("` instead"), 0, { .d_c = 0 }}})), v__token__Pos_extend(option_pos, v__token__Token_pos(&p->prev_tok))); } } if (is_option) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__option); } if (is_result) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__result); } if (is_shared) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__shared_f); } if (is_atomic) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__atomic_f); } if (_us32_eq(_const_v__ast__array_type,v__ast__Type_idx(typ)) && !p->builtin_mod && !(fast_string_eq(p->mod, _S("os")) || fast_string_eq(p->mod, _S("strconv")) || fast_string_eq(p->mod, _S("sync"))) && !p->inside_unsafe) { v__parser__Parser_error_with_pos(p, _S("`array` is an internal type, it cannot be used directly. Use `[]int`, `[]Foo` etc"), pos); } if (nr_muls > 0) { typ = v__ast__Type_set_nr_muls(typ, nr_muls); if (is_array && nr_amps > 0) { v__parser__Parser_error_with_pos(p, _S("V arrays are already references behind the scenes,\nthere is no need to use a reference to an array (e.g. use `[]string` instead of `&[]string`).\nIf you need to modify an array in a function, use a mutable argument instead: `fn foo(mut s []string) {}`."), pos); return 0; } } return typ; } VV_LOC v__ast__Type v__parser__Parser_parse_any_type(v__parser__Parser* p, v__ast__Language language, bool is_ptr, bool check_dot, bool is_option) { bool v__parser__Parser_parse_any_type_defer_0 = false; string name = p->tok.lit; if (language == v__ast__Language__c) { name = str_intp(2, _MOV((StrIntpData[]){{_S("C."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); } else if (language == v__ast__Language__js) { name = str_intp(2, _MOV((StrIntpData[]){{_S("JS."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); } else if (p->peek_tok.kind == v__token__Kind__dot && check_dot && p->tok.lit.len > 0 && !u8_is_capital(string_at(p->tok.lit, 0))) { string mod = name; v__token__Pos mod_pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__dot); string mod_last_part = mod; for (;;) { if (!(p->peek_tok.kind == v__token__Kind__dot)) break; mod_pos = v__token__Pos_extend(mod_pos, v__token__Token_pos(&p->tok)); mod_last_part = p->tok.lit; if (u8_is_capital(string_at(p->tok.lit, 0))) { break; } mod = string__plus(mod, str_intp(2, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = mod_last_part}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__dot); } if (!string__eq(mod, p->mod) && !v__parser__Parser_known_import(p, mod) && !p->pref->is_fmt) { string msg = str_intp(2, _MOV((StrIntpData[]){{_S("unknown module `"), 0xfe10, {.d_s = mod}}, {_S("`"), 0, { .d_c = 0 }}})); if (mod.len > mod_last_part.len && v__parser__Parser_known_import(p, mod_last_part)) { msg = string__plus(msg, str_intp(2, _MOV((StrIntpData[]){{_S("; did you mean `"), 0xfe10, {.d_s = mod_last_part}}, {_S("`?"), 0, { .d_c = 0 }}}))); } v__parser__Parser_error_with_pos(p, msg, mod_pos); return 0; } if (_IN_MAP(ADDR(string, mod), ADDR(map, p->imports))) { v__parser__Parser_register_used_import(p, mod); mod = (*(string*)map_get(ADDR(map, p->imports), &(string[]){mod}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })); if (p->tok.lit.len > 0 && !u8_is_capital(string_at(p->tok.lit, 0))) { v__parser__Parser_error(p, _S("imported types must start with a capital letter")); return 0; } } name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mod}}, {_S("."), 0xfe10, {.d_s = p->tok.lit}}, {_SLIT0, 0, { .d_c = 0 }}})); } else if ((p->expr_mod).len != 0 && !p->inside_generic_params) { name = string__plus(string__plus(p->expr_mod, _S(".")), name); } else if (_IN_MAP(ADDR(string, name), ADDR(map, p->imported_symbols))) { name = (*(string*)map_get(ADDR(map, p->imported_symbols), &(string[]){name}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })); v__parser__Parser_register_used_import_for_symbol_name(p, name); } else if (!p->builtin_mod && name.len > 1 && !_IN_MAP(ADDR(string, name), ADDR(map, p->table->type_idxs))) { name = string__plus(string__plus(p->mod, _S(".")), name); } if (p->tok.kind == (v__token__Kind__key_fn)) { return v__parser__Parser_parse_fn_type(p, _S(""), __new_array_with_default(0, 0, sizeof(v__ast__Type), 0)); } else if (p->tok.kind == (v__token__Kind__lsbr) || p->tok.kind == (v__token__Kind__nilsbr)) { p->array_dim++; v__parser__Parser_parse_any_type_defer_0 = true; v__ast__Type _t4 = v__parser__Parser_parse_array_type(p, p->tok.kind, is_option); // Defer begin if (v__parser__Parser_parse_any_type_defer_0) { p->array_dim--; } // Defer end return _t4; } else { if (p->tok.kind == v__token__Kind__lpar) { if (is_ptr) { v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = _S("`&` before multiple returns"),.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = _S("parse_type:"),.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); v__ast__Type _t5 = 0; // Defer begin if (v__parser__Parser_parse_any_type_defer_0) { p->array_dim--; } // Defer end return _t5; } v__ast__Type _t6 = v__parser__Parser_parse_multi_return_type(p); // Defer begin if (v__parser__Parser_parse_any_type_defer_0) { p->array_dim--; } // Defer end return _t6; } if (((p->peek_tok.kind == v__token__Kind__dot && v__parser__Parser_peek_token(p, 3).kind == v__token__Kind__pipe) || p->peek_tok.kind == v__token__Kind__pipe) && !p->inside_sum_type && !p->inside_receiver_param) { v__ast__Type _t7 = v__parser__Parser_parse_inline_sum_type(p); // Defer begin if (v__parser__Parser_parse_any_type_defer_0) { p->array_dim--; } // Defer end return _t7; } if (_SLIT_EQ(name.str, name.len, "map")) { v__ast__Type _t8 = v__parser__Parser_parse_map_type(p); // Defer begin if (v__parser__Parser_parse_any_type_defer_0) { p->array_dim--; } // Defer end return _t8; } if (_SLIT_EQ(name.str, name.len, "chan")) { v__ast__Type _t9 = v__parser__Parser_parse_chan_type(p); // Defer begin if (v__parser__Parser_parse_any_type_defer_0) { p->array_dim--; } // Defer end return _t9; } if (_SLIT_EQ(name.str, name.len, "thread")) { v__ast__Type _t10 = v__parser__Parser_parse_thread_type(p); // Defer begin if (v__parser__Parser_parse_any_type_defer_0) { p->array_dim--; } // Defer end return _t10; } v__ast__Type ret = _const_v__ast__no_type; if ((name).len == 0) { v__parser__Parser_error(p, _S("expecting type declaration")); } else { if (_SLIT_EQ(name.str, name.len, "voidptr")) { ret = _const_v__ast__voidptr_type; } else if (_SLIT_EQ(name.str, name.len, "byteptr")) { ret = _const_v__ast__byteptr_type; } else if (_SLIT_EQ(name.str, name.len, "charptr")) { ret = _const_v__ast__charptr_type; } else if (_SLIT_EQ(name.str, name.len, "i8")) { ret = _const_v__ast__i8_type; } else if (_SLIT_EQ(name.str, name.len, "i16")) { ret = _const_v__ast__i16_type; } else if (_SLIT_EQ(name.str, name.len, "int")) { ret = _const_v__ast__int_type; } else if (_SLIT_EQ(name.str, name.len, "i64")) { ret = _const_v__ast__i64_type; } else if (_SLIT_EQ(name.str, name.len, "u8")) { ret = _const_v__ast__u8_type; } else if (_SLIT_EQ(name.str, name.len, "u16")) { ret = _const_v__ast__u16_type; } else if (_SLIT_EQ(name.str, name.len, "u32")) { ret = _const_v__ast__u32_type; } else if (_SLIT_EQ(name.str, name.len, "u64")) { ret = _const_v__ast__u64_type; } else if (_SLIT_EQ(name.str, name.len, "f32")) { ret = _const_v__ast__f32_type; } else if (_SLIT_EQ(name.str, name.len, "f64")) { ret = _const_v__ast__f64_type; } else if (_SLIT_EQ(name.str, name.len, "string")) { ret = _const_v__ast__string_type; } else if (_SLIT_EQ(name.str, name.len, "char")) { ret = _const_v__ast__char_type; } else if (_SLIT_EQ(name.str, name.len, "bool")) { ret = _const_v__ast__bool_type; } else if (_SLIT_EQ(name.str, name.len, "float_literal")) { ret = _const_v__ast__float_literal_type; } else if (_SLIT_EQ(name.str, name.len, "int_literal")) { ret = _const_v__ast__int_literal_type; } else if (_SLIT_EQ(name.str, name.len, "any")) { ret = _const_v__ast__any_type; } else { v__parser__Parser_next(p); if (name.len == 1 && u8_is_capital(string_at(name, 0))) { v__ast__Type _t11 = v__parser__Parser_parse_generic_type(p, name); // Defer begin if (v__parser__Parser_parse_any_type_defer_0) { p->array_dim--; } // Defer end return _t11; } if ((p->tok.kind == v__token__Kind__lt || p->tok.kind == v__token__Kind__lsbr) && v__token__Token_is_next_to(p->tok, p->prev_tok)) { v__ast__Type _t12 = v__parser__Parser_parse_generic_inst_type(p, name); // Defer begin if (v__parser__Parser_parse_any_type_defer_0) { p->array_dim--; } // Defer end return _t12; } v__ast__Type _t13 = v__parser__Parser_find_type_or_add_placeholder(p, name, language); // Defer begin if (v__parser__Parser_parse_any_type_defer_0) { p->array_dim--; } // Defer end return _t13; } } v__parser__Parser_next(p); v__ast__Type _t14 = ret; // Defer begin if (v__parser__Parser_parse_any_type_defer_0) { p->array_dim--; } // Defer end return _t14; } return 0; } VV_LOC v__ast__Type v__parser__Parser_find_type_or_add_placeholder(v__parser__Parser* p, string name, v__ast__Language language) { int idx = v__ast__Table_find_type_idx_fn_scoped(p->table, name, p->cur_fn_scope); if (idx > 0) { v__ast__Type typ = v__ast__new_type(idx); v__ast__TypeSymbol* sym = v__ast__Table_sym(p->table, typ); if (sym->info._typ == 518 /* v.ast.Struct */) { if (p->init_generic_types.len > 0 && (*sym->info._v__ast__Struct).generic_types.len > 0 && !Array_v__ast__Type_arr_eq(p->init_generic_types, (*sym->info._v__ast__Struct).generic_types)) { _result_Array_string _t1 = v__parser__Parser_types_to_names(p, p->init_generic_types, v__token__Token_pos(&p->tok), _S("struct_init_generic_types")); if (_t1.is_error) { IError err = _t1.err; return _const_v__ast__no_type; } Array_string generic_names = (*(Array_string*)_t1.data); string sym_name = string__plus(sym->name, _S("<")); for (int i = 0; i < generic_names.len; ++i) { string gt = ((string*)generic_names.data)[i]; sym_name = string__plus(sym_name, gt); if (i != (int)(generic_names.len - 1)) { sym_name = string__plus(sym_name, _S(",")); } } sym_name = string__plus(sym_name, _S(">")); int existing_idx = (*(int*)map_get(ADDR(map, p->table->type_idxs), &(string[]){sym_name}, &(int[]){ 0 })); if (existing_idx > 0) { idx = existing_idx; } else { idx = v__ast__Table_register_sym(p->table, ((v__ast__TypeSymbol){.parent_idx = sym->idx,.info = (sym)->info,.kind = (sym)->kind,.name = sym_name,.cname = (sym)->cname,.rname = sym->name,.methods = (sym)->methods,.generic_types = array_clone_to_depth(&p->init_generic_types, 0),.mod = (sym)->mod,.is_pub = (sym)->is_pub,.is_builtin = (sym)->is_builtin,.language = (sym)->language,.idx = (sym)->idx,.size = (sym)->size,.align = (sym)->align,})); } typ = v__ast__new_type(idx); } } else if (sym->info._typ == 542 /* v.ast.Interface */) { if (p->init_generic_types.len > 0 && (*sym->info._v__ast__Interface).generic_types.len > 0 && !Array_v__ast__Type_arr_eq(p->init_generic_types, (*sym->info._v__ast__Interface).generic_types)) { _result_Array_string _t3 = v__parser__Parser_types_to_names(p, p->init_generic_types, v__token__Token_pos(&p->tok), _S("struct_init_generic_types")); if (_t3.is_error) { IError err = _t3.err; return _const_v__ast__no_type; } Array_string generic_names = (*(Array_string*)_t3.data); string sym_name = string__plus(sym->name, _S("<")); for (int i = 0; i < generic_names.len; ++i) { string gt = ((string*)generic_names.data)[i]; sym_name = string__plus(sym_name, gt); if (i != (int)(generic_names.len - 1)) { sym_name = string__plus(sym_name, _S(",")); } } sym_name = string__plus(sym_name, _S(">")); int existing_idx = (*(int*)map_get(ADDR(map, p->table->type_idxs), &(string[]){sym_name}, &(int[]){ 0 })); if (existing_idx > 0) { idx = existing_idx; } else { idx = v__ast__Table_register_sym(p->table, ((v__ast__TypeSymbol){.parent_idx = sym->idx,.info = (sym)->info,.kind = (sym)->kind,.name = sym_name,.cname = (sym)->cname,.rname = sym->name,.methods = (sym)->methods,.generic_types = array_clone_to_depth(&p->init_generic_types, 0),.mod = (sym)->mod,.is_pub = (sym)->is_pub,.is_builtin = (sym)->is_builtin,.language = (sym)->language,.idx = (sym)->idx,.size = (sym)->size,.align = (sym)->align,})); } typ = v__ast__new_type(idx); } } else if (sym->info._typ == 544 /* v.ast.SumType */) { if (p->init_generic_types.len > 0 && (*sym->info._v__ast__SumType).generic_types.len > 0 && !Array_v__ast__Type_arr_eq(p->init_generic_types, (*sym->info._v__ast__SumType).generic_types)) { _result_Array_string _t5 = v__parser__Parser_types_to_names(p, p->init_generic_types, v__token__Token_pos(&p->tok), _S("struct_init_generic_types")); if (_t5.is_error) { IError err = _t5.err; return _const_v__ast__no_type; } Array_string generic_names = (*(Array_string*)_t5.data); string sym_name = string__plus(sym->name, _S("<")); for (int i = 0; i < generic_names.len; ++i) { string gt = ((string*)generic_names.data)[i]; sym_name = string__plus(sym_name, gt); if (i != (int)(generic_names.len - 1)) { sym_name = string__plus(sym_name, _S(",")); } } sym_name = string__plus(sym_name, _S(">")); int existing_idx = (*(int*)map_get(ADDR(map, p->table->type_idxs), &(string[]){sym_name}, &(int[]){ 0 })); if (existing_idx > 0) { idx = existing_idx; } else { idx = v__ast__Table_register_sym(p->table, ((v__ast__TypeSymbol){.parent_idx = sym->idx,.info = (sym)->info,.kind = (sym)->kind,.name = sym_name,.cname = (sym)->cname,.rname = sym->name,.methods = (sym)->methods,.generic_types = array_clone_to_depth(&p->init_generic_types, 0),.mod = (sym)->mod,.is_pub = (sym)->is_pub,.is_builtin = (sym)->is_builtin,.language = (sym)->language,.idx = (sym)->idx,.size = (sym)->size,.align = (sym)->align,})); } typ = v__ast__new_type(idx); } } else if (sym->info._typ == 553 /* v.ast.FnType */) { if (p->init_generic_types.len > 0 && (*sym->info._v__ast__FnType).func.generic_names.len > 0) { _result_Array_string _t7 = v__parser__Parser_types_to_names(p, p->init_generic_types, v__token__Token_pos(&p->tok), _S("struct_init_generic_types")); if (_t7.is_error) { IError err = _t7.err; return _const_v__ast__no_type; } Array_string generic_names = (*(Array_string*)_t7.data); if (!Array_string_arr_eq(generic_names, (*sym->info._v__ast__FnType).func.generic_names)) { string sym_name = string__plus(sym->name, _S("<")); for (int i = 0; i < generic_names.len; ++i) { string gt = ((string*)generic_names.data)[i]; sym_name = string__plus(sym_name, gt); if (i != (int)(generic_names.len - 1)) { sym_name = string__plus(sym_name, _S(",")); } } sym_name = string__plus(sym_name, _S(">")); int existing_idx = (*(int*)map_get(ADDR(map, p->table->type_idxs), &(string[]){sym_name}, &(int[]){ 0 })); if (existing_idx > 0) { idx = existing_idx; } else { v__ast__Fn func = (*sym->info._v__ast__FnType).func; func.name = sym_name; func.generic_names = array_clone_to_depth(&generic_names, 0); if (v__ast__Type_has_flag(func.return_type, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t9; if (_t9 = v__ast__Table_convert_generic_type(p->table, func.return_type, (*sym->info._v__ast__FnType).func.generic_names, p->init_generic_types), _t9.state == 0) { v__ast__Type to_generic_typ = *(v__ast__Type*)_t9.data; func.return_type = to_generic_typ; } } for (int i = 0; i < func.params.len; ++i) { if (v__ast__Type_has_flag((*(v__ast__Param*)array_get(func.params, i)).typ, v__ast__TypeFlag__generic)) { _option_v__ast__Type _t10; if (_t10 = v__ast__Table_convert_generic_type(p->table, (*(v__ast__Param*)array_get(func.params, i)).typ, (*sym->info._v__ast__FnType).func.generic_names, p->init_generic_types), _t10.state == 0) { v__ast__Type to_generic_typ = *(v__ast__Type*)_t10.data; (*(v__ast__Param*)array_get(func.params, i)).typ = to_generic_typ; } } } idx = v__ast__Table_find_or_register_fn_type(p->table, func, false, false); } typ = v__ast__new_type(idx); } } } else { } return typ; } idx = v__ast__Table_add_placeholder_type(p->table, name, language); return v__ast__new_type(idx); } VV_LOC v__ast__Type v__parser__Parser_parse_generic_type(v__parser__Parser* p, string name) { int idx = v__ast__Table_find_type_idx(p->table, name); if (idx > 0) { return v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); } idx = v__ast__Table_register_sym(p->table, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__any,.name = name,.cname = v__util__no_dots(name),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = p->mod,.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); return v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic); } VV_LOC v__ast__Type v__parser__Parser_parse_generic_inst_type(v__parser__Parser* p, string name) { bool v__parser__Parser_parse_generic_inst_type_defer_0 = false; p->generic_type_level++; v__parser__Parser_parse_generic_inst_type_defer_0 = true; if (p->generic_type_level > 10) { v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("too many levels of Parser.parse_generic_inst_type() calls: "), 0xfe07, {.d_i32 = p->generic_type_level}}, {_S(", probably due to too many layers embedded generic type"), 0, { .d_c = 0 }}}))); v__ast__Type _t1 = _const_v__ast__void_type; // Defer begin if (v__parser__Parser_parse_generic_inst_type_defer_0) { p->generic_type_level--; } // Defer end return _t1; } if (p->tok.kind == v__token__Kind__lt) { v__parser__Parser_error(p, _S("The generic symbol `<>` is obsolete, please replace it with `[]`")); } string bs_name = name; string bs_cname = name; v__token__Pos start_pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); p->inside_generic_params = true; bs_name = string__plus(bs_name, _S("[")); bs_cname = string__plus(bs_cname, _S("_T_")); Array_v__ast__Type concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); bool is_instance = true; for (;;) { if (!(p->tok.kind != v__token__Kind__eof)) break; v__token__Pos type_pos = v__token__Token_pos(&p->tok); v__ast__Type gt = v__parser__Parser_parse_type(p); type_pos = v__token__Pos_extend(type_pos, v__token__Token_pos(&p->prev_tok)); if (v__ast__Type_has_flag(gt, v__ast__TypeFlag__generic)) { is_instance = false; } if (gt == 0) { v__ast__Type _t2 = _const_v__ast__void_type; // Defer begin if (v__parser__Parser_parse_generic_inst_type_defer_0) { p->generic_type_level--; } // Defer end return _t2; } v__ast__TypeSymbol* gts = v__ast__Table_sym(p->table, gt); if (gts->kind == v__ast__Kind__multi_return) { v__parser__Parser_error_with_pos(p, _S("cannot use multi return as generic concrete type"), type_pos); } if (v__ast__Type_is_ptr(gt)) { bs_name = string__plus(bs_name, _S("&")); } bs_name = string__plus(bs_name, gts->name); bs_cname = string__plus(bs_cname, gts->cname); array_push((array*)&concrete_types, _MOV((v__ast__Type[]){ gt })); if (p->tok.kind != v__token__Kind__comma) { break; } v__parser__Parser_next(p); bs_name = string__plus(bs_name, _S(", ")); bs_cname = string__plus(bs_cname, _S("_")); } if (!is_instance) { p->init_generic_types = concrete_types; } v__token__Pos concrete_types_pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->tok)); v__parser__Parser_next(p); p->inside_generic_params = false; bs_name = string__plus(bs_name, _S("]")); if ((is_instance || p->pref->is_fmt) && concrete_types.len > 0) { int gt_idx = v__ast__Table_find_type_idx(p->table, bs_name); if (gt_idx > 0) { v__ast__Type _t4 = v__ast__new_type(gt_idx); // Defer begin if (v__parser__Parser_parse_generic_inst_type_defer_0) { p->generic_type_level--; } // Defer end return _t4; } gt_idx = v__ast__Table_add_placeholder_type(p->table, bs_name, v__ast__Language__v); int parent_idx = (*(int*)map_get(ADDR(map, p->table->type_idxs), &(string[]){name}, &(int[]){ 0 })); if (parent_idx == 0) { parent_idx = v__ast__Table_add_placeholder_type(p->table, name, v__ast__Language__v); } v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(p->table, v__ast__new_type(parent_idx)); if (parent_sym->info._typ == 518 /* v.ast.Struct */) { if ((*parent_sym->info._v__ast__Struct).generic_types.len == 0) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("struct `"), 0xfe10, {.d_s = parent_sym->name}}, {_S("` is not a generic struct, cannot instantiate to the concrete types"), 0, { .d_c = 0 }}})), concrete_types_pos); } else if ((*parent_sym->info._v__ast__Struct).generic_types.len != concrete_types.len) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("the number of generic types of struct `"), 0xfe10, {.d_s = parent_sym->name}}, {_S("` is inconsistent with the concrete types"), 0, { .d_c = 0 }}})), concrete_types_pos); } } else if (parent_sym->info._typ == 542 /* v.ast.Interface */) { if ((*parent_sym->info._v__ast__Interface).generic_types.len == 0) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("interface `"), 0xfe10, {.d_s = parent_sym->name}}, {_S("` is not a generic interface, cannot instantiate to the concrete types"), 0, { .d_c = 0 }}})), concrete_types_pos); } else if ((*parent_sym->info._v__ast__Interface).generic_types.len != concrete_types.len) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("the number of generic types of interface `"), 0xfe10, {.d_s = parent_sym->name}}, {_S("` is inconsistent with the concrete types"), 0, { .d_c = 0 }}})), concrete_types_pos); } } else if (parent_sym->info._typ == 544 /* v.ast.SumType */) { if ((*parent_sym->info._v__ast__SumType).generic_types.len == 0) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("sumtype `"), 0xfe10, {.d_s = parent_sym->name}}, {_S("` is not a generic sumtype, cannot instantiate to the concrete types"), 0, { .d_c = 0 }}})), concrete_types_pos); } else if ((*parent_sym->info._v__ast__SumType).generic_types.len != concrete_types.len) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("the number of generic types of sumtype `"), 0xfe10, {.d_s = parent_sym->name}}, {_S("` is inconsistent with the concrete types"), 0, { .d_c = 0 }}})), concrete_types_pos); } } else { } int idx = v__ast__Table_register_sym(p->table, ((v__ast__TypeSymbol){.parent_idx = 0,.info = v__ast__GenericInst_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__GenericInst, (((v__ast__GenericInst){.parent_idx = parent_idx,.concrete_types = concrete_types,})))),.kind = v__ast__Kind__generic_inst,.name = bs_name,.cname = v__util__no_dots(bs_cname),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = p->mod,.is_pub = 0,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); v__ast__Type _t5 = v__ast__new_type(idx); // Defer begin if (v__parser__Parser_parse_generic_inst_type_defer_0) { p->generic_type_level--; } // Defer end return _t5; } v__ast__Type _t6 = v__ast__Type_set_flag(v__parser__Parser_find_type_or_add_placeholder(p, name, v__ast__Language__v), v__ast__TypeFlag__generic); // Defer begin if (v__parser__Parser_parse_generic_inst_type_defer_0) { p->generic_type_level--; } // Defer end return _t6; } VV_LOC _result_Array_string v__parser__Parser_types_to_names(v__parser__Parser* p, Array_v__ast__Type types, v__token__Pos pos, string error_label) { Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < types.len; ++_t1) { v__ast__Type t = ((v__ast__Type*)types.data)[_t1]; if (t == 0) { v__parser__Parser_error_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("unknown type found, "), 0xfe10, {.d_s = error_label}}, {_S(": "), 0xfe10, {.d_s = Array_v__ast__Type_str(types)}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); return (_result_Array_string){ .is_error=true, .err=_v_error(_S("unknown 0 type")), .data={E_STRUCT} }; } array_push((array*)&res, _MOV((string[]){ string_clone(v__ast__Table_sym(p->table, t)->name) })); } _result_Array_string _t4 = {0}; _result_ok(&(Array_string[]) { res }, (_result*)(&_t4), sizeof(Array_string)); return _t4; } v__ast__File* v__parser__parse_comptime(string tmpl_path, string text, v__ast__Table* table, v__pref__Preferences* pref_, v__ast__Scope* scope) { #if defined(CUSTOM_DEFINE_trace_parse_comptime) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> "), 0xfe10, {.d_s = _S("v.parser")}}, {_S("."), 0xfe10, {.d_s = _S("parse_comptime")}}, {_S(" text: "), 0xfe10, {.d_s = text}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__parser__Parser p = ((v__parser__Parser){ .pref = pref_, .file_base = (string){.str=(byteptr)"", .is_lit=1}, .file_path = tmpl_path, .file_display_path = (string){.str=(byteptr)"", .is_lit=1}, .unique_prefix = (string){.str=(byteptr)"", .is_lit=1}, .file_backend_mode = 0, .tok = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .prev_tok = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .peek_tok = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .language = 0, .fn_language = 0, .expr_level = 0, .inside_vlib_file = 0, .inside_test_file = 0, .inside_if = 0, .inside_comptime_if = 0, .inside_if_expr = 0, .inside_if_cond = 0, .inside_ct_if_expr = 0, .inside_or_expr = 0, .inside_for = 0, .inside_for_expr = 0, .inside_fn = 0, .inside_fn_return = 0, .inside_fn_concrete_type = 0, .inside_call_args = 0, .inside_unsafe_fn = 0, .inside_str_interp = 0, .inside_array_lit = 0, .inside_in_array = 0, .inside_infix = 0, .inside_assign_rhs = 0, .inside_match = 0, .inside_select = 0, .inside_match_case = 0, .inside_match_body = 0, .inside_unsafe = 0, .inside_sum_type = 0, .inside_asm_template = 0, .inside_asm = 0, .inside_defer = 0, .inside_generic_params = 0, .inside_receiver_param = 0, .inside_struct_field_decl = 0, .inside_struct_attr_decl = 0, .inside_map_init = 0, .inside_orm = 0, .inside_chan_decl = 0, .inside_attr_decl = 0, .array_dim = 0, .fixed_array_dim = 0, .or_is_handled = 0, .builtin_mod = 0, .mod = (string){.str=(byteptr)"", .is_lit=1}, .is_manualfree = 0, .has_globals = 0, .is_generated = 0, .is_translated = 0, .attrs = __new_array(0, 0, sizeof(v__ast__Attr)), .expr_mod = (string){.str=(byteptr)"", .is_lit=1}, .last_enum_name = (string){.str=(byteptr)"", .is_lit=1}, .last_enum_mod = (string){.str=(byteptr)"", .is_lit=1}, .imports = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .ast_imports = __new_array(0, 0, sizeof(v__ast__Import)), .used_imports = __new_array(0, 0, sizeof(string)), .auto_imports = __new_array(0, 0, sizeof(string)), .imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .is_amp = 0, .returns = 0, .is_stmt_ident = 0, .expecting_type = 0, .expecting_value = true, .cur_fn_name = (string){.str=(byteptr)"", .is_lit=1}, .cur_fn_scope = ((void*)0), .label_names = __new_array(0, 0, sizeof(string)), .name_error = 0, .n_asm = 0, .global_labels = __new_array(0, 0, sizeof(string)), .comptime_if_cond = 0, .defer_vars = __new_array(0, 0, sizeof(v__ast__Ident)), .should_abort = 0, .codegen_text = (string){.str=(byteptr)"", .is_lit=1}, .anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}), .init_generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .if_cond_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .left_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .script_mode = 0, .script_mode_start_token = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .generic_type_level = 0, .main_already_defined = 0, .is_vls = 0, .scanner = v__scanner__new_scanner(text, v__scanner__CommentsMode__skip_comments, pref_), .table = table, .scope = scope, .opened_scopes = 0, .max_opened_scopes = 100, .errors = __new_array_with_default(0, 0, sizeof(v__errors__Error), 0), .warnings = __new_array_with_default(0, 0, sizeof(v__errors__Warning), 0), .notices = __new_array(0, 0, sizeof(v__errors__Notice)), .template_paths = __new_array(0, 0, sizeof(string)), }); v__ast__File* res = v__parser__Parser_parse(&p); v__parser__Parser_free_scanner(&p); res->is_template_text = true; return res; } v__ast__File* v__parser__parse_text(string text, string path, v__ast__Table* table, v__scanner__CommentsMode comments_mode, v__pref__Preferences* pref_) { #if defined(CUSTOM_DEFINE_trace_parse_text) { eprintln(str_intp(6, _MOV((StrIntpData[]){{_S("> "), 0xfe10, {.d_s = _S("v.parser")}}, {_S("."), 0xfe10, {.d_s = _S("parse_text")}}, {_S(" comments_mode: "), 0x28fe10, {.d_s = v__scanner__CommentsMode_str(comments_mode)}}, {_S(" | path: "), 0x28fe10, {.d_s = path}}, {_S(" | text: "), 0xfe10, {.d_s = text}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__parser__Parser p = ((v__parser__Parser){ .pref = pref_, .file_base = (string){.str=(byteptr)"", .is_lit=1}, .file_path = (string){.str=(byteptr)"", .is_lit=1}, .file_display_path = (string){.str=(byteptr)"", .is_lit=1}, .unique_prefix = (string){.str=(byteptr)"", .is_lit=1}, .file_backend_mode = 0, .tok = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .prev_tok = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .peek_tok = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .language = 0, .fn_language = 0, .expr_level = 0, .inside_vlib_file = 0, .inside_test_file = 0, .inside_if = 0, .inside_comptime_if = 0, .inside_if_expr = 0, .inside_if_cond = 0, .inside_ct_if_expr = 0, .inside_or_expr = 0, .inside_for = 0, .inside_for_expr = 0, .inside_fn = 0, .inside_fn_return = 0, .inside_fn_concrete_type = 0, .inside_call_args = 0, .inside_unsafe_fn = 0, .inside_str_interp = 0, .inside_array_lit = 0, .inside_in_array = 0, .inside_infix = 0, .inside_assign_rhs = 0, .inside_match = 0, .inside_select = 0, .inside_match_case = 0, .inside_match_body = 0, .inside_unsafe = 0, .inside_sum_type = 0, .inside_asm_template = 0, .inside_asm = 0, .inside_defer = 0, .inside_generic_params = 0, .inside_receiver_param = 0, .inside_struct_field_decl = 0, .inside_struct_attr_decl = 0, .inside_map_init = 0, .inside_orm = 0, .inside_chan_decl = 0, .inside_attr_decl = 0, .array_dim = 0, .fixed_array_dim = 0, .or_is_handled = 0, .builtin_mod = 0, .mod = (string){.str=(byteptr)"", .is_lit=1}, .is_manualfree = 0, .has_globals = 0, .is_generated = 0, .is_translated = 0, .attrs = __new_array(0, 0, sizeof(v__ast__Attr)), .expr_mod = (string){.str=(byteptr)"", .is_lit=1}, .last_enum_name = (string){.str=(byteptr)"", .is_lit=1}, .last_enum_mod = (string){.str=(byteptr)"", .is_lit=1}, .imports = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .ast_imports = __new_array(0, 0, sizeof(v__ast__Import)), .used_imports = __new_array(0, 0, sizeof(string)), .auto_imports = __new_array(0, 0, sizeof(string)), .imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .is_amp = 0, .returns = 0, .is_stmt_ident = 0, .expecting_type = 0, .expecting_value = true, .cur_fn_name = (string){.str=(byteptr)"", .is_lit=1}, .cur_fn_scope = ((void*)0), .label_names = __new_array(0, 0, sizeof(string)), .name_error = 0, .n_asm = 0, .global_labels = __new_array(0, 0, sizeof(string)), .comptime_if_cond = 0, .defer_vars = __new_array(0, 0, sizeof(v__ast__Ident)), .should_abort = 0, .codegen_text = (string){.str=(byteptr)"", .is_lit=1}, .anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}), .init_generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .if_cond_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .left_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .script_mode = 0, .script_mode_start_token = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .generic_type_level = 0, .main_already_defined = 0, .is_vls = pref_->is_vls, .scanner = v__scanner__new_scanner(text, comments_mode, pref_), .table = table, .scope = ((v__ast__Scope*)memdup(&(v__ast__Scope){.objects = new_map(sizeof(string), sizeof(v__ast__ScopeObject), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.struct_fields = new_map(sizeof(string), sizeof(v__ast__ScopeStructField), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.parent = table->global_scope,.detached_from_parent = 0,.children = __new_array(0, 0, sizeof(v__ast__Scope*)),.start_pos = 0,.end_pos = 0,}, sizeof(v__ast__Scope))), .opened_scopes = 0, .max_opened_scopes = 100, .errors = __new_array_with_default(0, 0, sizeof(v__errors__Error), 0), .warnings = __new_array_with_default(0, 0, sizeof(v__errors__Warning), 0), .notices = __new_array(0, 0, sizeof(v__errors__Notice)), .template_paths = __new_array(0, 0, sizeof(string)), }); v__parser__Parser_set_path(&p, path); v__ast__File* res = v__parser__Parser_parse(&p); v__parser__Parser_free_scanner(&p); res->is_parse_text = true; return res; } void v__parser__Parser_free(v__parser__Parser* p) { v__parser__Parser_free_scanner(p); } VV_LOC void v__parser__Parser_free_scanner(v__parser__Parser* p) { { // Unsafe block if (p->scanner != 0) { v__scanner__Scanner_free(p->scanner); p->scanner = ((v__scanner__Scanner*)(((void*)0))); } } } void v__parser__Parser_set_path(v__parser__Parser* p, string path) { p->file_path = path; p->file_base = os__base(path); p->file_display_path = string_replace(string_replace_once(os__real_path(p->file_path), _const_v__parser__normalised_working_folder, _S("")), _S("\\"), _S("/")); p->inside_vlib_file = string_contains(os__dir(path), _S("vlib")); p->inside_test_file = string_ends_with(p->file_base, _S("_test.v")) || string_ends_with(p->file_base, _S("_test.vv")) || string_ends_with(string_all_before_last(string_all_before_last(p->file_base, _S(".v")), _S(".")), _S("_test")); u64 hash = hash__fnv1a__sum64_string(path); p->unique_prefix = u64_hex_full(hash); p->file_backend_mode = v__ast__Language__v; string before_dot_v = string_all_before_last(path, _S(".v")); string language = string_all_after_last(before_dot_v, _S(".")); string language_with_underscore = string_all_after_last(before_dot_v, _S("_")); if (string__eq(language, before_dot_v) && string__eq(language_with_underscore, before_dot_v)) { return; } string actual_language = (string__eq(language, before_dot_v) ? (language_with_underscore) : (language)); if (_SLIT_EQ(actual_language.str, actual_language.len, "c")) { p->file_backend_mode = v__ast__Language__c; } else if (_SLIT_EQ(actual_language.str, actual_language.len, "js")) { p->file_backend_mode = v__ast__Language__js; } else { _result_v__pref__Arch _t1 = v__pref__arch_from_string(actual_language); if (_t1.is_error) { IError err = _t1.err; *(v__pref__Arch*) _t1.data = v__pref__Arch___auto; } v__pref__Arch arch = (*(v__pref__Arch*)_t1.data); p->file_backend_mode = v__ast__pref_arch_to_table_language(arch); if (arch == v__pref__Arch___auto) { p->file_backend_mode = v__ast__Language__v; } } } v__ast__File* v__parser__parse_file(string path, v__ast__Table* table, v__scanner__CommentsMode comments_mode, v__pref__Preferences* pref_) { #if defined(CUSTOM_DEFINE_trace_parse_file) { eprintln(str_intp(5, _MOV((StrIntpData[]){{_S("> "), 0xfe10, {.d_s = _S("v.parser")}}, {_S("."), 0xfe10, {.d_s = _S("parse_file")}}, {_S(" comments_mode: "), 0x28fe10, {.d_s = v__scanner__CommentsMode_str(comments_mode)}}, {_S(" | path: "), 0xfe10, {.d_s = path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif _result_v__scanner__Scanner_ptr _t2 = v__scanner__new_scanner_file(path, comments_mode, pref_); if (_t2.is_error) { IError err = _t2.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } v__parser__Parser p = ((v__parser__Parser){ .pref = pref_, .file_base = (string){.str=(byteptr)"", .is_lit=1}, .file_path = (string){.str=(byteptr)"", .is_lit=1}, .file_display_path = (string){.str=(byteptr)"", .is_lit=1}, .unique_prefix = (string){.str=(byteptr)"", .is_lit=1}, .file_backend_mode = 0, .tok = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .prev_tok = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .peek_tok = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .language = 0, .fn_language = 0, .expr_level = 0, .inside_vlib_file = 0, .inside_test_file = 0, .inside_if = 0, .inside_comptime_if = 0, .inside_if_expr = 0, .inside_if_cond = 0, .inside_ct_if_expr = 0, .inside_or_expr = 0, .inside_for = 0, .inside_for_expr = 0, .inside_fn = 0, .inside_fn_return = 0, .inside_fn_concrete_type = 0, .inside_call_args = 0, .inside_unsafe_fn = 0, .inside_str_interp = 0, .inside_array_lit = 0, .inside_in_array = 0, .inside_infix = 0, .inside_assign_rhs = 0, .inside_match = 0, .inside_select = 0, .inside_match_case = 0, .inside_match_body = 0, .inside_unsafe = 0, .inside_sum_type = 0, .inside_asm_template = 0, .inside_asm = 0, .inside_defer = 0, .inside_generic_params = 0, .inside_receiver_param = 0, .inside_struct_field_decl = 0, .inside_struct_attr_decl = 0, .inside_map_init = 0, .inside_orm = 0, .inside_chan_decl = 0, .inside_attr_decl = 0, .array_dim = 0, .fixed_array_dim = 0, .or_is_handled = 0, .builtin_mod = 0, .mod = (string){.str=(byteptr)"", .is_lit=1}, .is_manualfree = 0, .has_globals = 0, .is_generated = 0, .is_translated = 0, .attrs = __new_array(0, 0, sizeof(v__ast__Attr)), .expr_mod = (string){.str=(byteptr)"", .is_lit=1}, .last_enum_name = (string){.str=(byteptr)"", .is_lit=1}, .last_enum_mod = (string){.str=(byteptr)"", .is_lit=1}, .imports = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .ast_imports = __new_array(0, 0, sizeof(v__ast__Import)), .used_imports = __new_array(0, 0, sizeof(string)), .auto_imports = __new_array(0, 0, sizeof(string)), .imported_symbols = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .is_amp = 0, .returns = 0, .is_stmt_ident = 0, .expecting_type = 0, .expecting_value = true, .cur_fn_name = (string){.str=(byteptr)"", .is_lit=1}, .cur_fn_scope = ((void*)0), .label_names = __new_array(0, 0, sizeof(string)), .name_error = 0, .n_asm = 0, .global_labels = __new_array(0, 0, sizeof(string)), .comptime_if_cond = 0, .defer_vars = __new_array(0, 0, sizeof(v__ast__Ident)), .should_abort = 0, .codegen_text = (string){.str=(byteptr)"", .is_lit=1}, .anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}), .init_generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .if_cond_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .left_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .script_mode = 0, .script_mode_start_token = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}), .generic_type_level = 0, .main_already_defined = 0, .is_vls = 0, .scanner = (*(v__scanner__Scanner**)_t2.data), .table = table, .scope = ((v__ast__Scope*)memdup(&(v__ast__Scope){.objects = new_map(sizeof(string), sizeof(v__ast__ScopeObject), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.struct_fields = new_map(sizeof(string), sizeof(v__ast__ScopeStructField), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.parent = table->global_scope,.detached_from_parent = 0,.children = __new_array(0, 0, sizeof(v__ast__Scope*)),.start_pos = 0,.end_pos = 0,}, sizeof(v__ast__Scope))), .opened_scopes = 0, .max_opened_scopes = 100, .errors = __new_array_with_default(0, 0, sizeof(v__errors__Error), 0), .warnings = __new_array_with_default(0, 0, sizeof(v__errors__Warning), 0), .notices = __new_array(0, 0, sizeof(v__errors__Notice)), .template_paths = __new_array(0, 0, sizeof(string)), }); v__parser__Parser_set_path(&p, path); v__ast__File* res = v__parser__Parser_parse(&p); v__parser__Parser_free_scanner(&p); return res; } v__ast__File* v__parser__Parser_parse(v__parser__Parser* p) { bool v__parser__Parser_parse_defer_0 = false; v__util__timing_start(_S("PARSE")); v__parser__Parser_parse_defer_0 = true; v__parser__Parser_init_parse_fns(p); v__parser__Parser_read_first_token(p); Array_v__ast__Stmt stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); for (;;) { if (!(p->tok.kind == v__token__Kind__comment)) break; array_push((array*)&stmts, _MOV((v__ast__Stmt[]){ v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (v__parser__Parser_comment_stmt(p)))) })); } v__ast__Module module_decl = v__parser__Parser_module_decl(p); if (module_decl.is_skipped) { array_insert(&stmts, 0, &(v__ast__Stmt[]){v__ast__Module_to_sumtype_v__ast__Stmt(&module_decl)}); } else { array_push((array*)&stmts, _MOV((v__ast__Stmt[]){ v__ast__Module_to_sumtype_v__ast__Stmt(&module_decl) })); } for (;;) { if (p->tok.kind == v__token__Kind__key_import) { array_push((array*)&stmts, _MOV((v__ast__Stmt[]){ v__ast__Import_to_sumtype_v__ast__Stmt(ADDR(v__ast__Import, (v__parser__Parser_import_stmt(p)))) })); continue; } if (p->tok.kind == v__token__Kind__comment) { array_push((array*)&stmts, _MOV((v__ast__Stmt[]){ v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (v__parser__Parser_comment_stmt(p)))) })); continue; } break; } for (;;) { if (p->tok.kind == v__token__Kind__eof) { v__parser__Parser_check_unused_imports(p); break; } v__ast__Stmt stmt = v__parser__Parser_top_stmt(p); if (!((stmt)._typ == 401 /* v.ast.ExprStmt */ && ((*(v__ast__ExprStmt*)__as_cast((stmt)._v__ast__ExprStmt,(stmt)._typ, 401)).expr)._typ == 348 /* v.ast.Comment */)) { p->attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); } array_push((array*)&stmts, _MOV((v__ast__Stmt[]){ stmt })); if (p->should_abort) { break; } } p->scope->end_pos = p->tok.pos; Array_v__errors__Error errors_ = array_clone_to_depth(&p->errors, 0); Array_v__errors__Warning warnings = array_clone_to_depth(&p->warnings, 0); Array_v__errors__Notice notices = array_clone_to_depth(&p->notices, 0); if (p->pref->check_only) { _PUSH_MANY(&errors_, (p->scanner->errors), _t6, Array_v__errors__Error); _PUSH_MANY(&warnings, (p->scanner->warnings), _t7, Array_v__errors__Warning); _PUSH_MANY(¬ices, (p->scanner->notices), _t8, Array_v__errors__Notice); } v__parser__Parser_handle_codegen_for_file(p); v__ast__File* ast_file = ((v__ast__File*)memdup(&(v__ast__File){.nr_lines = p->scanner->line_nr, .nr_bytes = p->scanner->text.len, .nr_tokens = p->scanner->all_tokens.len, .mod = module_decl, .global_scope = p->table->global_scope, .is_test = p->inside_test_file, .is_generated = p->is_generated, .is_translated = p->is_translated, .language = p->file_backend_mode, .idx = 0, .path = p->file_path, .path_base = p->file_base, .scope = p->scope, .stmts = stmts, .imports = p->ast_imports, .auto_imports = p->auto_imports, .embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)), .imported_symbols = p->imported_symbols, .errors = errors_, .warnings = warnings, .notices = notices, .generic_fns = __new_array(0, 0, sizeof(v__ast__FnDecl*)), .global_labels = p->global_labels, .template_paths = p->template_paths, .unique_prefix = p->unique_prefix, .is_parse_text = 0, .is_template_text = 0, }, sizeof(v__ast__File))); #if defined(CUSTOM_DEFINE_trace_parse_file_path_and_mod) { eprintln(str_intp(5, _MOV((StrIntpData[]){{_S(">> ast.File, tokens: "), 0xafe27, {.d_i32 = ast_file->nr_tokens}}, {_S(", mname: "), 0x28fe30, {.d_s = ast_file->mod.name}}, {_S(", sname: "), 0x16fe30, {.d_s = ast_file->mod.short_name}}, {_S(", path: "), 0xfe10, {.d_s = p->file_display_path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__ast__File* _t10 = ast_file; // Defer begin if (v__parser__Parser_parse_defer_0) { v__util__timing_measure_cumulative(_S("PARSE")); } // Defer end return _t10; } Array_v__ast__File_ptr v__parser__parse_files(Array_string paths, v__ast__Table* table, v__pref__Preferences* pref_) { v__util__Timers* timers = v__util__new_timers(((v__util__TimerParams){.should_print = false,.label = str_intp(2, _MOV((StrIntpData[]){{_S("parse_files: "), 0xfe10, {.d_s = Array_string_str(paths)}}, {_SLIT0, 0, { .d_c = 0 }}})),})); #if defined(CUSTOM_DEFINE_time_parsing) { timers->should_print = true; } #endif { // Unsafe block Array_v__ast__File_ptr files = __new_array_with_default(0, paths.len, sizeof(v__ast__File*), 0); for (int _t2 = 0; _t2 < paths.len; ++_t2) { string path = ((string*)paths.data)[_t2]; v__util__Timers_start(timers, str_intp(2, _MOV((StrIntpData[]){{_S("parse_file "), 0xfe10, {.d_s = path}}, {_SLIT0, 0, { .d_c = 0 }}}))); array_push((array*)&files, _MOV((v__ast__File*[]){ v__parser__parse_file(path, table, v__scanner__CommentsMode__skip_comments, pref_) })); v__util__Timers_show(timers, str_intp(2, _MOV((StrIntpData[]){{_S("parse_file "), 0xfe10, {.d_s = path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } v__parser__handle_codegen_for_multiple_files(&files); return files; } return __new_array(0, 0, sizeof(v__ast__File*)); } VV_LOC void v__parser__Parser_init_parse_fns(v__parser__Parser* p) { } VV_LOC void v__parser__Parser_read_first_token(v__parser__Parser* p) { v__parser__Parser_next(p); v__parser__Parser_next(p); } inline VV_LOC v__token__Token v__parser__Parser_peek_token(v__parser__Parser* p, int n) { return v__scanner__Scanner_peek_token(p->scanner, (int)(n - 2)); } VV_LOC v__token__Token v__parser__Parser_peek_token_after_var_list(v__parser__Parser* p) { int n = 0; v__token__Token tok = p->tok; for (;;) { if (!(tok.kind != v__token__Kind__eof)) break; if (tok.kind == v__token__Kind__key_mut) { n += 2; } else { n++; } tok = v__scanner__Scanner_peek_token(p->scanner, (int)(n - 2)); if (tok.kind != v__token__Kind__comma) { break; } else { n++; tok = v__scanner__Scanner_peek_token(p->scanner, (int)(n - 2)); } } return tok; } VV_LOC void v__parser__Parser_open_scope(v__parser__Parser* p) { if (p->opened_scopes > p->max_opened_scopes) { p->should_abort = true; v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("nested opened scopes limit reached: "), 0xfe07, {.d_i32 = p->max_opened_scopes}}, {_SLIT0, 0, { .d_c = 0 }}}))); return; } p->scope = ((v__ast__Scope*)memdup(&(v__ast__Scope){.objects = new_map(sizeof(string), sizeof(v__ast__ScopeObject), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.struct_fields = new_map(sizeof(string), sizeof(v__ast__ScopeStructField), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.parent = p->scope,.detached_from_parent = 0,.children = __new_array(0, 0, sizeof(v__ast__Scope*)),.start_pos = p->tok.pos,.end_pos = 0,}, sizeof(v__ast__Scope))); p->opened_scopes++; } VV_LOC void v__parser__Parser_close_scope(v__parser__Parser* p) { p->scope->end_pos = p->prev_tok.pos; array_push((array*)&p->scope->parent->children, _MOV((v__ast__Scope*[]){ p->scope })); p->scope = p->scope->parent; p->opened_scopes--; } VV_LOC Array_v__ast__Stmt v__parser__Parser_parse_block(v__parser__Parser* p) { v__parser__Parser_open_scope(p); Array_v__ast__Stmt stmts = v__parser__Parser_parse_block_no_scope(p, false); v__parser__Parser_close_scope(p); return stmts; } VV_LOC Array_v__ast__Stmt v__parser__Parser_parse_block_no_scope(v__parser__Parser* p, bool is_top_level) { v__parser__Parser_check(p, v__token__Kind__lcbr); Array_v__ast__Stmt stmts = __new_array_with_default(0, 20, sizeof(v__ast__Stmt), 0); bool old_assign_rhs = p->inside_assign_rhs; p->inside_assign_rhs = false; if (p->tok.kind != v__token__Kind__rcbr) { int count = 0; for (;;) { if (!(!(p->tok.kind == v__token__Kind__eof || p->tok.kind == v__token__Kind__rcbr))) break; array_push((array*)&stmts, _MOV((v__ast__Stmt[]){ v__parser__Parser_stmt(p, is_top_level) })); count++; if ((int)(count % 100000) == 0) { if (p->is_vls) { return __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); } eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("parsed "), 0xfe07, {.d_i32 = count}}, {_S(" statements so far from fn "), 0xfe10, {.d_s = p->cur_fn_name}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } if (count > 1000000) { v__parser__Parser_error_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_S("parsed over "), 0xfe07, {.d_i32 = count}}, {_S(" statements from fn "), 0xfe10, {.d_s = p->cur_fn_name}}, {_S(", the parser is probably stuck"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->tok)); return __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); } } } p->inside_assign_rhs = old_assign_rhs; if (is_top_level) { v__parser__Parser_top_level_statement_end(p); } v__parser__Parser_check(p, v__token__Kind__rcbr); if (p->inside_assign_rhs && stmts.len > 0) { v__ast__Stmt last_stmt = (*(v__ast__Stmt*)array_last(stmts)); v__parser__Parser_mark_last_call_return_as_used(p, &last_stmt); } return stmts; } VV_LOC void v__parser__Parser_mark_last_call_return_as_used(v__parser__Parser* p, v__ast__Stmt* last_stmt) { if (last_stmt->_typ == 401 /* v.ast.ExprStmt */) { if ((*last_stmt->_v__ast__ExprStmt).expr._typ == 344 /* v.ast.CallExpr */) { (*(*last_stmt->_v__ast__ExprStmt).expr._v__ast__CallExpr).is_return_used = true; } else if ((*last_stmt->_v__ast__ExprStmt).expr._typ == 359 /* v.ast.IfExpr */) { for (int _t1 = 0; _t1 < (*(*last_stmt->_v__ast__ExprStmt).expr._v__ast__IfExpr).branches.len; ++_t1) { v__ast__IfBranch* branch = ((v__ast__IfBranch*)(*(*last_stmt->_v__ast__ExprStmt).expr._v__ast__IfExpr).branches.data) + _t1; if (branch->stmts.len > 0) { v__ast__Stmt last_if_stmt = (*(v__ast__Stmt*)array_last(branch->stmts)); v__parser__Parser_mark_last_call_return_as_used(p, &last_if_stmt); } } } else if ((*last_stmt->_v__ast__ExprStmt).expr._typ == 352 /* v.ast.ConcatExpr */) { for (int _t2 = 0; _t2 < (*(*last_stmt->_v__ast__ExprStmt).expr._v__ast__ConcatExpr).vals.len; ++_t2) { v__ast__Expr* expr = ((v__ast__Expr*)(*(*last_stmt->_v__ast__ExprStmt).expr._v__ast__ConcatExpr).vals.data) + _t2; if ((expr)->_typ == 344 /* v.ast.CallExpr */) { (*expr->_v__ast__CallExpr).is_return_used = true; } } } else if ((*last_stmt->_v__ast__ExprStmt).expr._typ == 362 /* v.ast.InfixExpr */) { v__ast__Expr left_expr = (*(*last_stmt->_v__ast__ExprStmt).expr._v__ast__InfixExpr).left; for (;;) { if ((left_expr)._typ == 362 /* v.ast.InfixExpr */) { left_expr = (*left_expr._v__ast__InfixExpr).left; continue; } if ((left_expr)._typ == 344 /* v.ast.CallExpr */) { (*left_expr._v__ast__CallExpr).is_return_used = true; } break; } } else { } } else { } } inline VV_LOC void v__parser__Parser_next(v__parser__Parser* p) { p->prev_tok = p->tok; p->tok = p->peek_tok; p->peek_tok = v__scanner__Scanner_scan(p->scanner); } VV_LOC void v__parser__Parser_check(v__parser__Parser* p, v__token__Kind expected) { p->name_error = false; if (_likely_(p->tok.kind == expected)) { v__parser__Parser_next(p); } else { if (expected == v__token__Kind__name) { p->name_error = true; } string s = v__token__Kind_str(expected); if (v__token__is_key(s) || (s.len > 0 && !u8_is_letter(string_at(s, 0)))) { s = str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = s}}, {_S("`"), 0, { .d_c = 0 }}})); } v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = s,.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); } } VV_LOC string v__parser__Parser_check_js_name(v__parser__Parser* p) { string name = _S(""); for (;;) { if (!(p->peek_tok.kind == v__token__Kind__dot)) break; name = string__plus(name, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = p->tok.lit}}, {_S("."), 0, { .d_c = 0 }}}))); v__parser__Parser_next(p); v__parser__Parser_next(p); } name = string__plus(name, p->tok.lit); v__parser__Parser_next(p); return name; } VV_LOC bool v__parser__is_ident_name(string name) { if (name.len == 0) { return false; } if (!_const_v__util__name_char_table[name.str[ 0]]) { return false; } for (int i = 1; i < name.len; ++i) { if (!_const_v__util__func_char_table[name.str[ i]]) { return false; } } return true; } VV_LOC string v__parser__Parser_check_name(v__parser__Parser* p) { v__token__Pos pos = v__token__Token_pos(&p->tok); string name = p->tok.lit; if (p->tok.kind != v__token__Kind__name && p->peek_tok.kind == v__token__Kind__dot && _IN_MAP(ADDR(string, name), ADDR(map, p->imports))) { v__parser__Parser_register_used_import(p, name); } else if (p->tok.kind == v__token__Kind__name && p->peek_tok.kind == v__token__Kind__dot && _IN_MAP(ADDR(string, name), ADDR(map, p->imported_symbols))) { v__parser__Parser_register_used_import_for_symbol_name(p, (*(string*)map_get(ADDR(map, p->imported_symbols), &(string[]){name}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} }))); } if (!v__parser__is_ident_name(name)) { v__parser__Parser_check(p, v__token__Kind__name); } else { v__parser__Parser_next(p); } if (!p->inside_orm && !p->inside_attr_decl && _SLIT_EQ(name.str, name.len, "sql")) { v__parser__Parser_error_with_pos(p, _S("unexpected keyword `sql`, expecting name"), pos); } return name; } VV_LOC v__ast__Stmt v__parser__Parser_top_stmt(v__parser__Parser* p) { ; for (;;) { if (p->tok.kind == (v__token__Kind__key_pub)) { if (p->peek_tok.kind == (v__token__Kind__key_const)) { return v__ast__ConstDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__ConstDecl, (v__parser__Parser_const_decl(p)))); } else if (p->peek_tok.kind == (v__token__Kind__key_fn)) { return v__ast__FnDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__FnDecl, (v__parser__Parser_fn_decl(p)))); } else if (p->peek_tok.kind == (v__token__Kind__key_struct) || p->peek_tok.kind == (v__token__Kind__key_union)) { return v__ast__StructDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__StructDecl, (v__parser__Parser_struct_decl(p, false)))); } else if (p->peek_tok.kind == (v__token__Kind__key_interface)) { return v__ast__InterfaceDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__InterfaceDecl, (v__parser__Parser_interface_decl(p)))); } else if (p->peek_tok.kind == (v__token__Kind__key_enum)) { return v__ast__EnumDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__EnumDecl, (v__parser__Parser_enum_decl(p)))); } else if (p->peek_tok.kind == (v__token__Kind__key_type)) { return v__ast__TypeDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__TypeDecl, (v__parser__Parser_type_decl(p)))); } else { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, _S("wrong pub keyword usage"))))); } } else if (p->tok.kind == (v__token__Kind__at)) { if (p->peek_tok.kind == v__token__Kind__lsbr) { v__parser__Parser_attributes(p); continue; } else { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, _S("@[attr] expected"))))); } } else if (p->tok.kind == (v__token__Kind__lsbr)) { v__parser__Parser_attributes(p); continue; } else if (p->tok.kind == (v__token__Kind__key_interface)) { return v__ast__InterfaceDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__InterfaceDecl, (v__parser__Parser_interface_decl(p)))); } else if (p->tok.kind == (v__token__Kind__key_import)) { v__parser__Parser_error_with_pos(p, _S("`import x` can only be declared at the beginning of the file"), v__token__Token_pos(&p->tok)); return v__ast__Import_to_sumtype_v__ast__Stmt(ADDR(v__ast__Import, (v__parser__Parser_import_stmt(p)))); } else if (p->tok.kind == (v__token__Kind__key_global)) { return v__ast__GlobalDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__GlobalDecl, (v__parser__Parser_global_decl(p)))); } else if (p->tok.kind == (v__token__Kind__key_const)) { return v__ast__ConstDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__ConstDecl, (v__parser__Parser_const_decl(p)))); } else if (p->tok.kind == (v__token__Kind__key_fn)) { return v__ast__FnDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__FnDecl, (v__parser__Parser_fn_decl(p)))); } else if (p->tok.kind == (v__token__Kind__key_struct)) { return v__ast__StructDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__StructDecl, (v__parser__Parser_struct_decl(p, false)))); } else if (p->tok.kind == (v__token__Kind__dollar)) { if (p->peek_tok.kind == v__token__Kind__eof) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = _S("eof"),.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},}))))); } if (p->peek_tok.kind == v__token__Kind__key_for) { v__ast__ComptimeFor comptime_for_stmt = v__parser__Parser_comptime_for(p); return v__parser__Parser_other_stmts(p, v__ast__ComptimeFor_to_sumtype_v__ast__Stmt(&comptime_for_stmt)); } else if (p->peek_tok.kind == v__token__Kind__key_if) { v__ast__IfExpr if_expr = v__parser__Parser_if_expr(p, true, false); v__ast__ExprStmt cur_stmt = ((v__ast__ExprStmt){.pos = if_expr.pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__IfExpr_to_sumtype_v__ast__Expr(&if_expr),.is_expr = 0,.typ = 0,}); if (p->pref->is_fmt || v__parser__comptime_if_expr_contains_top_stmt(if_expr)) { return v__ast__ExprStmt_to_sumtype_v__ast__Stmt(&cur_stmt); } else { return v__parser__Parser_other_stmts(p, v__ast__ExprStmt_to_sumtype_v__ast__Stmt(&cur_stmt)); } } else { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = (string){.str=(byteptr)"", .is_lit=1},.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},}))))); } } else if (p->tok.kind == (v__token__Kind__hash)) { return v__ast__HashStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__HashStmt, (v__parser__Parser_hash(p)))); } else if (p->tok.kind == (v__token__Kind__key_type)) { return v__ast__TypeDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__TypeDecl, (v__parser__Parser_type_decl(p)))); } else if (p->tok.kind == (v__token__Kind__key_enum)) { return v__ast__EnumDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__EnumDecl, (v__parser__Parser_enum_decl(p)))); } else if (p->tok.kind == (v__token__Kind__key_union)) { return v__ast__StructDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__StructDecl, (v__parser__Parser_struct_decl(p, false)))); } else if (p->tok.kind == (v__token__Kind__comment)) { return v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (v__parser__Parser_comment_stmt(p)))); } else if (p->tok.kind == (v__token__Kind__semicolon)) { return v__ast__SemicolonStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__SemicolonStmt, (v__parser__Parser_semicolon_stmt(p)))); } else if (p->tok.kind == (v__token__Kind__key_asm)) { return v__ast__AsmStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__AsmStmt, (v__parser__Parser_asm_stmt(p, true)))); } else { return v__parser__Parser_other_stmts(p, _const_v__ast__empty_stmt); } if (p->should_abort) { break; } } return _const_v__ast__empty_stmt; } VV_LOC bool v__parser__comptime_if_expr_contains_top_stmt(v__ast__IfExpr if_expr) { for (int _t1 = 0; _t1 < if_expr.branches.len; ++_t1) { v__ast__IfBranch branch = ((v__ast__IfBranch*)if_expr.branches.data)[_t1]; for (int _t2 = 0; _t2 < branch.stmts.len; ++_t2) { v__ast__Stmt stmt = ((v__ast__Stmt*)branch.stmts.data)[_t2]; if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { if (((*stmt._v__ast__ExprStmt).expr)._typ == 359 /* v.ast.IfExpr */) { if (!v__parser__comptime_if_expr_contains_top_stmt((*(*stmt._v__ast__ExprStmt).expr._v__ast__IfExpr))) { return false; } } else if (((*stmt._v__ast__ExprStmt).expr)._typ == 344 /* v.ast.CallExpr */) { return false; } } else if ((stmt)._typ == 392 /* v.ast.AssignStmt */) { return false; } else if ((stmt)._typ == 408 /* v.ast.HashStmt */) { return true; } } } return true; } VV_LOC v__ast__Stmt v__parser__Parser_other_stmts(v__parser__Parser* p, v__ast__Stmt cur_stmt) { p->inside_fn = true; if (p->pref->is_script && !p->pref->is_test) { p->script_mode = true; p->script_mode_start_token = p->tok; if (p->main_already_defined) { v__parser__Parser_error(p, _S("function `main` is already defined, put your script statements inside it")); } v__parser__Parser_open_scope(p); p->cur_fn_name = _S("main.main"); Array_v__ast__Stmt stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); if (!v__ast__Stmt_sumtype_eq(cur_stmt, _const_v__ast__empty_stmt)) { array_push((array*)&stmts, _MOV((v__ast__Stmt[]){ cur_stmt })); } for (;;) { if (!(p->tok.kind != v__token__Kind__eof)) break; array_push((array*)&stmts, _MOV((v__ast__Stmt[]){ v__parser__Parser_stmt(p, false) })); } v__parser__Parser_close_scope(p); p->script_mode = false; return v__ast__FnDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__FnDecl, (((v__ast__FnDecl){ .name = _S("main.main"), .short_name = _S("main"), .mod = _S("main"), .is_deprecated = 0, .is_pub = 0, .is_c_variadic = 0, .is_c_extern = 0, .is_variadic = 0, .is_anon = 0, .is_noreturn = 0, .is_manualfree = 0, .is_main = true, .is_test = 0, .is_conditional = 0, .is_exported = 0, .is_keep_alive = 0, .is_unsafe = 0, .is_must_use = 0, .is_markused = 0, .is_file_translated = 0, .receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}), .receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_method = 0, .is_static_type_method = 0, .static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .method_idx = 0, .rec_mut = 0, .has_prev_newline = 0, .has_break_line = 0, .rec_share = 0, .language = 0, .file_mode = 0, .no_body = 0, .is_builtin = 0, .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .file = p->file_path, .generic_names = __new_array(0, 0, sizeof(string)), .is_direct_arr = 0, .attrs = __new_array(0, 0, sizeof(v__ast__Attr)), .ctdefine_idx = -1, .idx = 0, .params = __new_array(0, 0, sizeof(v__ast__Param)), .stmts = stmts, .defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)), .trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .return_type = _const_v__ast__void_type, .return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .has_return = 0, .should_be_skipped = 0, .ninstances = 0, .has_await = 0, .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .end_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .next_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .source_file = ((void*)0), .scope = p->scope, .label_names = p->label_names, .pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_expand_simple_interpolation = 0, })))); } else if (p->pref->is_fmt || p->pref->is_vet) { return v__parser__Parser_stmt(p, false); } else { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, string__plus(_S("bad top level statement "), v__token__Token_str(p->tok)))))); } return (v__ast__Stmt){._v__ast__AsmStmt=HEAP(v__ast__AsmStmt, ((v__ast__AsmStmt){.arch = 0,.is_basic = 0,.is_volatile = 0,.is_goto = 0,.clobbered = __new_array(0, 0, sizeof(v__ast__AsmClobbered)),.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.templates = __new_array(0, 0, sizeof(v__ast__AsmTemplate)),.scope = ((void*)0),.output = __new_array(0, 0, sizeof(v__ast__AsmIO)),.input = __new_array(0, 0, sizeof(v__ast__AsmIO)),.global_labels = __new_array(0, 0, sizeof(string)),.local_labels = __new_array(0, 0, sizeof(string)),})),._typ=390}; } VV_LOC v__ast__Comment v__parser__Parser_check_comment(v__parser__Parser* p) { if (p->tok.kind == v__token__Kind__comment) { return v__parser__Parser_comment(p); } return ((v__ast__Comment){.text = (string){.str=(byteptr)"", .is_lit=1},.is_multi = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); } VV_LOC v__ast__Comment v__parser__Parser_comment(v__parser__Parser* p) { v__token__Pos pos = v__token__Token_pos(&p->tok); string text = p->tok.lit; int num_newlines = string_count(text, _S("\n")); bool is_multi = num_newlines > 0; pos.last_line = (int)(pos.line_nr + num_newlines); v__parser__Parser_next(p); return ((v__ast__Comment){.text = text,.is_multi = is_multi,.pos = pos,}); } VV_LOC v__ast__ExprStmt v__parser__Parser_comment_stmt(v__parser__Parser* p) { v__ast__Comment comment = v__parser__Parser_comment(p); return ((v__ast__ExprStmt){.pos = comment.pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__Comment_to_sumtype_v__ast__Expr(&comment),.is_expr = 0,.typ = 0,}); } VV_LOC Array_v__ast__Comment v__parser__Parser_eat_comments(v__parser__Parser* p, v__parser__EatCommentsConfig cfg) { int line = (int)(p->prev_tok.line_nr + string_count(p->prev_tok.lit, _S("\n"))); Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); for (;;) { if (p->tok.kind != v__token__Kind__comment || (cfg.same_line && p->tok.line_nr > line) || (cfg.follow_up && p->tok.line_nr > (int)(line + 1))) { break; } array_push((array*)&comments, _MOV((v__ast__Comment[]){ v__parser__Parser_comment(p) })); if (cfg.follow_up) { line = (int)(p->prev_tok.line_nr + string_count(p->prev_tok.lit, _S("\n"))); } } return comments; } VV_LOC void v__parser__Parser_goto_eof(v__parser__Parser* p) { for (;;) { if (!(p->tok.kind != v__token__Kind__eof)) break; v__parser__Parser_next(p); } } VV_LOC v__ast__Stmt v__parser__Parser_stmt(v__parser__Parser* p, bool is_top_level) { if (p->should_abort) { v__token__Pos abort_pos = v__token__Token_pos(&p->tok); v__parser__Parser_goto_eof(p); return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (((v__ast__NodeError){.idx = 0,.pos = abort_pos,})))); } ; p->is_stmt_ident = p->tok.kind == v__token__Kind__name; switch (p->tok.kind) { case v__token__Kind__lcbr: { v__token__Pos pos = v__token__Token_pos(&p->tok); if (v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__colon) { v__ast__Expr expr = v__parser__Parser_expr(p, 0); return v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (((v__ast__ExprStmt){.pos = pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = expr,.is_expr = 0,.typ = 0,})))); } else { Array_v__ast__Stmt stmts = v__parser__Parser_parse_block(p); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); return v__ast__Block_to_sumtype_v__ast__Stmt(ADDR(v__ast__Block, (((v__ast__Block){.is_unsafe = 0,.pos = pos,.stmts = stmts,})))); } break; } case v__token__Kind__name: { if (p->peek_tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("sql"))) { return v__ast__SqlStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__SqlStmt, (v__parser__Parser_sql_stmt(p)))); } if (p->peek_tok.kind == v__token__Kind__colon) { v__token__Pos spos = v__token__Token_pos(&p->tok); string name = v__parser__Parser_check_name(p); if ((Array_string_contains(p->label_names, name))) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate label `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}})), spos)))); } array_push((array*)&p->label_names, _MOV((string[]){ string_clone(name) })); v__parser__Parser_next(p); if (p->tok.kind == v__token__Kind__key_for) { v__token__Pos for_pos = v__token__Token_pos(&p->tok); v__ast__Stmt stmt = v__parser__Parser_stmt(p, is_top_level); if (stmt._typ == 404 /* v.ast.ForStmt */) { (*stmt._v__ast__ForStmt).label = name; return v__ast__ForStmt_to_sumtype_v__ast__Stmt(&(*stmt._v__ast__ForStmt)); } else if (stmt._typ == 403 /* v.ast.ForInStmt */) { (*stmt._v__ast__ForInStmt).label = name; return v__ast__ForInStmt_to_sumtype_v__ast__Stmt(&(*stmt._v__ast__ForInStmt)); } else if (stmt._typ == 402 /* v.ast.ForCStmt */) { (*stmt._v__ast__ForCStmt).label = name; return v__ast__ForCStmt_to_sumtype_v__ast__Stmt(&(*stmt._v__ast__ForCStmt)); } else { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("unknown kind of For statement"), for_pos)))); } } return v__ast__GotoLabel_to_sumtype_v__ast__Stmt(ADDR(v__ast__GotoLabel, (((v__ast__GotoLabel){.name = name,.pos = v__token__Pos_extend(spos, v__token__Token_pos(&p->tok)),.is_used = 0,})))); } else if (p->peek_tok.kind == v__token__Kind__name) { if (p->is_vls) { v__parser__Parser_next(p); return v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (((v__ast__ExprStmt){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (v__parser__Parser_ident(p, v__ast__Language__v)))),.is_expr = 0,.typ = 0,})))); } return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = str_intp(2, _MOV((StrIntpData[]){{_S("name `"), 0xfe10, {.d_s = p->tok.lit}}, {_S("`"), 0, { .d_c = 0 }}})),.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},}))))); } else if (!p->inside_if_expr && !p->inside_match_body && !p->inside_or_expr && (p->peek_tok.kind == v__token__Kind__rcbr || p->peek_tok.kind == v__token__Kind__eof) && !v__ast__Scope_mark_var_as_used(p->scope, p->tok.lit)) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = p->tok.lit}}, {_S("` evaluated but not used"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->tok))))); } return v__parser__Parser_parse_multi_expr(p, is_top_level); } case v__token__Kind__key_for: { return v__parser__Parser_for_stmt(p); } case v__token__Kind__comment: { return v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (v__parser__Parser_comment_stmt(p)))); } case v__token__Kind__key_return: { if (!p->inside_defer) { return v__ast__Return_to_sumtype_v__ast__Stmt(ADDR(v__ast__Return, (v__parser__Parser_return_stmt(p)))); } else { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("`return` not allowed inside `defer` block"), v__token__Token_pos(&p->tok))))); } break; } case v__token__Kind__dollar: { if (p->peek_tok.kind == (v__token__Kind__key_if)) { v__token__Pos pos = v__token__Token_pos(&p->tok); v__ast__IfExpr expr = v__parser__Parser_if_expr(p, true, false); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); return v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (((v__ast__ExprStmt){.pos = pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__IfExpr_to_sumtype_v__ast__Expr(&expr),.is_expr = 0,.typ = 0,})))); } else if (p->peek_tok.kind == (v__token__Kind__key_for)) { return v__ast__ComptimeFor_to_sumtype_v__ast__Stmt(ADDR(v__ast__ComptimeFor, (v__parser__Parser_comptime_for(p)))); } else if (p->peek_tok.kind == (v__token__Kind__name)) { if (fast_string_eq(p->peek_tok.lit, _S("dbg"))) { return v__ast__DebuggerStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__DebuggerStmt, (v__parser__Parser_dbg_stmt(p)))); } else { v__token__Pos pos = v__token__Token_pos(&p->tok); v__ast__Expr expr = v__parser__Parser_expr(p, 0); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); return v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (((v__ast__ExprStmt){.pos = pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = expr,.is_expr = 0,.typ = 0,})))); } } else { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = _S("$"),.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},}))))); } break; } case v__token__Kind__key_continue: case v__token__Kind__key_break: { v__token__Token tok = p->tok; int line = p->tok.line_nr; v__parser__Parser_next(p); string label = _S(""); if (p->tok.line_nr == line && p->tok.kind == v__token__Kind__name) { label = v__parser__Parser_check_name(p); } return v__ast__BranchStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__BranchStmt, (((v__ast__BranchStmt){.kind = tok.kind,.label = label,.pos = v__token__Token_pos(&tok),})))); } case v__token__Kind__key_unsafe: { return v__parser__Parser_unsafe_stmt(p); } case v__token__Kind__hash: { return v__ast__HashStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__HashStmt, (v__parser__Parser_hash(p)))); } case v__token__Kind__key_assert: { v__parser__Parser_next(p); v__token__Pos pos = v__token__Token_pos(&p->tok); v__ast__Expr expr = v__parser__Parser_expr(p, 0); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); v__ast__Expr extra = _const_v__ast__empty_expr; v__token__Pos extra_pos = v__token__Token_pos(&p->tok); if (p->tok.kind == v__token__Kind__comma) { v__parser__Parser_next(p); extra_pos = v__token__Token_pos(&p->tok); extra = v__parser__Parser_expr(p, 0); extra_pos = v__token__Pos_extend(extra_pos, v__token__Token_pos(&p->tok)); } return v__ast__AssertStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__AssertStmt, (((v__ast__AssertStmt){.pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->tok)),.extra_pos = extra_pos,.expr = expr,.extra = extra,.is_used = p->inside_test_file || !p->pref->is_prod,})))); } case v__token__Kind__key_defer: { if (!p->inside_defer) { v__parser__Parser_next(p); v__token__Pos spos = v__token__Token_pos(&p->tok); p->inside_defer = true; p->defer_vars = __new_array_with_default(0, 0, sizeof(v__ast__Ident), 0); Array_v__ast__Stmt stmts = v__parser__Parser_parse_block(p); p->inside_defer = false; return v__ast__DeferStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__DeferStmt, (((v__ast__DeferStmt){.pos = v__token__Pos_extend_with_last_line(spos, v__token__Token_pos(&p->tok), p->prev_tok.line_nr),.stmts = stmts,.defer_vars = array_clone_to_depth(&p->defer_vars, 0),.ifdef = (string){.str=(byteptr)"", .is_lit=1},.idx_in_fn = -1,})))); } else { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("`defer` blocks cannot be nested"), v__token__Token_pos(&p->tok))))); } break; } case v__token__Kind__key_go: case v__token__Kind__key_spawn: { if ((p->pref->use_coroutines || p->pref->is_fmt) && p->tok.kind == v__token__Kind__key_go) { v__ast__GoExpr go_expr = v__parser__Parser_go_expr(p); return v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (((v__ast__ExprStmt){.pos = go_expr.pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__GoExpr_to_sumtype_v__ast__Expr(&go_expr),.is_expr = 0,.typ = 0,})))); } else { v__ast__SpawnExpr spawn_expr = v__parser__Parser_spawn_expr(p); return v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (((v__ast__ExprStmt){.pos = spawn_expr.pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__SpawnExpr_to_sumtype_v__ast__Expr(&spawn_expr),.is_expr = 0,.typ = 0,})))); } break; } case v__token__Kind__key_goto: { v__parser__Parser_next(p); v__token__Pos spos = v__token__Token_pos(&p->tok); string name = v__parser__Parser_check_name(p); return v__ast__GotoStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__GotoStmt, (((v__ast__GotoStmt){.name = name,.pos = spos,})))); } case v__token__Kind__key_const: { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("const can only be defined at the top level (outside of functions)"), v__token__Token_pos(&p->tok))))); } case v__token__Kind__key_asm: { return v__ast__AsmStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__AsmStmt, (v__parser__Parser_asm_stmt(p, false)))); } case v__token__Kind__semicolon: { return v__ast__SemicolonStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__SemicolonStmt, (v__parser__Parser_semicolon_stmt(p)))); } case v__token__Kind__key_struct: case v__token__Kind__key_union: { return v__ast__StructDecl_to_sumtype_v__ast__Stmt(ADDR(v__ast__StructDecl, (v__parser__Parser_struct_decl(p, false)))); } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__plus: case v__token__Kind__minus: case v__token__Kind__mul: case v__token__Kind__div: case v__token__Kind__mod: case v__token__Kind__xor: case v__token__Kind__pipe: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__and: case v__token__Kind__logical_or: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__amp: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__left_shift: case v__token__Kind__right_shift: case v__token__Kind__unsigned_right_shift: case v__token__Kind__not_in: case v__token__Kind__not_is: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__eq: case v__token__Kind__ne: case v__token__Kind__gt: case v__token__Kind__lt: case v__token__Kind__ge: case v__token__Kind__le: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_atomic: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_in: case v__token__Kind__key_interface: case v__token__Kind__key_is: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { return v__parser__Parser_parse_multi_expr(p, is_top_level); } } } return (v__ast__Stmt){._v__ast__AsmStmt=HEAP(v__ast__AsmStmt, ((v__ast__AsmStmt){.arch = 0,.is_basic = 0,.is_volatile = 0,.is_goto = 0,.clobbered = __new_array(0, 0, sizeof(v__ast__AsmClobbered)),.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.templates = __new_array(0, 0, sizeof(v__ast__AsmTemplate)),.scope = ((void*)0),.output = __new_array(0, 0, sizeof(v__ast__AsmIO)),.input = __new_array(0, 0, sizeof(v__ast__AsmIO)),.global_labels = __new_array(0, 0, sizeof(string)),.local_labels = __new_array(0, 0, sizeof(string)),})),._typ=390}; } VV_LOC v__ast__DebuggerStmt v__parser__Parser_dbg_stmt(v__parser__Parser* p) { v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__dollar); v__parser__Parser_check(p, v__token__Kind__name); v__parser__Parser_register_auto_import(p, _S("v.debug")); return ((v__ast__DebuggerStmt){.pos = pos,}); } VV_LOC v__ast__SemicolonStmt v__parser__Parser_semicolon_stmt(v__parser__Parser* p) { v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__semicolon); return ((v__ast__SemicolonStmt){.pos = pos,}); } VV_LOC Array_v__ast__Expr v__parser__Parser_expr_list(v__parser__Parser* p, bool expect_value) { Array_v__ast__Expr exprs = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); for (;;) { v__ast__Expr expr = (expect_value ? (v__parser__Parser_expr(p, 0)) : (v__parser__Parser_expr_no_value(p, 0))); if ((expr)._typ != 348 /* v.ast.Comment */) { array_push((array*)&exprs, _MOV((v__ast__Expr[]){ expr })); if (p->tok.kind != v__token__Kind__comma) { break; } v__parser__Parser_next(p); } } return exprs; } VV_LOC v__ast__Stmt v__parser__Parser_parse_multi_expr(v__parser__Parser* p, bool is_top_level) { v__token__Token tok = p->tok; v__token__Pos pos = v__token__Token_pos(&tok); Array_v__ast__Ident defer_vars = array_clone_to_depth(&p->defer_vars, 0); p->defer_vars = __new_array_with_default(0, 0, sizeof(v__ast__Ident), 0); Array_v__ast__Expr left = v__parser__Parser_expr_list(p, p->inside_assign_rhs); if (!(p->inside_defer && p->tok.kind == v__token__Kind__decl_assign)) { _PUSH_MANY(&defer_vars, (p->defer_vars), _t1, Array_v__ast__Ident); } p->defer_vars = defer_vars; v__ast__Expr left0 = ((v__ast__Expr*)left.data)[0]; if ((tok.kind == v__token__Kind__key_mut || tok.kind == v__token__Kind__key_shared || tok.kind == v__token__Kind__key_atomic) && v__ast__Expr_is_blank_ident(left0)) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use `"), 0xfe10, {.d_s = v__token__Kind_str(tok.kind)}}, {_S("` on `_`"), 0, { .d_c = 0 }}})), v__token__Token_pos(&tok))))); } if (tok.kind == v__token__Kind__key_mut && p->tok.kind != v__token__Kind__decl_assign) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, _S("expecting `:=` (e.g. `mut x :=`)"))))); } if (v__token__Kind_is_assign(p->tok.kind)) { return v__parser__Parser_partial_assign_stmt(p, left); } else if (!p->pref->translated && !p->is_translated && !p->pref->is_fmt && !p->pref->is_vet && !(tok.kind == v__token__Kind__key_if || tok.kind == v__token__Kind__key_match || tok.kind == v__token__Kind__key_lock || tok.kind == v__token__Kind__key_rlock || tok.kind == v__token__Kind__key_select)) { for (int _t5 = 0; _t5 < left.len; ++_t5) { v__ast__Expr node = ((v__ast__Expr*)left.data)[_t5]; if ((is_top_level || !(p->tok.kind == v__token__Kind__comment || p->tok.kind == v__token__Kind__rcbr)) && !((node)._typ == 344 /* v.ast.CallExpr */ || (node)._typ == 375 /* v.ast.PostfixExpr */ || (node)._typ == 349 /* v.ast.ComptimeCall */ || (node)._typ == 379 /* v.ast.SelectorExpr */ || (node)._typ == 353 /* v.ast.DumpExpr */)) { bool is_complex_infix_expr = (node)._typ == 362 /* v.ast.InfixExpr */ && ((*(v__ast__InfixExpr*)__as_cast((node)._v__ast__InfixExpr,(node)._typ, 362)).op == v__token__Kind__left_shift || (*(v__ast__InfixExpr*)__as_cast((node)._v__ast__InfixExpr,(node)._typ, 362)).op == v__token__Kind__right_shift || (*(v__ast__InfixExpr*)__as_cast((node)._v__ast__InfixExpr,(node)._typ, 362)).op == v__token__Kind__unsigned_right_shift || (*(v__ast__InfixExpr*)__as_cast((node)._v__ast__InfixExpr,(node)._typ, 362)).op == v__token__Kind__arrow); if (!is_complex_infix_expr && !p->is_vls) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("expression evaluated but not used"), v__ast__Expr_pos(node))))); } } } } v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); if (left.len == 1) { return v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (((v__ast__ExprStmt){.pos = v__ast__Expr_pos(left0),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = left0,.is_expr = p->inside_for,.typ = 0,})))); } return v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (((v__ast__ExprStmt){.pos = pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = v__ast__ConcatExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__ConcatExpr, (((v__ast__ConcatExpr){.vals = left,.pos = v__token__Token_pos(&tok),.return_type = 0,})))),.is_expr = 0,.typ = 0,})))); } VV_LOC v__ast__Ident v__parser__Parser_ident(v__parser__Parser* p, v__ast__Language language) { bool is_option = p->tok.kind == v__token__Kind__question && p->peek_tok.kind == v__token__Kind__lsbr; if (is_option) { v__parser__Parser_next(p); } bool is_shared = p->tok.kind == v__token__Kind__key_shared; bool is_atomic = p->tok.kind == v__token__Kind__key_atomic; if (is_shared) { v__parser__Parser_register_auto_import(p, _S("sync")); } v__token__Pos mut_pos = v__token__Token_pos(&p->tok); v__token__Kind modifier_kind = p->tok.kind; bool is_mut = p->tok.kind == v__token__Kind__key_mut || is_shared || is_atomic; if (is_mut) { v__parser__Parser_next(p); } bool is_static = p->tok.kind == v__token__Kind__key_static; if (is_static) { v__parser__Parser_next(p); } bool is_volatile = p->tok.kind == v__token__Kind__key_volatile; if (is_volatile) { v__parser__Parser_next(p); } if (!(p->tok.kind == v__token__Kind__name || p->tok.kind == v__token__Kind__key_type)) { if (is_mut || is_static || is_volatile) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("the `"), 0xfe10, {.d_s = v__token__Kind_str(modifier_kind)}}, {_S("` keyword is invalid here"), 0, { .d_c = 0 }}})), mut_pos); } else { v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = str_intp(2, _MOV((StrIntpData[]){{_S("token `"), 0xfe10, {.d_s = p->tok.lit}}, {_S("`"), 0, { .d_c = 0 }}})),.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); } return ((v__ast__Ident){.language = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comptime = 0,.scope = p->scope,.obj = _const_v__ast__empty_scope_object,.mod = (string){.str=(byteptr)"", .is_lit=1},.name = (string){.str=(byteptr)"", .is_lit=1},.full_name = (string){.str=(byteptr)"", .is_lit=1},.cached_name = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.info = (v__ast__IdentInfo){._v__ast__IdentFn=HEAP(v__ast__IdentFn, ((v__ast__IdentFn){.typ = 0,})),._typ=476},.is_mut = 0,.or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.ct_expr = 0,}); } bool in_select = p->prev_tok.kind == v__token__Kind__arrow; v__token__Pos pos = v__token__Token_pos(&p->tok); string name = v__parser__Parser_check_name(p); if (_SLIT_EQ(name.str, name.len, "_")) { return ((v__ast__Ident){ .language = 0, .tok_kind = p->tok.kind, .pos = pos, .mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .comptime = p->comptime_if_cond, .scope = p->scope, .obj = _const_v__ast__empty_scope_object, .mod = (string){.str=(byteptr)"", .is_lit=1}, .name = _S("_"), .full_name = (string){.str=(byteptr)"", .is_lit=1}, .cached_name = (string){.str=(byteptr)"", .is_lit=1}, .kind = v__ast__IdentKind__blank_ident, .info = v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentVar, (((v__ast__IdentVar){.typ = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_option = is_option,.share = 0,})))), .is_mut = 0, .or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .ct_expr = 0, }); } bool is_following_concrete_types = v__parser__Parser_is_following_concrete_types(p); Array_v__ast__Type concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); if (p->expr_mod.len > 0) { name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = p->expr_mod}}, {_S("."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); } bool allowed_cases = !in_select && !p->inside_comptime_if && !p->inside_ct_if_expr; v__ast__OrKind or_kind = v__ast__OrKind__absent; Array_v__ast__Stmt or_stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); v__token__Pos or_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (allowed_cases && p->tok.kind == v__token__Kind__question && p->peek_tok.kind != v__token__Kind__lpar) { or_kind = v__ast__OrKind__propagate_option; v__parser__Parser_check(p, v__token__Kind__question); } else if (allowed_cases && p->tok.kind == v__token__Kind__key_orelse) { or_kind = v__ast__OrKind__block; multi_return_Array_v__ast__Stmt_v__token__Pos mr_33489 = v__parser__Parser_or_block(p, v__parser__OrBlockErrVarMode__no_err_var); or_stmts = mr_33489.arg0; or_pos = mr_33489.arg1; } else if (is_following_concrete_types) { concrete_types = v__parser__Parser_parse_concrete_types(p); } int_literal _t3 = 0; if (p->peek_tok.kind == (v__token__Kind__string)) { _t3 = _const_v__ast__string_type_idx; } else if (p->peek_tok.kind == (v__token__Kind__lsbr)) { _t3 = _const_v__ast__array_type_idx; } else { v__ast__Type _t4; /* if prepend */ if (p->tok.kind == v__token__Kind__dot) { v__ast__Type _t5; /* if prepend */ _option_v__ast__Var_ptr _t6; if (_t6 = v__ast__Scope_find_var(p->scope, name), _t6.state == 0) { v__ast__Var* var = *(v__ast__Var**)_t6.data; _t5 = var->typ; } else { IError err = _t6.err; _t5 = 0; } _t4 = _t5; } else { _t4 = 0; } _t3 = _t4; }int typ = _t3; return ((v__ast__Ident){ .language = language, .tok_kind = p->tok.kind, .pos = pos, .mut_pos = mut_pos, .comptime = p->comptime_if_cond, .scope = p->scope, .obj = _const_v__ast__empty_scope_object, .mod = p->mod, .name = name, .full_name = (string){.str=(byteptr)"", .is_lit=1}, .cached_name = (string){.str=(byteptr)"", .is_lit=1}, .kind = v__ast__IdentKind__unresolved, .info = v__ast__IdentVar_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentVar, (((v__ast__IdentVar){ .typ = typ, .is_mut = is_mut, .is_static = is_static, .is_volatile = is_volatile, .is_option = or_kind != v__ast__OrKind__absent, .share = v__ast__sharetype_from_flags(is_shared, is_atomic), })))), .is_mut = is_mut, .or_expr = ((v__ast__OrExpr){.kind = or_kind,.pos = or_pos,.stmts = or_stmts,}), .concrete_types = concrete_types, .ct_expr = 0, }); } VV_LOC v__ast__Type v__parser__Parser_alias_array_type(v__parser__Parser* p) { string full_name = v__parser__Parser_prepend_mod(p, p->tok.lit); int* _t2 = (int*)(map_get_check(ADDR(map, p->table->type_idxs), &(string[]){full_name})); _option_int _t1 = {0}; if (_t2) { *((int*)&_t1.data) = *((int*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { int idx = (*(int*)_t1.data); if (idx == 0) { return _const_v__ast__void_type; } v__ast__TypeSymbol* sym = v__ast__Table_sym(p->table, v__ast__idx_to_type(idx)); if ((sym->info)._typ == 539 /* v.ast.Alias */) { if ((*sym->info._v__ast__Alias).parent_type == 0) { return _const_v__ast__void_type; } if (v__ast__Table_sym(p->table, (*sym->info._v__ast__Alias).parent_type)->kind == v__ast__Kind__array) { return idx; } } } return _const_v__ast__void_type; } VV_LOC v__ast__Expr v__parser__Parser_name_expr(v__parser__Parser* p) { v__token__Kind prev_tok_kind = p->prev_tok.kind; v__ast__Expr node = _const_v__ast__empty_expr; if (p->expecting_type) { if (p->tok.kind == v__token__Kind__dollar) { node = v__ast__ComptimeType_to_sumtype_v__ast__Expr(ADDR(v__ast__ComptimeType, (v__parser__Parser_parse_comptime_type(p)))); p->expecting_type = false; return node; } p->expecting_type = false; bool is_known_var = v__ast__Scope_known_var(p->scope, p->tok.lit); if (is_known_var) { v__ast__Scope_mark_var_as_used(p->scope, p->tok.lit); return v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (v__parser__Parser_ident(p, v__ast__Language__v)))); } else { v__token__Pos type_pos = v__token__Token_pos(&p->tok); v__ast__Type typ = v__parser__Parser_parse_type(p); return v__ast__TypeNode_to_sumtype_v__ast__Expr(ADDR(v__ast__TypeNode, (((v__ast__TypeNode){.pos = type_pos,.typ = typ,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),})))); } } v__ast__Language language = ((_SLIT_EQ(p->tok.lit.str, p->tok.lit.len, "C"))? (v__ast__Language__c) : (_SLIT_EQ(p->tok.lit.str, p->tok.lit.len, "JS"))? (v__ast__Language__js) : (_SLIT_EQ(p->tok.lit.str, p->tok.lit.len, "WASM"))? (v__ast__Language__wasm) : (v__ast__Language__v)); if (language != v__ast__Language__v) { v__parser__Parser_check_for_impure_v(p, language, v__token__Token_pos(&p->tok)); } bool is_option = p->tok.kind == v__token__Kind__question; if (is_option) { if (p->peek_tok.kind == v__token__Kind__name || p->peek_tok.kind == v__token__Kind__lsbr) { v__parser__Parser_check(p, v__token__Kind__question); } } bool is_array = p->tok.kind == v__token__Kind__lsbr; bool is_fixed_array = is_array && p->peek_tok.kind == v__token__Kind__number; string mod = _S(""); p->expr_mod = _S(""); if (p->peek_tok.kind == v__token__Kind__lsbr && fast_string_eq(p->tok.lit, _S("map"))) { v__token__Pos pos = v__token__Token_pos(&p->tok); v__ast__Type map_type = v__parser__Parser_parse_map_type(p); if (p->tok.kind == v__token__Kind__lcbr) { v__parser__Parser_next(p); if (p->tok.kind == v__token__Kind__rcbr) { pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->tok)); v__parser__Parser_next(p); } else { if (p->pref->is_fmt) { v__ast__MapInit map_init = v__parser__Parser_map_init(p); v__parser__Parser_check(p, v__token__Kind__rcbr); return v__ast__MapInit_to_sumtype_v__ast__Expr(&map_init); } v__parser__Parser_error(p, _S("`}` expected; explicit `map` initialization does not support parameters")); } } if (is_option) { map_type = v__ast__Type_set_flag(map_type, v__ast__TypeFlag__option); } node = v__ast__MapInit_to_sumtype_v__ast__Expr(ADDR(v__ast__MapInit, (((v__ast__MapInit){.pos = pos,.comments = __new_array(0, 0, sizeof(Array_v__ast__Comment)),.pre_cmnts = __new_array(0, 0, sizeof(v__ast__Comment)),.keys = __new_array(0, 0, sizeof(v__ast__Expr)),.vals = __new_array(0, 0, sizeof(v__ast__Expr)),.val_types = __new_array(0, 0, sizeof(v__ast__Type)),.typ = map_type,.key_type = 0,.value_type = 0,.has_update_expr = 0,.update_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_expr_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.update_expr_comments = __new_array(0, 0, sizeof(v__ast__Comment)),})))); if (p->tok.kind == v__token__Kind__lpar) { v__parser__Parser_check(p, v__token__Kind__lpar); v__ast__Expr expr = v__parser__Parser_expr(p, 0); v__parser__Parser_check(p, v__token__Kind__rpar); return v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = map_type,.expr = expr,.typname = v__ast__Table_sym(p->table, map_type)->name,.expr_type = 0,.has_arg = 0,.pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->tok)),})))); } return node; } if (fast_string_eq(p->tok.lit, _S("chan"))) { v__token__Pos first_pos = v__token__Token_pos(&p->tok); v__token__Pos last_pos = first_pos; v__token__Pos elem_type_pos = v__token__Token_pos(&p->peek_tok); if (p->peek_tok.kind == v__token__Kind__not) { return v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("cannot use chan with Result type"), v__token__Token_pos(&p->peek_tok))))); } v__ast__Type chan_type = v__parser__Parser_parse_chan_type(p); elem_type_pos = v__token__Pos_extend(elem_type_pos, v__token__Token_pos(&p->prev_tok)); bool has_cap = false; v__ast__Expr cap_expr = _const_v__ast__empty_expr; v__parser__Parser_check(p, v__token__Kind__lcbr); if (p->tok.kind == v__token__Kind__rcbr) { last_pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); } else { string key = v__parser__Parser_check_name(p); v__parser__Parser_check(p, v__token__Kind__colon); if (_SLIT_EQ(key.str, key.len, "cap")) { has_cap = true; cap_expr = v__parser__Parser_expr(p, 0); } else if (_SLIT_EQ(key.str, key.len, "len") || _SLIT_EQ(key.str, key.len, "init")) { return v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = key}}, {_S("` cannot be initialized for `chan`. Did you mean `cap`?"), 0, { .d_c = 0 }}})))))); } else { return v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("wrong field `"), 0xfe10, {.d_s = key}}, {_S("`, expecting `cap`"), 0, { .d_c = 0 }}})))))); } last_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__rcbr); } if (chan_type == _const_v__ast__chan_type) { v__parser__Parser_error_with_pos(p, _S("`chan` has no type specified. Use `chan Type{}` instead of `chan{}`"), v__token__Pos_extend(first_pos, last_pos)); } return v__ast__ChanInit_to_sumtype_v__ast__Expr(ADDR(v__ast__ChanInit, (((v__ast__ChanInit){.pos = v__token__Pos_extend(first_pos, last_pos),.elem_type_pos = elem_type_pos,.has_cap = has_cap,.cap_expr = cap_expr,.typ = chan_type,.elem_type = 0,})))); } if (p->peek_tok.kind == v__token__Kind__string && p->tok.line_nr == p->peek_tok.line_nr && !p->inside_str_interp && v__parser__Parser_peek_token(p, 2).kind != v__token__Kind__colon) { if (p->tok.kind == v__token__Kind__name && (fast_string_eq(p->tok.lit, _S("r")) || fast_string_eq(p->tok.lit, _S("c")) || fast_string_eq(p->tok.lit, _S("js")))) { return v__parser__Parser_string_expr(p); } else { return v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("only `c`, `r`, `js` are recognized string prefixes, but you tried to use `"), 0xfe10, {.d_s = p->tok.lit}}, {_S("`"), 0, { .d_c = 0 }}})))))); } } if (p->peek_tok.kind == v__token__Kind__chartoken && p->tok.lit.len == 1 && (p->tok.lit.str[ 0] == 'r' || p->tok.lit.str[ 0] == 'c')) { string opt = (fast_string_eq(p->tok.lit, _S("r")) ? (_S("`r` (raw string)")) : (_S("`c` (c string)"))); return v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot use "), 0xfe10, {.d_s = opt}}, {_S(" with `byte` and `rune`"), 0, { .d_c = 0 }}})))))); } bool known_var = (v__token__Kind_is_assign(p->peek_tok.kind) ? (v__ast__Scope_known_var(p->scope, p->tok.lit)) : (v__ast__Scope_mark_var_as_used(p->scope, p->tok.lit))); bool is_mod_cast = false; if (p->peek_tok.kind == v__token__Kind__dot && !known_var && (language != v__ast__Language__v || v__parser__Parser_known_import(p, p->tok.lit) || string__eq(string_all_after_last(p->mod, _S(".")), p->tok.lit))) { if (language == v__ast__Language__c || language == v__ast__Language__js || language == v__ast__Language__wasm) { mod = string_to_upper_ascii(v__ast__Language_str(language)); } else { if (_IN_MAP(ADDR(string, p->tok.lit), ADDR(map, p->imports))) { v__parser__Parser_register_used_import(p, p->tok.lit); v__token__Token tk2 = v__parser__Parser_peek_token(p, 2); if (p->peek_tok.kind == v__token__Kind__dot && tk2.kind != v__token__Kind__eof && tk2.lit.len > 0 && u8_is_capital(tk2.lit.str[ 0])) { is_mod_cast = true; } else if (p->peek_tok.kind == v__token__Kind__dot && tk2.kind != v__token__Kind__eof && tk2.lit.len == 0) { v__ast__Ident ident = v__parser__Parser_ident(p, language); node = v__ast__Ident_to_sumtype_v__ast__Expr(&ident); v__parser__Parser_add_defer_var(p, ident); return node; } } mod = (*(string*)map_get(ADDR(map, p->imports), &(string[]){p->tok.lit}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })); } v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__dot); p->expr_mod = mod; } bool lit0_is_capital = (p->tok.kind != v__token__Kind__eof && p->tok.lit.len > 0 ? (u8_is_capital(p->tok.lit.str[ 0])) : (false)); bool is_generic_call = v__parser__Parser_is_generic_call(p); bool is_generic_cast = v__parser__Parser_is_generic_cast(p); bool is_generic_struct_init = v__parser__Parser_is_generic_struct_init(p); if (p->peek_tok.kind == v__token__Kind__lpar && p->tok.line_nr != p->peek_tok.line_nr && v__token__Token_is_next_to(v__parser__Parser_peek_token(p, 2), p->peek_tok)) { v__ast__Ident ident = v__parser__Parser_ident(p, language); node = v__ast__Ident_to_sumtype_v__ast__Expr(&ident); v__parser__Parser_add_defer_var(p, ident); } else if (p->peek_tok.kind == v__token__Kind__lpar || is_generic_call || is_generic_cast || (p->tok.kind == v__token__Kind__lsbr && p->peek_tok.kind == v__token__Kind__rsbr && (v__parser__Parser_peek_token(p, 3).kind == v__token__Kind__lpar || v__parser__Parser_peek_token(p, 5).kind == v__token__Kind__lpar)) || (p->tok.kind == v__token__Kind__lsbr && p->peek_tok.kind == v__token__Kind__number && v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__rsbr && (v__parser__Parser_peek_token(p, 4).kind == v__token__Kind__lpar || v__parser__Parser_peek_token(p, 6).kind == v__token__Kind__lpar))) { string original_name = (is_array ? (v__parser__Parser_peek_token(p, (is_fixed_array ? (3) : (2))).lit) : (p->tok.lit)); if (is_fixed_array && v__parser__Parser_peek_token(p, 4).kind == v__token__Kind__dot) { mod = original_name; original_name = v__parser__Parser_peek_token(p, 5).lit; } else if (is_array && v__parser__Parser_peek_token(p, 3).kind == v__token__Kind__dot) { mod = original_name; original_name = v__parser__Parser_peek_token(p, 4).lit; } string name = ((mod).len != 0 ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mod}}, {_S("."), 0xfe10, {.d_s = original_name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (original_name)); string name_w_mod = v__parser__Parser_prepend_mod(p, name); bool is_c_pointer_cast = language == v__ast__Language__c && prev_tok_kind == v__token__Kind__amp; bool is_c_type_cast = language == v__ast__Language__c && ((_SLIT_EQ(original_name.str, original_name.len, "intptr_t") || _SLIT_EQ(original_name.str, original_name.len, "uintptr_t")) || (_IN_MAP(ADDR(string, name), ADDR(map, p->table->type_idxs)) && u8_is_capital(original_name.str[ 0]))); bool is_js_cast = language == v__ast__Language__js && u8_is_capital(string_all_after_last(name, _S(".")).str[ 0]); if ((is_option || (p->peek_tok.kind == v__token__Kind__lsbr || p->peek_tok.kind == v__token__Kind__lt || p->peek_tok.kind == v__token__Kind__lpar)) && (is_mod_cast || is_c_pointer_cast || is_c_type_cast || is_js_cast || is_generic_cast || (language == v__ast__Language__v && (name).len != 0 && (u8_is_capital(name.str[ 0]) || (!known_var && (_IN_MAP(ADDR(string, name), ADDR(map, p->table->type_idxs)) || _IN_MAP(ADDR(string, name_w_mod), ADDR(map, p->table->type_idxs)))) || u8_is_capital(string_all_after_last(name, _S(".")).str[ 0]))))) { v__token__Pos start_pos = v__token__Token_pos(&p->tok); v__ast__Type to_typ = v__parser__Parser_parse_type(p); p->is_amp = false; v__parser__Parser_check(p, v__token__Kind__lpar); v__ast__Expr expr = _const_v__ast__empty_expr; v__ast__Expr arg = _const_v__ast__empty_expr; bool has_arg = false; expr = v__parser__Parser_expr(p, 0); if (p->tok.kind == v__token__Kind__comma && v__ast__Type_idx(to_typ) == 21) { v__parser__Parser_next(p); arg = v__parser__Parser_expr(p, 0); has_arg = true; } if (p->tok.kind == v__token__Kind__comma && p->peek_tok.kind == v__token__Kind__rpar) { v__parser__Parser_next(p); } v__token__Pos end_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__rpar); if (is_option) { to_typ = v__ast__Type_set_flag(to_typ, v__ast__TypeFlag__option); } node = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){ .arg = arg, .typ = to_typ, .expr = expr, .typname = (to_typ != 0 ? (v__ast__Table_sym(p->table, to_typ)->name) : (_S("unknown typename"))), .expr_type = 0, .has_arg = has_arg, .pos = v__token__Pos_extend(start_pos, end_pos), })))); p->expr_mod = _S(""); return node; } else { if (is_option) { v__parser__Parser_unexpected_with_pos(p, v__token__Token_pos(&p->prev_tok), ((v__parser__ParamsForUnexpected){.got = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__token__Token_str(p->prev_tok)}}, {_SLIT0, 0, { .d_c = 0 }}})),.expecting = (string){.str=(byteptr)"", .is_lit=1},.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); } if (p->peek_tok.kind == v__token__Kind__dot && (v__parser__Parser_peek_token(p, 3).kind == v__token__Kind__comma || v__parser__Parser_peek_token(p, 3).kind == v__token__Kind__rpar)) { node = v__ast__EnumVal_to_sumtype_v__ast__Expr(ADDR(v__ast__EnumVal, (v__parser__Parser_enum_val_expr(p, mod)))); } else { node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (v__parser__Parser_call_expr(p, language, mod)))); if (p->tok.kind == v__token__Kind__lpar && p->prev_tok.line_nr == p->tok.line_nr) { v__parser__Parser_next(p); v__token__Pos pos = v__token__Token_pos(&p->tok); Array_v__ast__CallArg args = v__parser__Parser_call_args(p); v__parser__Parser_check(p, v__token__Kind__rpar); v__ast__OrExpr or_block = v__parser__Parser_gen_or_block(p); node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (((v__ast__CallExpr){ .pos = pos, .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .mod = (string){.str=(byteptr)"", .is_lit=1}, .name = (string){.str=(byteptr)"", .is_lit=1}, .is_method = 0, .is_field = 0, .is_fn_var = 0, .is_fn_a_const = 0, .is_keep_alive = 0, .is_noreturn = 0, .is_ctor_new = 0, .is_file_translated = 0, .is_static_method = 0, .args = args, .expected_arg_types = __new_array(0, 0, sizeof(v__ast__Type)), .comptime_ret_val = 0, .language = 0, .or_block = or_block, .left = node, .left_type = 0, .receiver_type = 0, .receiver_concrete_type = 0, .return_type = 0, .return_type_generic = 0, .nr_ret_values = -1, .fn_var_type = 0, .const_name = (string){.str=(byteptr)"", .is_lit=1}, .should_be_skipped = 0, .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .concrete_list_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .raw_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .free_receiver = 0, .scope = p->scope, .from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)), .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .is_return_used = p->expecting_value, .is_expand_simple_interpolation = 0, .is_unwrapped_fn_selector = 0, })))); } } } } else if (!known_var && (p->peek_tok.kind == v__token__Kind__lcbr || is_generic_struct_init) && (!p->inside_match || (p->inside_select && prev_tok_kind == v__token__Kind__arrow && lit0_is_capital)) && !p->inside_match_case && (!p->inside_if || p->inside_select) && (!p->inside_for || p->inside_select)) { v__ast__Type alias_array_type = v__parser__Parser_alias_array_type(p); if (alias_array_type != _const_v__ast__void_type) { return v__ast__ArrayInit_to_sumtype_v__ast__Expr(ADDR(v__ast__ArrayInit, (v__parser__Parser_array_init(p, is_option, alias_array_type)))); } else { return v__ast__StructInit_to_sumtype_v__ast__Expr(ADDR(v__ast__StructInit, (v__parser__Parser_struct_init(p, string__plus(string__plus(p->mod, _S(".")), p->tok.lit), v__ast__StructInitKind__normal, is_option)))); } } else if (p->peek_tok.kind == v__token__Kind__lcbr && ((p->inside_if && lit0_is_capital && p->tok.lit.len > 1 && !known_var && language == v__ast__Language__v) || (p->inside_match_case && lit0_is_capital && p->tok.kind == v__token__Kind__name && v__token__Token_is_next_to(p->peek_tok, p->tok)))) { return v__ast__StructInit_to_sumtype_v__ast__Expr(ADDR(v__ast__StructInit, (v__parser__Parser_struct_init(p, string__plus(string__plus(p->mod, _S(".")), p->tok.lit), v__ast__StructInitKind__normal, is_option)))); } else if (p->peek_tok.kind == v__token__Kind__dot && lit0_is_capital && !known_var && language == v__ast__Language__v) { if (v__parser__Parser_is_generic_name(p) && v__parser__Parser_peek_token(p, 3).kind != v__token__Kind__lpar) { v__token__Pos pos = v__token__Token_pos(&p->tok); string name = v__parser__Parser_check_name(p); v__parser__Parser_check(p, v__token__Kind__dot); string field = v__parser__Parser_check_name(p); v__ast__GenericKindField fkind = ((_SLIT_EQ(field.str, field.len, "name"))? (v__ast__GenericKindField__name) : (_SLIT_EQ(field.str, field.len, "typ"))? (v__ast__GenericKindField__typ) : (_SLIT_EQ(field.str, field.len, "unaliased_typ"))? (v__ast__GenericKindField__unaliased_typ) : (_SLIT_EQ(field.str, field.len, "indirections"))? (v__ast__GenericKindField__indirections) : (v__ast__GenericKindField__unknown)); v__token__Pos_extend(pos, v__token__Token_pos(&p->tok)); return v__ast__SelectorExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__SelectorExpr, (((v__ast__SelectorExpr){.pos = pos,.field_name = field,.is_mut = 0,.mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.next_token = 0,.expr = v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (((v__ast__Ident){.language = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comptime = 0,.scope = p->scope,.obj = _const_v__ast__empty_scope_object,.mod = (string){.str=(byteptr)"", .is_lit=1},.name = name,.full_name = (string){.str=(byteptr)"", .is_lit=1},.cached_name = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.info = (v__ast__IdentInfo){._v__ast__IdentFn=HEAP(v__ast__IdentFn, ((v__ast__IdentFn){.typ = 0,})),._typ=476},.is_mut = 0,.or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.ct_expr = 0,})))),.expr_type = 0,.typ = 0,.name_type = 0,.or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.gkind_field = fkind,.scope = p->scope,.from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)),.generic_from_embed_types = __new_array(0, 0, sizeof(Array_v__ast__Type)),.has_hidden_receiver = 0,.is_field_typ = 0,})))); } if (!known_var && v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__name && v__parser__Parser_peek_token(p, 3).kind == v__token__Kind__lpar) { if (lit0_is_capital && p->peek_tok.kind == v__token__Kind__dot && language == v__ast__Language__v) { p->expr_mod = _S(""); return v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (v__parser__Parser_call_expr(p, language, mod)))); } else { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = lit0_is_capital ? _S("true") : _S("false")}}, {_S(" the receiver of the method call must be an instantiated object, e.g. `foo.bar()`"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->tok)); } } if (!known_var && lit0_is_capital && p->peek_tok.kind == v__token__Kind__dot && language == v__ast__Language__v && v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__name) { _option_v__ast__Fn _t21; if (_t21 = v__ast__Table_find_fn(p->table, string__plus(string__plus(v__parser__Parser_prepend_mod(p, p->tok.lit), _S("__static__")), v__parser__Parser_peek_token(p, 2).lit)), _t21.state == 0) { v__ast__Fn func = *(v__ast__Fn*)_t21.data; v__ast__Type fn_type = v__ast__new_type(v__ast__Table_find_or_register_fn_type(p->table, func, false, true)); v__token__Pos pos = v__token__Token_pos(&p->tok); string typ_name = v__parser__Parser_check_name(p); v__parser__Parser_check(p, v__token__Kind__dot); string field_name = v__parser__Parser_check_name(p); v__token__Pos_extend(pos, v__token__Token_pos(&p->tok)); return v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (((v__ast__Ident){ .language = 0, .tok_kind = 0, .pos = pos, .mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .comptime = 0, .scope = p->scope, .obj = _const_v__ast__empty_scope_object, .mod = p->mod, .name = string__plus(string__plus(v__parser__Parser_prepend_mod(p, typ_name), _S("__static__")), field_name), .full_name = (string){.str=(byteptr)"", .is_lit=1}, .cached_name = (string){.str=(byteptr)"", .is_lit=1}, .kind = v__ast__IdentKind__function, .info = v__ast__IdentFn_to_sumtype_v__ast__IdentInfo(ADDR(v__ast__IdentFn, (((v__ast__IdentFn){.typ = fn_type,})))), .is_mut = 0, .or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .ct_expr = 0, })))); } } return v__ast__EnumVal_to_sumtype_v__ast__Expr(ADDR(v__ast__EnumVal, (v__parser__Parser_enum_val_expr(p, mod)))); } else if (language == v__ast__Language__js && p->peek_tok.kind == v__token__Kind__dot && v__parser__Parser_peek_token(p, 2).kind == v__token__Kind__name) { node = v__ast__CallExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CallExpr, (v__parser__Parser_call_expr(p, language, mod)))); } else { if (p->inside_in_array && ((lit0_is_capital && !known_var && language == v__ast__Language__v) || (p->peek_tok.kind == v__token__Kind__dot && v__parser__Parser_peek_token(p, 2).lit.len > 0 && u8_is_capital(v__parser__Parser_peek_token(p, 2).lit.str[ 0])) || v__ast__Table_find_type_idx(p->table, string__plus(string__plus(p->mod, _S(".")), p->tok.lit)) > 0 || p->inside_comptime_if)) { v__token__Pos type_pos = v__token__Token_pos(&p->tok); v__ast__Type typ = v__parser__Parser_parse_type(p); if (is_option) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__option); } return v__ast__TypeNode_to_sumtype_v__ast__Expr(ADDR(v__ast__TypeNode, (((v__ast__TypeNode){.pos = type_pos,.typ = typ,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),})))); } else if (!known_var && language == v__ast__Language__v && (lit0_is_capital || v__ast__Table_known_type(p->table, p->tok.lit)) && p->peek_tok.kind == v__token__Kind__pipe) { v__token__Pos start_pos = v__token__Token_pos(&p->tok); v__ast__Type to_typ = v__parser__Parser_parse_type(p); v__parser__Parser_check(p, v__token__Kind__lpar); v__ast__Expr expr = v__parser__Parser_expr(p, 0); v__token__Pos end_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__rpar); node = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){ .arg = _const_v__ast__empty_expr, .typ = to_typ, .expr = expr, .typname = (to_typ != 0 ? (v__ast__Table_sym(p->table, to_typ)->name) : (_S("unknown type name"))), .expr_type = 0, .has_arg = false, .pos = v__token__Pos_extend(start_pos, end_pos), })))); p->expr_mod = _S(""); return node; } else if (is_option && p->tok.kind == v__token__Kind__lsbr) { return v__ast__ArrayInit_to_sumtype_v__ast__Expr(ADDR(v__ast__ArrayInit, (v__parser__Parser_array_init(p, is_option, _const_v__ast__void_type)))); } else if (!known_var && language == v__ast__Language__v && p->peek_tok.kind == v__token__Kind__dot && !p->pref->is_fmt) { v__token__Token peek_tok2 = v__parser__Parser_peek_token(p, 2); v__token__Token peek_tok3 = v__parser__Parser_peek_token(p, 3); mod = p->tok.lit; int n = -1; for (;;) { if (!(v__parser__Parser_peek_token(p, n).kind == v__token__Kind__dot && v__parser__Parser_peek_token(p, (int)(n - 1)).kind == v__token__Kind__name)) break; mod = string__plus(string__plus(v__parser__Parser_peek_token(p, (int)(n - 1)).lit, _S(".")), mod); n -= 2; } if (peek_tok2.kind == v__token__Kind__name && peek_tok2.lit.len > 0 && u8_is_capital(peek_tok2.lit.str[ 0]) && peek_tok3.kind == v__token__Kind__lcbr && (mod.len > p->tok.lit.len || !v__parser__Parser_known_import(p, p->tok.lit))) { string msg = str_intp(2, _MOV((StrIntpData[]){{_S("unknown module `"), 0xfe10, {.d_s = mod}}, {_S("`"), 0, { .d_c = 0 }}})); if (mod.len > p->tok.lit.len && v__parser__Parser_known_import(p, p->tok.lit)) { msg = string__plus(msg, str_intp(2, _MOV((StrIntpData[]){{_S("; did you mean `"), 0xfe10, {.d_s = p->tok.lit}}, {_S("`?"), 0, { .d_c = 0 }}}))); } v__parser__Parser_error_with_pos(p, msg, v__token__Token_pos(&p->tok)); } } v__ast__Ident ident = v__parser__Parser_ident(p, language); node = v__ast__Ident_to_sumtype_v__ast__Expr(&ident); v__parser__Parser_add_defer_var(p, ident); } p->expr_mod = _S(""); return node; } VV_LOC multi_return_Array_v__ast__Stmt_v__token__Pos v__parser__Parser_or_block(v__parser__Parser* p, v__parser__OrBlockErrVarMode err_var_mode) { bool v__parser__Parser_or_block_defer_0 = false; bool was_inside_or_expr; bool v__parser__Parser_or_block_defer_1 = false; was_inside_or_expr = p->inside_or_expr; v__parser__Parser_or_block_defer_0 = true; p->inside_or_expr = true; v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); v__parser__Parser_open_scope(p); v__parser__Parser_or_block_defer_1 = true; if (err_var_mode == v__parser__OrBlockErrVarMode__with_err_var) { v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = _S("err"),.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = 0,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = _const_v__ast__error_type,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = v__token__Token_pos(&p->tok),.is_used = true,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = true,}))))); } Array_v__ast__Stmt stmts = v__parser__Parser_parse_block_no_scope(p, false); pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)); multi_return_Array_v__ast__Stmt_v__token__Pos _t1 = (multi_return_Array_v__ast__Stmt_v__token__Pos){.arg0=stmts, .arg1=pos}; // Defer begin if (v__parser__Parser_or_block_defer_1) { v__parser__Parser_close_scope(p); } // Defer end // Defer begin if (v__parser__Parser_or_block_defer_0) { p->inside_or_expr = was_inside_or_expr; } // Defer end return _t1; } VV_LOC v__ast__IndexExpr v__parser__Parser_index_expr(v__parser__Parser* p, v__ast__Expr left, bool is_gated) { v__token__Pos start_pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); bool has_low = true; if (p->tok.kind == v__token__Kind__dotdot) { has_low = false; v__parser__Parser_next(p); v__ast__Expr high = _const_v__ast__empty_expr; bool has_high = false; if (p->tok.kind != v__token__Kind__rsbr) { high = v__parser__Parser_expr(p, 0); has_high = true; } v__token__Pos pos_high = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->tok)); v__parser__Parser_check(p, v__token__Kind__rsbr); v__ast__OrKind or_kind_high = v__ast__OrKind__absent; Array_v__ast__Stmt or_stmts_high = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); v__token__Pos or_pos_high = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (!p->or_is_handled) { if (p->tok.kind == v__token__Kind__key_orelse) { multi_return_Array_v__ast__Stmt_v__token__Pos mr_50311 = v__parser__Parser_or_block(p, v__parser__OrBlockErrVarMode__no_err_var); or_stmts_high = mr_50311.arg0; or_pos_high = mr_50311.arg1; return ((v__ast__IndexExpr){.pos = pos_high,.index = v__ast__RangeExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__RangeExpr, (((v__ast__RangeExpr){.has_high = has_high,.has_low = 0,.pos = pos_high,.is_gated = is_gated,.low = _const_v__ast__empty_expr,.high = high,.typ = 0,})))),.or_expr = ((v__ast__OrExpr){.kind = v__ast__OrKind__block,.pos = or_pos_high,.stmts = or_stmts_high,}),.left = left,.left_type = 0,.is_setter = 0,.is_map = 0,.is_array = 0,.is_farray = 0,.is_option = 0,.is_direct = 0,.is_gated = is_gated,.typ = 0,}); } if (p->tok.kind == v__token__Kind__not) { or_pos_high = v__token__Token_pos(&p->tok); or_kind_high = v__ast__OrKind__propagate_result; v__parser__Parser_next(p); } else if (p->tok.kind == v__token__Kind__question) { v__parser__Parser_error_with_pos(p, _S("`?` for propagating errors from index expressions is no longer supported, use `!` instead of `?`"), v__token__Token_pos(&p->tok)); } } return ((v__ast__IndexExpr){.pos = pos_high,.index = v__ast__RangeExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__RangeExpr, (((v__ast__RangeExpr){.has_high = has_high,.has_low = 0,.pos = pos_high,.is_gated = is_gated,.low = _const_v__ast__empty_expr,.high = high,.typ = 0,})))),.or_expr = ((v__ast__OrExpr){.kind = or_kind_high,.pos = or_pos_high,.stmts = or_stmts_high,}),.left = left,.left_type = 0,.is_setter = 0,.is_map = 0,.is_array = 0,.is_farray = 0,.is_option = 0,.is_direct = 0,.is_gated = is_gated,.typ = 0,}); } v__ast__Expr expr = v__parser__Parser_expr(p, 0); bool has_high = false; if (p->tok.kind == v__token__Kind__dotdot) { v__parser__Parser_next(p); v__ast__Expr high = _const_v__ast__empty_expr; if (p->tok.kind != v__token__Kind__rsbr) { has_high = true; high = v__parser__Parser_expr(p, 0); } v__token__Pos pos_low = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->tok)); v__parser__Parser_check(p, v__token__Kind__rsbr); v__ast__OrKind or_kind_low = v__ast__OrKind__absent; Array_v__ast__Stmt or_stmts_low = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); v__token__Pos or_pos_low = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (!p->or_is_handled) { if (p->tok.kind == v__token__Kind__key_orelse) { multi_return_Array_v__ast__Stmt_v__token__Pos mr_51903 = v__parser__Parser_or_block(p, v__parser__OrBlockErrVarMode__no_err_var); or_stmts_low = mr_51903.arg0; or_pos_low = mr_51903.arg1; return ((v__ast__IndexExpr){.pos = pos_low,.index = v__ast__RangeExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__RangeExpr, (((v__ast__RangeExpr){ .has_high = has_high, .has_low = has_low, .pos = pos_low, .is_gated = is_gated, .low = expr, .high = high, .typ = 0, })))),.or_expr = ((v__ast__OrExpr){.kind = v__ast__OrKind__block,.pos = or_pos_low,.stmts = or_stmts_low,}),.left = left,.left_type = 0,.is_setter = 0,.is_map = 0,.is_array = 0,.is_farray = 0,.is_option = 0,.is_direct = 0,.is_gated = is_gated,.typ = 0,}); } if (p->tok.kind == v__token__Kind__not) { or_pos_low = v__token__Token_pos(&p->tok); or_kind_low = v__ast__OrKind__propagate_result; v__parser__Parser_next(p); } else if (p->tok.kind == v__token__Kind__question) { v__parser__Parser_error_with_pos(p, _S("`?` for propagating errors from index expressions is no longer supported, use `!` instead of `?`"), v__token__Token_pos(&p->tok)); } } return ((v__ast__IndexExpr){.pos = pos_low,.index = v__ast__RangeExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__RangeExpr, (((v__ast__RangeExpr){ .has_high = has_high, .has_low = has_low, .pos = pos_low, .is_gated = is_gated, .low = expr, .high = high, .typ = 0, })))),.or_expr = ((v__ast__OrExpr){.kind = or_kind_low,.pos = or_pos_low,.stmts = or_stmts_low,}),.left = left,.left_type = 0,.is_setter = 0,.is_map = 0,.is_array = 0,.is_farray = 0,.is_option = 0,.is_direct = 0,.is_gated = is_gated,.typ = 0,}); } v__token__Pos pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->tok)); v__parser__Parser_check(p, v__token__Kind__rsbr); v__ast__OrKind or_kind = v__ast__OrKind__absent; Array_v__ast__Stmt or_stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); v__token__Pos or_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (!p->or_is_handled) { if (p->tok.kind == v__token__Kind__key_orelse) { multi_return_Array_v__ast__Stmt_v__token__Pos mr_53235 = v__parser__Parser_or_block(p, v__parser__OrBlockErrVarMode__no_err_var); or_stmts = mr_53235.arg0; or_pos = mr_53235.arg1; return ((v__ast__IndexExpr){.pos = pos,.index = expr,.or_expr = ((v__ast__OrExpr){.kind = v__ast__OrKind__block,.pos = or_pos,.stmts = or_stmts,}),.left = left,.left_type = 0,.is_setter = 0,.is_map = 0,.is_array = 0,.is_farray = 0,.is_option = 0,.is_direct = 0,.is_gated = is_gated,.typ = 0,}); } if (p->tok.kind == v__token__Kind__not) { or_pos = v__token__Token_pos(&p->tok); or_kind = v__ast__OrKind__propagate_result; v__parser__Parser_next(p); } else if (p->tok.kind == v__token__Kind__question) { v__parser__Parser_error_with_pos(p, _S("`?` for propagating errors from index expressions is no longer supported, use `!` instead of `?`"), v__token__Token_pos(&p->tok)); } } return ((v__ast__IndexExpr){.pos = pos,.index = expr,.or_expr = ((v__ast__OrExpr){.kind = or_kind,.pos = or_pos,.stmts = or_stmts,}),.left = left,.left_type = 0,.is_setter = 0,.is_map = 0,.is_array = 0,.is_farray = 0,.is_option = 0,.is_direct = 0,.is_gated = is_gated,.typ = 0,}); } VV_LOC v__ast__Expr v__parser__Parser_dot_expr(v__parser__Parser* p, v__ast__Expr left) { bool v__parser__Parser_dot_expr_defer_0 = false; int prev_line = v__token__Token_pos(&p->prev_tok).line_nr; v__parser__Parser_next(p); if (p->tok.kind == v__token__Kind__dollar) { return v__parser__Parser_comptime_selector(p, left); } bool is_generic_call = v__parser__Parser_is_generic_call(p); v__token__Pos name_pos = v__token__Token_pos(&p->tok); if (!is_generic_call && p->tok.kind == v__token__Kind__name && p->inside_array_lit && (p->last_enum_name).len != 0 && prev_line != name_pos.line_nr) { p->name_error = true; return v__ast__EnumVal_to_sumtype_v__ast__Expr(ADDR(v__ast__EnumVal, (((v__ast__EnumVal){.enum_name = p->last_enum_name,.val = v__parser__Parser_check_name(p),.mod = p->last_enum_mod,.pos = v__token__Token_pos(&p->tok),.typ = 0,})))); } string field_name = _S(""); if (v__token__Token_pos(&p->prev_tok).line_nr == name_pos.line_nr || p->tok.kind != v__token__Kind__name) { if (p->is_vls) { if (p->tok.kind == v__token__Kind__rpar || p->tok.kind == v__token__Kind__rcbr) { return left; } else if (name_pos.line_nr != p->tok.line_nr) { return left; } } field_name = v__parser__Parser_check_name(p); } else { p->name_error = true; } bool is_filter = (_SLIT_EQ(field_name.str, field_name.len, "filter") || _SLIT_EQ(field_name.str, field_name.len, "map") || _SLIT_EQ(field_name.str, field_name.len, "any") || _SLIT_EQ(field_name.str, field_name.len, "all") || _SLIT_EQ(field_name.str, field_name.len, "count")); if (is_filter || _SLIT_EQ(field_name.str, field_name.len, "sort") || _SLIT_EQ(field_name.str, field_name.len, "sorted")) { if (p->file_backend_mode == v__ast__Language__v || p->file_backend_mode == v__ast__Language__c) { v__parser__Parser_register_auto_import(p, _S("builtin.closure")); } v__parser__Parser_open_scope(p); v__parser__Parser_dot_expr_defer_0 = true; } if (p->tok.kind == v__token__Kind__not && p->peek_tok.kind == v__token__Kind__lpar) { v__parser__Parser_next(p); } Array_v__ast__Type concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); v__token__Pos concrete_list_pos = v__token__Token_pos(&p->tok); if (is_generic_call) { concrete_types = v__parser__Parser_parse_concrete_types(p); concrete_list_pos = v__token__Pos_extend(concrete_list_pos, v__token__Token_pos(&p->prev_tok)); bool _t5 = false; Array_v__ast__Type _t5_orig = concrete_types; int _t5_len = _t5_orig.len; for (int _t6 = 0; _t6 < _t5_len; ++_t6) { v__ast__Type it = ((v__ast__Type*) _t5_orig.data)[_t6]; if (v__ast__Type_has_flag(it, v__ast__TypeFlag__generic)) { _t5 = true; break; } } bool has_generic =_t5; if (!has_generic) { v__ast__Table_register_fn_concrete_types(p->table, field_name, concrete_types); } } if (p->tok.kind == v__token__Kind__lpar) { v__parser__Parser_next(p); Array_v__ast__CallArg args = v__parser__Parser_call_args(p); v__parser__Parser_check(p, v__token__Kind__rpar); v__ast__OrExpr or_block = v__parser__Parser_gen_or_block(p); v__token__Pos end_pos = v__token__Token_pos(&p->prev_tok); v__token__Pos pos = v__token__Pos_extend(name_pos, end_pos); Array_v__ast__Comment comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})); v__ast__Expr left_node = left; if ((left_node)._typ == 344 /* v.ast.CallExpr */) { (*left_node._v__ast__CallExpr).is_return_used = true; } v__ast__CallExpr mcall_expr = ((v__ast__CallExpr){ .pos = pos, .name_pos = name_pos, .mod = (string){.str=(byteptr)"", .is_lit=1}, .name = field_name, .is_method = true, .is_field = 0, .is_fn_var = 0, .is_fn_a_const = 0, .is_keep_alive = 0, .is_noreturn = 0, .is_ctor_new = 0, .is_file_translated = 0, .is_static_method = 0, .args = args, .expected_arg_types = __new_array(0, 0, sizeof(v__ast__Type)), .comptime_ret_val = 0, .language = 0, .or_block = or_block, .left = left, .left_type = 0, .receiver_type = 0, .receiver_concrete_type = 0, .return_type = 0, .return_type_generic = 0, .nr_ret_values = -1, .fn_var_type = 0, .const_name = (string){.str=(byteptr)"", .is_lit=1}, .should_be_skipped = 0, .concrete_types = concrete_types, .concrete_list_pos = concrete_list_pos, .raw_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .free_receiver = 0, .scope = p->scope, .from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)), .comments = comments, .is_return_used = p->expecting_value, .is_expand_simple_interpolation = 0, .is_unwrapped_fn_selector = 0, }); v__ast__Expr _t7 = v__ast__CallExpr_to_sumtype_v__ast__Expr(&mcall_expr); // Defer begin if (v__parser__Parser_dot_expr_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t7; } bool is_mut = false; v__token__Pos mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (p->inside_match || p->inside_if_expr || p->inside_for) { if (left._typ == 358 /* v.ast.Ident */) { is_mut = (*left._v__ast__Ident).is_mut; mut_pos = (*left._v__ast__Ident).mut_pos; } else if (left._typ == 379 /* v.ast.SelectorExpr */) { is_mut = (*left._v__ast__SelectorExpr).is_mut; mut_pos = (*left._v__ast__SelectorExpr).mut_pos; } else { } } v__token__Pos pos = (p->name_error ? (v__token__Pos_extend(v__ast__Expr_pos(left), name_pos)) : (name_pos)); v__ast__OrKind or_kind = v__ast__OrKind__absent; Array_v__ast__Stmt or_stmts = __new_array_with_default(0, 0, sizeof(v__ast__Stmt), 0); v__token__Pos or_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (p->tok.kind == v__token__Kind__key_orelse) { or_kind = v__ast__OrKind__block; multi_return_Array_v__ast__Stmt_v__token__Pos mr_57184 = v__parser__Parser_or_block(p, v__parser__OrBlockErrVarMode__with_err_var); or_stmts = mr_57184.arg0; or_pos = mr_57184.arg1; } else if (p->tok.kind == v__token__Kind__not) { or_kind = v__ast__OrKind__propagate_result; or_pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); } else if (p->tok.kind == v__token__Kind__question) { or_kind = v__ast__OrKind__propagate_option; or_pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); } v__ast__SelectorExpr sel_expr = ((v__ast__SelectorExpr){ .pos = pos, .field_name = field_name, .is_mut = is_mut, .mut_pos = mut_pos, .next_token = p->tok.kind, .expr = left, .expr_type = 0, .typ = 0, .name_type = 0, .or_block = ((v__ast__OrExpr){.kind = or_kind,.pos = or_pos,.stmts = or_stmts,}), .gkind_field = 0, .scope = p->scope, .from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)), .generic_from_embed_types = __new_array(0, 0, sizeof(Array_v__ast__Type)), .has_hidden_receiver = 0, .is_field_typ = 0, }); v__ast__Expr left_node = left; if ((left_node)._typ == 344 /* v.ast.CallExpr */) { (*left_node._v__ast__CallExpr).is_return_used = true; } v__ast__Expr _t8 = v__ast__SelectorExpr_to_sumtype_v__ast__Expr(&sel_expr); // Defer begin if (v__parser__Parser_dot_expr_defer_0) { v__parser__Parser_close_scope(p); } // Defer end return _t8; } VV_LOC multi_return_Array_v__ast__Type_Array_string v__parser__Parser_parse_generic_types(v__parser__Parser* p) { Array_v__ast__Type types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); Array_string param_names = __new_array_with_default(0, 0, sizeof(string), 0); if (p->tok.kind == v__token__Kind__lt) { v__parser__Parser_error(p, _S("The generic symbol `<>` is obsolete, please replace it with `[]`")); } if (p->tok.kind != v__token__Kind__lsbr) { return (multi_return_Array_v__ast__Type_Array_string){.arg0=types, .arg1=param_names}; } v__token__Kind end_kind = v__token__Kind__rsbr; v__parser__Parser_next(p); bool first_done = false; int count = 0; for (;;) { if (!(!(p->tok.kind == end_kind || p->tok.kind == v__token__Kind__eof))) break; if (first_done) { v__parser__Parser_check(p, v__token__Kind__comma); } string name = p->tok.lit; if ((name).len != 0 && !u8_is_capital(string_at(name, 0))) { v__parser__Parser_error(p, _S("generic parameter needs to be uppercase")); } if (name.len > 1) { v__parser__Parser_error(p, _S("generic parameter name needs to be exactly one char")); } if (!v__util__is_generic_type_name(p->tok.lit)) { v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = p->tok.lit}}, {_S("` is a reserved name and cannot be used for generics"), 0, { .d_c = 0 }}}))); } if ((Array_string_contains(param_names, name))) { v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("duplicated generic parameter `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}}))); } if (count > 8) { v__parser__Parser_error(p, _S("cannot have more than 9 generic parameters")); } v__parser__Parser_check(p, v__token__Kind__name); array_push((array*)¶m_names, _MOV((string[]){ string_clone(name) })); int idx = v__ast__Table_find_type_idx(p->table, name); if (idx == 0) { idx = v__ast__Table_register_sym(p->table, ((v__ast__TypeSymbol){.parent_idx = 0,.info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557},.kind = v__ast__Kind__any,.name = name,.cname = v__util__no_dots(name),.rname = (string){.str=(byteptr)"", .is_lit=1},.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.mod = p->mod,.is_pub = true,.is_builtin = 0,.language = 0,.idx = 0,.size = -1,.align = -1,})); } array_push((array*)&types, _MOV((v__ast__Type[]){ v__ast__Type_set_flag(v__ast__new_type(idx), v__ast__TypeFlag__generic) })); first_done = true; count++; } v__parser__Parser_check(p, end_kind); return (multi_return_Array_v__ast__Type_Array_string){.arg0=types, .arg1=param_names}; } VV_LOC Array_v__ast__Type v__parser__Parser_parse_concrete_types(v__parser__Parser* p) { bool v__parser__Parser_parse_concrete_types_defer_0 = false; Array_v__ast__Type types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); if (p->tok.kind == v__token__Kind__lt) { v__parser__Parser_error(p, _S("The generic symbol `<>` is obsolete, please replace it with `[]`")); } if (p->tok.kind != v__token__Kind__lsbr) { return types; } p->inside_fn_concrete_type = true; v__parser__Parser_parse_concrete_types_defer_0 = true; v__token__Kind end_kind = v__token__Kind__rsbr; v__parser__Parser_next(p); bool first_done = false; for (;;) { if (!(!(p->tok.kind == v__token__Kind__eof || p->tok.kind == end_kind))) break; if (first_done) { v__parser__Parser_check(p, v__token__Kind__comma); } array_push((array*)&types, _MOV((v__ast__Type[]){ v__parser__Parser_parse_type(p) })); first_done = true; } v__parser__Parser_check(p, end_kind); Array_v__ast__Type _t3 = types; // Defer begin if (v__parser__Parser_parse_concrete_types_defer_0) { p->inside_fn_concrete_type = false; } // Defer end return _t3; } VV_LOC v__ast__Expr v__parser__Parser_string_expr(v__parser__Parser* p) { bool is_raw = p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("r")); bool is_cstr = p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("c")); bool is_js_str = p->tok.kind == v__token__Kind__name && fast_string_eq(p->tok.lit, _S("js")); if (is_raw || is_cstr || is_js_str) { v__parser__Parser_next(p); } v__ast__Expr node = _const_v__ast__empty_expr; string val = p->tok.lit; v__token__Pos pos = v__token__Token_pos(&p->tok); pos.last_line = (int)(pos.line_nr + string_count(val, _S("\n"))); if (p->peek_tok.kind != v__token__Kind__str_dollar) { v__parser__Parser_next(p); bool _t1 = true; v__ast__Language _t2 = 0; if (_t1 == (is_cstr)) { _t2 = v__ast__Language__c; } else if (_t1 == (is_js_str)) { _t2 = v__ast__Language__js; } else { _t2 = v__ast__Language__v; }node = v__ast__StringLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__StringLiteral, (((v__ast__StringLiteral){.val = val,.is_raw = is_raw,.language = _t2,.pos = pos,})))); return node; } Array_v__ast__Expr exprs = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); Array_string vals = __new_array_with_default(0, 0, sizeof(string), 0); Array_bool has_fmts = __new_array_with_default(0, 0, sizeof(bool), 0); Array_int fwidths = __new_array_with_default(0, 0, sizeof(int), 0); Array_int precisions = __new_array_with_default(0, 0, sizeof(int), 0); Array_bool visible_pluss = __new_array_with_default(0, 0, sizeof(bool), 0); Array_bool fills = __new_array_with_default(0, 0, sizeof(bool), 0); Array_u8 fmts = __new_array_with_default(0, 0, sizeof(u8), 0); Array_v__token__Pos fposs = __new_array_with_default(0, 0, sizeof(v__token__Pos), 0); p->inside_str_interp = true; for (;;) { if (!(p->tok.kind == v__token__Kind__string)) break; array_push((array*)&vals, _MOV((string[]){ string_clone(p->tok.lit) })); v__parser__Parser_next(p); if (p->tok.kind != v__token__Kind__str_dollar) { break; } v__parser__Parser_next(p); array_push((array*)&exprs, _MOV((v__ast__Expr[]){ v__parser__Parser_expr(p, 0) })); bool has_fmt = false; int fwidth = 0; bool fwidthneg = false; int precision = 987698; bool visible_plus = false; bool fill = false; rune fmt = '_'; if (p->tok.kind == v__token__Kind__colon) { v__parser__Parser_next(p); if (p->tok.kind == v__token__Kind__minus) { fwidthneg = true; v__parser__Parser_next(p); } else if (p->tok.kind == v__token__Kind__plus) { visible_plus = true; v__parser__Parser_next(p); } if (p->tok.kind == v__token__Kind__number) { Array_string fields = string_split(p->tok.lit, _S(".")); if ((*(string*)array_get(fields, 0)).len > 0 && string_at((*(string*)array_get(fields, 0)), 0) == '0') { fill = true; } fwidth = string_int((*(string*)array_get(fields, 0))); if (fwidthneg) { fwidth = -fwidth; } if (fields.len > 1) { precision = string_int((*(string*)array_get(fields, 1))); } v__parser__Parser_next(p); } if (p->tok.kind == v__token__Kind__name) { if (p->tok.lit.len == 1) { fmt = string_at(p->tok.lit, 0); has_fmt = true; v__parser__Parser_next(p); } else { return v__ast__NodeError_to_sumtype_v__ast__Expr(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, _S("format specifier may only be one letter"))))); } } } array_push((array*)&fwidths, _MOV((int[]){ fwidth })); array_push((array*)&has_fmts, _MOV((bool[]){ has_fmt })); array_push((array*)&precisions, _MOV((int[]){ precision })); array_push((array*)&visible_pluss, _MOV((bool[]){ visible_plus })); array_push((array*)&fmts, _MOV((u8[]){ fmt })); array_push((array*)&fills, _MOV((bool[]){ fill })); array_push((array*)&fposs, _MOV((v__token__Pos[]){ v__token__Token_pos(&p->prev_tok) })); } pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->prev_tok)); node = v__ast__StringInterLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__StringInterLiteral, (((v__ast__StringInterLiteral){ .vals = vals, .fwidths = fwidths, .precisions = precisions, .pluss = visible_pluss, .fills = fills, .fmt_poss = fposs, .pos = pos, .exprs = exprs, .expr_types = __new_array(0, 0, sizeof(v__ast__Type)), .fmts = fmts, .need_fmts = has_fmts, })))); p->inside_str_interp = false; return node; } VV_LOC v__ast__Expr v__parser__Parser_parse_number_literal(v__parser__Parser* p) { v__token__Pos pos = v__token__Token_pos(&p->tok); bool is_neg = p->tok.kind == v__token__Kind__minus; if (is_neg) { v__parser__Parser_next(p); pos = v__token__Pos_extend(pos, v__token__Token_pos(&p->tok)); } string lit = p->tok.lit; string full_lit = (is_neg ? (string__plus(_S("-"), lit)) : (lit)); v__ast__Expr node = _const_v__ast__empty_expr; if (string_index_any(lit, _S(".eE")) >= 0 && !(fast_string_eq(string_substr(lit, 0, 2), _S("0x")) || fast_string_eq(string_substr(lit, 0, 2), _S("0X")) || fast_string_eq(string_substr(lit, 0, 2), _S("0o")) || fast_string_eq(string_substr(lit, 0, 2), _S("0O")) || fast_string_eq(string_substr(lit, 0, 2), _S("0b")) || fast_string_eq(string_substr(lit, 0, 2), _S("0B")))) { node = v__ast__FloatLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__FloatLiteral, (((v__ast__FloatLiteral){.val = full_lit,.pos = pos,})))); } else { node = v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = full_lit,.pos = pos,})))); } v__parser__Parser_next(p); return node; } VV_LOC v__ast__ConstDecl v__parser__Parser_const_decl(v__parser__Parser* p) { v__parser__Parser_top_level_statement_start(p); Array_v__ast__Attr attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); if (p->attrs.len > 0) { attrs = array_clone_to_depth(&p->attrs, 0); p->attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); } bool is_markused = false; for (int _t1 = 0; _t1 < attrs.len; ++_t1) { v__ast__Attr ga = ((v__ast__Attr*)attrs.data)[_t1]; if (_SLIT_EQ(ga.name.str, ga.name.len, "markused")) { is_markused = true; } else { } } v__token__Pos start_pos = v__token__Token_pos(&p->tok); bool is_pub = p->tok.kind == v__token__Kind__key_pub; if (is_pub) { v__parser__Parser_next(p); } v__token__Pos const_pos = v__token__Token_pos(&p->tok); if (v__parser__Parser_disallow_declarations_in_script_mode(p)) { return ((v__ast__ConstDecl){.is_pub = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.fields = __new_array(0, 0, sizeof(v__ast__ConstField)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_block = 0,}); } v__parser__Parser_check(p, v__token__Kind__key_const); bool is_block = p->tok.kind == v__token__Kind__lpar; if (is_block) { v__parser__Parser_next(p); } Array_v__ast__ConstField fields = __new_array_with_default(0, 0, sizeof(v__ast__ConstField), 0); Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); Array_v__ast__Comment end_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); for (;;) { comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); if (is_block && p->tok.kind == v__token__Kind__eof) { v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = _S("eof"),.expecting = _S("\302\264)\302\264"),.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); return ((v__ast__ConstDecl){.is_pub = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.fields = __new_array(0, 0, sizeof(v__ast__ConstField)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_block = 0,}); } if (p->tok.kind == v__token__Kind__rpar) { break; } v__token__Pos pos = v__token__Token_pos(&p->tok); string name = v__parser__Parser_check_name(p); _PUSH_MANY(&end_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t4, Array_v__ast__Comment); bool is_virtual_c_const = false; v__ast__Type typ = _const_v__ast__void_type; if (_SLIT_EQ(name.str, name.len, "C") && p->tok.kind == v__token__Kind__dot) { v__parser__Parser_next(p); name = string__plus(name, string__plus(_S("."), v__parser__Parser_check_name(p))); typ = v__parser__Parser_parse_type(p); is_virtual_c_const = true; } if (!p->pref->translated && !p->is_translated && v__util__contains_capital(name) && !is_virtual_c_const) { v__parser__Parser_error_with_pos(p, _S("const names cannot contain uppercase letters, use snake_case instead"), pos); } string full_name = (is_virtual_c_const ? (name) : (v__parser__Parser_prepend_mod(p, name))); if (p->tok.kind == v__token__Kind__comma) { v__parser__Parser_error_with_pos(p, _S("const declaration do not support multiple assign yet"), v__token__Token_pos(&p->tok)); } if (p->tok.kind == v__token__Kind__decl_assign) { v__parser__Parser_check(p, v__token__Kind__decl_assign); } else { if (!is_virtual_c_const) { v__parser__Parser_check(p, v__token__Kind__assign); } } _PUSH_MANY(&end_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t5, Array_v__ast__Comment); if (p->tok.kind == v__token__Kind__key_fn && !is_virtual_c_const) { v__parser__Parser_error(p, _S("const initializer fn literal is not a constant")); return ((v__ast__ConstDecl){.is_pub = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.fields = __new_array(0, 0, sizeof(v__ast__ConstField)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_block = 0,}); } if (p->tok.kind == v__token__Kind__eof) { v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = _S("eof"),.expecting = _S("an expression"),.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); return ((v__ast__ConstDecl){.is_pub = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.fields = __new_array(0, 0, sizeof(v__ast__ConstField)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_block = 0,}); } v__ast__Expr expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}; if (!is_virtual_c_const) { expr = v__parser__Parser_expr(p, 0); } if (is_block) { _PUSH_MANY(&end_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,}))), _t8, Array_v__ast__Comment); } v__ast__ConstField field = ((v__ast__ConstField){ .mod = p->mod, .name = full_name, .is_pub = is_pub, .is_markused = is_markused, .pos = v__token__Pos_extend(pos, v__ast__Expr_pos(expr)), .attrs = attrs, .is_virtual_c = is_virtual_c_const, .expr = expr, .typ = 0, .comments = comments, .end_comments = end_comments, .comptime_expr_value = _const_v__ast__empty_comptime_const_value, }); if (is_virtual_c_const) { field.typ = typ; } array_push((array*)&fields, _MOV((v__ast__ConstField[]){ field })); v__ast__Scope_register(p->table->global_scope, v__ast__ConstField_to_sumtype_v__ast__ScopeObject(&field)); comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); if (is_block) { end_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); } if (!is_block) { break; } } v__parser__Parser_top_level_statement_end(p); if (is_block) { v__parser__Parser_check(p, v__token__Kind__rpar); } else { _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,}))), _t10, Array_v__ast__Comment); } return ((v__ast__ConstDecl){ .is_pub = is_pub, .pos = v__token__Pos_extend_with_last_line(start_pos, const_pos, p->prev_tok.line_nr), .attrs = attrs, .fields = fields, .end_comments = comments, .is_block = is_block, }); } VV_LOC v__ast__Return v__parser__Parser_return_stmt(v__parser__Parser* p) { v__token__Pos first_pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); Array_v__ast__Comment comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); if (p->tok.kind == v__token__Kind__rcbr || (p->tok.kind == v__token__Kind__name && p->peek_tok.kind == v__token__Kind__colon)) { return ((v__ast__Return){.pos = first_pos,.comments = comments,.exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.types = __new_array(0, 0, sizeof(v__ast__Type)),}); } bool old_assign_rhs = p->inside_assign_rhs; p->inside_assign_rhs = true; Array_v__ast__Expr exprs = v__parser__Parser_expr_list(p, true); p->inside_assign_rhs = old_assign_rhs; v__token__Pos end_pos = v__ast__Expr_pos((*(v__ast__Expr*)array_last(exprs))); return ((v__ast__Return){.pos = v__token__Pos_extend(first_pos, end_pos),.comments = comments,.exprs = exprs,.types = __new_array(0, 0, sizeof(v__ast__Type)),}); } VV_LOC v__ast__GlobalDecl v__parser__Parser_global_decl(v__parser__Parser* p) { Array_v__ast__Attr attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); if (p->attrs.len > 0) { attrs = array_clone_to_depth(&p->attrs, 0); p->attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); } bool is_markused = false; bool is_exported = false; for (int _t1 = 0; _t1 < attrs.len; ++_t1) { v__ast__Attr ga = ((v__ast__Attr*)attrs.data)[_t1]; if (_SLIT_EQ(ga.name.str, ga.name.len, "export")) { is_exported = true; } else if (_SLIT_EQ(ga.name.str, ga.name.len, "markused")) { is_markused = true; } else { } } if (!p->has_globals && !p->pref->enable_globals && !p->pref->is_fmt && !p->pref->is_vet && !p->pref->translated && !p->is_translated && !p->pref->is_livemain && !p->pref->building_v && !p->builtin_mod) { v__parser__Parser_error(p, _S("use `v -enable-globals ...` to enable globals")); return ((v__ast__GlobalDecl){.mod = (string){.str=(byteptr)"", .is_lit=1},.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_block = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.fields = __new_array(0, 0, sizeof(v__ast__GlobalField)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } v__token__Pos start_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__key_global); if (v__parser__Parser_disallow_declarations_in_script_mode(p)) { return ((v__ast__GlobalDecl){.mod = (string){.str=(byteptr)"", .is_lit=1},.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_block = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.fields = __new_array(0, 0, sizeof(v__ast__GlobalField)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } bool is_block = p->tok.kind == v__token__Kind__lpar; if (is_block) { v__parser__Parser_next(p); } Array_v__ast__GlobalField fields = __new_array_with_default(0, 0, sizeof(v__ast__GlobalField), 0); Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); for (;;) { comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); bool is_volatile = p->tok.kind == v__token__Kind__key_volatile; if (is_volatile) { v__parser__Parser_next(p); } if (is_block && p->tok.kind == v__token__Kind__eof) { v__parser__Parser_unexpected(p, ((v__parser__ParamsForUnexpected){.got = _S("eof"),.expecting = _S("`)`"),.prepend_msg = (string){.str=(byteptr)"", .is_lit=1},.additional_msg = (string){.str=(byteptr)"", .is_lit=1},})); return ((v__ast__GlobalDecl){.mod = (string){.str=(byteptr)"", .is_lit=1},.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_block = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.fields = __new_array(0, 0, sizeof(v__ast__GlobalField)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); } if (p->tok.kind == v__token__Kind__rpar) { break; } v__token__Pos pos = v__token__Token_pos(&p->tok); string name = v__parser__Parser_check_name(p); bool has_expr = p->tok.kind == v__token__Kind__assign; v__ast__Expr expr = _const_v__ast__empty_expr; v__ast__Type typ = _const_v__ast__void_type; v__token__Pos typ_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (has_expr) { v__parser__Parser_next(p); expr = v__parser__Parser_expr(p, 0); if (expr._typ == 345 /* v.ast.CastExpr */) { typ = (*expr._v__ast__CastExpr).typ; } else if (expr._typ == 385 /* v.ast.StructInit */) { typ = (*expr._v__ast__StructInit).typ; } else if (expr._typ == 338 /* v.ast.ArrayInit */) { typ = (*expr._v__ast__ArrayInit).typ; } else if (expr._typ == 346 /* v.ast.ChanInit */) { typ = (*expr._v__ast__ChanInit).typ; } else if (expr._typ == 342 /* v.ast.BoolLiteral */) { typ = _const_v__ast__bool_type; } else if (expr._typ == 364 /* v.ast.IsRefType */) { typ = _const_v__ast__bool_type; } else if (expr._typ == 347 /* v.ast.CharLiteral */) { typ = _const_v__ast__char_type; } else if (expr._typ == 356 /* v.ast.FloatLiteral */) { typ = _const_v__ast__f64_type; } else if (expr._typ == 363 /* v.ast.IntegerLiteral */) { typ = _const_v__ast__int_type; } else if (expr._typ == 380 /* v.ast.SizeOf */) { typ = _const_v__ast__int_type; } else if (expr._typ == 384 /* v.ast.StringLiteral */) { typ = _const_v__ast__string_type; } else if (expr._typ == 383 /* v.ast.StringInterLiteral */) { typ = _const_v__ast__string_type; } else { } } else { typ_pos = v__token__Token_pos(&p->tok); typ = v__parser__Parser_parse_type(p); } v__ast__GlobalField field = ((v__ast__GlobalField){ .name = name, .has_expr = has_expr, .pos = pos, .typ_pos = typ_pos, .is_markused = is_markused, .is_volatile = is_volatile, .is_exported = is_exported, .expr = expr, .typ = typ, .comments = comments, }); array_push((array*)&fields, _MOV((v__ast__GlobalField[]){ field })); if (!(Array_string_contains(_const_v__ast__global_reserved_type_names, name))) { v__ast__Scope_register(p->table->global_scope, v__ast__GlobalField_to_sumtype_v__ast__ScopeObject(&field)); } comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); if (!is_block) { break; } } if (is_block) { v__parser__Parser_check(p, v__token__Kind__rpar); } return ((v__ast__GlobalDecl){ .mod = p->mod, .pos = v__token__Pos_extend(start_pos, v__token__Token_pos(&p->prev_tok)), .is_block = is_block, .attrs = attrs, .fields = fields, .end_comments = comments, }); } VV_LOC string v__parser__source_name(string name) { if (v__token__is_key(name)) { return str_intp(2, _MOV((StrIntpData[]){{_S("@"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); } return name; } VV_LOC v__ast__TypeDecl v__parser__Parser_type_decl(v__parser__Parser* p) { Array_v__ast__Attr attrs = p->attrs; v__token__Pos start_pos = v__token__Token_pos(&p->tok); bool is_pub = p->tok.kind == v__token__Kind__key_pub; if (is_pub) { v__parser__Parser_next(p); } v__parser__Parser_check(p, v__token__Kind__key_type); v__token__Pos end_pos = v__token__Token_pos(&p->tok); v__token__Pos decl_pos = v__token__Pos_extend(start_pos, end_pos); v__token__Pos name_pos = v__token__Token_pos(&p->tok); if (v__parser__Parser_disallow_declarations_in_script_mode(p)) { return v__ast__SumTypeDecl_to_sumtype_v__ast__TypeDecl(ADDR(v__ast__SumTypeDecl, (((v__ast__SumTypeDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.variants = __new_array(0, 0, sizeof(v__ast__TypeNode)),.is_markused = 0,})))); } string name = v__parser__Parser_check_name(p); v__ast__Language language = v__ast__Language__v; if (name.len == 1 && u8_is_capital(string_at(name, 0))) { if (_SLIT_EQ(name.str, name.len, "C") && p->tok.kind == v__token__Kind__dot) { v__parser__Parser_next(p); name = string__plus(_S("C."), v__parser__Parser_check_name(p)); language = v__ast__Language__c; } else { v__parser__Parser_error_with_pos(p, _S("single letter capital names are reserved for generic template types"), name_pos); return v__ast__FnTypeDecl_to_sumtype_v__ast__TypeDecl(ADDR(v__ast__FnTypeDecl, (((v__ast__FnTypeDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.typ = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_markused = 0,})))); } } if (_IN_MAP(ADDR(string, name), ADDR(map, p->imported_symbols))) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot register alias `"), 0xfe10, {.d_s = name}}, {_S("`, this type was already imported"), 0, { .d_c = 0 }}})), end_pos); return v__ast__AliasTypeDecl_to_sumtype_v__ast__TypeDecl(ADDR(v__ast__AliasTypeDecl, (((v__ast__AliasTypeDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.typ = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.parent_type = 0,.is_markused = 0,})))); } Array_v__ast__TypeNode sum_variants = __new_array_with_default(0, 0, sizeof(v__ast__TypeNode), 0); multi_return_Array_v__ast__Type_Array_string mr_70255 = v__parser__Parser_parse_generic_types(p); Array_v__ast__Type generic_types = mr_70255.arg0; v__token__Pos decl_pos_with_generics = v__token__Pos_extend(decl_pos, v__token__Token_pos(&p->prev_tok)); v__parser__Parser_check(p, v__token__Kind__assign); v__token__Pos type_pos = v__token__Token_pos(&p->tok); Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); if (p->tok.kind == v__token__Kind__key_fn && v__parser__Parser_is_fn_type_decl(p)) { string fn_name = v__parser__Parser_prepend_mod(p, name); v__ast__Type fn_type = v__parser__Parser_parse_fn_type(p, fn_name, generic_types); v__ast__Table_sym(p->table, fn_type)->is_pub = is_pub; type_pos = v__token__Pos_extend(type_pos, v__token__Token_pos(&p->tok)); comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})); p->attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); return v__ast__FnTypeDecl_to_sumtype_v__ast__TypeDecl(ADDR(v__ast__FnTypeDecl, (((v__ast__FnTypeDecl){ .name = fn_name, .is_pub = is_pub, .typ = fn_type, .pos = decl_pos, .type_pos = type_pos, .comments = comments, .generic_types = generic_types, .attrs = attrs, .is_markused = Array_v__ast__Attr_contains(attrs, _S("markused")), })))); } _PUSH_MANY(&sum_variants, (v__parser__Parser_parse_sum_type_variants(p)), _t5, Array_v__ast__TypeNode); if (sum_variants.len > 1) { for (int _t6 = 0; _t6 < sum_variants.len; ++_t6) { v__ast__TypeNode variant = ((v__ast__TypeNode*)sum_variants.data)[_t6]; if (variant.typ == 0) { continue; } v__ast__TypeSymbol* variant_sym = v__ast__Table_sym(p->table, variant.typ); if (variant_sym->kind == v__ast__Kind__none) { v__parser__Parser_error_with_pos(p, _S("named sum type cannot have none as its variant"), variant.pos); return v__ast__AliasTypeDecl_to_sumtype_v__ast__TypeDecl(ADDR(v__ast__AliasTypeDecl, (((v__ast__AliasTypeDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.typ = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.parent_type = 0,.is_markused = 0,})))); } } Array_v__ast__Type _t8 = {0}; Array_v__ast__TypeNode _t8_orig = sum_variants; int _t8_len = _t8_orig.len; _t8 = __new_array(0, _t8_len, sizeof(v__ast__Type)); for (int _t10 = 0; _t10 < _t8_len; ++_t10) { v__ast__TypeNode it = ((v__ast__TypeNode*) _t8_orig.data)[_t10]; v__ast__Type _t9 = it.typ; array_push((array*)&_t8, &_t9); } Array_v__ast__Type variant_types =_t8; string prepend_mod_name = v__parser__Parser_prepend_mod(p, name); int typ = v__ast__Table_register_sym(p->table, ((v__ast__TypeSymbol){ .parent_idx = 0, .info = v__ast__SumType_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__SumType, (((v__ast__SumType){.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.found_fields = 0,.is_anon = 0,.is_generic = generic_types.len > 0,.variants = variant_types,.generic_types = generic_types,.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.parent_type = 0,})))), .kind = v__ast__Kind__sum_type, .name = prepend_mod_name, .cname = v__util__no_dots(prepend_mod_name), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = p->mod, .is_pub = is_pub, .is_builtin = 0, .language = 0, .idx = 0, .size = -1, .align = -1, })); if (typ == _const_v__ast__string_type_idx || typ == _const_v__ast__rune_type_idx || typ == _const_v__ast__array_type_idx || typ == _const_v__ast__map_type_idx) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot register sum type `"), 0xfe10, {.d_s = name}}, {_S("`, another type with this name exists"), 0, { .d_c = 0 }}})), name_pos); return v__ast__SumTypeDecl_to_sumtype_v__ast__TypeDecl(ADDR(v__ast__SumTypeDecl, (((v__ast__SumTypeDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.typ = 0,.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.variants = __new_array(0, 0, sizeof(v__ast__TypeNode)),.is_markused = 0,})))); } v__ast__SumTypeDecl node = ((v__ast__SumTypeDecl){ .name = name, .is_pub = is_pub, .pos = decl_pos, .name_pos = name_pos, .typ = typ, .generic_types = generic_types, .attrs = p->attrs, .variants = sum_variants, .is_markused = Array_v__ast__Attr_contains(attrs, _S("markused")), }); v__ast__Table_register_sumtype(p->table, node); return v__ast__SumTypeDecl_to_sumtype_v__ast__TypeDecl(&node); } if (generic_types.len > 0) { v__parser__Parser_error_with_pos(p, _S("generic type aliases are not yet implemented"), decl_pos_with_generics); return v__ast__AliasTypeDecl_to_sumtype_v__ast__TypeDecl(ADDR(v__ast__AliasTypeDecl, (((v__ast__AliasTypeDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.typ = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.parent_type = 0,.is_markused = 0,})))); } v__ast__Type parent_type = (*(v__ast__TypeNode*)array_get(sum_variants, 0)).typ; int pidx = v__ast__Type_idx(parent_type); v__ast__Language parent_language = v__ast__Language__v; if (parent_type != 0) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(p->table, parent_type); parent_language = parent_sym->language; v__parser__Parser_check_for_impure_v(p, parent_sym->language, decl_pos); } string prepend_mod_name = (language == v__ast__Language__v ? (v__parser__Parser_prepend_mod(p, name)) : (name)); int idx = v__ast__Table_register_sym(p->table, ((v__ast__TypeSymbol){ .parent_idx = pidx, .info = v__ast__Alias_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Alias, (((v__ast__Alias){.parent_type = parent_type,.language = parent_language,.is_import = 0,})))), .kind = v__ast__Kind__alias, .name = prepend_mod_name, .cname = v__util__no_dots(prepend_mod_name), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = p->mod, .is_pub = is_pub, .is_builtin = 0, .language = 0, .idx = 0, .size = -1, .align = -1, })); v__token__Pos type_end_pos = v__token__Token_pos(&p->prev_tok); if (idx == _const_v__ast__string_type_idx || idx == _const_v__ast__rune_type_idx || idx == _const_v__ast__array_type_idx || idx == _const_v__ast__map_type_idx) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot register alias `"), 0xfe10, {.d_s = name}}, {_S("`, another type with this name exists"), 0, { .d_c = 0 }}})), name_pos); return v__ast__AliasTypeDecl_to_sumtype_v__ast__TypeDecl(ADDR(v__ast__AliasTypeDecl, (((v__ast__AliasTypeDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.typ = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.parent_type = 0,.is_markused = 0,})))); } if (idx == pidx) { v__token__Pos type_alias_pos = (*(v__ast__TypeNode*)array_get(sum_variants, 0)).pos; v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("a type alias can not refer to itself: "), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})), v__token__Pos_extend(decl_pos, type_alias_pos)); return v__ast__AliasTypeDecl_to_sumtype_v__ast__TypeDecl(ADDR(v__ast__AliasTypeDecl, (((v__ast__AliasTypeDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.typ = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.parent_type = 0,.is_markused = 0,})))); } comments = array_clone_to_depth(&(*(v__ast__TypeNode*)array_get(sum_variants, 0)).end_comments, 0); p->attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); return v__ast__AliasTypeDecl_to_sumtype_v__ast__TypeDecl(ADDR(v__ast__AliasTypeDecl, (((v__ast__AliasTypeDecl){ .name = name, .is_pub = is_pub, .typ = idx, .pos = decl_pos, .type_pos = v__token__Pos_extend(type_pos, type_end_pos), .comments = comments, .attrs = attrs, .parent_type = parent_type, .is_markused = Array_v__ast__Attr_contains(attrs, _S("markused")), })))); } VV_LOC v__ast__Expr v__parser__Parser_new_true_expr(v__parser__Parser* p) { return v__ast__BoolLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__BoolLiteral, (((v__ast__BoolLiteral){.val = true,.pos = v__token__Token_pos(&p->tok),})))); } VV_LOC void v__parser__Parser_top_level_statement_start(v__parser__Parser* p) { if (p->scanner->comments_mode == v__scanner__CommentsMode__toplevel_comments) { v__scanner__Scanner_set_is_inside_toplevel_statement(p->scanner, true); v__parser__Parser_rewind_scanner_to_current_token_in_new_mode(p); #if defined(CUSTOM_DEFINE_trace_scanner) { eprintln(str_intp(7, _MOV((StrIntpData[]){{_S(">> p.top_level_statement_start | tidx:"), 0xafe07, {.d_i32 = p->tok.tidx}}, {_S(" | p.tok.kind: "), 0x14fe10, {.d_s = v__token__Kind_str(p->tok.kind)}}, {_S(" | p.tok.lit: "), 0xfe10, {.d_s = p->tok.lit}}, {_S(" "), 0xfe10, {.d_s = p->peek_tok.lit}}, {_S(" "), 0xfe10, {.d_s = v__parser__Parser_peek_token(p, 2).lit}}, {_S(" "), 0xfe10, {.d_s = v__parser__Parser_peek_token(p, 3).lit}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } #endif } } VV_LOC void v__parser__Parser_top_level_statement_end(v__parser__Parser* p) { if (p->scanner->comments_mode == v__scanner__CommentsMode__toplevel_comments) { v__scanner__Scanner_set_is_inside_toplevel_statement(p->scanner, false); v__parser__Parser_rewind_scanner_to_current_token_in_new_mode(p); #if defined(CUSTOM_DEFINE_trace_scanner) { eprintln(str_intp(7, _MOV((StrIntpData[]){{_S(">> p.top_level_statement_end | tidx:"), 0xafe07, {.d_i32 = p->tok.tidx}}, {_S(" | p.tok.kind: "), 0x14fe10, {.d_s = v__token__Kind_str(p->tok.kind)}}, {_S(" | p.tok.lit: "), 0xfe10, {.d_s = p->tok.lit}}, {_S(" "), 0xfe10, {.d_s = p->peek_tok.lit}}, {_S(" "), 0xfe10, {.d_s = v__parser__Parser_peek_token(p, 2).lit}}, {_S(" "), 0xfe10, {.d_s = v__parser__Parser_peek_token(p, 3).lit}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } #endif } } VV_LOC void v__parser__Parser_rewind_scanner_to_current_token_in_new_mode(v__parser__Parser* p) { int tidx = p->tok.tidx; v__scanner__Scanner_set_current_tidx(p->scanner, (int)(tidx - 5)); v__token__Token no_token = ((v__token__Token){.kind = 0,.lit = (string){.str=(byteptr)"", .is_lit=1},.line_nr = 0,.col = 0,.pos = 0,.len = 0,.tidx = 0,}); p->prev_tok = no_token; p->tok = no_token; p->peek_tok = no_token; v__parser__Parser_next(p); for (;;) { v__parser__Parser_next(p); if (tidx == p->tok.tidx) { break; } } } VV_LOC v__ast__Stmt v__parser__Parser_unsafe_stmt(v__parser__Parser* p) { bool v__parser__Parser_unsafe_stmt_defer_0 = false; v__token__Pos pos = v__token__Token_pos(&p->tok); v__parser__Parser_next(p); if (p->tok.kind != v__token__Kind__lcbr) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("please use `unsafe {`"), v__token__Token_pos(&p->tok))))); } v__parser__Parser_next(p); if (p->inside_unsafe) { return v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, _S("already inside `unsafe` block"), pos)))); } if (p->tok.kind == v__token__Kind__rcbr) { v__token__Pos_update_last_line(&pos, p->tok.line_nr); v__parser__Parser_next(p); return v__ast__Block_to_sumtype_v__ast__Stmt(ADDR(v__ast__Block, (((v__ast__Block){.is_unsafe = true,.pos = pos,.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),})))); } p->inside_unsafe = true; v__parser__Parser_open_scope(p); v__parser__Parser_unsafe_stmt_defer_0 = true; v__ast__Stmt stmt = v__parser__Parser_stmt(p, false); if (p->tok.kind == v__token__Kind__rcbr) { if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { if (v__ast__Expr_is_expr((*stmt._v__ast__ExprStmt).expr)) { v__parser__Parser_next(p); v__token__Pos_update_last_line(&pos, p->prev_tok.line_nr); v__ast__UnsafeExpr ue = ((v__ast__UnsafeExpr){.pos = pos,.expr = (*stmt._v__ast__ExprStmt).expr,}); v__ast__Expr expr = v__parser__Parser_expr_with_left(p, v__ast__UnsafeExpr_to_sumtype_v__ast__Expr(&ue), 0, p->is_stmt_ident); v__ast__Stmt _t4 = v__ast__ExprStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__ExprStmt, (((v__ast__ExprStmt){.pos = pos,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = expr,.is_expr = 0,.typ = 0,})))); // Defer begin if (v__parser__Parser_unsafe_stmt_defer_0) { p->inside_unsafe = false; v__parser__Parser_close_scope(p); } // Defer end return _t4; } } } Array_v__ast__Stmt stmts = new_array_from_c_array(1, 1, sizeof(v__ast__Stmt), _MOV((v__ast__Stmt[1]){stmt})); for (;;) { if (!(p->tok.kind != v__token__Kind__rcbr)) break; array_push((array*)&stmts, _MOV((v__ast__Stmt[]){ v__parser__Parser_stmt(p, false) })); } v__parser__Parser_next(p); v__token__Pos_update_last_line(&pos, p->tok.line_nr); v__ast__Stmt _t6 = v__ast__Block_to_sumtype_v__ast__Stmt(ADDR(v__ast__Block, (((v__ast__Block){.is_unsafe = true,.pos = pos,.stmts = stmts,})))); // Defer begin if (v__parser__Parser_unsafe_stmt_defer_0) { p->inside_unsafe = false; v__parser__Parser_close_scope(p); } // Defer end return _t6; } VV_LOC bool v__parser__Parser_disallow_declarations_in_script_mode(v__parser__Parser* p) { if (p->script_mode) { v__parser__Parser_note_with_pos(p, _S("script mode started here"), v__token__Token_pos(&p->script_mode_start_token)); v__parser__Parser_error_with_pos(p, _S("all definitions must occur before code in script mode"), v__token__Token_pos(&p->tok)); return true; } return false; } VV_LOC void v__parser__Parser_add_defer_var(v__parser__Parser* p, v__ast__Ident ident) { if (p->inside_defer) { bool _t1 = false; Array_v__ast__Ident _t1_orig = p->defer_vars; int _t1_len = _t1_orig.len; for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__Ident it = ((v__ast__Ident*) _t1_orig.data)[_t2]; if (string__eq(it.name, ident.name) && string__eq(it.mod, ident.mod)) { _t1 = true; break; } } if (!_t1 && !(fast_string_eq(ident.name, _S("err")) || fast_string_eq(ident.name, _S("it")))) { array_push((array*)&p->defer_vars, _MOV((v__ast__Ident[]){ ident })); } } } VV_LOC v__ast__StructDecl v__parser__Parser_struct_decl(v__parser__Parser* p, bool is_anon) { bool v__parser__Parser_struct_decl_defer_0 = false; v__parser__Parser_top_level_statement_start(p); Array_v__ast__Attr attrs = p->attrs; v__token__Pos start_pos = v__token__Token_pos(&p->tok); bool is_pub = p->tok.kind == v__token__Kind__key_pub; bool is_shared = p->tok.kind == v__token__Kind__key_shared; bool is_option = is_anon && p->prev_tok.kind == v__token__Kind__question; if (is_pub) { v__parser__Parser_next(p); } if (is_anon) { if (is_shared) { v__parser__Parser_register_auto_import(p, _S("sync")); v__parser__Parser_next(p); } is_pub = true; } bool is_union = p->tok.kind == v__token__Kind__key_union; if (p->tok.kind == v__token__Kind__key_struct) { v__parser__Parser_next(p); } else { v__parser__Parser_check(p, v__token__Kind__key_union); } v__ast__Language language = v__parser__Parser_parse_language(p); v__token__Pos name_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check_for_impure_v(p, language, name_pos); if (v__parser__Parser_disallow_declarations_in_script_mode(p)) { return ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); } string _t2; /* if prepend */ if (is_anon) { string _t3; /* if prepend */ if (is_union) { p->table->anon_union_counter++; _t3 = str_intp(2, _MOV((StrIntpData[]){{_S("_VAnonUnion"), 0xfe07, {.d_i32 = p->table->anon_union_counter}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { p->table->anon_struct_counter++; _t3 = str_intp(2, _MOV((StrIntpData[]){{_S("_VAnonStruct"), 0xfe07, {.d_i32 = p->table->anon_struct_counter}}, {_SLIT0, 0, { .d_c = 0 }}})); } _t2 = _t3; } else { _t2 = v__parser__Parser_check_name(p); } string name = _t2; if (name.len == 1 && u8_is_capital(string_at(name, 0))) { v__parser__Parser_error_with_pos(p, _S("single letter capital names are reserved for generic template types."), name_pos); return ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); } if (_SLIT_EQ(name.str, name.len, "IError") && !fast_string_eq(p->mod, _S("builtin"))) { v__parser__Parser_error_with_pos(p, _S("cannot register struct `IError`, it is builtin interface type"), name_pos); } v__ast__Table_start_parsing_type(p->table, v__parser__Parser_prepend_mod(p, name)); v__parser__Parser_struct_decl_defer_0 = true; multi_return_Array_v__ast__Type_Array_string mr_1732 = v__parser__Parser_parse_generic_types(p); Array_v__ast__Type generic_types = mr_1732.arg0; Array_v__ast__Comment pre_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); bool no_body = p->tok.kind != v__token__Kind__lcbr && p->tok.kind != v__token__Kind__key_implements; if (language == v__ast__Language__v && no_body) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = p->tok.lit}}, {_S("` lacks body"), 0, { .d_c = 0 }}})), name_pos); v__ast__StructDecl _t5 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t5; } if (name.len == 1) { v__parser__Parser_error_with_pos(p, _S("struct names must have more than one character"), name_pos); v__ast__StructDecl _t6 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t6; } if (_IN_MAP(ADDR(string, name), ADDR(map, p->imported_symbols))) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot register struct `"), 0xfe10, {.d_s = name}}, {_S("`, this type was already imported"), 0, { .d_c = 0 }}})), name_pos); v__ast__StructDecl _t7 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t7; } string orig_name = name; if (language == v__ast__Language__c) { name = str_intp(2, _MOV((StrIntpData[]){{_S("C."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); orig_name = name; } else if (language == v__ast__Language__js) { name = str_intp(2, _MOV((StrIntpData[]){{_S("JS."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); orig_name = name; } else if (language == v__ast__Language__wasm) { name = str_intp(2, _MOV((StrIntpData[]){{_S("WASM."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); orig_name = name; } else { name = v__parser__Parser_prepend_mod(p, name); } Array_v__ast__StructField ast_fields = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); Array_v__ast__StructField fields = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); Array_v__ast__Type embed_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); Array_v__ast__Embed embeds = __new_array_with_default(0, 0, sizeof(v__ast__Embed), 0); Array_string embed_field_names = __new_array_with_default(0, 0, sizeof(string), 0); int mut_pos = -1; int pub_pos = -1; int pub_mut_pos = -1; int global_pos = -1; int module_pos = -1; bool is_field_mut = language == v__ast__Language__c; bool is_field_pub = language == v__ast__Language__c; bool is_field_global = false; bool is_implements = false; Array_v__ast__TypeNode implements_types = __new_array_with_default(0, 3, sizeof(v__ast__TypeNode), 0); int last_line = (int)(v__token__Token_pos(&p->prev_tok).line_nr + 1); Array_v__ast__Comment end_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); bool has_option = false; if (!no_body) { if (p->tok.kind == v__token__Kind__key_implements) { is_implements = true; for (;;) { v__parser__Parser_next(p); v__token__Pos type_pos = v__token__Token_pos(&p->tok); array_push((array*)&implements_types, _MOV((v__ast__TypeNode[]){ ((v__ast__TypeNode){.pos = type_pos,.typ = v__parser__Parser_parse_type(p),.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}) })); if (p->tok.kind != v__token__Kind__comma) { break; } } } v__parser__Parser_check(p, v__token__Kind__lcbr); _PUSH_MANY(&pre_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t9, Array_v__ast__Comment); int i = 0; for (;;) { if (!(p->tok.kind != v__token__Kind__rcbr)) break; Array_v__ast__Comment comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); if (p->tok.kind == v__token__Kind__rcbr) { end_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})); break; } if (p->tok.kind == v__token__Kind__key_pub && (p->peek_tok.kind == v__token__Kind__key_mut || p->peek_tok.kind == v__token__Kind__colon)) { v__parser__Parser_next(p); if (p->tok.kind == v__token__Kind__key_mut) { if (pub_mut_pos != -1) { v__parser__Parser_error(p, _S("redefinition of `pub mut` section")); v__ast__StructDecl _t10 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t10; } v__parser__Parser_next(p); pub_mut_pos = ast_fields.len; is_field_pub = true; is_field_mut = true; is_field_global = false; } else { if (pub_pos != -1) { v__parser__Parser_error(p, _S("redefinition of `pub` section")); v__ast__StructDecl _t11 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t11; } pub_pos = ast_fields.len; is_field_pub = true; is_field_mut = false; is_field_global = false; } v__parser__Parser_check(p, v__token__Kind__colon); } else if (p->tok.kind == v__token__Kind__key_mut && p->peek_tok.kind == v__token__Kind__colon) { if (mut_pos != -1) { v__parser__Parser_error(p, _S("redefinition of `mut` section")); v__ast__StructDecl _t12 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t12; } v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__colon); mut_pos = ast_fields.len; is_field_pub = false; is_field_mut = true; is_field_global = false; } else if (p->tok.kind == v__token__Kind__key_global && p->peek_tok.kind == v__token__Kind__colon) { if (global_pos != -1) { v__parser__Parser_error(p, _S("redefinition of `global` section")); v__ast__StructDecl _t13 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t13; } v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__colon); global_pos = ast_fields.len; is_field_pub = true; is_field_mut = true; is_field_global = true; } else if (p->tok.kind == v__token__Kind__key_module && p->peek_tok.kind == v__token__Kind__colon) { if (module_pos != -1) { v__parser__Parser_error(p, _S("redefinition of `module` section")); v__ast__StructDecl _t14 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t14; } v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__colon); module_pos = ast_fields.len; is_field_pub = false; is_field_mut = false; is_field_global = false; } Array_v__ast__Comment pre_field_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); Array_v__ast__Comment next_field_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); v__token__Pos field_start_pos = v__token__Token_pos(&p->tok); bool is_field_volatile = false; bool is_field_deprecated = false; if (p->tok.kind == v__token__Kind__key_volatile && v__parser__Parser_peek_token(p, 2).line_nr == p->tok.line_nr) { v__parser__Parser_next(p); is_field_volatile = true; } bool is_embed = ((p->tok.lit.len > 1 && u8_is_capital(string_at(p->tok.lit, 0)) && (p->peek_tok.line_nr != p->tok.line_nr || !(p->peek_tok.kind == v__token__Kind__name || p->peek_tok.kind == v__token__Kind__amp)) && (p->peek_tok.kind != v__token__Kind__lsbr || v__parser__Parser_peek_token(p, 2).kind != v__token__Kind__rsbr)) || p->peek_tok.kind == v__token__Kind__dot) && language == v__ast__Language__v && p->peek_tok.kind != v__token__Kind__key_fn; bool is_on_top = ast_fields.len == 0 && !(is_field_pub || is_field_mut || is_field_global); bool has_prev_newline = v__parser__Parser_has_prev_newline(p); bool has_break_line = has_prev_newline || v__parser__Parser_has_prev_line_comment_or_label(p); string field_name = _S(""); v__ast__Type typ = _const_v__ast__no_type; v__token__Pos type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); v__token__Pos field_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); v__token__Pos option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); if (p->tok.kind == v__token__Kind__rcbr) { if (ast_fields.len > 0) { _PUSH_MANY(&(*(v__ast__StructField*)array_last(ast_fields)).next_comments, (pre_field_comments), _t15, Array_v__ast__Comment); } break; } if (is_embed) { if (p->peek_tok.kind == v__token__Kind__dot && p->peek_tok.line_nr == v__parser__Parser_peek_token(p, 3).line_nr && v__parser__Parser_peek_token(p, 3).kind == v__token__Kind__name) { v__parser__Parser_error_with_pos(p, _S("invalid field name"), v__token__Token_pos(&p->tok)); v__ast__StructDecl _t16 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t16; } type_pos = v__token__Token_pos(&p->tok); typ = v__parser__Parser_parse_type(p); _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t17, Array_v__ast__Comment); type_pos = v__token__Pos_extend(type_pos, v__token__Token_pos(&p->prev_tok)); if (!is_on_top) { v__parser__Parser_error_with_pos(p, _S("struct embedding must be declared at the beginning of the struct body"), type_pos); v__ast__StructDecl _t18 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t18; } v__ast__TypeSymbol* sym = v__ast__Table_sym(p->table, typ); if ((Array_v__ast__Type_contains(embed_types, typ))) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot embed `"), 0xfe10, {.d_s = sym->name}}, {_S("` more than once"), 0, { .d_c = 0 }}})), type_pos); v__ast__StructDecl _t19 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t19; } field_name = v__ast__TypeSymbol_embed_name(sym); if ((Array_string_contains(embed_field_names, field_name))) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate field `"), 0xfe10, {.d_s = field_name}}, {_S("`"), 0, { .d_c = 0 }}})), type_pos); v__ast__StructDecl _t20 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t20; } if (p->tok.kind == v__token__Kind__lsbr) { v__parser__Parser_error(p, _S("cannot use attributes on embedded structs")); } array_push((array*)&embed_field_names, _MOV((string[]){ string_clone(field_name) })); array_push((array*)&embed_types, _MOV((v__ast__Type[]){ typ })); array_push((array*)&embeds, _MOV((v__ast__Embed[]){ ((v__ast__Embed){.typ = typ,.pos = type_pos,.comments = comments,}) })); } else { field_name = v__parser__Parser_check_name(p); p->inside_struct_field_decl = true; bool is_anon_struct = p->tok.kind == v__token__Kind__key_struct || (p->tok.kind == v__token__Kind__key_shared && p->peek_tok.kind == v__token__Kind__key_struct); bool is_anon_union = p->tok.kind == v__token__Kind__key_union || (p->tok.kind == v__token__Kind__key_shared && p->peek_tok.kind == v__token__Kind__key_union); if (is_anon_struct || is_anon_union) { bool field_is_shared = p->tok.kind == v__token__Kind__key_shared; p->anon_struct_decl = v__parser__Parser_struct_decl(p, true); p->anon_struct_decl.language = language; typ = v__ast__Table_find_type_idx(p->table, p->anon_struct_decl.name); if (field_is_shared) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__shared_f); typ = v__ast__Type_set_nr_muls(typ, 1); } } else { v__token__Pos start_type_pos = v__token__Token_pos(&p->tok); typ = v__parser__Parser_parse_type(p); type_pos = v__token__Pos_extend(start_type_pos, v__token__Token_pos(&p->prev_tok)); } p->inside_struct_field_decl = false; if (v__ast__Type_idx(typ) == 0) { v__ast__StructDecl _t24 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t24; } if (p->file_backend_mode == v__ast__Language__v || p->file_backend_mode == v__ast__Language__c) { v__ast__TypeSymbol* sym = v__ast__Table_sym(p->table, typ); v__ast__Kind elem_kind = v__ast__Kind__placeholder; if (sym->kind == v__ast__Kind__array && ((sym->info)._typ == 513 /* v.ast.Array */ || (sym->info)._typ == 539 /* v.ast.Alias */)) { elem_kind = v__ast__Table_sym(p->table, v__ast__TypeSymbol_array_info(sym).elem_type)->kind; } else if (sym->kind == v__ast__Kind__array_fixed && ((sym->info)._typ == 549 /* v.ast.ArrayFixed */ || (sym->info)._typ == 539 /* v.ast.Alias */)) { elem_kind = v__ast__Table_sym(p->table, v__ast__TypeSymbol_array_fixed_info(sym).elem_type)->kind; } if (elem_kind == v__ast__Kind__function) { v__parser__Parser_register_auto_import(p, _S("builtin.closure")); } } field_pos = v__token__Pos_extend(field_start_pos, v__token__Token_pos(&p->prev_tok)); if (v__ast__Type_has_option_or_result(typ)) { option_pos = v__token__Token_pos(ADDR(v__token__Token, v__parser__Parser_peek_token(p, -2))); has_option = true; } } Array_v__ast__Attr prev_attrs = p->attrs; p->attrs = __new_array_with_default(0, 0, sizeof(v__ast__Attr), 0); if (p->tok.kind == v__token__Kind__lsbr) { p->inside_struct_attr_decl = true; v__parser__Parser_attributes(p); for (int _t25 = 0; _t25 < p->attrs.len; ++_t25) { v__ast__Attr fa = ((v__ast__Attr*)p->attrs.data)[_t25]; if (fast_string_eq(fa.name, _S("deprecated"))) { is_field_deprecated = true; } } p->inside_struct_attr_decl = false; } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,}))), _t26, Array_v__ast__Comment); v__ast__Expr default_expr = _const_v__ast__empty_expr; bool has_default_expr = false; if (!is_embed) { if (p->tok.kind == v__token__Kind__assign) { v__parser__Parser_next(p); default_expr = v__parser__Parser_expr(p, 0); if (default_expr._typ == 355 /* v.ast.EnumVal */) { (*default_expr._v__ast__EnumVal).typ = typ; } else { } has_default_expr = true; _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,}))), _t27, Array_v__ast__Comment); } if (p->tok.kind == v__token__Kind__at) { p->inside_struct_attr_decl = true; v__parser__Parser_attributes(p); for (int _t28 = 0; _t28 < p->attrs.len; ++_t28) { v__ast__Attr fa = ((v__ast__Attr*)p->attrs.data)[_t28]; if (fast_string_eq(fa.name, _S("deprecated"))) { is_field_deprecated = true; } } p->inside_struct_attr_decl = false; _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,}))), _t29, Array_v__ast__Comment); } next_field_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = true,})); array_push((array*)&ast_fields, _MOV((v__ast__StructField[]){ ((v__ast__StructField){ .pos = field_pos, .type_pos = type_pos, .option_pos = option_pos, .pre_comments = pre_field_comments, .comments = comments, .i = i, .has_default_expr = has_default_expr, .has_prev_newline = has_prev_newline, .has_break_line = has_break_line, .attrs = p->attrs, .is_pub = is_embed || is_field_pub, .default_val = (string){.str=(byteptr)"", .is_lit=1}, .is_mut = is_embed || is_field_mut, .is_global = is_field_global, .is_volatile = is_field_volatile, .is_deprecated = is_field_deprecated, .is_embed = 0, .next_comments = next_field_comments, .is_recursive = 0, .is_part_of_union = 0, .container_typ = 0, .default_expr = default_expr, .default_expr_typ = 0, .name = field_name, .typ = typ, .unaliased_typ = 0, .anon_struct_decl = p->anon_struct_decl, }) })); } array_push((array*)&fields, _MOV((v__ast__StructField[]){ ((v__ast__StructField){ .pos = field_pos, .type_pos = type_pos, .option_pos = option_pos, .pre_comments = pre_field_comments, .comments = comments, .i = i, .has_default_expr = has_default_expr, .has_prev_newline = 0, .has_break_line = 0, .attrs = p->attrs, .is_pub = is_embed || is_field_pub, .default_val = (string){.str=(byteptr)"", .is_lit=1}, .is_mut = is_embed || is_field_mut, .is_global = is_field_global, .is_volatile = is_field_volatile, .is_deprecated = is_field_deprecated, .is_embed = is_embed, .next_comments = next_field_comments, .is_recursive = 0, .is_part_of_union = 0, .container_typ = 0, .default_expr = default_expr, .default_expr_typ = 0, .name = field_name, .typ = typ, .unaliased_typ = 0, .anon_struct_decl = p->anon_struct_decl, }) })); p->anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); p->attrs = prev_attrs; i++; } v__parser__Parser_top_level_statement_end(p); last_line = p->tok.line_nr; v__parser__Parser_check(p, v__token__Kind__rcbr); end_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})); } string scoped_name = _S(""); if (!is_anon && p->inside_fn && p->cur_fn_scope != ((void*)0)) { scoped_name = str_intp(3, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = name}}, {_S("_"), 0xfe07, {.d_i32 = p->cur_fn_scope->start_pos}}, {_SLIT0, 0, { .d_c = 0 }}})); } bool is_minify = Array_v__ast__Attr_contains(attrs, _S("minify")); v__ast__TypeSymbol sym = ((v__ast__TypeSymbol){ .parent_idx = 0, .info = v__ast__Struct_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Struct, (((v__ast__Struct){ .attrs = attrs, .scoped_name = scoped_name, .embeds = embed_types, .fields = fields, .is_typedef = Array_v__ast__Attr_contains(attrs, _S("typedef")), .is_union = is_union, .is_heap = Array_v__ast__Attr_contains(attrs, _S("heap")), .is_minify = is_minify, .is_anon = is_anon, .is_generic = generic_types.len > 0, .is_shared = is_shared, .is_markused = Array_v__ast__Attr_contains(attrs, _S("markused")), .has_option = has_option, .generic_types = generic_types, .concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .parent_type = 0, })))), .kind = v__ast__Kind__struct, .name = name, .cname = v__util__no_dots(name), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = p->mod, .is_pub = is_pub, .is_builtin = (Array_string_contains(_const_v__ast__builtins, name)), .language = language, .idx = 0, .size = -1, .align = -1, }); if (v__ast__Table_has_deep_child_no_ref(p->table, &sym, name)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("invalid recursive struct `"), 0xfe10, {.d_s = orig_name}}, {_S("`"), 0, { .d_c = 0 }}})), name_pos); v__ast__StructDecl _t32 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t32; } int ret = v__ast__Table_register_sym(p->table, sym); if (is_anon) { if (is_union) { v__ast__Table_register_anon_union(p->table, name, ret); } else { v__ast__Table_register_anon_struct(p->table, name, ret); } } if (ret == -1 && language != v__ast__Language__c) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot register struct `"), 0xfe10, {.d_s = name}}, {_S("`, another type with this name exists"), 0, { .d_c = 0 }}})), name_pos); v__ast__StructDecl _t33 = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t33; } p->expr_mod = _S(""); v__ast__StructDecl _t34 = ((v__ast__StructDecl){ .pos = v__token__Pos_extend_with_last_line(start_pos, name_pos, last_line), .name = name, .scoped_name = scoped_name, .generic_types = generic_types, .is_pub = is_pub, .mut_pos = mut_pos, .pub_pos = pub_pos, .pub_mut_pos = pub_mut_pos, .global_pos = global_pos, .module_pos = module_pos, .is_union = is_union, .is_option = is_option, .attrs = (is_anon ? (__new_array_with_default(0, 0, sizeof(v__ast__Attr), 0)) : (attrs)), .pre_comments = pre_comments, .end_comments = end_comments, .embeds = embeds, .is_implements = is_implements, .implements_types = implements_types, .language = language, .fields = ast_fields, .idx = 0, }); // Defer begin if (v__parser__Parser_struct_decl_defer_0) { v__ast__Table_reset_parsing_type(p->table); } // Defer end return _t34; } VV_LOC v__ast__StructInit v__parser__Parser_struct_init(v__parser__Parser* p, string typ_str, v__ast__StructInitKind kind, bool is_option) { v__token__Pos first_pos = v__token__Token_pos(ADDR(v__token__Token, ((kind == v__ast__StructInitKind__short_syntax && p->prev_tok.kind == v__token__Kind__lcbr ? (p->prev_tok) : (p->tok))))); p->init_generic_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); v__ast__Type typ = (kind == v__ast__StructInitKind__short_syntax ? (_const_v__ast__void_type) : (v__parser__Parser_parse_type(p))); Array_v__ast__Type struct_init_generic_types = array_clone_to_depth(&p->init_generic_types, 0); if (is_option) { typ = v__ast__Type_set_flag(typ, v__ast__TypeFlag__option); } p->expr_mod = _S(""); if (kind != v__ast__StructInitKind__short_syntax) { v__parser__Parser_check(p, v__token__Kind__lcbr); } Array_v__ast__Comment pre_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); Array_v__ast__StructInitField init_fields = __new_array_with_default(0, 0, sizeof(v__ast__StructInitField), 0); int i = 0; bool no_keys = p->peek_tok.kind != v__token__Kind__colon && p->tok.kind != v__token__Kind__rcbr && p->tok.kind != v__token__Kind__ellipsis; bool saved_is_amp = p->is_amp; p->is_amp = false; v__ast__Expr update_expr = _const_v__ast__empty_expr; Array_v__ast__Comment update_expr_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); bool has_update_expr = false; v__token__Pos update_expr_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); bool has_prev_newline = false; bool has_break_line = false; for (;;) { if (!(!(p->tok.kind == v__token__Kind__rcbr || p->tok.kind == v__token__Kind__rpar || p->tok.kind == v__token__Kind__eof))) break; string field_name = _S(""); v__ast__Expr expr = _const_v__ast__empty_expr; v__token__Pos field_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); v__token__Pos first_field_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); Array_v__ast__Comment prev_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); Array_v__ast__Comment end_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); Array_v__ast__Comment nline_comments = __new_array_with_default(0, 0, sizeof(v__ast__Comment), 0); bool is_update_expr = init_fields.len == 0 && p->tok.kind == v__token__Kind__ellipsis; if (no_keys) { expr = v__parser__Parser_expr(p, 0); field_pos = v__ast__Expr_pos(expr); first_field_pos = field_pos; end_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})); } else if (is_update_expr) { update_expr_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check(p, v__token__Kind__ellipsis); update_expr = v__parser__Parser_expr(p, 0); _PUSH_MANY(&update_expr_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,}))), _t1, Array_v__ast__Comment); has_update_expr = true; } else { prev_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); first_field_pos = v__token__Token_pos(&p->tok); has_prev_newline = v__parser__Parser_has_prev_newline(p); has_break_line = has_prev_newline || v__parser__Parser_has_prev_line_comment_or_label(p); field_name = v__parser__Parser_check_name(p); if (p->is_vls) { if (p->tok.kind != v__token__Kind__colon) { { // Unsafe block goto end; } } } v__parser__Parser_check(p, v__token__Kind__colon); expr = v__parser__Parser_expr(p, 0); end_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,})); v__token__Pos last_field_pos = v__ast__Expr_pos(expr); int field_len = (last_field_pos.len > 0 ? ((int)((int)(last_field_pos.pos - first_field_pos.pos) + last_field_pos.len)) : ((int)(first_field_pos.len + 1))); field_pos = ((v__token__Pos){.len = field_len,.line_nr = first_field_pos.line_nr,.pos = first_field_pos.pos,.col = first_field_pos.col,.last_line = 0,}); } i++; if (p->tok.kind == v__token__Kind__comma) { v__parser__Parser_next(p); } _PUSH_MANY(&end_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,}))), _t2, Array_v__ast__Comment); _PUSH_MANY(&nline_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = true,}))), _t3, Array_v__ast__Comment); if (!is_update_expr) { array_push((array*)&init_fields, _MOV((v__ast__StructInitField[]){ ((v__ast__StructInitField){ .pos = field_pos, .name_pos = first_field_pos, .pre_comments = prev_comments, .end_comments = end_comments, .next_comments = nline_comments, .has_prev_newline = has_prev_newline, .has_break_line = has_break_line, .is_embed = field_name.len > 0 && u8_is_capital(string_at(field_name, 0)), .expr = expr, .name = field_name, .typ = 0, .expected_type = 0, .parent_type = typ, }) })); } } if (kind != v__ast__StructInitKind__short_syntax) { v__parser__Parser_check(p, v__token__Kind__rcbr); } p->is_amp = saved_is_amp; end: {} return ((v__ast__StructInit){ .pos = v__token__Pos_extend(first_pos, (kind == v__ast__StructInitKind__short_syntax ? (v__token__Token_pos(&p->tok)) : (v__token__Token_pos(&p->prev_tok)))), .name_pos = first_pos, .no_keys = no_keys, .is_short_syntax = kind == v__ast__StructInitKind__short_syntax, .is_anon = kind == v__ast__StructInitKind__anon, .unresolved = v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic), .pre_comments = pre_comments, .typ_str = typ_str, .typ = typ, .update_expr = update_expr, .update_expr_type = 0, .update_expr_pos = update_expr_pos, .update_expr_comments = update_expr_comments, .is_update_embed = 0, .has_update_expr = has_update_expr, .init_fields = init_fields, .generic_types = struct_init_generic_types, .language = 0, }); } VV_LOC v__ast__InterfaceDecl v__parser__Parser_interface_decl(v__parser__Parser* p) { v__parser__Parser_top_level_statement_start(p); v__token__Pos pos = v__token__Token_pos(&p->tok); Array_v__ast__Attr attrs = p->attrs; bool is_pub = p->tok.kind == v__token__Kind__key_pub; if (is_pub) { v__parser__Parser_next(p); } v__parser__Parser_next(p); v__ast__Language language = v__parser__Parser_parse_language(p); v__token__Pos name_pos = v__token__Token_pos(&p->tok); v__parser__Parser_check_for_impure_v(p, language, name_pos); if (v__parser__Parser_disallow_declarations_in_script_mode(p)) { return ((v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,}); } string modless_name = v__parser__Parser_check_name(p); if (modless_name.len == 1 && u8_is_capital(string_at(modless_name, 0))) { v__parser__Parser_error_with_pos(p, _S("single letter capital names are reserved for generic template types."), name_pos); return ((v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,}); } if (_SLIT_EQ(modless_name.str, modless_name.len, "IError") && !fast_string_eq(p->mod, _S("builtin"))) { v__parser__Parser_error_with_pos(p, _S("cannot register interface `IError`, it is builtin interface type"), name_pos); } string interface_name = _S(""); if (language == v__ast__Language__js) { interface_name = string__plus(_S("JS."), modless_name); } else { interface_name = v__parser__Parser_prepend_mod(p, modless_name); } multi_return_Array_v__ast__Type_Array_string mr_19436 = v__parser__Parser_parse_generic_types(p); Array_v__ast__Type generic_types = mr_19436.arg0; Array_v__ast__Comment pre_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); v__parser__Parser_check(p, v__token__Kind__lcbr); _PUSH_MANY(&pre_comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,}))), _t3, Array_v__ast__Comment); if (_IN_MAP(ADDR(string, modless_name), ADDR(map, p->imported_symbols))) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot register interface `"), 0xfe10, {.d_s = interface_name}}, {_S("`, this type was already imported"), 0, { .d_c = 0 }}})), name_pos); return ((v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,}); } int reg_idx = v__ast__Table_register_sym(p->table, ((v__ast__TypeSymbol){ .parent_idx = 0, .info = v__ast__Interface_to_sumtype_v__ast__TypeInfo(ADDR(v__ast__Interface, (((v__ast__Interface){.types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.methods = __new_array(0, 0, sizeof(v__ast__Fn)),.embeds = __new_array(0, 0, sizeof(v__ast__Type)),.conversions = (__shared__Map_int_Array_v__ast__Type*)__dup__shared__Map_int_Array_v__ast__Type(&(__shared__Map_int_Array_v__ast__Type){.mtx= {0}, .val=new_map(sizeof(int), sizeof(Array_v__ast__Type), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop)}, sizeof(__shared__Map_int_Array_v__ast__Type)),.is_generic = generic_types.len > 0,.is_markused = Array_v__ast__Attr_contains(attrs, _S("markused")),.generic_types = generic_types,.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.parent_type = 0,})))), .kind = v__ast__Kind__interface, .name = interface_name, .cname = v__util__no_dots(interface_name), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = p->mod, .is_pub = is_pub, .is_builtin = 0, .language = language, .idx = 0, .size = -1, .align = -1, })); if (reg_idx == -1) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot register interface `"), 0xfe10, {.d_s = interface_name}}, {_S("`, another type with this name exists"), 0, { .d_c = 0 }}})), name_pos); return ((v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,}); } v__ast__Type typ = v__ast__new_type(reg_idx); v__ast__TypeSymbol* ts = v__ast__Table_sym(p->table, typ); v__ast__Interface info = *(v__ast__Interface*)__as_cast((ts->info)._v__ast__Interface,(ts->info)._typ, 542); ts->methods = __new_array_with_default(0, 20, sizeof(v__ast__Fn), 0); Array_v__ast__StructField fields = __new_array_with_default(0, 20, sizeof(v__ast__StructField), 0); Array_v__ast__FnDecl methods = __new_array_with_default(0, 20, sizeof(v__ast__FnDecl), 0); Array_v__ast__InterfaceEmbedding embeds = __new_array_with_default(0, 0, sizeof(v__ast__InterfaceEmbedding), 0); bool is_mut = false; int mut_pos = -1; for (;;) { if (!(p->tok.kind != v__token__Kind__rcbr && p->tok.kind != v__token__Kind__eof)) break; if (p->tok.kind == v__token__Kind__name && p->tok.lit.len > 0 && u8_is_capital(string_at(p->tok.lit, 0)) && (p->peek_tok.line_nr != p->tok.line_nr || !(p->peek_tok.kind == v__token__Kind__name || p->peek_tok.kind == v__token__Kind__amp || p->peek_tok.kind == v__token__Kind__lsbr || p->peek_tok.kind == v__token__Kind__lpar) || (p->peek_tok.kind == v__token__Kind__lsbr && v__token__Token_is_next_to(p->peek_tok, p->tok)))) { v__token__Pos iface_pos = v__token__Token_pos(&p->tok); string iface_name = p->tok.lit; v__ast__Type iface_type = v__parser__Parser_parse_type(p); if (_SLIT_EQ(iface_name.str, iface_name.len, "JS")) { iface_name = v__ast__Table_sym(p->table, iface_type)->name; } Array_v__ast__Comment comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); array_push((array*)&embeds, _MOV((v__ast__InterfaceEmbedding[]){ ((v__ast__InterfaceEmbedding){.name = iface_name,.typ = iface_type,.pos = iface_pos,.comments = comments,}) })); if (p->tok.kind == v__token__Kind__rcbr) { break; } continue; } if (p->tok.kind == v__token__Kind__name && p->peek_tok.kind == v__token__Kind__dot) { if (!_IN_MAP(ADDR(string, p->tok.lit), ADDR(map, p->imports))) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("mod `"), 0xfe10, {.d_s = p->tok.lit}}, {_S("` not imported"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->tok)); break; } string mod_name = p->tok.lit; v__ast__Type from_mod_typ = v__parser__Parser_parse_type(p); string from_mod_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mod_name}}, {_S("."), 0xfe10, {.d_s = p->prev_tok.lit}}, {_SLIT0, 0, { .d_c = 0 }}})); if (string_is_lower(from_mod_name)) { v__parser__Parser_error_with_pos(p, _S("the interface name need to have the pascal case"), v__token__Token_pos(&p->prev_tok)); break; } Array_v__ast__Comment comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); array_push((array*)&embeds, _MOV((v__ast__InterfaceEmbedding[]){ ((v__ast__InterfaceEmbedding){.name = from_mod_name,.typ = from_mod_typ,.pos = v__token__Token_pos(&p->prev_tok),.comments = comments,}) })); if (p->tok.kind == v__token__Kind__rcbr) { break; } continue; } if (p->tok.kind == v__token__Kind__key_mut) { if (is_mut) { v__parser__Parser_error_with_pos(p, _S("redefinition of `mut` section"), v__token__Token_pos(&p->tok)); return ((v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,}); } v__parser__Parser_next(p); v__parser__Parser_check(p, v__token__Kind__colon); is_mut = true; mut_pos = fields.len; } if (p->peek_tok.kind == v__token__Kind__lsbr && v__token__Token_is_next_to(p->peek_tok, p->tok)) { if (generic_types.len == 0) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("non-generic interface `"), 0xfe10, {.d_s = interface_name}}, {_S("` cannot define a generic method"), 0, { .d_c = 0 }}})), v__token__Token_pos(&p->peek_tok)); } else { v__parser__Parser_error_with_pos(p, _S("no need to add generic type names in generic interface's method"), v__token__Token_pos(&p->peek_tok)); } return ((v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,}); } Array_v__ast__Comment comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = 0,})); if (p->peek_tok.kind == v__token__Kind__lpar) { v__token__Pos method_start_pos = v__token__Token_pos(&p->tok); bool has_prev_newline = v__parser__Parser_has_prev_newline(p); bool has_break_line = has_prev_newline || v__parser__Parser_has_prev_line_comment_or_label(p); int line_nr = p->tok.line_nr; string name = v__parser__Parser_check_name(p); if (_SLIT_EQ(name.str, name.len, "type_name") || _SLIT_EQ(name.str, name.len, "type_idx")) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("cannot override built-in method `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}})), method_start_pos); return ((v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,}); } if (v__ast__TypeSymbol_has_method(ts, name)) { v__parser__Parser_error_with_pos(p, str_intp(2, _MOV((StrIntpData[]){{_S("duplicate method `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}})), method_start_pos); return ((v__ast__InterfaceDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.language = 0,.field_names = __new_array(0, 0, sizeof(string)),.is_pub = 0,.mut_pos = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.methods = __new_array(0, 0, sizeof(v__ast__FnDecl)),.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.embeds = __new_array(0, 0, sizeof(v__ast__InterfaceEmbedding)),.are_embeds_expanded = 0,}); } multi_return_Array_v__ast__Param_bool_bool_bool mr_23320 = v__parser__Parser_fn_params(p); Array_v__ast__Param params_t = mr_23320.arg0; bool is_variadic = mr_23320.arg2; Array_v__ast__Param params = new_array_from_c_array(1, 1, sizeof(v__ast__Param), _MOV((v__ast__Param[1]){((v__ast__Param){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = _S("x"),.is_mut = is_mut,.is_shared = 0,.is_atomic = 0,.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_hidden = true,.on_newline = 0,.typ = typ,})})); _PUSH_MANY(¶ms, (params_t), _t12, Array_v__ast__Param); v__ast__FnDecl method = ((v__ast__FnDecl){ .name = name, .short_name = name, .mod = p->mod, .is_deprecated = 0, .is_pub = true, .is_c_variadic = 0, .is_c_extern = 0, .is_variadic = is_variadic, .is_anon = 0, .is_noreturn = 0, .is_manualfree = 0, .is_main = 0, .is_test = 0, .is_conditional = 0, .is_exported = 0, .is_keep_alive = 0, .is_unsafe = 0, .is_must_use = 0, .is_markused = 0, .is_file_translated = 0, .receiver = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}), .receiver_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_method = 0, .is_static_type_method = 0, .static_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .method_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .method_idx = 0, .rec_mut = 0, .has_prev_newline = has_prev_newline, .has_break_line = has_break_line, .rec_share = 0, .language = 0, .file_mode = 0, .no_body = 0, .is_builtin = 0, .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .body_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .file = p->file_path, .generic_names = __new_array(0, 0, sizeof(string)), .is_direct_arr = 0, .attrs = __new_array(0, 0, sizeof(v__ast__Attr)), .ctdefine_idx = -1, .idx = 0, .params = params, .stmts = __new_array(0, 0, sizeof(v__ast__Stmt)), .defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)), .trace_fns = new_map(sizeof(string), sizeof(v__ast__FnTrace), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .return_type = _const_v__ast__void_type, .return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .has_return = 0, .should_be_skipped = 0, .ninstances = 0, .has_await = 0, .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .end_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .next_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .source_file = ((void*)0), .scope = p->scope, .label_names = __new_array(0, 0, sizeof(string)), .pos = v__token__Pos_extend(method_start_pos, v__token__Token_pos(&p->prev_tok)), .end_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .is_expand_simple_interpolation = 0, }); if (v__token__Kind_is_start_of_type(p->tok.kind) && p->tok.line_nr == line_nr) { method.return_type_pos = v__token__Token_pos(&p->tok); method.return_type = v__parser__Parser_parse_type(p); method.return_type_pos = v__token__Pos_extend(method.return_type_pos, v__token__Token_pos(&p->tok)); method.pos = v__token__Pos_extend(method.pos, method.return_type_pos); } _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = true,.follow_up = 0,}))), _t13, Array_v__ast__Comment); Array_v__ast__Comment mnext_comments = v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = true,})); method.comments = comments; method.next_comments = mnext_comments; array_push((array*)&methods, _MOV((v__ast__FnDecl[]){ method })); v__ast__Fn tmethod = ((v__ast__Fn){ .is_variadic = is_variadic, .is_c_variadic = 0, .language = 0, .is_pub = true, .is_ctor_new = 0, .is_deprecated = 0, .is_noreturn = 0, .is_unsafe = 0, .is_must_use = 0, .is_placeholder = 0, .is_main = 0, .is_test = 0, .is_keep_alive = 0, .is_method = true, .is_static_type_method = 0, .no_body = true, .is_file_translated = 0, .mod = (string){.str=(byteptr)"", .is_lit=1}, .file = (string){.str=(byteptr)"", .is_lit=1}, .file_mode = 0, .pos = method.pos, .name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .return_type = method.return_type, .receiver_type = typ, .name = name, .params = params, .source_fn = 0, .usages = 0, .generic_names = __new_array(0, 0, sizeof(string)), .dep_names = __new_array(0, 0, sizeof(string)), .attrs = __new_array(0, 0, sizeof(v__ast__Attr)), .is_conditional = 0, .ctdefine_idx = 0, .from_embedded_type = 0, .is_expand_simple_interpolation = 0, }); v__ast__TypeSymbol_register_method(ts, tmethod); array_push((array*)&info.methods, _MOV((v__ast__Fn[]){ tmethod })); } else { v__token__Pos field_pos = v__token__Token_pos(&p->tok); bool has_prev_newline = v__parser__Parser_has_prev_newline(p); bool has_break_line = has_prev_newline || v__parser__Parser_has_prev_line_comment_or_label(p); string field_name = v__parser__Parser_check_name(p); v__token__Pos type_pos = v__token__Token_pos(&p->tok); v__ast__Type field_typ = v__parser__Parser_parse_type(p); type_pos = v__token__Pos_extend(type_pos, v__token__Token_pos(&p->prev_tok)); _PUSH_MANY(&comments, (v__parser__Parser_eat_comments(p, ((v__parser__EatCommentsConfig){.same_line = 0,.follow_up = true,}))), _t16, Array_v__ast__Comment); array_push((array*)&fields, _MOV((v__ast__StructField[]){ ((v__ast__StructField){ .pos = field_pos, .type_pos = type_pos, .option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .comments = comments, .i = 0, .has_default_expr = 0, .has_prev_newline = has_prev_newline, .has_break_line = has_break_line, .attrs = __new_array(0, 0, sizeof(v__ast__Attr)), .is_pub = true, .default_val = (string){.str=(byteptr)"", .is_lit=1}, .is_mut = 0, .is_global = 0, .is_volatile = 0, .is_deprecated = 0, .is_embed = 0, .next_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .is_recursive = 0, .is_part_of_union = 0, .container_typ = 0, .default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .default_expr_typ = 0, .name = field_name, .typ = field_typ, .unaliased_typ = 0, .anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}), }) })); array_push((array*)&info.fields, _MOV((v__ast__StructField[]){ ((v__ast__StructField){ .pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .i = 0, .has_default_expr = 0, .has_prev_newline = has_prev_newline, .has_break_line = has_break_line, .attrs = __new_array(0, 0, sizeof(v__ast__Attr)), .is_pub = true, .default_val = (string){.str=(byteptr)"", .is_lit=1}, .is_mut = is_mut, .is_global = 0, .is_volatile = 0, .is_deprecated = 0, .is_embed = 0, .next_comments = __new_array(0, 0, sizeof(v__ast__Comment)), .is_recursive = 0, .is_part_of_union = 0, .container_typ = 0, .default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .default_expr_typ = 0, .name = field_name, .typ = field_typ, .unaliased_typ = 0, .anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}), }) })); } } Array_v__ast__Type _t19 = {0}; Array_v__ast__InterfaceEmbedding _t19_orig = embeds; int _t19_len = _t19_orig.len; _t19 = __new_array(0, _t19_len, sizeof(v__ast__Type)); for (int _t21 = 0; _t21 < _t19_len; ++_t21) { v__ast__InterfaceEmbedding it = ((v__ast__InterfaceEmbedding*) _t19_orig.data)[_t21]; v__ast__Type _t20 = it.typ; array_push((array*)&_t19, &_t20); } info.embeds =_t19; ts->info = v__ast__Interface_to_sumtype_v__ast__TypeInfo(&info); v__parser__Parser_top_level_statement_end(p); v__parser__Parser_check(p, v__token__Kind__rcbr); pos = v__token__Pos_extend_with_last_line(pos, v__token__Token_pos(&p->prev_tok), p->prev_tok.line_nr); v__ast__InterfaceDecl res = ((v__ast__InterfaceDecl){ .name = interface_name, .typ = typ, .name_pos = name_pos, .language = language, .field_names = __new_array(0, 0, sizeof(string)), .is_pub = is_pub, .mut_pos = mut_pos, .pos = pos, .pre_comments = pre_comments, .generic_types = generic_types, .attrs = attrs, .methods = methods, .fields = fields, .embeds = embeds, .are_embeds_expanded = 0, }); v__ast__Table_register_interface(p->table, res); return res; } VV_LOC void v__parser__State_update(v__parser__State* state, string line) { string trimmed_line = string_trim_space(line); if (v__parser__is_html_open_tag(_S("style"), line)) { *state = v__parser__State__css; } else if (_SLIT_EQ(trimmed_line.str, trimmed_line.len, "")) { *state = v__parser__State__html; } else if (v__parser__is_html_open_tag(_S("script"), line)) { *state = v__parser__State__js; } else if (_SLIT_EQ(trimmed_line.str, trimmed_line.len, "")) { *state = v__parser__State__html; } } VV_LOC bool v__parser__is_html_open_tag(string name, string s) { string trimmed_line = string_trim_space(s); int len = trimmed_line.len; if (len < name.len) { return false; } string sub = string_substr(trimmed_line, 0, 1); if (_SLIT_NE(sub.str, sub.len, "<")) { return false; } sub = string_substr(trimmed_line, (int)(len - 1), len); if (_SLIT_NE(sub.str, sub.len, ">")) { return false; } sub = string_substr(trimmed_line, (int)(len - 2), (int)(len - 1)); if (_SLIT_EQ(sub.str, sub.len, "/")) { return false; } sub = string_substr(trimmed_line, 1, (int)(len - 1)); if (string_contains_any(sub, _S("<>"))) { return false; } if (string__eq(sub, name)) { return true; } else { len = name.len; if (sub.len <= len) { return false; } if (!string__eq(string_substr(sub, 0, (int)(len + 1)), str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = name}}, {_S(" "), 0, { .d_c = 0 }}})))) { return false; } return true; } return 0; } VV_LOC string v__parser__insert_template_code(string fn_name, string tmpl_str_start, string line) { string trailing_bs = string__plus(string__plus(_S("')\n"), str_intp(2, _MOV((StrIntpData[]){{_S("sb_"), 0xfe10, {.d_s = fn_name}}, {_S(".write_u8(92)\n"), 0, { .d_c = 0 }}}))), tmpl_str_start); Array_string replace_pairs = new_array_from_c_array(10, 10, sizeof(string), _MOV((string[10]){ _S("\\"), _S("\\\\"), _S("'"), _S("\\'"), _S("@@"), _S("@"), _S("@"), _S("$"), _S("$$"), _S("\\@")})); string rline = string_replace_each(line, replace_pairs); string comptime_call_str = string_find_between(rline, _S("${"), _S("}")); if (string_contains(comptime_call_str, _S("\\'"))) { rline = string_replace(rline, comptime_call_str, string_replace(comptime_call_str, _S("\\'"), _S("'"))); } if (string_ends_with(rline, _S("\\"))) { rline = string__plus(string_substr(rline, 0, (int)(rline.len - 2)), trailing_bs); } return rline; } VV_LOC string v__parser__IncludeError_msg(v__parser__IncludeError err) { return err.message; } VV_LOC int v__parser__IncludeError_line_nr(v__parser__IncludeError err) { return err.line_nr; } VV_LOC int v__parser__IncludeError_pos(v__parser__IncludeError err) { return err.position; } VV_LOC string v__parser__IncludeError_calling_file(v__parser__IncludeError err) { return err.calling_file; } VV_LOC int v__parser__IncludeError_col(v__parser__IncludeError err) { return err.col; } VV_LOC _result_Array_string v__parser__Parser_process_includes(v__parser__Parser* p, string calling_file, int line_number, string line, v__parser__DependencyCache* dc) { string base_path = os__dir(calling_file); int tline_number = line_number; string _t1; /* if prepend */ if (string_contains(line, _S("\""))) { _t1 = (*(string*)array_get(string_split(line, _S("\"")), 1)); } else if (string_contains(line, _S("'"))) { _t1 = (*(string*)array_get(string_split(line, _S("'")), 1)); } else { _option_int _t2 = string_index(line, _S("@include ")); if (_t2.state != 0) { IError err = _t2.err; *(int*) _t2.data = 0; } int position = (*(int*)_t2.data); return (_result_Array_string){ .is_error=true, .err=I_v__parser__IncludeError_to_Interface_IError(((v__parser__IncludeError*)memdup(&(v__parser__IncludeError){.Error = ((Error){E_STRUCT}),.calling_file = calling_file,.line_nr = tline_number,.position = (int)(position + 9),.col = (int)(position + 9),.message = _S("path for @include must be quoted with \' or \""),}, sizeof(v__parser__IncludeError)))), .data={E_STRUCT} }; } string file_name = _t1; string file_ext = os__file_ext(file_name); if ((file_ext).len == 0) { file_ext = _S(".html"); } file_name = string_replace(file_name, file_ext, _S("")); string file_path = os__real_path(os__join_path_single(base_path, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = file_name}}, {_SLIT0, 0xfe10, {.d_s = file_ext}}, {_SLIT0, 0, { .d_c = 0 }}})))); if (!os__exists(file_path) && !string_contains(file_name, _S("../"))) { Array_string path_arr = string_split_any(base_path, _S("/\\")); int idx = Array_string_index(path_arr, _S("templates")); string root_path = Array_string_join(array_slice(path_arr, 0, (int)(idx + 1)), _S("/")); file_name = (*(string*)array_get(string_rsplit(file_name, _S("../")), 0)); file_path = os__real_path(os__join_path_single(root_path, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = file_name}}, {_SLIT0, 0xfe10, {.d_s = file_ext}}, {_SLIT0, 0, { .d_c = 0 }}})))); } if (!Array_string_contains((*(Array_string*)map_get(ADDR(map, dc->dependencies), &(string[]){file_path}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })), calling_file)) { array_push((array*)&(*(Array_string*)map_get_and_set((map*)&dc->dependencies, &(string[]){file_path}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })), _MOV((string[]){ string_clone(calling_file) })); } Array_string _t5 = (*(Array_string*)map_get(ADDR(map, dc->dependencies), &(string[]){file_path}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })); for (int _t6 = 0; _t6 < _t5.len; ++_t6) { string callee = ((string*)_t5.data)[_t6]; if (Array_string_contains((*(Array_string*)map_get(ADDR(map, dc->dependencies), &(string[]){callee}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })), file_path)) { _option_int _t8 = string_index(line, _S("@include ")); if (_t8.state != 0) { IError err = _t8.err; *(int*) _t8.data = 0; } return (_result_Array_string){ .is_error=true, .err=I_v__parser__IncludeError_to_Interface_IError(((v__parser__IncludeError*)memdup(&(v__parser__IncludeError){.Error = ((Error){E_STRUCT}),.calling_file = calling_file,.line_nr = tline_number,.position = (*(int*)_t8.data),.col = 0,.message = str_intp(2, _MOV((StrIntpData[]){{_S("A recursive call is being made on template "), 0xfe10, {.d_s = file_name}}, {_SLIT0, 0, { .d_c = 0 }}})),}, sizeof(v__parser__IncludeError)))), .data={E_STRUCT} }; } } Array_string file_content = __new_array_with_default(0, 0, sizeof(string), 0); if (_IN_MAP(ADDR(string, file_path), ADDR(map, dc->cache))) { file_content = (*(Array_string*)map_get(ADDR(map, dc->cache), &(string[]){file_path}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })); } else { _result_Array_string _t9 = os__read_lines(file_path); if (_t9.is_error) { IError err = _t9.err; _option_int _t10 = string_index(line, _S("@include ")); if (_t10.state != 0) { IError err = _t10.err; *(int*) _t10.data = 0; } int position = (int)((*(int*)_t10.data) + 9); return (_result_Array_string){ .is_error=true, .err=I_v__parser__IncludeError_to_Interface_IError(((v__parser__IncludeError*)memdup(&(v__parser__IncludeError){.Error = ((Error){E_STRUCT}),.calling_file = calling_file,.line_nr = tline_number,.position = position,.col = 0,.message = str_intp(3, _MOV((StrIntpData[]){{_S("Reading file `"), 0xfe10, {.d_s = file_name}}, {_S("` from path: "), 0xfe10, {.d_s = file_path}}, {_S(" failed"), 0, { .d_c = 0 }}})),}, sizeof(v__parser__IncludeError)))), .data={E_STRUCT} }; } file_content = (*(Array_string*)_t9.data); } tline_number = 1; for (int i = 0; i < file_content.len; ++i) { string l = ((string*)file_content.data)[i]; if (string_contains(l, _S("@include "))) { _result_Array_string _t12 = v__parser__Parser_process_includes(p, file_path, tline_number, l, dc); if (_t12.is_error) { IError err = _t12.err; return (_result_Array_string){ .is_error=true, .err=err, .data={E_STRUCT} }; } Array_string processed = (*(Array_string*)_t12.data); array_delete(&file_content, i); Array_string _t14 = array_reverse(processed); for (int _t15 = 0; _t15 < _t14.len; ++_t15) { string processed_line = ((string*)_t14.data)[_t15]; array_insert(&file_content, i, &(string[]){string_clone(processed_line)}); tline_number--; } } } array_push((array*)&p->template_paths, _MOV((string[]){ string_clone(file_path) })); (*(Array_string*)map_get_and_set((map*)&dc->cache, &(string[]){file_path}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })) = file_content; _result_Array_string _t17 = {0}; _result_ok(&(Array_string[]) { file_content }, (_result*)(&_t17), sizeof(Array_string)); return _t17; } string v__parser__Parser_compile_template_file(v__parser__Parser* p, string template_file, string fn_name) { _result_Array_string _t1 = os__read_lines(template_file); if (_t1.is_error) { IError err = _t1.err; v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_S("reading from "), 0xfe10, {.d_s = template_file}}, {_S(" failed"), 0, { .d_c = 0 }}}))); return _S(""); } Array_string lines = (*(Array_string*)_t1.data); array_push((array*)&p->template_paths, _MOV((string[]){ string_clone(template_file) })); v__parser__DependencyCache dc = ((v__parser__DependencyCache){.dependencies = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.cache = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}); int lstartlength = (int)(lines.len * 30); string tmpl_str_start = str_intp(2, _MOV((StrIntpData[]){{_S("\tsb_"), 0xfe10, {.d_s = fn_name}}, {_S(".write_string('"), 0, { .d_c = 0 }}})); strings__Builder source = strings__new_builder(1000); strings__Builder_writeln(&source, str_intp(5, _MOV((StrIntpData[]){{_S("\nimport strings\n// === veb html template for file: "), 0xfe10, {.d_s = template_file}}, {_S(" ===\nfn veb_tmpl_"), 0xfe10, {.d_s = fn_name}}, {_S("() string {\n\011mut sb_"), 0xfe10, {.d_s = fn_name}}, {_S(" := strings.new_builder("), 0xfe07, {.d_i32 = lstartlength}}, {_S(")\n\n\n"), 0, { .d_c = 0 }}}))); strings__Builder_write_string(&source, tmpl_str_start); v__parser__State state = v__parser__State__simple; string template_ext = os__file_ext(template_file); if (string__eq(string_to_lower_ascii(template_ext), _S(".html"))) { state = v__parser__State__html; } bool in_span = false; int end_of_line_pos = 0; int start_of_line_pos = 0; int tline_number = -1; for (int i = 0; i < lines.len; i++) { string line = (*(string*)array_get(lines, i)); tline_number++; start_of_line_pos = end_of_line_pos; end_of_line_pos += (int)(line.len + 1); if (state != v__parser__State__simple) { v__parser__State_update(&state, line); } #if defined(CUSTOM_DEFINE_trace_tmpl) { eprintln(str_intp(8, _MOV((StrIntpData[]){{_S(">>> tfile: "), 0xfe10, {.d_s = template_file}}, {_S(", spos: "), 0xcfe27, {.d_i32 = start_of_line_pos}}, {_S(", epos:"), 0xcfe27, {.d_i32 = end_of_line_pos}}, {_S(", fi: "), 0xafe27, {.d_i32 = tline_number}}, {_S(", i: "), 0xafe27, {.d_i32 = i}}, {_S(", state: "), 0x14fe30, {.d_s = v__parser__State_str(state)}}, {_S(", line: "), 0xfe10, {.d_s = line}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif if (string_contains(line, _S("@header"))) { _option_int _t5 = string_index(line, _S("@header")); if (_t5.state != 0) { IError err = _t5.err; *(int*) _t5.data = 0; } int position = (*(int*)_t5.data); v__parser__Parser_error_with_error(p, ((v__errors__Error){.CompilerMessage = ((v__errors__CompilerMessage){.message = _S("Please use @include 'header' instead of @header (deprecated)"),.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = template_file,.pos = ((v__token__Pos){.len = 7,.line_nr = tline_number,.pos = (int)(start_of_line_pos + position),.col = 0,.last_line = lines.len,}),.reporter = v__errors__Reporter__parser,}),})); continue; } if (string_contains(line, _S("@footer"))) { _option_int _t6 = string_index(line, _S("@footer")); if (_t6.state != 0) { IError err = _t6.err; *(int*) _t6.data = 0; } int position = (*(int*)_t6.data); v__parser__Parser_error_with_error(p, ((v__errors__Error){.CompilerMessage = ((v__errors__CompilerMessage){.message = _S("Please use @include 'footer' instead of @footer (deprecated)"),.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = template_file,.pos = ((v__token__Pos){.len = 7,.line_nr = tline_number,.pos = (int)(start_of_line_pos + position),.col = 0,.last_line = lines.len,}),.reporter = v__errors__Reporter__parser,}),})); continue; } if (string_contains(line, _S("@include "))) { array_delete(&lines, i); _result_Array_string _t7 = v__parser__Parser_process_includes(p, template_file, tline_number, line, &dc); if (_t7.is_error) { IError err = _t7.err; Array_string _t8; /* if prepend */ if ((err)._typ == _IError_v__parser__IncludeError_index) { v__parser__Parser_error_with_error(p, ((v__errors__Error){.CompilerMessage = ((v__errors__CompilerMessage){.message = v__parser__IncludeError_msg(*(err._v__parser__IncludeError)),.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = v__parser__IncludeError_calling_file(*(err._v__parser__IncludeError)),.pos = ((v__token__Pos){.len = 9,.line_nr = v__parser__IncludeError_line_nr(*(err._v__parser__IncludeError)),.pos = (int)(start_of_line_pos + v__parser__IncludeError_pos(*(err._v__parser__IncludeError))),.col = v__parser__IncludeError_col(*(err._v__parser__IncludeError)),.last_line = lines.len,}),.reporter = v__errors__Reporter__parser,}),})); _t8 = __new_array_with_default(0, 0, sizeof(string), 0); } else { v__parser__Parser_error_with_error(p, ((v__errors__Error){.CompilerMessage = ((v__errors__CompilerMessage){.message = _S("An unknown error has occurred"),.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = template_file,.pos = ((v__token__Pos){.len = 9,.line_nr = tline_number,.pos = start_of_line_pos,.col = 0,.last_line = lines.len,}),.reporter = v__errors__Reporter__parser,}),})); _t8 = __new_array_with_default(0, 0, sizeof(string), 0); } *(Array_string*) _t7.data = _t8; } Array_string resolved = (*(Array_string*)_t7.data); Array_string _t9 = array_reverse(resolved); for (int _t10 = 0; _t10 < _t9.len; ++_t10) { string resolved_line = ((string*)_t9.data)[_t10]; tline_number--; array_insert(&lines, i, &(string[]){string_clone(resolved_line)}); } i--; continue; } if (string_contains(line, _S("@if "))) { strings__Builder_writeln(&source, _const_v__parser__tmpl_str_end); _option_int _t11 = string_index(line, _S("@if")); if (_t11.state != 0) { IError err = _t11.err; continue; } int pos = (*(int*)_t11.data); strings__Builder_writeln(&source, string__plus(string__plus(_S("if "), string_substr(line, (int)(pos + 4), 2147483647)), _S("{"))); strings__Builder_write_string(&source, tmpl_str_start); continue; } if (string_contains(line, _S("@end"))) { strings__Builder_writeln(&source, _const_v__parser__tmpl_str_end); strings__Builder_writeln(&source, _S("}")); strings__Builder_write_string(&source, tmpl_str_start); continue; } if (string_contains(line, _S("@else"))) { strings__Builder_writeln(&source, _const_v__parser__tmpl_str_end); _option_int _t12 = string_index(line, _S("@else")); if (_t12.state != 0) { IError err = _t12.err; continue; } int pos = (*(int*)_t12.data); strings__Builder_writeln(&source, string__plus(string__plus(_S("}"), string_substr(line, (int)(pos + 1), 2147483647)), _S("{"))); strings__Builder_write_string(&source, tmpl_str_start); continue; } if (string_contains(line, _S("@for"))) { strings__Builder_writeln(&source, _const_v__parser__tmpl_str_end); _option_int _t13 = string_index(line, _S("@for")); if (_t13.state != 0) { IError err = _t13.err; continue; } int pos = (*(int*)_t13.data); strings__Builder_writeln(&source, string__plus(string__plus(_S("for "), string_substr(line, (int)(pos + 4), 2147483647)), _S("{"))); strings__Builder_write_string(&source, tmpl_str_start); continue; } if (state == v__parser__State__simple) { strings__Builder_writeln(&source, v__parser__insert_template_code(fn_name, tmpl_str_start, line)); continue; } if (state != v__parser__State__simple) { if (string_contains(line, _S("@js "))) { _option_int _t14 = string_index(line, _S("@js")); if (_t14.state != 0) { IError err = _t14.err; continue; } int pos = (*(int*)_t14.data); strings__Builder_write_string(&source, _S("")); continue; } if (string_contains(line, _S("@css "))) { _option_int _t15 = string_index(line, _S("@css")); if (_t15.state != 0) { IError err = _t15.err; continue; } int pos = (*(int*)_t15.data); strings__Builder_write_string(&source, _S("")); continue; } } if (state == (v__parser__State__html)) { string line_t = string_trim_space(line); if (string_starts_with(line_t, _S("span.")) && string_ends_with(line, _S("{"))) { string __v_class = string_trim_space(string_find_between(line, _S("span."), _S("{"))); strings__Builder_writeln(&source, str_intp(2, _MOV((StrIntpData[]){{_S(""), 0, { .d_c = 0 }}}))); in_span = true; continue; } else if (string_starts_with(line_t, _S(".")) && string_ends_with(line, _S("{"))) { string __v_class = string_trim_space(string_find_between(line, _S("."), _S("{"))); string trimmed = string_trim_space(line); strings__Builder_write_string(&source, strings__repeat('\t', (int)(line.len - trimmed.len))); strings__Builder_writeln(&source, str_intp(2, _MOV((StrIntpData[]){{_S("
"), 0, { .d_c = 0 }}}))); continue; } else if (string_starts_with(line_t, _S("#")) && string_ends_with(line, _S("{"))) { string __v_class = string_trim_space(string_find_between(line, _S("#"), _S("{"))); strings__Builder_writeln(&source, str_intp(2, _MOV((StrIntpData[]){{_S("
"), 0, { .d_c = 0 }}}))); continue; } else if (_SLIT_EQ(line_t.str, line_t.len, "}")) { strings__Builder_write_string(&source, strings__repeat('\t', (int)(line.len - line_t.len))); if (in_span) { strings__Builder_writeln(&source, _S("")); in_span = false; } else { strings__Builder_writeln(&source, _S("
")); } continue; } } else if (state == (v__parser__State__js)) { strings__Builder_writeln(&source, v__parser__insert_template_code(fn_name, tmpl_str_start, line)); continue; } else if (state == (v__parser__State__css)) { strings__Builder_writeln(&source, string_replace(string_replace(line, _S(".$"), _S(".@")), _S("'"), _S("\\'"))); continue; } else { } _option_int _t16; if (_t16 = string_index(line, _S("%")), _t16.state == 0) { int pos = *(int*)_t16.data; string line_ = line; if ((int)(pos + 1) < line.len && u8_is_letter(string_at(line, (int)(pos + 1)))) { int end = (int)(pos + 1); for (;;) { if (!(end < line.len && (u8_is_letter(string_at(line, end)) || string_at(line, end) == '_'))) break; end++; } string key = string_substr(line, (int)(pos + 1), end); line_ = string_replace(line, str_intp(2, _MOV((StrIntpData[]){{_S("%"), 0xfe10, {.d_s = key}}, {_SLIT0, 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S("${veb.tr(ctx.lang.str(), \""), 0xfe10, {.d_s = key}}, {_S("\")}"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&source, v__parser__insert_template_code(fn_name, tmpl_str_start, line_)); } else { IError err = _t16.err; strings__Builder_writeln(&source, v__parser__insert_template_code(fn_name, tmpl_str_start, line)); } } strings__Builder_writeln(&source, _const_v__parser__tmpl_str_end); strings__Builder_writeln(&source, str_intp(3, _MOV((StrIntpData[]){{_S("\t_tmpl_res_"), 0xfe10, {.d_s = fn_name}}, {_S(" := sb_"), 0xfe10, {.d_s = fn_name}}, {_S(".str() "), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&source, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn _tmpl_res_"), 0xfe10, {.d_s = fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); strings__Builder_writeln(&source, _S("}")); strings__Builder_writeln(&source, str_intp(2, _MOV((StrIntpData[]){{_S("// === end of veb html template_file: "), 0xfe10, {.d_s = template_file}}, {_S(" ==="), 0, { .d_c = 0 }}}))); string result = strings__Builder_str(&source); if (string_contains(result, _S("veb."))) { result = string__plus(_S("import veb\n"), result); } #if defined(CUSTOM_DEFINE_trace_tmpl_expansion) { eprintln(_S(">>>>>>> template expanded to:")); eprintln(result); eprintln(_S("-----------------------------")); } #endif return result; } void v__callgraph__show(v__ast__Table* table, v__pref__Preferences* pref_, Array_v__ast__File_ptr ast_files) { v__callgraph__Mapper* mapper = ((v__callgraph__Mapper*)memdup(&(v__callgraph__Mapper){.pos = 0,.pref = pref_,.table = table,.file = ((void*)0),.node = ((void*)0),.fn_decl = ((void*)0),.caller_name = (string){.str=(byteptr)"", .is_lit=1},.dot_caller_name = (string){.str=(byteptr)"", .is_lit=1},.is_caller_used = 0,.dg = *v__dotgraph__new(_S("CallGraph"), str_intp(2, _MOV((StrIntpData[]){{_S("CallGraph for "), 0xfe10, {.d_s = pref_->path}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("green")),}, sizeof(v__callgraph__Mapper))); for (int _t1 = 0; _t1 < ast_files.len; ++_t1) { v__ast__File* afile = ((v__ast__File**)ast_files.data)[_t1]; v__ast__walker__walk(HEAP(v__ast__walker__Visitor, I_v__callgraph__Mapper_to_Interface_v__ast__walker__Visitor(mapper)), HEAP(v__ast__Node, v__ast__File_to_sumtype_v__ast__Node(afile))); } v__dotgraph__DotGraph_finish(&mapper->dg); } VV_LOC string v__callgraph__Mapper_dot_normalise_node_name(v__callgraph__Mapper* m, string name) { string res = string_replace_each(name, new_array_from_c_array(26, 26, sizeof(string), _MOV((string[26]){ _S("."), _S("_"), _S("=="), _S("op_eq"), _S(">="), _S("op_greater_eq"), _S("<="), _S("op_lesser_eq"), _S(">"), _S("op_greater"), _S("<"), _S("op_lesser"), _S("+"), _S("op_plus"), _S("-"), _S("op_minus"), _S("/"), _S("op_divide"), _S("*"), _S("op_multiply"), _S("^"), _S("op_xor"), _S("|"), _S("op_or"), _S("&"), _S("op_and")}))); return res; } VV_LOC string v__callgraph__Mapper_fn_name(v__callgraph__Mapper* m, string fname, v__ast__Type receiver_type, bool is_method) { if (!is_method) { return fname; } v__ast__TypeSymbol* rec_sym = v__ast__Table_sym(m->table, receiver_type); return str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = rec_sym->name}}, {_S("."), 0xfe10, {.d_s = fname}}, {_SLIT0, 0, { .d_c = 0 }}})); } VV_LOC string v__callgraph__Mapper_dot_fn_name(v__callgraph__Mapper* m, string fname, v__ast__Type recv_type, bool is_method) { if (is_method) { return string__plus(string__plus(string__plus(_S("Node_method_"), int_str(((int)(recv_type)))), _S("_")), v__callgraph__Mapper_dot_normalise_node_name(m, fname)); } return string__plus(_S("Node_fn_"), v__callgraph__Mapper_dot_normalise_node_name(m, fname)); } VV_LOC _result_void v__callgraph__Mapper_visit(v__callgraph__Mapper* m, v__ast__Node* node) { m->node = node; if (node->_typ == 228 /* v.ast.File */) { m->file = &(*node->_v__ast__File); } else if (node->_typ == 416 /* v.ast.Stmt */) { if ((*node->_v__ast__Stmt)._typ == 237 /* v.ast.FnDecl */) { m->is_caller_used = true; if (m->pref->skip_unused) { m->is_caller_used = (*(bool*)map_get(ADDR(map, m->table->used_features->used_fns), &(string[]){v__ast__FnDecl_fkey(&(*(*node->_v__ast__Stmt)._v__ast__FnDecl))}, &(bool[]){ 0 })); } m->fn_decl = &(*(*node->_v__ast__Stmt)._v__ast__FnDecl); m->caller_name = v__callgraph__Mapper_fn_name(m, (*(*node->_v__ast__Stmt)._v__ast__FnDecl).name, (*(*node->_v__ast__Stmt)._v__ast__FnDecl).receiver.typ, (*(*node->_v__ast__Stmt)._v__ast__FnDecl).is_method); m->dot_caller_name = v__callgraph__Mapper_dot_fn_name(m, (*(*node->_v__ast__Stmt)._v__ast__FnDecl).name, (*(*node->_v__ast__Stmt)._v__ast__FnDecl).receiver.typ, (*(*node->_v__ast__Stmt)._v__ast__FnDecl).is_method); if (m->is_caller_used) { v__dotgraph__DotGraph_new_node(&m->dg, m->caller_name, ((v__dotgraph__NewNodeConfig){.node_name = m->dot_caller_name,.should_highlight = fast_string_eq(m->caller_name, _S("main.main")),.tooltip = (string){.str=(byteptr)"", .is_lit=1},.ctx = ((void*)0),.name2node_fn = v__dotgraph__node_name,})); } } else { } } else if (node->_typ == 389 /* v.ast.Expr */) { if ((*node->_v__ast__Expr)._typ == 344 /* v.ast.CallExpr */) { if (m->is_caller_used) { string dot_called_name = v__callgraph__Mapper_dot_fn_name(m, (*(*node->_v__ast__Expr)._v__ast__CallExpr).name, (*(*node->_v__ast__Expr)._v__ast__CallExpr).receiver_type, (*(*node->_v__ast__Expr)._v__ast__CallExpr).is_method); v__dotgraph__DotGraph_new_edge(&m->dg, m->dot_caller_name, dot_called_name, ((v__dotgraph__NewEdgeConfig){.should_highlight = fast_string_eq(m->caller_name, _S("main.main")),.ctx = ((void*)0),.name2node_fn = v__dotgraph__node_name,})); } } else { } } else { } return (_result_void){0}; } VV_LOC void v__gen__c__Gen_array_init(v__gen__c__Gen* g, v__ast__ArrayInit node, string var_name) { v__gen__c__Type array_type = v__gen__c__Gen_unwrap(g, node.typ); string array_styp = _S(""); v__gen__c__Type elem_type = v__gen__c__Gen_unwrap(g, node.elem_type); string shared_styp = _S(""); bool is_amp = g->is_amp; g->is_amp = false; if (is_amp) { v__gen__c__Gen_go_back(g, 1); } if (g->is_shared) { shared_styp = v__gen__c__Gen_styp(g, v__ast__Type_set_flag(array_type.typ, v__ast__TypeFlag__shared_f)); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = shared_styp}}, {_S("*)__dup_shared_array(&("), 0xfe10, {.d_s = shared_styp}}, {_S("){.mtx = {0}, .val ="), 0, { .d_c = 0 }}}))); } else if (is_amp) { array_styp = v__gen__c__Gen_styp(g, array_type.typ); { v__gen__c__Gen_write(g, _S("HEAP(")); v__gen__c__Gen_write(g, array_styp); v__gen__c__Gen_write(g, _S(", ")); } } int len = node.exprs.len; v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, node.elem_type)); if (array_type.unaliased_sym->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_fixed_array_init(g, node, array_type, var_name, is_amp); if (is_amp) { v__gen__c__Gen_write(g, _S(")")); } } else if (len == 0) { v__gen__c__Gen_array_init_with_fields(g, node, elem_type, is_amp, shared_styp, var_name); } else { string elem_styp = v__gen__c__Gen_styp(g, elem_type.typ); string noscan = v__gen__c__Gen_check_noscan(g, elem_type.typ); if (elem_type.unaliased_sym->kind == v__ast__Kind__function) { { v__gen__c__Gen_write(g, _S("new_array_from_c_array(")); v__gen__c__Gen_write_decimal(g, len); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, len); v__gen__c__Gen_write(g, _S(", sizeof(voidptr), _MOV((voidptr[")); v__gen__c__Gen_write_decimal(g, len); v__gen__c__Gen_write(g, _S("]){")); } } else { { v__gen__c__Gen_write(g, _S("new_array_from_c_array")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write_decimal(g, len); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, len); v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, elem_styp); v__gen__c__Gen_write(g, _S("), _MOV((")); v__gen__c__Gen_write(g, elem_styp); v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_write_decimal(g, len); v__gen__c__Gen_write(g, _S("]){")); } } if (len > 8) { v__gen__c__Gen_writeln(g, _S("")); v__gen__c__Gen_write(g, _S("\t\t")); } bool is_iface_or_sumtype = (elem_sym->kind == v__ast__Kind__sum_type || elem_sym->kind == v__ast__Kind__interface); for (int i = 0; i < node.exprs.len; ++i) { v__ast__Expr expr = ((v__ast__Expr*)node.exprs.data)[i]; v__ast__Type expr_type = (node.expr_types.len > i ? ((*(v__ast__Type*)array_get(node.expr_types, i))) : (node.elem_type)); if (expr_type == _const_v__ast__string_type && !((expr)._typ == 361 /* v.ast.IndexExpr */ || (expr)._typ == 344 /* v.ast.CallExpr */ || (expr)._typ == 384 /* v.ast.StringLiteral */ || (expr)._typ == 383 /* v.ast.StringInterLiteral */ || (expr)._typ == 362 /* v.ast.InfixExpr */)) { if (is_iface_or_sumtype) { v__gen__c__Gen_expr_with_cast(g, expr, expr_type, node.elem_type); } else { v__gen__c__Gen_write(g, _S("string_clone(")); v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } } else { if (v__ast__Type_has_flag(node.elem_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_opt(g, expr, expr_type, node.elem_type); } else if (elem_type.unaliased_sym->kind == v__ast__Kind__array_fixed && ((expr)._typ == 358 /* v.ast.Ident */ || (expr)._typ == 379 /* v.ast.SelectorExpr */)) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((elem_type.unaliased_sym->info)._v__ast__ArrayFixed,(elem_type.unaliased_sym->info)._typ, 549); v__gen__c__Gen_fixed_array_var_init(g, v__gen__c__Gen_expr_string(g, expr), v__ast__Expr_is_auto_deref_var(expr), info.elem_type, info.size); } else { v__gen__c__Gen_expr_with_cast(g, expr, expr_type, node.elem_type); } } if (i != (int)(len - 1)) { if (i > 0 && (i & 7) == 0) { v__gen__c__Gen_writeln(g, _S(",")); v__gen__c__Gen_write(g, _S("\t\t")); } else { v__gen__c__Gen_write(g, _S(", ")); } } } v__gen__c__Gen_write(g, _S("}))")); if (g->is_shared) { { v__gen__c__Gen_write(g, _S("}, sizeof(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("))")); } } else if (is_amp) { v__gen__c__Gen_write(g, _S(")")); } } } VV_LOC void v__gen__c__Gen_fixed_array_init(v__gen__c__Gen* g, v__ast__ArrayInit node, v__gen__c__Type array_type, string var_name, bool is_amp) { bool v__gen__c__Gen_fixed_array_init_defer_0 = false; bool prev_inside_lambda; bool v__gen__c__Gen_fixed_array_init_defer_1 = false; v__gen__c__PastTmpVar past; bool v__gen__c__Gen_fixed_array_init_defer_2 = false; bool tmp_inside_array; prev_inside_lambda = g->inside_lambda; g->inside_lambda = true; v__gen__c__Gen_fixed_array_init_defer_0 = true; v__ast__ArrayFixed array_info = v__ast__TypeSymbol_array_fixed_info(array_type.unaliased_sym); if (node.has_index) { past = v__gen__c__Gen_past_tmp_var_from_var_name(g, var_name); v__gen__c__Gen_fixed_array_init_defer_1 = true; string ret_typ_str = v__gen__c__Gen_styp(g, node.typ); string elem_typ_str = v__gen__c__Gen_styp(g, node.elem_type); if ((var_name).len == 0) { { v__gen__c__Gen_write(g, ret_typ_str); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, past.tmp_var); v__gen__c__Gen_write(g, _S(" =")); } } v__gen__c__Gen_write(g, _S("{")); if (node.has_val) { v__gen__c__Gen_write_c99_0_elements_for_array(g, node.exprs.len); } else if (node.has_init) { v__gen__c__Gen_write_c99_0_elements_for_array(g, array_info.size); } else { v__gen__c__Gen_write(g, _S("0")); } v__gen__c__Gen_write(g, _S("}")); v__gen__c__Gen_writeln2(g, _S(";"), _S("{")); g->indent++; v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = elem_typ_str}}, {_S("* pelem = ("), 0xfe10, {.d_s = elem_typ_str}}, {_S("*)"), 0xfe10, {.d_s = past.tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("int _len = (int)sizeof("), 0xfe10, {.d_s = past.tmp_var}}, {_S(") / sizeof("), 0xfe10, {.d_s = elem_typ_str}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("for (int index=0; index<_len; index++, pelem++) {")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); g->indent++; v__gen__c__Gen_writeln(g, _S("int it = index;")); v__gen__c__Gen_write(g, _S("*pelem = ")); v__gen__c__Gen_expr_with_init(g, node); v__gen__c__Gen_writeln(g, _S(";")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); // Defer begin if (v__gen__c__Gen_fixed_array_init_defer_1) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end // Defer begin if (v__gen__c__Gen_fixed_array_init_defer_0) { g->inside_lambda = prev_inside_lambda; } // Defer end return; } bool is_none = node.is_option && !node.has_init && !node.has_val; if ((g->inside_struct_init && g->inside_cast && !g->inside_memset && !g->inside_opt_or_res) || (node.is_option && !is_none)) { string ret_typ_str = v__gen__c__Gen_styp(g, node.typ); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, ret_typ_str); v__gen__c__Gen_write(g, _S(")")); } } v__ast__TypeSymbol* elem_sym = v__ast__Table_final_sym(g->table, node.elem_type); bool is_struct = g->inside_array_fixed_struct && elem_sym->kind == v__ast__Kind__struct; if (!is_struct && !is_none) { v__gen__c__Gen_write(g, _S("{")); } if (node.is_option && !is_none) { v__gen__c__Gen_write(g, _S(".state=0, .err=_const_none__, .data={")); } if (node.has_val) { tmp_inside_array = g->inside_array_item; g->inside_array_item = true; v__gen__c__Gen_fixed_array_init_defer_2 = true; int nelen = node.exprs.len; for (int i = 0; i < node.exprs.len; ++i) { v__ast__Expr expr = ((v__ast__Expr*)node.exprs.data)[i]; if (elem_sym->kind == v__ast__Kind__array_fixed && ((expr)._typ == 358 /* v.ast.Ident */ || (expr)._typ == 379 /* v.ast.SelectorExpr */)) { v__ast__ArrayFixed elem_info = v__ast__TypeSymbol_array_fixed_info(elem_sym); v__gen__c__Gen_fixed_array_var_init(g, v__gen__c__Gen_expr_string(g, expr), v__ast__Expr_is_auto_deref_var(expr), elem_info.elem_type, elem_info.size); } else if (elem_sym->kind == v__ast__Kind__array_fixed && (expr)._typ == 344 /* v.ast.CallExpr */ && v__ast__Table_final_sym(g->table, (*(v__ast__CallExpr*)__as_cast((expr)._v__ast__CallExpr,(expr)._typ, 344)).return_type)->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed elem_info = v__ast__TypeSymbol_array_fixed_info(elem_sym); string tmp_var = v__gen__c__Gen_expr_with_var(g, expr, (*(v__ast__Type*)array_get(node.expr_types, i)), false); v__gen__c__Gen_fixed_array_var_init(g, tmp_var, false, elem_info.elem_type, elem_info.size); } else { if (v__ast__Expr_is_auto_deref_var(expr)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, expr); } v__gen__c__Gen_add_commas_and_prevent_long_lines(g, i, nelen); } } else if (node.has_init) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((array_type.unaliased_sym->info)._v__ast__ArrayFixed,(array_type.unaliased_sym->info)._typ, 549); if (v__ast__Type_has_flag(node.elem_type, v__ast__TypeFlag__option)) { for (int i = 0; i < info.size; ++i) { v__gen__c__Gen_expr_with_init(g, node); v__gen__c__Gen_add_commas_and_prevent_long_lines(g, i, info.size); } } else { if (v__ast__Table_final_sym(g->table, info.elem_type)->kind == v__ast__Kind__struct || v__ast__Table_final_sym(g->table, info.elem_type)->kind == v__ast__Kind__interface) { for (int i = 0; i < info.size; ++i) { v__gen__c__Gen_expr_with_init(g, node); v__gen__c__Gen_add_commas_and_prevent_long_lines(g, i, info.size); } } else { int before_expr_pos = g->out.len; { v__gen__c__Gen_expr_with_init(g, node); } string sexpr = strings__Builder_cut_to(&g->out, before_expr_pos); v__gen__c__Gen_write_c99_elements_for_array(g, info.size, sexpr); } } } else if (is_amp) { v__gen__c__Gen_write(g, _S("0")); } else { if (elem_sym->kind == v__ast__Kind__map) { v__ast__Map map_info = v__ast__TypeSymbol_map_info(elem_sym); int before_map_expr_pos = g->out.len; { v__gen__c__Gen_expr(g, v__ast__MapInit_to_sumtype_v__ast__Expr(ADDR(v__ast__MapInit, (((v__ast__MapInit){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comments = __new_array(0, 0, sizeof(Array_v__ast__Comment)),.pre_cmnts = __new_array(0, 0, sizeof(v__ast__Comment)),.keys = __new_array(0, 0, sizeof(v__ast__Expr)),.vals = __new_array(0, 0, sizeof(v__ast__Expr)),.val_types = __new_array(0, 0, sizeof(v__ast__Type)),.typ = 0,.key_type = map_info.key_type,.value_type = map_info.value_type,.has_update_expr = 0,.update_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_expr_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.update_expr_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}))))); } string smap_expr = strings__Builder_cut_to(&g->out, before_map_expr_pos); v__gen__c__Gen_write_all_n_elements_for_array(g, array_info.size, smap_expr); } else if (elem_sym->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed arr_info = v__ast__TypeSymbol_array_fixed_info(elem_sym); int before_arr_expr_pos = g->out.len; { v__gen__c__Gen_expr(g, v__ast__ArrayInit_to_sumtype_v__ast__Expr(ADDR(v__ast__ArrayInit, (((v__ast__ArrayInit){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.elem_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.ecmnts = __new_array(0, 0, sizeof(Array_v__ast__Comment)),.pre_cmnts = __new_array(0, 0, sizeof(v__ast__Comment)),.is_fixed = 0,.is_option = 0,.has_val = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.has_len = 0,.has_cap = 0,.has_init = 0,.has_index = 0,.exprs = new_array_from_c_array(1, 1, sizeof(v__ast__Expr), _MOV((v__ast__Expr[1]){v__ast__IntegerLiteral_to_sumtype_v__ast__Expr(ADDR(v__ast__IntegerLiteral, (((v__ast__IntegerLiteral){.val = (string){.str=(byteptr)"", .is_lit=1},.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}))))})),.len_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.cap_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.init_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.expr_types = __new_array(0, 0, sizeof(v__ast__Type)),.elem_type = arr_info.elem_type,.init_type = 0,.typ = node.elem_type,.alias_type = 0,.has_callexpr = 0,}))))); } string sarr_expr = strings__Builder_cut_to(&g->out, before_arr_expr_pos); v__gen__c__Gen_write_c99_elements_for_array(g, array_info.size, sarr_expr); } else if (elem_sym->kind == v__ast__Kind__chan) { v__ast__Chan chan_info = v__ast__TypeSymbol_chan_info(elem_sym); int before_chan_expr_pos = g->out.len; v__gen__c__Gen_expr(g, v__ast__ChanInit_to_sumtype_v__ast__Expr(ADDR(v__ast__ChanInit, (((v__ast__ChanInit){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.elem_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_cap = 0,.cap_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = node.elem_type,.elem_type = chan_info.elem_type,}))))); string schan_expr = strings__Builder_cut_to(&g->out, before_chan_expr_pos); v__gen__c__Gen_write_c99_elements_for_array(g, array_info.size, schan_expr); } else if (is_none) { v__gen__c__Gen_gen_option_error(g, node.typ, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}))))); } else { string std = v__gen__c__Gen_type_default(g, node.elem_type); if (v__gen__c__Gen_can_use_c99_designators(g) && _SLIT_EQ(std.str, std.len, "0")) { v__gen__c__Gen_write(g, _S("0")); } else if (v__ast__Type_has_flag(node.elem_type, v__ast__TypeFlag__option)) { for (int i = 0; i < array_info.size; ++i) { v__gen__c__Gen_expr_with_opt(g, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))), _const_v__ast__none_type, node.elem_type); v__gen__c__Gen_add_commas_and_prevent_long_lines(g, i, array_info.size); } } else { v__gen__c__Gen_write_c99_elements_for_array(g, array_info.size, std); } } } if (node.is_option && !is_none) { v__gen__c__Gen_write(g, _S("}")); } if (!is_struct && !is_none) { v__gen__c__Gen_write(g, _S("}")); } // Defer begin if (v__gen__c__Gen_fixed_array_init_defer_2) { g->inside_array_item = tmp_inside_array; } // Defer end // Defer begin if (v__gen__c__Gen_fixed_array_init_defer_1) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end // Defer begin if (v__gen__c__Gen_fixed_array_init_defer_0) { g->inside_lambda = prev_inside_lambda; } // Defer end } VV_LOC void v__gen__c__Gen_expr_with_init(v__gen__c__Gen* g, v__ast__ArrayInit node) { if (v__ast__Type_has_flag(node.elem_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_opt(g, node.init_expr, node.init_type, node.elem_type); } else { v__gen__c__Gen_expr_with_cast(g, node.init_expr, node.init_type, node.elem_type); } } VV_LOC bool v__gen__c__Gen_struct_has_array_or_map_field(v__gen__c__Gen* g, v__ast__Type elem_typ) { v__ast__TypeSymbol* unaliased_sym = v__ast__Table_final_sym(g->table, elem_typ); if (unaliased_sym->kind == v__ast__Kind__struct) { v__ast__Struct info = *(v__ast__Struct*)__as_cast((unaliased_sym->info)._v__ast__Struct,(unaliased_sym->info)._typ, 518); for (int _t1 = 0; _t1 < info.fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[_t1]; v__ast__TypeSymbol* field_sym = v__ast__Table_final_sym(g->table, field.typ); if (field_sym->kind == v__ast__Kind__array || field_sym->kind == v__ast__Kind__map) { return true; } } } return false; } VV_LOC void v__gen__c__Gen_array_init_with_fields(v__gen__c__Gen* g, v__ast__ArrayInit node, v__gen__c__Type elem_type, bool is_amp, string shared_styp, string var_name) { bool v__gen__c__Gen_array_init_with_fields_defer_0 = false; bool prev_inside_lambda; bool v__gen__c__Gen_array_init_with_fields_defer_1 = false; v__gen__c__PastTmpVar past; prev_inside_lambda = g->inside_lambda; g->inside_lambda = true; v__gen__c__Gen_array_init_with_fields_defer_0 = true; string elem_styp = v__gen__c__Gen_styp(g, elem_type.typ); string noscan = v__gen__c__Gen_check_noscan(g, elem_type.typ); bool is_default_array = elem_type.unaliased_sym->kind == v__ast__Kind__array && node.has_init; bool is_default_map = elem_type.unaliased_sym->kind == v__ast__Kind__map && node.has_init; bool needs_more_defaults = node.has_len && (v__gen__c__Gen_struct_has_array_or_map_field(g, elem_type.typ) || (elem_type.unaliased_sym->kind == v__ast__Kind__array || elem_type.unaliased_sym->kind == v__ast__Kind__map)); if (node.has_index) { past = v__gen__c__Gen_past_tmp_var_from_var_name(g, var_name); v__gen__c__Gen_array_init_with_fields_defer_1 = true; string ret_typ = v__gen__c__Gen_styp(g, node.typ); string elem_typ = v__gen__c__Gen_styp(g, node.elem_type); if ((var_name).len == 0) { { v__gen__c__Gen_write(g, ret_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, past.tmp_var); v__gen__c__Gen_write(g, _S(" =")); } } if (is_default_array) { { v__gen__c__Gen_write(g, _S("__new_array_with_array_default")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); } } else if (is_default_map) { { v__gen__c__Gen_write(g, _S("__new_array_with_map_default")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); } } else { { v__gen__c__Gen_write(g, _S("__new_array_with_default")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); } } if (node.has_len) { v__gen__c__Gen_expr(g, node.len_expr); v__gen__c__Gen_write(g, _S(", ")); } else { v__gen__c__Gen_write(g, _S("0, ")); } if (node.has_cap) { v__gen__c__Gen_expr(g, node.cap_expr); v__gen__c__Gen_write(g, _S(", ")); } else { v__gen__c__Gen_write(g, _S("0, ")); } if (elem_type.unaliased_sym->kind == v__ast__Kind__function) { v__gen__c__Gen_write(g, _S("sizeof(voidptr), ")); } else { { v__gen__c__Gen_write(g, _S("sizeof(")); v__gen__c__Gen_write(g, elem_styp); v__gen__c__Gen_write(g, _S("), ")); } } if (is_default_array) { v__ast__Array info = *(v__ast__Array*)__as_cast((elem_type.unaliased_sym->info)._v__ast__Array,(elem_type.unaliased_sym->info)._typ, 513); int depth = (v__ast__Table_sym(g->table, info.elem_type)->kind == v__ast__Kind__array ? (1) : (0)); v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = elem_styp}}, {_S("[]){"), 0, { .d_c = 0 }}})), v__gen__c__Gen_type_default(g, node.elem_type)); { v__gen__c__Gen_write(g, _S("}[0], ")); v__gen__c__Gen_write_decimal(g, depth); v__gen__c__Gen_write(g, _S(")")); } } else if (node.has_len && node.elem_type == _const_v__ast__string_type) { v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_S("&("), 0xfe10, {.d_s = elem_styp}}, {_S("[]){"), 0, { .d_c = 0 }}})), _S("_S(\"\")")); v__gen__c__Gen_write(g, _S("})")); } else if (node.has_len && (elem_type.unaliased_sym->kind == v__ast__Kind__array || elem_type.unaliased_sym->kind == v__ast__Kind__map)) { v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_S("(voidptr)&("), 0xfe10, {.d_s = elem_styp}}, {_S("[]){"), 0, { .d_c = 0 }}})), v__gen__c__Gen_type_default(g, node.elem_type)); v__gen__c__Gen_write(g, _S("}[0])")); } else { v__gen__c__Gen_write(g, _S("0)")); } if (g->is_shared) { { v__gen__c__Gen_write(g, _S("}, sizeof(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("))")); } } else if (is_amp) { v__gen__c__Gen_write(g, _S(")")); } v__gen__c__Gen_writeln2(g, _S(";"), _S("{")); g->indent++; v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = elem_typ}}, {_S("* pelem = ("), 0xfe10, {.d_s = elem_typ}}, {_S("*)"), 0xfe10, {.d_s = past.tmp_var}}, {_S(".data;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("for (int index=0; index<"), 0xfe10, {.d_s = past.tmp_var}}, {_S(".len; index++, pelem++) {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); g->indent++; v__gen__c__Gen_writeln(g, _S("int it = index;")); if (elem_type.unaliased_sym->kind != v__ast__Kind__array_fixed) { v__gen__c__Gen_write(g, _S("*pelem = ")); v__gen__c__Gen_expr_with_init(g, node); v__gen__c__Gen_writeln(g, _S(";")); } else { v__gen__c__Gen_write(g, _S("memcpy(pelem, ")); v__gen__c__Gen_expr_with_init(g, node); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = elem_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } g->indent--; v__gen__c__Gen_writeln(g, _S("}")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); // Defer begin if (v__gen__c__Gen_array_init_with_fields_defer_1) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end // Defer begin if (v__gen__c__Gen_array_init_with_fields_defer_0) { g->inside_lambda = prev_inside_lambda; } // Defer end return; } if (is_default_array) { { v__gen__c__Gen_write(g, _S("__new_array_with_array_default")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); } } else if (is_default_map) { { v__gen__c__Gen_write(g, _S("__new_array_with_map_default")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); } } else if (needs_more_defaults) { { v__gen__c__Gen_write(g, _S("__new_array_with_multi_default")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); } } else { { v__gen__c__Gen_write(g, _S("__new_array_with_default")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); } } if (node.has_len) { v__gen__c__Gen_expr(g, node.len_expr); v__gen__c__Gen_write(g, _S(", ")); } else { v__gen__c__Gen_write(g, _S("0, ")); } if (node.has_cap) { v__gen__c__Gen_expr(g, node.cap_expr); v__gen__c__Gen_write(g, _S(", ")); } else { v__gen__c__Gen_write(g, _S("0, ")); } if (elem_type.unaliased_sym->kind == v__ast__Kind__function) { v__gen__c__Gen_write(g, _S("sizeof(voidptr), ")); } else { { v__gen__c__Gen_write(g, _S("sizeof(")); v__gen__c__Gen_write(g, elem_styp); v__gen__c__Gen_write(g, _S("), ")); } } if (is_default_array) { v__ast__Array info = *(v__ast__Array*)__as_cast((elem_type.unaliased_sym->info)._v__ast__Array,(elem_type.unaliased_sym->info)._typ, 513); int depth = (v__ast__Table_sym(g->table, info.elem_type)->kind == v__ast__Kind__array ? (1) : (0)); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, elem_styp); v__gen__c__Gen_write(g, _S("[]){")); } v__gen__c__Gen_expr(g, node.init_expr); { v__gen__c__Gen_write(g, _S("}[0], ")); v__gen__c__Gen_write_decimal(g, depth); v__gen__c__Gen_write(g, _S(")")); } } else if (is_default_map) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, elem_styp); v__gen__c__Gen_write(g, _S("[]){")); } v__gen__c__Gen_expr(g, node.init_expr); v__gen__c__Gen_write(g, _S("}[0])")); } else if (needs_more_defaults) { string tmp = v__gen__c__Gen_new_tmp_var(g); string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; { v__gen__c__Gen_write(g, elem_styp); v__gen__c__Gen_write(g, _S("* ")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S(" = (")); v__gen__c__Gen_write(g, elem_styp); v__gen__c__Gen_write(g, _S("*) _v_malloc((")); } v__gen__c__Gen_expr(g, node.len_expr); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(") * sizeof("), 0xfe10, {.d_s = elem_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); string ind = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, _S("for (int ")); v__gen__c__Gen_write(g, ind); v__gen__c__Gen_write(g, _S("=0; ")); v__gen__c__Gen_write(g, ind); v__gen__c__Gen_write(g, _S("<")); } v__gen__c__Gen_expr(g, node.len_expr); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("; "), 0xfe10, {.d_s = ind}}, {_S("++) {"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_write(g, ind); v__gen__c__Gen_write(g, _S("] = ")); } if (node.has_init) { v__gen__c__Gen_expr_with_init(g, node); } else { if (v__ast__Type_has_flag(node.elem_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_opt(g, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))), _const_v__ast__none_type, node.elem_type); } else { v__gen__c__Gen_write(g, v__gen__c__Gen_type_default(g, node.elem_type)); } } v__gen__c__Gen_writeln2(g, _S(";"), _S("}")); v__gen__c__Gen_write2(g, line, str_intp(2, _MOV((StrIntpData[]){{_S(" (voidptr)"), 0xfe10, {.d_s = tmp}}, {_S(")"), 0, { .d_c = 0 }}}))); } else if (node.has_init) { { v__gen__c__Gen_write(g, _S("&(")); v__gen__c__Gen_write(g, elem_styp); v__gen__c__Gen_write(g, _S("[]){")); } v__gen__c__Gen_expr_with_init(g, node); v__gen__c__Gen_write(g, _S("})")); } else if (node.has_len && v__ast__Type_has_flag(node.elem_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_write(g, _S("&")); v__gen__c__Gen_expr_with_opt(g, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))), _const_v__ast__none_type, node.elem_type); v__gen__c__Gen_write(g, _S(")")); } else if (node.has_len && node.elem_type == _const_v__ast__string_type) { v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_S("&("), 0xfe10, {.d_s = elem_styp}}, {_S("[]){"), 0, { .d_c = 0 }}})), _S("_S(\"\")")); v__gen__c__Gen_write(g, _S("})")); } else if (node.has_len && (elem_type.unaliased_sym->kind == v__ast__Kind__struct || elem_type.unaliased_sym->kind == v__ast__Kind__array || elem_type.unaliased_sym->kind == v__ast__Kind__map)) { v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_S("(voidptr)&("), 0xfe10, {.d_s = elem_styp}}, {_S("[]){"), 0, { .d_c = 0 }}})), v__gen__c__Gen_type_default(g, node.elem_type)); v__gen__c__Gen_write(g, _S("}[0])")); } else { v__gen__c__Gen_write(g, _S("0)")); } if (g->is_shared) { { v__gen__c__Gen_write(g, _S("}, sizeof(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("))")); } } else if (is_amp) { v__gen__c__Gen_write(g, _S(")")); } // Defer begin if (v__gen__c__Gen_array_init_with_fields_defer_1) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end // Defer begin if (v__gen__c__Gen_array_init_with_fields_defer_0) { g->inside_lambda = prev_inside_lambda; } // Defer end } VV_LOC void v__gen__c__Gen_declare_closure_fn(v__gen__c__Gen* g, v__ast__AnonFn* expr, string var_name) { Array_v__ast__Type _t1 = {0}; Array_v__ast__Param _t1_orig = expr->decl.params; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Param it = ((v__ast__Param*) _t1_orig.data)[_t3]; v__ast__Type _t2 = it.typ; array_push((array*)&_t1, &_t2); } string decl_var = v__gen__c__Gen_fn_var_signature(g, expr->decl.return_type,_t1, var_name); { v__gen__c__Gen_write(g, decl_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_gen_anon_fn(g, expr); v__gen__c__Gen_writeln(g, _S(";")); } VV_LOC void v__gen__c__Gen_write_closure_fn(v__gen__c__Gen* g, v__ast__AnonFn* expr, string var_name, string declared_var) { if ((declared_var).len == 0) { v__gen__c__PastTmpVar past = v__gen__c__Gen_past_tmp_var_new(g); v__gen__c__Gen_declare_closure_fn(g, expr, past.var_name); v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } else { { v__gen__c__Gen_write(g, declared_var); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } } VV_LOC void v__gen__c__Gen_gen_array_map(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_gen_array_map_defer_0 = false; bool prev_inside_lambda; bool v__gen__c__Gen_gen_array_map_defer_1 = false; v__gen__c__PastTmpVar past; prev_inside_lambda = g->inside_lambda; g->inside_lambda = true; v__gen__c__Gen_gen_array_map_defer_0 = true; past = v__gen__c__Gen_past_tmp_var_new(g); v__gen__c__Gen_gen_array_map_defer_1 = true; v__ast__Type _t1; /* if prepend */ if (v__type_resolver__TypeResolver_is_generic_expr(&g->type_resolver, (*(v__ast__CallArg*)array_get(node.args, 0)).expr)) { v__ast__Type ctyp = _const_v__ast__void_type; if (((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast(((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._v__ast__CallExpr,((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ, 344)).return_type_generic != 0 && v__ast__Type_has_flag((*(v__ast__CallExpr*)__as_cast(((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._v__ast__CallExpr,((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ, 344)).return_type_generic, v__ast__TypeFlag__generic)) { ctyp = v__gen__c__Gen_resolve_return_type(g, (*(*(v__ast__CallArg*)array_get(node.args, 0)).expr._v__ast__CallExpr)); if (Array_v__ast__Kind_contains(new_array_from_c_array(2, 2, sizeof(v__ast__Kind), _MOV((v__ast__Kind[2]){v__ast__Kind__array, v__ast__Kind__array_fixed})), v__ast__Table_type_kind(g->table, (*(*(v__ast__CallArg*)array_get(node.args, 0)).expr._v__ast__CallExpr).return_type_generic))) { ctyp = v__ast__new_type(v__ast__Table_find_or_register_array(g->table, ctyp)); } } if (ctyp == _const_v__ast__void_type) { ctyp = v__type_resolver__TypeResolver_unwrap_generic_expr(&g->type_resolver, (*(v__ast__CallArg*)array_get(node.args, 0)).expr, node.return_type); } _t1 = (!(Array_v__ast__Kind_contains(new_array_from_c_array(2, 2, sizeof(v__ast__Kind), _MOV((v__ast__Kind[2]){v__ast__Kind__array, v__ast__Kind__array_fixed})), v__ast__Table_type_kind(g->table, v__gen__c__Gen_unwrap_generic(g, ctyp)))) ? (v__ast__new_type(v__ast__Table_find_or_register_array(g->table, ctyp))) : (ctyp)); } else { _t1 = node.return_type; } v__ast__Type return_type = _t1; string ret_styp = v__gen__c__Gen_styp(g, return_type); v__ast__TypeSymbol* ret_sym = v__ast__Table_final_sym(g->table, return_type); bool left_is_array = v__ast__Table_final_sym(g->table, node.left_type)->kind == v__ast__Kind__array; v__ast__TypeSymbol* inp_sym = v__ast__Table_final_sym(g->table, node.receiver_type); v__ast__Type ret_elem_type = (left_is_array ? ((*(v__ast__Array*)__as_cast((ret_sym->info)._v__ast__Array,(ret_sym->info)._typ, 513)).elem_type) : ((*(v__ast__ArrayFixed*)__as_cast((ret_sym->info)._v__ast__ArrayFixed,(ret_sym->info)._typ, 549)).elem_type)); string ret_elem_styp = v__gen__c__Gen_styp(g, ret_elem_type); v__ast__Type inp_elem_type = (left_is_array ? ((*(v__ast__Array*)__as_cast((inp_sym->info)._v__ast__Array,(inp_sym->info)._typ, 513)).elem_type) : ((*(v__ast__ArrayFixed*)__as_cast((inp_sym->info)._v__ast__ArrayFixed,(inp_sym->info)._typ, 549)).elem_type)); string inp_elem_styp = v__gen__c__Gen_styp(g, inp_elem_type); if (!(inp_sym->kind == v__ast__Kind__array || inp_sym->kind == v__ast__Kind__array_fixed)) { v__gen__c__verror(_S("map() requires an array or a fixed array")); VUNREACHABLE(); } v__ast__Expr expr = (*(v__ast__CallArg*)array_get(node.args, 0)).expr; string closure_var_decl = _S(""); string tmp_map_expr_result_name = v__gen__c__Gen_new_tmp_var(g); if ((expr)._typ == 379 /* v.ast.SelectorExpr */) { if ((*expr._v__ast__SelectorExpr).typ != _const_v__ast__void_type) { v__ast__TypeSymbol* var_sym = v__ast__Table_sym(g->table, (*expr._v__ast__SelectorExpr).typ); if ((var_sym->info)._typ == 553 /* v.ast.FnType */) { ret_elem_styp = _S("voidptr"); Array_v__ast__Type _t2 = {0}; Array_v__ast__Param _t2_orig = (*var_sym->info._v__ast__FnType).func.params; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(v__ast__Type)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Param it = ((v__ast__Param*) _t2_orig.data)[_t4]; v__ast__Type _t3 = it.typ; array_push((array*)&_t2, &_t3); } closure_var_decl = v__gen__c__Gen_fn_var_signature(g, (*var_sym->info._v__ast__FnType).func.return_type,_t2, tmp_map_expr_result_name); } } } string noscan = v__gen__c__Gen_check_noscan(g, ret_elem_type); bool has_infix_left_var_name = v__gen__c__Gen_write_prepared_tmp_value(g, past.tmp_var, (voidptr)&node, ret_styp, _S("{0}")); if (left_is_array) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = past.tmp_var}}, {_S(" = __new_array"), 0xfe10, {.d_s = noscan}}, {_S("(0, "), 0xfe10, {.d_s = past.tmp_var}}, {_S("_len, sizeof("), 0xfe10, {.d_s = ret_elem_styp}}, {_S("));\n"), 0, { .d_c = 0 }}}))); } string closure_var = _S(""); if ((expr)._typ == 336 /* v.ast.AnonFn */) { if ((*expr._v__ast__AnonFn).inherited_vars.len > 0) { closure_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_declare_closure_fn(g, &/*mut*/(*expr._v__ast__AnonFn), closure_var); } } string i = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = i}}, {_S(" = 0; "), 0xfe10, {.d_s = i}}, {_S(" < "), 0xfe10, {.d_s = past.tmp_var}}, {_S("_len; ++"), 0xfe10, {.d_s = i}}, {_S(") {"), 0, { .d_c = 0 }}}))); g->indent++; string var_name = v__gen__c__Gen_get_array_expr_param_name(g, &expr); bool is_auto_heap = (expr)._typ == 345 /* v.ast.CastExpr */ && (((*(v__ast__CastExpr*)__as_cast((expr)._v__ast__CastExpr,(expr)._typ, 345)).expr)._typ == 358 /* v.ast.Ident */ && v__ast__Ident_is_auto_heap(((v__ast__Ident*)__as_cast((((v__ast__CastExpr*)__as_cast((expr)._v__ast__CastExpr,(expr)._typ, 345))->expr)._v__ast__Ident,(((v__ast__CastExpr*)__as_cast((expr)._v__ast__CastExpr,(expr)._typ, 345))->expr)._typ, 358)))); v__gen__c__Gen_write_prepared_var(g, var_name, inp_elem_type, inp_elem_styp, past.tmp_var, i, left_is_array, is_auto_heap); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); bool is_embed_map_filter = false; if (expr._typ == 336 /* v.ast.AnonFn */) { { v__gen__c__Gen_write(g, ret_elem_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_map_expr_result_name); v__gen__c__Gen_write(g, _S(" = ")); } if ((*expr._v__ast__AnonFn).inherited_vars.len > 0) { v__gen__c__Gen_write_closure_fn(g, &/*mut*/(*expr._v__ast__AnonFn), var_name, closure_var); } else { v__gen__c__Gen_gen_anon_fn_decl(g, &/*mut*/(*expr._v__ast__AnonFn)); { v__gen__c__Gen_write(g, (*expr._v__ast__AnonFn).decl.name); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } } else if (expr._typ == 358 /* v.ast.Ident */) { { v__gen__c__Gen_write(g, ret_elem_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_map_expr_result_name); v__gen__c__Gen_write(g, _S(" = ")); } if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__function) { if (((*expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast(((*expr._v__ast__Ident).obj)._v__ast__Var,((*expr._v__ast__Ident).obj)._typ, 422)).is_inherited) { v__gen__c__Gen_write(g, _S("_V_closure_ctx->")); } { v__gen__c__Gen_write(g, v__gen__c__c_name((*expr._v__ast__Ident).name)); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } else if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__variable) { v__ast__IdentVar var_info = v__ast__Ident_var_info(&(*expr._v__ast__Ident)); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, var_info.typ); if (sym->kind == v__ast__Kind__function) { if (((*expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast(((*expr._v__ast__Ident).obj)._v__ast__Var,((*expr._v__ast__Ident).obj)._typ, 422)).is_inherited) { v__gen__c__Gen_write(g, _S("_V_closure_ctx->")); } { v__gen__c__Gen_write(g, v__gen__c__c_name((*expr._v__ast__Ident).name)); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } else { v__gen__c__Gen_expr(g, expr); } } else { v__gen__c__Gen_expr(g, expr); } } else if (expr._typ == 344 /* v.ast.CallExpr */) { if (fast_string_eq((*expr._v__ast__CallExpr).name, _S("map")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("filter")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("all")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("any")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("count"))) { is_embed_map_filter = true; v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } { v__gen__c__Gen_write(g, ret_elem_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_map_expr_result_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, expr); } else if (expr._typ == 345 /* v.ast.CastExpr */) { if (((*expr._v__ast__CastExpr).expr)._typ == 358 /* v.ast.Ident */ && (node.left)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node.left)._v__ast__Ident,(node.left)._typ, 358)).ct_expr) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(&g->type_resolver, node.left); if (ctyp != _const_v__ast__void_type) { (*expr._v__ast__CastExpr).expr_type = v__ast__Table_value_type(g->table, ctyp); } } { v__gen__c__Gen_write(g, ret_elem_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_map_expr_result_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, expr); } else if (expr._typ == 365 /* v.ast.LambdaExpr */) { { v__gen__c__Gen_write(g, ret_elem_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_map_expr_result_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, (*expr._v__ast__LambdaExpr).expr); } else if (expr._typ == 379 /* v.ast.SelectorExpr */) { if ((*expr._v__ast__SelectorExpr).typ != _const_v__ast__void_type && v__ast__Table_final_sym(g->table, (*expr._v__ast__SelectorExpr).typ)->kind == v__ast__Kind__array_fixed) { string atype = v__gen__c__Gen_styp(g, (*expr._v__ast__SelectorExpr).typ); if ((closure_var_decl).len != 0) { { v__gen__c__Gen_write(g, _S("memcpy(&")); v__gen__c__Gen_write(g, closure_var_decl); v__gen__c__Gen_write(g, _S(", &")); } v__gen__c__Gen_expr(g, expr); { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, atype); v__gen__c__Gen_write(g, _S("))")); } } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_elem_styp}}, {_S(" "), 0xfe10, {.d_s = tmp_map_expr_result_name}}, {_S(";"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("memcpy(&")); v__gen__c__Gen_write(g, tmp_map_expr_result_name); v__gen__c__Gen_write(g, _S(", &")); } v__gen__c__Gen_expr(g, expr); { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, atype); v__gen__c__Gen_write(g, _S("))")); } } } else { if ((closure_var_decl).len != 0) { { v__gen__c__Gen_write(g, closure_var_decl); v__gen__c__Gen_write(g, _S(" = ")); } } else { { v__gen__c__Gen_write(g, ret_elem_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_map_expr_result_name); v__gen__c__Gen_write(g, _S(" = ")); } } v__gen__c__Gen_expr(g, expr); } } else if (expr._typ == 339 /* v.ast.AsCast */) { if (v__ast__Type_has_flag((*expr._v__ast__AsCast).typ, v__ast__TypeFlag__generic)) { ret_elem_styp = v__gen__c__Gen_styp(g, v__gen__c__Gen_unwrap_generic(g, (*expr._v__ast__AsCast).typ)); } { v__gen__c__Gen_write(g, ret_elem_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_map_expr_result_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, expr); } else { if ((closure_var_decl).len != 0) { { v__gen__c__Gen_write(g, closure_var_decl); v__gen__c__Gen_write(g, _S(" = ")); } } else { { v__gen__c__Gen_write(g, ret_elem_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_map_expr_result_name); v__gen__c__Gen_write(g, _S(" = ")); } } v__gen__c__Gen_expr(g, expr); } if (left_is_array) { v__gen__c__Gen_writeln2(g, _S(";"), str_intp(4, _MOV((StrIntpData[]){{_S("array_push"), 0xfe10, {.d_s = noscan}}, {_S("((array*)&"), 0xfe10, {.d_s = past.tmp_var}}, {_S(", &"), 0xfe10, {.d_s = tmp_map_expr_result_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln2(g, _S(";"), str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = past.tmp_var}}, {_S("["), 0xfe10, {.d_s = i}}, {_S("] = "), 0xfe10, {.d_s = tmp_map_expr_result_name}}, {_S(";"), 0, { .d_c = 0 }}}))); } g->indent--; v__gen__c__Gen_writeln(g, _S("}")); if (!is_embed_map_filter) { v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } if (has_infix_left_var_name) { g->indent--; v__gen__c__Gen_writeln(g, _S("}")); } // Defer begin if (v__gen__c__Gen_gen_array_map_defer_1) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end // Defer begin if (v__gen__c__Gen_gen_array_map_defer_0) { g->inside_lambda = prev_inside_lambda; } // Defer end } VV_LOC void v__gen__c__Gen_gen_array_sorted(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_gen_array_sorted_defer_0 = false; v__gen__c__PastTmpVar past; past = v__gen__c__Gen_past_tmp_var_new(g); v__gen__c__Gen_gen_array_sorted_defer_0 = true; string atype = v__gen__c__Gen_styp(g, node.return_type); v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, node.return_type); bool left_is_array = sym->kind == v__ast__Kind__array; v__ast__Type elem_type = (left_is_array ? ((*(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513)).elem_type) : ((*(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549)).elem_type)); if (left_is_array) { int depth = v__gen__c__Gen_get_array_depth(g, elem_type); bool deref_field = (v__ast__Type_nr_muls(node.receiver_type) > v__ast__Type_nr_muls(node.left_type) && v__ast__Type_is_ptr(node.left_type) ? (true) : (false)); if (!deref_field) { { v__gen__c__Gen_write(g, atype); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, past.tmp_var); v__gen__c__Gen_write(g, _S(" = array_clone_to_depth(ADDR(")); v__gen__c__Gen_write(g, atype); v__gen__c__Gen_write(g, _S(",")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("), "), 0xfe07, {.d_i32 = depth}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { { v__gen__c__Gen_write(g, atype); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, past.tmp_var); v__gen__c__Gen_write(g, _S(" = array_clone_to_depth(")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", "), 0xfe07, {.d_i32 = depth}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = atype}}, {_S(" "), 0xfe10, {.d_s = past.tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("memcpy(&")); v__gen__c__Gen_write(g, past.tmp_var); v__gen__c__Gen_write(g, _S(", &")); } if ((node.left)._typ == 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*node.left._v__ast__ArrayInit), node.left_type); } else { v__gen__c__Gen_expr(g, node.left); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = atype}}, {_S("));"), 0, { .d_c = 0 }}}))); } { // Unsafe block node.left = v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (((v__ast__Ident){.language = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comptime = 0,.scope = ((void*)0),.obj = _const_v__ast__empty_scope_object,.mod = (string){.str=(byteptr)"", .is_lit=1},.name = past.tmp_var,.full_name = (string){.str=(byteptr)"", .is_lit=1},.cached_name = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.info = (v__ast__IdentInfo){._v__ast__IdentFn=HEAP(v__ast__IdentFn, ((v__ast__IdentFn){.typ = 0,})),._typ=476},.is_mut = 0,.or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.ct_expr = 0,})))); } v__gen__c__Gen_gen_array_sort(g, node); v__gen__c__Gen_writeln(g, _S(";")); // Defer begin if (v__gen__c__Gen_gen_array_sorted_defer_0) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end } VV_LOC void v__gen__c__Gen_gen_array_sort(v__gen__c__Gen* g, v__ast__CallExpr node) { v__ast__TypeSymbol* rec_sym = v__ast__Table_final_sym(g->table, node.receiver_type); if (!(rec_sym->kind == v__ast__Kind__array || rec_sym->kind == v__ast__Kind__array_fixed)) { v__gen__c__verror(_S(".sort() is an array method or a fixed array method")); VUNREACHABLE(); } if (g->pref->is_bare) { v__gen__c__Gen_writeln(g, _S("bare_panic(_S(\"sort does not work with -freestanding\"))")); return; } bool left_is_array = rec_sym->kind == v__ast__Kind__array; v__ast__Type elem_type = (left_is_array ? ((*(v__ast__Array*)__as_cast((rec_sym->info)._v__ast__Array,(rec_sym->info)._typ, 513)).elem_type) : ((*(v__ast__ArrayFixed*)__as_cast((rec_sym->info)._v__ast__ArrayFixed,(rec_sym->info)._typ, 549)).elem_type)); string elem_stype = v__gen__c__Gen_styp(g, elem_type); string compare_fn = str_intp(3, _MOV((StrIntpData[]){{_S("compare_"), 0xfe08, {.d_u64 = g->unique_file_path_hash}}, {_S("_"), 0xfe10, {.d_s = string_replace(elem_stype, _S("*"), _S("_ptr"))}}, {_SLIT0, 0, { .d_c = 0 }}})); v__gen__c__Type comparison_type = v__gen__c__Gen_unwrap(g, _const_v__ast__void_type); string left_expr = _S(""); string right_expr = _S(""); bool use_lambda = false; string lambda_fn_name = _S(""); if (node.args.len == 0) { comparison_type = v__gen__c__Gen_unwrap(g, v__ast__Type_set_nr_muls(elem_type, 0)); sync__RwMutex_rlock(&g->array_sort_fn->mtx); /*lock*/ { if ((Array_string_contains(g->array_sort_fn->val, compare_fn))) { v__gen__c__Gen_gen_array_sort_call(g, node, compare_fn, left_is_array); sync__RwMutex_runlock(&g->array_sort_fn->mtx);return; } } sync__RwMutex_runlock(&g->array_sort_fn->mtx);; left_expr = _S("*a"); right_expr = _S("*b"); } else if (((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ == 365 /* v.ast.LambdaExpr */) { lambda_fn_name = (*(*(v__ast__CallArg*)array_get(node.args, 0)).expr._v__ast__LambdaExpr).func->decl.name; compare_fn = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = lambda_fn_name}}, {_S("_lambda_wrapper"), 0, { .d_c = 0 }}})); use_lambda = true; v__ast__LambdaExpr lambda_node = (*(*(v__ast__CallArg*)array_get(node.args, 0)).expr._v__ast__LambdaExpr); v__gen__c__Gen_gen_anon_fn_decl(g, lambda_node.func); } else { v__ast__InfixExpr infix_expr = *(v__ast__InfixExpr*)__as_cast(((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._v__ast__InfixExpr,((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ, 362); comparison_type = v__gen__c__Gen_unwrap(g, v__ast__Type_set_nr_muls(infix_expr.left_type, 0)); string left_name = v__ast__Expr_str(&infix_expr.left); if (left_name.len > 1) { compare_fn = string__plus(compare_fn, string__plus(_S("_by"), string_replace_each(string_substr(left_name, 1, 2147483647), new_array_from_c_array(18, 18, sizeof(string), _MOV((string[18]){ _S("."), _S("_"), _S("["), _S("_"), _S("]"), _S("_"), _S("'"), _S("_"), _S("\""), _S("_"), _S("("), _S(""), _S(")"), _S(""), _S(","), _S(""), _S("/"), _S("_")}))))); } bool is_reverse = (string_starts_with(left_name, _S("a")) && infix_expr.op == v__token__Kind__gt) || (string_starts_with(left_name, _S("b")) && infix_expr.op == v__token__Kind__lt); if (is_reverse) { compare_fn = string__plus(compare_fn, _S("_reverse")); } sync__RwMutex_rlock(&g->array_sort_fn->mtx); /*lock*/ { if ((Array_string_contains(g->array_sort_fn->val, compare_fn))) { v__gen__c__Gen_gen_array_sort_call(g, node, compare_fn, left_is_array); sync__RwMutex_runlock(&g->array_sort_fn->mtx);return; } } sync__RwMutex_runlock(&g->array_sort_fn->mtx);; if (string_starts_with(left_name, _S("a")) != is_reverse) { left_expr = v__gen__c__Gen_expr_string(g, infix_expr.left); right_expr = v__gen__c__Gen_expr_string(g, infix_expr.right); if ((infix_expr.left)._typ == 358 /* v.ast.Ident */) { left_expr = string__plus(_S("*"), left_expr); } if ((infix_expr.right)._typ == 358 /* v.ast.Ident */) { right_expr = string__plus(_S("*"), right_expr); } } else { left_expr = v__gen__c__Gen_expr_string(g, infix_expr.right); right_expr = v__gen__c__Gen_expr_string(g, infix_expr.left); if ((infix_expr.left)._typ == 358 /* v.ast.Ident */) { right_expr = string__plus(_S("*"), right_expr); } if ((infix_expr.right)._typ == 358 /* v.ast.Ident */) { left_expr = string__plus(_S("*"), left_expr); } } } sync__RwMutex_lock(&g->array_sort_fn->mtx); /*lock*/ { array_push((array*)&g->array_sort_fn->val, _MOV((string[]){ string_clone(compare_fn) })); } sync__RwMutex_unlock(&g->array_sort_fn->mtx);; string stype_arg = v__gen__c__Gen_styp(g, elem_type); strings__Builder_writeln(&g->sort_fn_definitions, str_intp(5, _MOV((StrIntpData[]){{_S("VV_LOC "), 0xfe10, {.d_s = g->static_modifier}}, {_S(" int "), 0xfe10, {.d_s = compare_fn}}, {_S("("), 0xfe10, {.d_s = stype_arg}}, {_S("* a, "), 0xfe10, {.d_s = stype_arg}}, {_S("* b) {"), 0, { .d_c = 0 }}}))); string c_condition = (v__ast__TypeSymbol_has_method(comparison_type.sym, _S("<")) ? (str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, comparison_type.typ)}}, {_S("__lt("), 0xfe10, {.d_s = left_expr}}, {_S(", "), 0xfe10, {.d_s = right_expr}}, {_S(")"), 0, { .d_c = 0 }}}))) : v__ast__TypeSymbol_has_method(comparison_type.unaliased_sym, _S("<")) ? (str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, comparison_type.unaliased)}}, {_S("__lt("), 0xfe10, {.d_s = left_expr}}, {_S(", "), 0xfe10, {.d_s = right_expr}}, {_S(")"), 0, { .d_c = 0 }}}))) : use_lambda ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = lambda_fn_name}}, {_S("(a, b)"), 0, { .d_c = 0 }}}))) : (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = left_expr}}, {_S(" < "), 0xfe10, {.d_s = right_expr}}, {_SLIT0, 0, { .d_c = 0 }}})))); strings__Builder_writeln(&g->sort_fn_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = c_condition}}, {_S(") return -1;"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->sort_fn_definitions, _S("\telse return 1;")); strings__Builder_writeln(&g->sort_fn_definitions, _S("}\n")); v__gen__c__Gen_gen_array_sort_call(g, node, compare_fn, left_is_array); } VV_LOC void v__gen__c__Gen_gen_array_sort_call(v__gen__c__Gen* g, v__ast__CallExpr node, string compare_fn, bool is_array) { string deref_field = (v__ast__Type_nr_muls(node.receiver_type) > v__ast__Type_nr_muls(node.left_type) && v__ast__Type_is_ptr(node.left_type) ? (v__gen__c__Gen_dot_or_ptr(g, v__ast__Type_deref(node.left_type))) : (v__gen__c__Gen_dot_or_ptr(g, node.left_type))); g->empty_line = true; if (is_array) { v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = deref_field}}, {_S("len > 0) { "), 0, { .d_c = 0 }}})), _S("qsort(")); v__gen__c__Gen_expr(g, node.left); { v__gen__c__Gen_write(g, deref_field); v__gen__c__Gen_write(g, _S("data, ")); } v__gen__c__Gen_expr(g, node.left); { v__gen__c__Gen_write(g, deref_field); v__gen__c__Gen_write(g, _S("len, ")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write2(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = deref_field}}, {_S("element_size, (voidptr)"), 0xfe10, {.d_s = compare_fn}}, {_S(");"), 0, { .d_c = 0 }}})), _S(" }")); } else { v__ast__ArrayFixed info = ({ v__ast__TypeInfo _t1 = v__ast__Table_final_sym(g->table, node.left_type)->info; *(v__ast__ArrayFixed*)__as_cast(_t1._v__ast__ArrayFixed,_t1._typ, 549); }); string elem_styp = v__gen__c__Gen_styp(g, info.elem_type); v__gen__c__Gen_write(g, _S("qsort(&")); v__gen__c__Gen_expr(g, node.left); { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, info.size); v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, elem_styp); v__gen__c__Gen_write(g, _S("), (voidptr)")); v__gen__c__Gen_write(g, compare_fn); v__gen__c__Gen_write(g, _S(");")); } } v__gen__c__Gen_writeln(g, _S("")); } VV_LOC void v__gen__c__Gen_gen_fixed_array_sorted_with_compare(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_gen_fixed_array_sorted_with_compare_defer_0 = false; v__gen__c__PastTmpVar past; past = v__gen__c__Gen_past_tmp_var_new(g); v__gen__c__Gen_gen_fixed_array_sorted_with_compare_defer_0 = true; string atype = v__gen__c__Gen_styp(g, node.return_type); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = atype}}, {_S(" "), 0xfe10, {.d_s = past.tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("memcpy(&")); v__gen__c__Gen_write(g, past.tmp_var); v__gen__c__Gen_write(g, _S(", &")); } if ((node.left)._typ == 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*node.left._v__ast__ArrayInit), node.left_type); } else { v__gen__c__Gen_expr(g, node.left); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = atype}}, {_S("));"), 0, { .d_c = 0 }}}))); { // Unsafe block node.left = v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (((v__ast__Ident){.language = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comptime = 0,.scope = ((void*)0),.obj = _const_v__ast__empty_scope_object,.mod = (string){.str=(byteptr)"", .is_lit=1},.name = past.tmp_var,.full_name = (string){.str=(byteptr)"", .is_lit=1},.cached_name = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.info = (v__ast__IdentInfo){._v__ast__IdentFn=HEAP(v__ast__IdentFn, ((v__ast__IdentFn){.typ = 0,})),._typ=476},.is_mut = 0,.or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.ct_expr = 0,})))); } v__gen__c__Gen_gen_fixed_array_sort_with_compare(g, node); // Defer begin if (v__gen__c__Gen_gen_fixed_array_sorted_with_compare_defer_0) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end } VV_LOC void v__gen__c__Gen_gen_fixed_array_sort_with_compare(v__gen__c__Gen* g, v__ast__CallExpr node) { string compare_fn = _S(""); if (((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ == 365 /* v.ast.LambdaExpr */) { string lambda_fn_name = (*(*(v__ast__CallArg*)array_get(node.args, 0)).expr._v__ast__LambdaExpr).func->decl.name; compare_fn = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = lambda_fn_name}}, {_S("_lambda_wrapper"), 0, { .d_c = 0 }}})); v__ast__LambdaExpr lambda_node = (*(*(v__ast__CallArg*)array_get(node.args, 0)).expr._v__ast__LambdaExpr); v__gen__c__Gen_gen_anon_fn_decl(g, lambda_node.func); } else if (((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ == 336 /* v.ast.AnonFn */) { v__ast__AnonFn fn_expr = (*(*(v__ast__CallArg*)array_get(node.args, 0)).expr._v__ast__AnonFn); v__gen__c__Gen_gen_anon_fn_decl(g, (voidptr)&fn_expr); compare_fn = (*(*(v__ast__CallArg*)array_get(node.args, 0)).expr._v__ast__AnonFn).decl.name; } else if (((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ == 358 /* v.ast.Ident */) { compare_fn = (*(*(v__ast__CallArg*)array_get(node.args, 0)).expr._v__ast__Ident).name; } else { compare_fn = v__ast__Expr_str(&(*(v__ast__CallArg*)array_get(node.args, 0)).expr); } v__gen__c__Gen_gen_array_sort_call(g, node, compare_fn, false); } VV_LOC void v__gen__c__Gen_gen_fixed_array_reverse(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_gen_fixed_array_reverse_defer_0 = false; v__gen__c__PastTmpVar past; past = v__gen__c__Gen_past_tmp_var_new(g); v__gen__c__Gen_gen_fixed_array_reverse_defer_0 = true; string atype = v__gen__c__Gen_styp(g, node.return_type); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = atype}}, {_S(" "), 0xfe10, {.d_s = past.tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("memcpy(&")); v__gen__c__Gen_write(g, past.tmp_var); v__gen__c__Gen_write(g, _S(", &")); } if ((node.left)._typ == 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*node.left._v__ast__ArrayInit), node.left_type); } else { v__gen__c__Gen_expr(g, node.left); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = atype}}, {_S("));"), 0, { .d_c = 0 }}}))); { // Unsafe block node.left = v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (((v__ast__Ident){.language = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comptime = 0,.scope = ((void*)0),.obj = _const_v__ast__empty_scope_object,.mod = (string){.str=(byteptr)"", .is_lit=1},.name = past.tmp_var,.full_name = (string){.str=(byteptr)"", .is_lit=1},.cached_name = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.info = (v__ast__IdentInfo){._v__ast__IdentFn=HEAP(v__ast__IdentFn, ((v__ast__IdentFn){.typ = 0,})),._typ=476},.is_mut = 0,.or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.ct_expr = 0,})))); } v__gen__c__Gen_gen_fixed_array_reverse_in_place(g, node); // Defer begin if (v__gen__c__Gen_gen_fixed_array_reverse_defer_0) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end } VV_LOC void v__gen__c__Gen_gen_fixed_array_reverse_in_place(v__gen__c__Gen* g, v__ast__CallExpr node) { v__ast__TypeSymbol* left_sym = v__ast__Table_final_sym(g->table, node.left_type); v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((left_sym->info)._v__ast__ArrayFixed,(left_sym->info)._typ, 549); v__ast__Type elem_type = info.elem_type; string elem_styp = v__gen__c__Gen_styp(g, elem_type); string tmp_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = elem_styp}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); string i = v__gen__c__Gen_new_tmp_var(g); string left_var = v__gen__c__Gen_expr_string(g, node.left); g->empty_line = true; v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = i}}, {_S(" = 0; "), 0xfe10, {.d_s = i}}, {_S(" < "), 0xfe07, {.d_i32 = info.size}}, {_S("/2; ++"), 0xfe10, {.d_s = i}}, {_S(") {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\tmemcpy(&"), 0xfe10, {.d_s = tmp_var}}, {_S(", &"), 0xfe10, {.d_s = left_var}}, {_S("["), 0xfe10, {.d_s = i}}, {_S("], sizeof("), 0xfe10, {.d_s = elem_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(7, _MOV((StrIntpData[]){{_S("\tmemcpy(&"), 0xfe10, {.d_s = left_var}}, {_S("["), 0xfe10, {.d_s = i}}, {_S("], &"), 0xfe10, {.d_s = left_var}}, {_S("["), 0xfe07, {.d_i32 = info.size}}, {_S("-"), 0xfe10, {.d_s = i}}, {_S("-1], sizeof("), 0xfe10, {.d_s = elem_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("\tmemcpy(&"), 0xfe10, {.d_s = left_var}}, {_S("["), 0xfe07, {.d_i32 = info.size}}, {_S("-"), 0xfe10, {.d_s = i}}, {_S("-1], &"), 0xfe10, {.d_s = tmp_var}}, {_S(", sizeof("), 0xfe10, {.d_s = elem_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("}")); } VV_LOC void v__gen__c__Gen_gen_array_filter(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_gen_array_filter_defer_0 = false; v__gen__c__PastTmpVar past; past = v__gen__c__Gen_past_tmp_var_new(g); v__gen__c__Gen_gen_array_filter_defer_0 = true; v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, node.return_type); if (sym->kind != v__ast__Kind__array) { v__gen__c__verror(_S("filter() requires an array")); VUNREACHABLE(); } v__ast__Array info = *(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513); string styp = v__gen__c__Gen_styp(g, node.return_type); string elem_type_str = v__gen__c__Gen_styp(g, info.elem_type); string noscan = v__gen__c__Gen_check_noscan(g, info.elem_type); bool has_infix_left_var_name = v__gen__c__Gen_write_prepared_tmp_value(g, past.tmp_var, (voidptr)&node, styp, _S("{0}")); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = past.tmp_var}}, {_S(" = __new_array"), 0xfe10, {.d_s = noscan}}, {_S("(0, "), 0xfe10, {.d_s = past.tmp_var}}, {_S("_len, sizeof("), 0xfe10, {.d_s = elem_type_str}}, {_S("));\n"), 0, { .d_c = 0 }}}))); v__ast__Expr expr = (*(v__ast__CallArg*)array_get(node.args, 0)).expr; string var_name = v__gen__c__Gen_get_array_expr_param_name(g, &expr); string closure_var = _S(""); if ((expr)._typ == 336 /* v.ast.AnonFn */) { if ((*expr._v__ast__AnonFn).inherited_vars.len > 0) { closure_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_declare_closure_fn(g, &/*mut*/(*expr._v__ast__AnonFn), closure_var); } } string i = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = i}}, {_S(" = 0; "), 0xfe10, {.d_s = i}}, {_S(" < "), 0xfe10, {.d_s = past.tmp_var}}, {_S("_len; ++"), 0xfe10, {.d_s = i}}, {_S(") {"), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_write_prepared_var(g, var_name, info.elem_type, elem_type_str, past.tmp_var, i, true, false); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); bool is_embed_map_filter = false; if (expr._typ == 336 /* v.ast.AnonFn */) { v__gen__c__Gen_write(g, _S("if (")); if ((*expr._v__ast__AnonFn).inherited_vars.len > 0) { v__gen__c__Gen_write_closure_fn(g, &/*mut*/(*expr._v__ast__AnonFn), var_name, closure_var); } else { v__gen__c__Gen_gen_anon_fn_decl(g, &/*mut*/(*expr._v__ast__AnonFn)); { v__gen__c__Gen_write(g, (*expr._v__ast__AnonFn).decl.name); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } } else if (expr._typ == 358 /* v.ast.Ident */) { v__gen__c__Gen_write(g, _S("if (")); if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__function) { { v__gen__c__Gen_write(g, v__gen__c__c_name((*expr._v__ast__Ident).name)); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } else if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__variable) { v__ast__IdentVar var_info = v__ast__Ident_var_info(&(*expr._v__ast__Ident)); v__ast__TypeSymbol* sym_t = v__ast__Table_sym(g->table, var_info.typ); if (sym_t->kind == v__ast__Kind__function) { { v__gen__c__Gen_write(g, v__gen__c__c_name((*expr._v__ast__Ident).name)); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } else { v__gen__c__Gen_expr(g, expr); } } else { v__gen__c__Gen_expr(g, expr); } } else if (expr._typ == 344 /* v.ast.CallExpr */) { if (fast_string_eq((*expr._v__ast__CallExpr).name, _S("map")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("filter")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("all")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("any")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("count"))) { is_embed_map_filter = true; v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_expr(g, expr); } else if (expr._typ == 365 /* v.ast.LambdaExpr */) { v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_expr(g, (*expr._v__ast__LambdaExpr).expr); } else { v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_expr(g, expr); } v__gen__c__Gen_writeln2(g, _S(") {"), str_intp(4, _MOV((StrIntpData[]){{_S("\tarray_push"), 0xfe10, {.d_s = noscan}}, {_S("((array*)&"), 0xfe10, {.d_s = past.tmp_var}}, {_S(", &"), 0xfe10, {.d_s = var_name}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("}")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); if (!is_embed_map_filter) { v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } if (has_infix_left_var_name) { g->indent--; v__gen__c__Gen_writeln(g, _S("}")); } // Defer begin if (v__gen__c__Gen_gen_array_filter_defer_0) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end } VV_LOC void v__gen__c__Gen_gen_array_insert(v__gen__c__Gen* g, v__ast__CallExpr node) { v__ast__TypeSymbol* left_sym = v__ast__Table_final_sym(g->table, node.left_type); v__ast__Array left_info = *(v__ast__Array*)__as_cast((left_sym->info)._v__ast__Array,(left_sym->info)._typ, 513); string elem_type_str = v__gen__c__Gen_styp(g, left_info.elem_type); v__ast__TypeSymbol* arg2_sym = v__ast__Table_final_sym(g->table, (*(v__ast__CallArg*)array_get(node.args, 1)).typ); bool is_arg2_array = arg2_sym->kind == v__ast__Kind__array && v__ast__Table_unaliased_type(g->table, v__ast__Type_clear_flag((*(v__ast__CallArg*)array_get(node.args, 1)).typ, v__ast__TypeFlag__variadic)) == v__ast__Table_unaliased_type(g->table, node.left_type); string noscan = v__gen__c__Gen_check_noscan(g, left_info.elem_type); string addr = (v__ast__Type_is_ptr(node.left_type) ? (_S("")) : (_S("&"))); if (is_arg2_array) { { v__gen__c__Gen_write(g, _S("array_insert_many")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, addr); } } else { { v__gen__c__Gen_write(g, _S("array_insert")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, addr); } } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 0)).expr); if (is_arg2_array) { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 1)).expr); v__gen__c__Gen_write(g, _S(".data, ")); v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 1)).expr); v__gen__c__Gen_write(g, _S(".len)")); } else { bool needs_clone = left_info.elem_type == _const_v__ast__string_type && !(((*(v__ast__CallArg*)array_get(node.args, 1)).expr)._typ == 361 /* v.ast.IndexExpr */ || ((*(v__ast__CallArg*)array_get(node.args, 1)).expr)._typ == 344 /* v.ast.CallExpr */ || ((*(v__ast__CallArg*)array_get(node.args, 1)).expr)._typ == 384 /* v.ast.StringLiteral */ || ((*(v__ast__CallArg*)array_get(node.args, 1)).expr)._typ == 383 /* v.ast.StringInterLiteral */ || ((*(v__ast__CallArg*)array_get(node.args, 1)).expr)._typ == 362 /* v.ast.InfixExpr */); { v__gen__c__Gen_write(g, _S(", &(")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("[]){")); } if (needs_clone) { v__gen__c__Gen_write(g, _S("string_clone(")); } v__gen__c__Gen_expr_with_cast(g, (*(v__ast__CallArg*)array_get(node.args, 1)).expr, (*(v__ast__CallArg*)array_get(node.args, 1)).typ, left_info.elem_type); if (needs_clone) { v__gen__c__Gen_write(g, _S(")")); } v__gen__c__Gen_write(g, _S("})")); } } VV_LOC void v__gen__c__Gen_gen_array_prepend(v__gen__c__Gen* g, v__ast__CallExpr node) { v__ast__TypeSymbol* left_sym = v__ast__Table_final_sym(g->table, node.left_type); v__ast__Array left_info = *(v__ast__Array*)__as_cast((left_sym->info)._v__ast__Array,(left_sym->info)._typ, 513); string elem_type_str = v__gen__c__Gen_styp(g, left_info.elem_type); v__ast__TypeSymbol* arg_sym = v__ast__Table_final_sym(g->table, (*(v__ast__CallArg*)array_get(node.args, 0)).typ); bool is_arg_array = arg_sym->kind == v__ast__Kind__array && v__ast__Table_unaliased_type(g->table, (*(v__ast__CallArg*)array_get(node.args, 0)).typ) == v__ast__Table_unaliased_type(g->table, node.left_type); string noscan = v__gen__c__Gen_check_noscan(g, left_info.elem_type); string addr = (v__ast__Type_is_ptr(node.left_type) ? (_S("")) : (_S("&"))); if (is_arg_array) { { v__gen__c__Gen_write(g, _S("array_prepend_many")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, addr); } } else { { v__gen__c__Gen_write(g, _S("array_prepend")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, addr); } } v__gen__c__Gen_expr(g, node.left); if (is_arg_array) { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 0)).expr); v__gen__c__Gen_write(g, _S(".data, ")); v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 0)).expr); v__gen__c__Gen_write(g, _S(".len)")); } else { { v__gen__c__Gen_write(g, _S(", &(")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("[]){")); } v__gen__c__Gen_expr_with_cast(g, (*(v__ast__CallArg*)array_get(node.args, 0)).expr, (*(v__ast__CallArg*)array_get(node.args, 0)).typ, left_info.elem_type); v__gen__c__Gen_write(g, _S("})")); } } VV_LOC string v__gen__c__Gen_get_array_contains_method(v__gen__c__Gen* g, v__ast__Type typ) { int t = v__ast__Table_final_sym(g->table, v__ast__Type_set_nr_muls(v__gen__c__Gen_unwrap_generic(g, typ), 0))->idx; array_push((array*)&g->array_contains_types, _MOV((v__ast__Type[]){ t })); return string__plus(v__gen__c__Gen_styp(g, v__ast__idx_to_type(t)), _S("_contains")); } VV_LOC void v__gen__c__Gen_gen_array_contains_methods(v__gen__c__Gen* g) { Array_v__ast__Type done = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); bool got_int_str = false; #if defined(CUSTOM_DEFINE_new_int) { println(Array_v__ast__Type_str(g->array_contains_types)); } #endif for (int _t2 = 0; _t2 < g->array_contains_types.len; ++_t2) { v__ast__Type t = ((v__ast__Type*)g->array_contains_types.data)[_t2]; v__ast__TypeSymbol* left_final_sym = v__ast__Table_final_sym(g->table, t); if ((Array_v__ast__Type_contains(done, left_final_sym->idx)) || v__ast__TypeSymbol_has_method(v__ast__Table_sym(g->table, t), _S("contains"))) { continue; } array_push((array*)&done, _MOV((v__ast__Type[]){ t })); strings__Builder fn_builder = strings__new_builder(512); string left_type_str = v__gen__c__Gen_styp(g, t); string fn_name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = left_type_str}}, {_S("_contains"), 0, { .d_c = 0 }}})); #if defined(CUSTOM_DEFINE_new_int) { if (_SLIT_EQ(fn_name.str, fn_name.len, "Array_i64_contains")) { if (got_int_str) { continue; } else { got_int_str = true; } } } #endif if (left_final_sym->kind == v__ast__Kind__array) { v__ast__Type elem_type = (*(v__ast__Array*)__as_cast((left_final_sym->info)._v__ast__Array,(left_final_sym->info)._typ, 513)).elem_type; string elem_type_str = v__gen__c__Gen_styp(g, elem_type); v__ast__Kind elem_kind = v__ast__Table_sym(g->table, elem_type)->kind; bool elem_is_not_ptr = v__ast__Type_nr_muls(elem_type) == 0; if (elem_kind == v__ast__Kind__function) { left_type_str = _S("Array_voidptr"); elem_type_str = _S("voidptr"); } strings__Builder_writeln(&g->type_definitions, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("bool "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = left_type_str}}, {_S(" a, "), 0xfe10, {.d_s = elem_type_str}}, {_S(" v);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("bool "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = left_type_str}}, {_S(" a, "), 0xfe10, {.d_s = elem_type_str}}, {_S(" v) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\tfor (int i = 0; i < a.len; ++i) {")); if (elem_kind == v__ast__Kind__string) { strings__Builder_writeln(&fn_builder, _S("\t\tif (fast_string_eq(((string*)a.data)[i], v)) {")); } else if ((elem_kind == v__ast__Kind__array || elem_kind == v__ast__Kind__array_fixed) && elem_is_not_ptr) { string ptr_typ = v__gen__c__Gen_equality_fn(g, elem_type); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_arr_eq((("), 0xfe10, {.d_s = elem_type_str}}, {_S("*)a.data)[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_kind == v__ast__Kind__function) { strings__Builder_writeln(&fn_builder, _S("\t\tif (((voidptr*)a.data)[i] == v) {")); } else if (elem_kind == v__ast__Kind__map && elem_is_not_ptr) { string ptr_typ = v__gen__c__Gen_equality_fn(g, elem_type); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_map_eq((("), 0xfe10, {.d_s = elem_type_str}}, {_S("*)a.data)[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_kind == v__ast__Kind__struct && elem_is_not_ptr) { string ptr_typ = v__gen__c__Gen_equality_fn(g, elem_type); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_struct_eq((("), 0xfe10, {.d_s = elem_type_str}}, {_S("*)a.data)[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_kind == v__ast__Kind__interface && elem_is_not_ptr) { string ptr_typ = v__gen__c__Gen_equality_fn(g, elem_type); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_interface_eq((("), 0xfe10, {.d_s = elem_type_str}}, {_S("*)a.data)[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_kind == v__ast__Kind__sum_type && elem_is_not_ptr) { string ptr_typ = v__gen__c__Gen_equality_fn(g, elem_type); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_sumtype_eq((("), 0xfe10, {.d_s = elem_type_str}}, {_S("*)a.data)[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_kind == v__ast__Kind__alias && elem_is_not_ptr) { if ((*(bool*)map_get(ADDR(map, g->no_eq_method_types), &(v__ast__Type[]){elem_type}, &(bool[]){ 0 }))) { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ((("), 0xfe10, {.d_s = elem_type_str}}, {_S("*)a.data)[i] == v) {"), 0, { .d_c = 0 }}}))); } else { string ptr_typ = v__gen__c__Gen_equality_fn(g, elem_type); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_alias_eq((("), 0xfe10, {.d_s = elem_type_str}}, {_S("*)a.data)[i], v)) {"), 0, { .d_c = 0 }}}))); } } else { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ((("), 0xfe10, {.d_s = elem_type_str}}, {_S("*)a.data)[i] == v) {"), 0, { .d_c = 0 }}}))); } } else if (left_final_sym->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed left_info = *(v__ast__ArrayFixed*)__as_cast((left_final_sym->info)._v__ast__ArrayFixed,(left_final_sym->info)._typ, 549); int size = left_info.size; v__ast__Type elem_type = left_info.elem_type; string elem_type_str = v__gen__c__Gen_styp(g, elem_type); v__ast__Kind elem_kind = v__ast__Table_sym(g->table, elem_type)->kind; bool elem_is_not_ptr = v__ast__Type_nr_muls(elem_type) == 0; if (elem_kind == v__ast__Kind__function) { elem_type_str = _S("voidptr"); } strings__Builder_writeln(&g->type_definitions, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("bool "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = left_type_str}}, {_S(" a, "), 0xfe10, {.d_s = elem_type_str}}, {_S(" v);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("bool "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = left_type_str}}, {_S(" a, "), 0xfe10, {.d_s = elem_type_str}}, {_S(" v) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tfor (int i = 0; i < "), 0xfe07, {.d_i32 = size}}, {_S("; ++i) {"), 0, { .d_c = 0 }}}))); if (elem_kind == v__ast__Kind__string) { strings__Builder_writeln(&fn_builder, _S("\t\tif (fast_string_eq(a[i], v)) {")); } else if ((elem_kind == v__ast__Kind__array || elem_kind == v__ast__Kind__array_fixed) && elem_is_not_ptr) { string ptr_typ = v__gen__c__Gen_equality_fn(g, left_info.elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_arr_eq(a[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_kind == v__ast__Kind__function) { strings__Builder_writeln(&fn_builder, _S("\t\tif (a[i] == v) {")); } else if (elem_kind == v__ast__Kind__map && elem_is_not_ptr) { string ptr_typ = v__gen__c__Gen_equality_fn(g, elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_map_eq(a[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_kind == v__ast__Kind__struct && elem_is_not_ptr) { string ptr_typ = v__gen__c__Gen_equality_fn(g, elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_struct_eq(a[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_kind == v__ast__Kind__interface && elem_is_not_ptr) { string ptr_typ = v__gen__c__Gen_equality_fn(g, elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_interface_eq(a[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_kind == v__ast__Kind__sum_type && elem_is_not_ptr) { string ptr_typ = v__gen__c__Gen_equality_fn(g, elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_sumtype_eq(a[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_kind == v__ast__Kind__alias && elem_is_not_ptr) { if ((*(bool*)map_get(ADDR(map, g->no_eq_method_types), &(v__ast__Type[]){elem_type}, &(bool[]){ 0 }))) { strings__Builder_writeln(&fn_builder, _S("\t\tif (a[i] == v) {")); } else { string ptr_typ = v__gen__c__Gen_equality_fn(g, elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_alias_eq(a[i], v)) {"), 0, { .d_c = 0 }}}))); } } else { strings__Builder_writeln(&fn_builder, _S("\t\tif (a[i] == v) {")); } } strings__Builder_writeln(&fn_builder, _S("\t\t\treturn true;")); strings__Builder_writeln(&fn_builder, _S("\t\t}")); strings__Builder_writeln(&fn_builder, _S("\t}")); strings__Builder_writeln(&fn_builder, _S("\treturn false;")); strings__Builder_writeln(&fn_builder, _S("}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } } VV_LOC void v__gen__c__Gen_gen_array_contains(v__gen__c__Gen* g, v__ast__Type left_type, v__ast__Expr left, v__ast__Type right_type, v__ast__Expr right) { string fn_name = v__gen__c__Gen_get_array_contains_method(g, left_type); v__ast__TypeSymbol* left_sym = v__ast__Table_final_sym(g->table, left_type); v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_name}}, {_S("("), 0, { .d_c = 0 }}})), strings__repeat('*', v__ast__Type_nr_muls(left_type))); if (v__ast__Type_share(left_type) == v__ast__ShareType__shared_t) { v__gen__c__Gen_go_back(g, 1); } if (left_sym->kind == v__ast__Kind__array_fixed && (left)._typ == 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*left._v__ast__ArrayInit), left_type); } else { v__gen__c__Gen_expr(g, left); } if (v__ast__Type_share(left_type) == v__ast__ShareType__shared_t) { v__gen__c__Gen_write(g, _S("->val")); } v__gen__c__Gen_write(g, _S(", ")); v__ast__Type elem_typ = (left_sym->kind == v__ast__Kind__array ? (v__ast__TypeSymbol_array_info(left_sym).elem_type) : (v__ast__TypeSymbol_array_fixed_info(left_sym).elem_type)); bool is_auto_deref_var = v__ast__Expr_is_auto_deref_var(right); if ((is_auto_deref_var && !v__ast__Type_is_ptr(elem_typ)) || (!(v__ast__Table_sym(g->table, elem_typ)->kind == v__ast__Kind__interface || v__ast__Table_sym(g->table, elem_typ)->kind == v__ast__Kind__sum_type || v__ast__Table_sym(g->table, elem_typ)->kind == v__ast__Kind__struct) && (right)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((right)._v__ast__Ident,(right)._typ, 358)).info)._typ == 477 /* v.ast.IdentVar */ && (v__ast__Table_sym(g->table, (*((*(v__ast__Ident*)__as_cast((right)._v__ast__Ident,(right)._typ, 358)).obj.typ)))->kind == v__ast__Kind__interface || v__ast__Table_sym(g->table, (*((*(v__ast__Ident*)__as_cast((right)._v__ast__Ident,(right)._typ, 358)).obj.typ)))->kind == v__ast__Kind__sum_type))) { v__gen__c__Gen_write(g, _S("*")); } if (v__ast__Table_sym(g->table, elem_typ)->kind == v__ast__Kind__interface || v__ast__Table_sym(g->table, elem_typ)->kind == v__ast__Kind__sum_type) { v__gen__c__Gen_expr_with_cast(g, right, right_type, elem_typ); } else if ((right)._typ == 338 /* v.ast.ArrayInit */ && v__ast__Table_final_sym(g->table, right_type)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*right._v__ast__ArrayInit), right_type); } else { v__gen__c__Gen_expr(g, right); } v__gen__c__Gen_write(g, _S(")")); } VV_LOC string v__gen__c__Gen_get_array_index_method(v__gen__c__Gen* g, v__ast__Type typ) { v__ast__Type t = v__ast__Type_set_nr_muls(v__gen__c__Gen_unwrap_generic(g, typ), 0); array_push((array*)&g->array_index_types, _MOV((v__ast__Type[]){ t })); return string__plus(v__gen__c__Gen_styp(g, t), _S("_index")); } VV_LOC void v__gen__c__Gen_gen_array_index_methods(v__gen__c__Gen* g) { Array_v__ast__Type done = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t1 = 0; _t1 < g->array_index_types.len; ++_t1) { v__ast__Type t = ((v__ast__Type*)g->array_index_types.data)[_t1]; if ((Array_v__ast__Type_contains(done, t)) || v__ast__TypeSymbol_has_method(v__ast__Table_sym(g->table, t), _S("index"))) { continue; } array_push((array*)&done, _MOV((v__ast__Type[]){ t })); v__ast__TypeSymbol* final_left_sym = v__ast__Table_final_sym(g->table, t); string left_type_str = v__gen__c__Gen_styp(g, t); string fn_name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = left_type_str}}, {_S("_index"), 0, { .d_c = 0 }}})); strings__Builder fn_builder = strings__new_builder(512); if (final_left_sym->kind == v__ast__Kind__array) { v__ast__Array info = *(v__ast__Array*)__as_cast((final_left_sym->info)._v__ast__Array,(final_left_sym->info)._typ, 513); string elem_type_str = v__gen__c__Gen_styp(g, info.elem_type); v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, info.elem_type); if (elem_sym->kind == v__ast__Kind__function) { left_type_str = _S("Array_voidptr"); elem_type_str = _S("voidptr"); } strings__Builder_writeln(&g->type_definitions, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("int "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = left_type_str}}, {_S(" a, "), 0xfe10, {.d_s = elem_type_str}}, {_S(" v);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("int "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = left_type_str}}, {_S(" a, "), 0xfe10, {.d_s = elem_type_str}}, {_S(" v) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = elem_type_str}}, {_S("* pelem = a.data;"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\tfor (int i = 0; i < a.len; ++i, ++pelem) {")); if (elem_sym->kind == v__ast__Kind__string) { strings__Builder_writeln(&fn_builder, _S("\t\tif (fast_string_eq(*pelem, v)) {")); } else if ((elem_sym->kind == v__ast__Kind__array || elem_sym->kind == v__ast__Kind__array_fixed) && !v__ast__Type_is_ptr(info.elem_type)) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_arr_eq(*pelem, v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_sym->kind == v__ast__Kind__function && !v__ast__Type_is_ptr(info.elem_type)) { strings__Builder_writeln(&fn_builder, _S("\t\tif ( *pelem == v) {")); } else if (elem_sym->kind == v__ast__Kind__map && !v__ast__Type_is_ptr(info.elem_type)) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_map_eq((*pelem, v))) {"), 0, { .d_c = 0 }}}))); } else if (elem_sym->kind == v__ast__Kind__struct && !v__ast__Type_is_ptr(info.elem_type)) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_struct_eq(*pelem, v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_sym->kind == v__ast__Kind__interface) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); if (v__ast__Type_is_ptr(info.elem_type)) { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_interface_eq(**pelem, *v)) {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_interface_eq(*pelem, v)) {"), 0, { .d_c = 0 }}}))); } } else if (elem_sym->kind == v__ast__Kind__sum_type) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); if (v__ast__Type_is_ptr(info.elem_type)) { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_sumtype_eq(**pelem, *v)) {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_sumtype_eq(*pelem, v)) {"), 0, { .d_c = 0 }}}))); } } else if (elem_sym->kind == v__ast__Kind__alias) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_alias_eq(*pelem, v)) {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, _S("\t\tif (*pelem == v) {")); } } else if (final_left_sym->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((final_left_sym->info)._v__ast__ArrayFixed,(final_left_sym->info)._typ, 549); string elem_type_str = v__gen__c__Gen_styp(g, info.elem_type); v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, info.elem_type); if (elem_sym->kind == v__ast__Kind__function) { elem_type_str = _S("voidptr"); } strings__Builder_writeln(&g->type_definitions, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("int "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = left_type_str}}, {_S(" a, "), 0xfe10, {.d_s = elem_type_str}}, {_S(" v);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("int "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = left_type_str}}, {_S(" a, "), 0xfe10, {.d_s = elem_type_str}}, {_S(" v) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tfor (int i = 0; i < "), 0xfe07, {.d_i32 = info.size}}, {_S("; ++i) {"), 0, { .d_c = 0 }}}))); if (elem_sym->kind == v__ast__Kind__string) { strings__Builder_writeln(&fn_builder, _S("\t\tif (fast_string_eq(a[i], v)) {")); } else if ((elem_sym->kind == v__ast__Kind__array || elem_sym->kind == v__ast__Kind__array_fixed) && !v__ast__Type_is_ptr(info.elem_type)) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_arr_eq(a[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_sym->kind == v__ast__Kind__function && !v__ast__Type_is_ptr(info.elem_type)) { strings__Builder_writeln(&fn_builder, _S("\t\tif (a[i] == v) {")); } else if (elem_sym->kind == v__ast__Kind__map && !v__ast__Type_is_ptr(info.elem_type)) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_map_eq((a[i], v))) {"), 0, { .d_c = 0 }}}))); } else if (elem_sym->kind == v__ast__Kind__struct && !v__ast__Type_is_ptr(info.elem_type)) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_struct_eq(a[i], v)) {"), 0, { .d_c = 0 }}}))); } else if (elem_sym->kind == v__ast__Kind__interface) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); if (v__ast__Type_is_ptr(info.elem_type)) { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_interface_eq(*a[i], *v)) {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_interface_eq(a[i], v)) {"), 0, { .d_c = 0 }}}))); } } else if (elem_sym->kind == v__ast__Kind__sum_type) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); if (v__ast__Type_is_ptr(info.elem_type)) { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_sumtype_eq(*a[i], *v)) {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_sumtype_eq(a[i], v)) {"), 0, { .d_c = 0 }}}))); } } else if (elem_sym->kind == v__ast__Kind__alias) { string ptr_typ = v__gen__c__Gen_equality_fn(g, info.elem_type); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = ptr_typ}}, {_S("_alias_eq(a[i], v)) {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, _S("\t\tif (a[i] == v) {")); } } strings__Builder_writeln(&fn_builder, _S("\t\t\treturn i;")); strings__Builder_writeln(&fn_builder, _S("\t\t}")); strings__Builder_writeln(&fn_builder, _S("\t}")); strings__Builder_writeln(&fn_builder, _S("\treturn -1;")); strings__Builder_writeln(&fn_builder, _S("}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } } VV_LOC void v__gen__c__Gen_gen_array_index(v__gen__c__Gen* g, v__ast__CallExpr node) { string fn_name = v__gen__c__Gen_get_array_index_method(g, node.left_type); v__ast__TypeSymbol* left_sym = v__ast__Table_final_sym(g->table, node.left_type); { v__gen__c__Gen_write(g, fn_name); v__gen__c__Gen_write(g, _S("(")); } if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, _S("*")); } if (left_sym->kind == v__ast__Kind__array_fixed && (node.left)._typ == 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*node.left._v__ast__ArrayInit), node.left_type); } else { v__gen__c__Gen_expr(g, node.left); } v__gen__c__Gen_write(g, _S(", ")); v__ast__Type elem_typ = (left_sym->kind == v__ast__Kind__array ? (v__ast__TypeSymbol_array_info(left_sym).elem_type) : (v__ast__TypeSymbol_array_fixed_info(left_sym).elem_type)); if (v__ast__Expr_is_auto_deref_var((*(v__ast__CallArg*)array_get(node.args, 0)).expr) && !(v__ast__Table_sym(g->table, elem_typ)->kind == v__ast__Kind__interface || v__ast__Table_sym(g->table, elem_typ)->kind == v__ast__Kind__sum_type)) { v__gen__c__Gen_write(g, _S("*")); } if (v__ast__Table_sym(g->table, elem_typ)->kind == v__ast__Kind__interface || v__ast__Table_sym(g->table, elem_typ)->kind == v__ast__Kind__sum_type) { v__gen__c__Gen_expr_with_cast(g, (*(v__ast__CallArg*)array_get(node.args, 0)).expr, (*(v__ast__CallArg*)array_get(node.args, 0)).typ, elem_typ); } else if (((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ == 338 /* v.ast.ArrayInit */ && v__ast__Table_final_sym(g->table, (*(v__ast__CallArg*)array_get(node.args, 0)).typ)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*(*(v__ast__CallArg*)array_get(node.args, 0)).expr._v__ast__ArrayInit), (*(v__ast__CallArg*)array_get(node.args, 0)).typ); } else { v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 0)).expr); } v__gen__c__Gen_write(g, _S(")")); } VV_LOC void v__gen__c__Gen_gen_array_wait(v__gen__c__Gen* g, v__ast__CallExpr node) { v__ast__TypeSymbol* arr = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, node.receiver_type)); v__ast__Type thread_type = v__ast__TypeSymbol_array_info(arr).elem_type; v__ast__TypeSymbol* thread_sym = v__ast__Table_sym(g->table, thread_type); v__ast__Type thread_ret_type = v__ast__TypeSymbol_thread_info(thread_sym).return_type; string eltyp = v__ast__Table_sym(g->table, thread_ret_type)->cname; string fn_name = v__gen__c__Gen_register_thread_array_wait_call(g, eltyp); { v__gen__c__Gen_write(g, fn_name); v__gen__c__Gen_write(g, _S("(")); } if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } VV_LOC void v__gen__c__Gen_gen_fixed_array_wait(v__gen__c__Gen* g, v__ast__CallExpr node) { v__ast__TypeSymbol* arr = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, node.receiver_type)); v__ast__Type thread_type = v__ast__TypeSymbol_array_fixed_info(arr).elem_type; v__ast__TypeSymbol* thread_sym = v__ast__Table_sym(g->table, thread_type); v__ast__Type thread_ret_type = v__ast__TypeSymbol_thread_info(thread_sym).return_type; string eltyp = v__ast__Table_sym(g->table, thread_ret_type)->cname; string fn_name = v__gen__c__Gen_register_thread_fixed_array_wait_call(g, node, eltyp); { v__gen__c__Gen_write(g, fn_name); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } VV_LOC void v__gen__c__Gen_gen_array_any(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_gen_array_any_defer_0 = false; v__gen__c__PastTmpVar past; past = v__gen__c__Gen_past_tmp_var_new(g); v__gen__c__Gen_gen_array_any_defer_0 = true; v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, node.left_type); bool left_is_array = sym->kind == v__ast__Kind__array; v__ast__Type elem_type = (left_is_array ? ((*(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513)).elem_type) : ((*(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549)).elem_type)); string elem_type_str = v__gen__c__Gen_styp(g, elem_type); bool has_infix_left_var_name = v__gen__c__Gen_write_prepared_tmp_value(g, past.tmp_var, (voidptr)&node, _S("bool"), _S("false")); v__ast__Expr expr = (*(v__ast__CallArg*)array_get(node.args, 0)).expr; string var_name = v__gen__c__Gen_get_array_expr_param_name(g, &expr); string closure_var = _S(""); if ((expr)._typ == 336 /* v.ast.AnonFn */) { if ((*expr._v__ast__AnonFn).inherited_vars.len > 0) { closure_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_declare_closure_fn(g, &/*mut*/(*expr._v__ast__AnonFn), closure_var); } } string i = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = i}}, {_S(" = 0; "), 0xfe10, {.d_s = i}}, {_S(" < "), 0xfe10, {.d_s = past.tmp_var}}, {_S("_len; ++"), 0xfe10, {.d_s = i}}, {_S(") {"), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_write_prepared_var(g, var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array, false); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); bool is_embed_map_filter = false; if (expr._typ == 336 /* v.ast.AnonFn */) { v__gen__c__Gen_write(g, _S("if (")); if ((*expr._v__ast__AnonFn).inherited_vars.len > 0) { v__gen__c__Gen_write_closure_fn(g, &/*mut*/(*expr._v__ast__AnonFn), var_name, closure_var); } else { v__gen__c__Gen_gen_anon_fn_decl(g, &/*mut*/(*expr._v__ast__AnonFn)); { v__gen__c__Gen_write(g, (*expr._v__ast__AnonFn).decl.name); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } } else if (expr._typ == 358 /* v.ast.Ident */) { v__gen__c__Gen_write(g, _S("if (")); if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__function) { { v__gen__c__Gen_write(g, v__gen__c__c_name((*expr._v__ast__Ident).name)); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } else if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__variable) { v__ast__IdentVar var_info = v__ast__Ident_var_info(&(*expr._v__ast__Ident)); v__ast__TypeSymbol* sym_t = v__ast__Table_sym(g->table, var_info.typ); if (sym_t->kind == v__ast__Kind__function) { { v__gen__c__Gen_write(g, v__gen__c__c_name((*expr._v__ast__Ident).name)); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } else { v__gen__c__Gen_expr(g, expr); } } else { v__gen__c__Gen_expr(g, expr); } } else if (expr._typ == 344 /* v.ast.CallExpr */) { if (fast_string_eq((*expr._v__ast__CallExpr).name, _S("map")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("filter")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("all")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("any")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("count"))) { is_embed_map_filter = true; v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_expr(g, expr); } else if (expr._typ == 365 /* v.ast.LambdaExpr */) { v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_expr(g, (*expr._v__ast__LambdaExpr).expr); } else { v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_expr(g, expr); } v__gen__c__Gen_writeln2(g, _S(") {"), str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = past.tmp_var}}, {_S(" = true;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln2(g, _S("\tbreak;"), _S("}")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); if (!is_embed_map_filter) { v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } if (has_infix_left_var_name) { g->indent--; v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } // Defer begin if (v__gen__c__Gen_gen_array_any_defer_0) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end } VV_LOC void v__gen__c__Gen_gen_array_count(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_gen_array_count_defer_0 = false; v__gen__c__PastTmpVar past; past = v__gen__c__Gen_past_tmp_var_new(g); v__gen__c__Gen_gen_array_count_defer_0 = true; v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, node.left_type); bool left_is_array = sym->kind == v__ast__Kind__array; v__ast__Type elem_type = (left_is_array ? ((*(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513)).elem_type) : ((*(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549)).elem_type)); string elem_type_str = v__gen__c__Gen_styp(g, elem_type); bool has_infix_left_var_name = v__gen__c__Gen_write_prepared_tmp_value(g, past.tmp_var, (voidptr)&node, _S("int"), _S("0")); v__ast__Expr expr = (*(v__ast__CallArg*)array_get(node.args, 0)).expr; string var_name = v__gen__c__Gen_get_array_expr_param_name(g, &expr); string closure_var = _S(""); if ((expr)._typ == 336 /* v.ast.AnonFn */) { if ((*expr._v__ast__AnonFn).inherited_vars.len > 0) { closure_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_declare_closure_fn(g, &/*mut*/(*expr._v__ast__AnonFn), closure_var); } } string i = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = i}}, {_S(" = 0; "), 0xfe10, {.d_s = i}}, {_S(" < "), 0xfe10, {.d_s = past.tmp_var}}, {_S("_len; ++"), 0xfe10, {.d_s = i}}, {_S(") {"), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_write_prepared_var(g, var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array, false); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); bool is_embed_map_filter = false; if (expr._typ == 336 /* v.ast.AnonFn */) { v__gen__c__Gen_write(g, _S("if (")); if ((*expr._v__ast__AnonFn).inherited_vars.len > 0) { v__gen__c__Gen_write_closure_fn(g, &/*mut*/(*expr._v__ast__AnonFn), var_name, closure_var); } else { v__gen__c__Gen_gen_anon_fn_decl(g, &/*mut*/(*expr._v__ast__AnonFn)); { v__gen__c__Gen_write(g, (*expr._v__ast__AnonFn).decl.name); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } } else if (expr._typ == 358 /* v.ast.Ident */) { v__gen__c__Gen_write(g, _S("if (")); if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__function) { { v__gen__c__Gen_write(g, v__gen__c__c_name((*expr._v__ast__Ident).name)); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } else if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__variable) { v__ast__IdentVar var_info = v__ast__Ident_var_info(&(*expr._v__ast__Ident)); v__ast__TypeSymbol* sym_t = v__ast__Table_sym(g->table, var_info.typ); if (sym_t->kind == v__ast__Kind__function) { { v__gen__c__Gen_write(g, v__gen__c__c_name((*expr._v__ast__Ident).name)); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } else { v__gen__c__Gen_expr(g, expr); } } else { v__gen__c__Gen_expr(g, expr); } } else if (expr._typ == 344 /* v.ast.CallExpr */) { if (fast_string_eq((*expr._v__ast__CallExpr).name, _S("map")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("filter")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("all")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("any")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("count"))) { is_embed_map_filter = true; v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_expr(g, expr); } else if (expr._typ == 365 /* v.ast.LambdaExpr */) { v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_expr(g, (*expr._v__ast__LambdaExpr).expr); } else { v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_expr(g, expr); } v__gen__c__Gen_writeln2(g, _S(") {"), str_intp(2, _MOV((StrIntpData[]){{_S("\t++"), 0xfe10, {.d_s = past.tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("}")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); if (!is_embed_map_filter) { v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } if (has_infix_left_var_name) { g->indent--; v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } // Defer begin if (v__gen__c__Gen_gen_array_count_defer_0) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end } VV_LOC void v__gen__c__Gen_gen_array_all(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_gen_array_all_defer_0 = false; v__gen__c__PastTmpVar past; past = v__gen__c__Gen_past_tmp_var_new(g); v__gen__c__Gen_gen_array_all_defer_0 = true; v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, node.left_type); bool left_is_array = sym->kind == v__ast__Kind__array; v__ast__Type elem_type = (left_is_array ? ((*(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513)).elem_type) : ((*(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549)).elem_type)); string elem_type_str = v__gen__c__Gen_styp(g, elem_type); bool has_infix_left_var_name = v__gen__c__Gen_write_prepared_tmp_value(g, past.tmp_var, (voidptr)&node, _S("bool"), _S("true")); string i = v__gen__c__Gen_new_tmp_var(g); v__ast__Expr expr = (*(v__ast__CallArg*)array_get(node.args, 0)).expr; string var_name = v__gen__c__Gen_get_array_expr_param_name(g, &expr); string closure_var = _S(""); if ((expr)._typ == 336 /* v.ast.AnonFn */) { if ((*expr._v__ast__AnonFn).inherited_vars.len > 0) { closure_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_declare_closure_fn(g, &/*mut*/(*expr._v__ast__AnonFn), closure_var); } } v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = i}}, {_S(" = 0; "), 0xfe10, {.d_s = i}}, {_S(" < "), 0xfe10, {.d_s = past.tmp_var}}, {_S("_len; ++"), 0xfe10, {.d_s = i}}, {_S(") {"), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_write_prepared_var(g, var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array, false); g->empty_line = true; v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); bool is_embed_map_filter = false; if (expr._typ == 336 /* v.ast.AnonFn */) { v__gen__c__Gen_write(g, _S("if (!(")); if ((*expr._v__ast__AnonFn).inherited_vars.len > 0) { v__gen__c__Gen_write_closure_fn(g, &/*mut*/(*expr._v__ast__AnonFn), var_name, closure_var); } else { v__gen__c__Gen_gen_anon_fn_decl(g, &/*mut*/(*expr._v__ast__AnonFn)); { v__gen__c__Gen_write(g, (*expr._v__ast__AnonFn).decl.name); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } } else if (expr._typ == 358 /* v.ast.Ident */) { v__gen__c__Gen_write(g, _S("if (!(")); if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__function) { { v__gen__c__Gen_write(g, v__gen__c__c_name((*expr._v__ast__Ident).name)); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } else if ((*expr._v__ast__Ident).kind == v__ast__IdentKind__variable) { v__ast__IdentVar var_info = v__ast__Ident_var_info(&(*expr._v__ast__Ident)); v__ast__TypeSymbol* sym_t = v__ast__Table_sym(g->table, var_info.typ); if (sym_t->kind == v__ast__Kind__function) { { v__gen__c__Gen_write(g, v__gen__c__c_name((*expr._v__ast__Ident).name)); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(")")); } } else { v__gen__c__Gen_expr(g, expr); } } else { v__gen__c__Gen_expr(g, expr); } } else if (expr._typ == 344 /* v.ast.CallExpr */) { if (fast_string_eq((*expr._v__ast__CallExpr).name, _S("map")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("filter")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("all")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("any")) || fast_string_eq((*expr._v__ast__CallExpr).name, _S("count"))) { is_embed_map_filter = true; v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } v__gen__c__Gen_write(g, _S("if (!(")); v__gen__c__Gen_expr(g, expr); } else if (expr._typ == 365 /* v.ast.LambdaExpr */) { v__gen__c__Gen_write(g, _S("if (!(")); v__gen__c__Gen_expr(g, (*expr._v__ast__LambdaExpr).expr); } else { v__gen__c__Gen_write(g, _S("if (!(")); v__gen__c__Gen_expr(g, expr); } v__gen__c__Gen_writeln2(g, _S(")) {"), str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = past.tmp_var}}, {_S(" = false;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln2(g, _S("\tbreak;"), _S("}")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); if (!is_embed_map_filter) { v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } if (has_infix_left_var_name) { g->indent--; v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } // Defer begin if (v__gen__c__Gen_gen_array_all_defer_0) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end } VV_LOC bool v__gen__c__Gen_write_prepared_tmp_value(v__gen__c__Gen* g, string tmp, v__ast__CallExpr* node, string tmp_stype, string initial_value) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_stype}}, {_S(" "), 0xfe10, {.d_s = tmp}}, {_S(" = "), 0xfe10, {.d_s = initial_value}}, {_S(";"), 0, { .d_c = 0 }}}))); bool has_infix_left_var_name = g->infix_left_var_name.len > 0; if (has_infix_left_var_name) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = g->infix_left_var_name}}, {_S(") {"), 0, { .d_c = 0 }}}))); g->infix_left_var_name = _S(""); g->indent++; } v__ast__Type left_type = (v__ast__Type_has_flag(node->left_type, v__ast__TypeFlag__shared_f) ? (v__ast__Type_deref(v__ast__Type_clear_flag(node->left_type, v__ast__TypeFlag__shared_f))) : v__ast__Type_is_ptr(node->left_type) ? (v__ast__Type_deref(node->left_type)) : (node->left_type)); v__ast__TypeSymbol* left_sym = v__ast__Table_final_sym(g->table, left_type); if (left_sym->kind == v__ast__Kind__array) { { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, left_type)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S("_orig = ")); } if (!v__ast__Type_has_flag(node->left_type, v__ast__TypeFlag__shared_f) && v__ast__Type_is_ptr(node->left_type)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, node->left); if (v__ast__Type_has_flag(node->left_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("->val")); } v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("int "), 0xfe10, {.d_s = tmp}}, {_S("_len = "), 0xfe10, {.d_s = tmp}}, {_S("_orig.len;"), 0, { .d_c = 0 }}}))); } else if (left_sym->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed left_info = *(v__ast__ArrayFixed*)__as_cast((left_sym->info)._v__ast__ArrayFixed,(left_sym->info)._typ, 549); string left_styp = v__gen__c__Gen_styp(g, left_type); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = left_styp}}, {_S(" "), 0xfe10, {.d_s = tmp}}, {_S("_orig;"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("memcpy(&")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S("_orig, &")); } if ((node->left)._typ == 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*node->left._v__ast__ArrayInit), node->left_type); } else { if (!v__ast__Type_has_flag(node->left_type, v__ast__TypeFlag__shared_f) && v__ast__Type_is_ptr(node->left_type)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, node->left); if (v__ast__Type_has_flag(node->left_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("->val")); } } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = left_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("int "), 0xfe10, {.d_s = tmp}}, {_S("_len = "), 0xfe07, {.d_i32 = left_info.size}}, {_S(";"), 0, { .d_c = 0 }}}))); } return has_infix_left_var_name; } VV_LOC void v__gen__c__Gen_write_prepared_var(v__gen__c__Gen* g, string var_name, v__ast__Type elem_type, string inp_elem_type, string tmp, string i, bool is_array, bool auto_heap) { v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, elem_type); if (is_array) { if (elem_sym->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = inp_elem_type}}, {_S(" "), 0xfe10, {.d_s = var_name}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("memcpy(&"), 0xfe10, {.d_s = var_name}}, {_S(", (("), 0xfe10, {.d_s = inp_elem_type}}, {_S("*) "), 0xfe10, {.d_s = tmp}}, {_S("_orig.data)["), 0xfe10, {.d_s = i}}, {_S("], sizeof("), 0xfe10, {.d_s = inp_elem_type}}, {_S("));"), 0, { .d_c = 0 }}}))); } else if (elem_sym->kind == v__ast__Kind__function) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("voidptr "), 0xfe10, {.d_s = var_name}}, {_S(" = (("), 0xfe10, {.d_s = inp_elem_type}}, {_S("*) "), 0xfe10, {.d_s = tmp}}, {_S("_orig.data)["), 0xfe10, {.d_s = i}}, {_S("];"), 0, { .d_c = 0 }}}))); } else { { v__gen__c__Gen_write(g, inp_elem_type); v__gen__c__Gen_write(g, _S(" ")); } if (auto_heap) { v__gen__c__Gen_write(g, _S("*")); } { v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(" = ")); } if (auto_heap) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("(("), 0xfe10, {.d_s = inp_elem_type}}, {_S("*) "), 0xfe10, {.d_s = tmp}}, {_S("_orig.data)["), 0xfe10, {.d_s = i}}, {_S("];"), 0, { .d_c = 0 }}}))); } } else { if (elem_sym->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = inp_elem_type}}, {_S(" "), 0xfe10, {.d_s = var_name}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("memcpy(&"), 0xfe10, {.d_s = var_name}}, {_S(", &"), 0xfe10, {.d_s = tmp}}, {_S("_orig["), 0xfe10, {.d_s = i}}, {_S("], sizeof("), 0xfe10, {.d_s = inp_elem_type}}, {_S("));"), 0, { .d_c = 0 }}}))); } else if (auto_heap) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = inp_elem_type}}, {_S(" *"), 0xfe10, {.d_s = var_name}}, {_S(" = &"), 0xfe10, {.d_s = tmp}}, {_S("_orig["), 0xfe10, {.d_s = i}}, {_S("];"), 0, { .d_c = 0 }}}))); } else if (elem_sym->kind == v__ast__Kind__function) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("voidptr "), 0xfe10, {.d_s = var_name}}, {_S(" = (voidptr)"), 0xfe10, {.d_s = tmp}}, {_S("_orig["), 0xfe10, {.d_s = i}}, {_S("];"), 0, { .d_c = 0 }}}))); } else { { v__gen__c__Gen_write(g, inp_elem_type); v__gen__c__Gen_write(g, _S(" ")); } if (auto_heap) { v__gen__c__Gen_write(g, _S("*")); } { v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(" = ")); } if (auto_heap) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp}}, {_S("_orig["), 0xfe10, {.d_s = i}}, {_S("];"), 0, { .d_c = 0 }}}))); } } } VV_LOC void v__gen__c__Gen_fixed_array_init_with_cast(v__gen__c__Gen* g, v__ast__ArrayInit expr, v__ast__Type typ) { if (g->is_cc_msvc) { string stmts = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); string tmp_var = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, typ)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, v__ast__ArrayInit_to_sumtype_v__ast__Expr(&expr)); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write2(g, stmts, tmp_var); } else { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, typ)); v__gen__c__Gen_write(g, _S(")")); } v__gen__c__Gen_expr(g, v__ast__ArrayInit_to_sumtype_v__ast__Expr(&expr)); } } VV_LOC void v__gen__c__Gen_fixed_array_update_expr_field(v__gen__c__Gen* g, string expr_str, v__ast__Type field_type, string field_name, bool is_auto_deref, v__ast__Type elem_type, int size, bool is_update_embed) { bool v__gen__c__Gen_fixed_array_update_expr_field_defer_0 = false; v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, elem_type); if (!g->inside_array_fixed_struct) { v__gen__c__Gen_write(g, _S("{")); v__gen__c__Gen_fixed_array_update_expr_field_defer_0 = true; } string embed_field = (is_update_embed ? (v__gen__c__Gen_get_embed_field_name(g, field_type, field_name)) : (_S(""))); for (int i = 0; i < size; ++i) { if ((elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { string init_str = (g->inside_array_fixed_struct ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = expr_str}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = expr_str}}, {_S("->"), 0xfe10, {.d_s = embed_field}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field_name)}}, {_S("["), 0xfe07, {.d_i32 = i}}, {_S("]"), 0, { .d_c = 0 }}})))); v__gen__c__Gen_fixed_array_update_expr_field(g, init_str, field_type, field_name, is_auto_deref, (*elem_sym->info._v__ast__ArrayFixed).elem_type, (*elem_sym->info._v__ast__ArrayFixed).size, is_update_embed); } else { v__gen__c__Gen_write(g, expr_str); if (!string_ends_with(expr_str, _S("]"))) { if (v__ast__Type_is_ptr(field_type)) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } if (is_update_embed) { v__gen__c__Gen_write(g, embed_field); } v__gen__c__Gen_write(g, v__gen__c__c_name(field_name)); } { v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_write_decimal(g, i); v__gen__c__Gen_write(g, _S("]")); } } v__gen__c__Gen_add_commas_and_prevent_long_lines(g, i, size); } // Defer begin if (v__gen__c__Gen_fixed_array_update_expr_field_defer_0) { v__gen__c__Gen_write(g, _S("}")); } // Defer end } VV_LOC void v__gen__c__Gen_fixed_array_var_init(v__gen__c__Gen* g, string expr_str, bool is_auto_deref, v__ast__Type elem_type, int size) { bool v__gen__c__Gen_fixed_array_var_init_defer_0 = false; v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, elem_type); if (!g->inside_array_fixed_struct) { v__gen__c__Gen_write(g, _S("{")); v__gen__c__Gen_fixed_array_var_init_defer_0 = true; } for (int i = 0; i < size; ++i) { if ((elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { string init_str = (g->inside_array_fixed_struct ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = expr_str}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = expr_str}}, {_S("["), 0xfe07, {.d_i32 = i}}, {_S("]"), 0, { .d_c = 0 }}})))); v__gen__c__Gen_fixed_array_var_init(g, init_str, is_auto_deref, (*elem_sym->info._v__ast__ArrayFixed).elem_type, (*elem_sym->info._v__ast__ArrayFixed).size); } else { if (is_auto_deref) { v__gen__c__Gen_write(g, _S("(*")); } v__gen__c__Gen_write(g, expr_str); if (is_auto_deref) { v__gen__c__Gen_write(g, _S(")")); } if (!string_starts_with(expr_str, _S("(")) && !string_starts_with(expr_str, _S("{"))) { { v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_write_decimal(g, i); v__gen__c__Gen_write(g, _S("]")); } } } v__gen__c__Gen_add_commas_and_prevent_long_lines(g, i, size); } // Defer begin if (v__gen__c__Gen_fixed_array_var_init_defer_0) { v__gen__c__Gen_write(g, _S("}")); } // Defer end } VV_LOC string v__gen__c__Gen_get_array_expr_param_name(v__gen__c__Gen* g, v__ast__Expr* expr) { return ((expr)->_typ == 365 /* v.ast.LambdaExpr */ ? ((*(v__ast__Ident*)array_get((*expr->_v__ast__LambdaExpr).params, 0)).name) : (_S("it"))); } VV_LOC void v__gen__c__Gen_add_commas_and_prevent_long_lines(v__gen__c__Gen* g, int i, int len) { if (i != (int)(len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } if ((i & 0x0F) == 0x0F && (int)(len - i) > 0x0F) { v__gen__c__Gen_writeln(g, _S("")); } } inline VV_LOC bool v__gen__c__Gen_can_use_c99_designators(v__gen__c__Gen* g) { return !g->is_cc_msvc && !g->pref->output_cross_c; } VV_LOC void v__gen__c__Gen_write_all_n_elements_for_array(v__gen__c__Gen* g, int len, string value) { for (int i = 0; i < len; ++i) { v__gen__c__Gen_write(g, value); v__gen__c__Gen_add_commas_and_prevent_long_lines(g, i, len); } } VV_LOC void v__gen__c__Gen_write_c99_elements_for_array(v__gen__c__Gen* g, int len, string value) { if (len == 0) { return; } if (v__gen__c__Gen_can_use_c99_designators(g)) { if (_SLIT_EQ(value.str, value.len, "0") || _SLIT_EQ(value.str, value.len, "{0}") || _SLIT_EQ(value.str, value.len, "((u8)(0))") || _SLIT_EQ(value.str, value.len, "{((u8)(0))}") || _SLIT_EQ(value.str, value.len, "((u32)(0))") || _SLIT_EQ(value.str, value.len, "{((u32)(0))}")) { v__gen__c__Gen_write(g, _S("0")); return; } if (len > 64) { if (g->pref->ccompiler_type != v__pref__CompilerType__gcc) { if (!string_contains(value, _S("){."))) { { v__gen__c__Gen_write(g, _S(" [0 ... ")); v__gen__c__Gen_write_decimal(g, (int)(len - 1)); v__gen__c__Gen_write(g, _S("] = ")); v__gen__c__Gen_write(g, value); v__gen__c__Gen_write(g, _S(" ")); } return; } } } } v__gen__c__Gen_write_all_n_elements_for_array(g, len, value); } inline VV_LOC void v__gen__c__Gen_write_c99_0_elements_for_array(v__gen__c__Gen* g, int len) { if (v__gen__c__Gen_can_use_c99_designators(g)) { v__gen__c__Gen_write(g, _S("0")); return; } v__gen__c__Gen_write_all_n_elements_for_array(g, len, _S("0")); } VV_LOC void v__gen__c__Gen_assert_stmt(v__gen__c__Gen* g, v__ast__AssertStmt original_assert_statement) { if (!original_assert_statement.is_used) { return; } v__ast__AssertStmt node = original_assert_statement; v__gen__c__Gen_writeln(g, _S("// assert")); v__ast__Expr save_left = _const_v__ast__empty_expr; v__ast__Expr save_right = _const_v__ast__empty_expr; if ((node.expr)._typ == 362 /* v.ast.InfixExpr */) { _result_v__ast__Expr _t1; if (_t1 = v__gen__c__Gen_assert_subexpression_to_ctemp(g, (*node.expr._v__ast__InfixExpr).left, (*node.expr._v__ast__InfixExpr).left_type), !_t1.is_error) { v__ast__Expr subst_expr = *(v__ast__Expr*)_t1.data; save_left = (*node.expr._v__ast__InfixExpr).left; (*node.expr._v__ast__InfixExpr).left = subst_expr; } _result_v__ast__Expr _t2; if (_t2 = v__gen__c__Gen_assert_subexpression_to_ctemp(g, (*node.expr._v__ast__InfixExpr).right, (*node.expr._v__ast__InfixExpr).right_type), !_t2.is_error) { v__ast__Expr subst_expr = *(v__ast__Expr*)_t2.data; save_right = (*node.expr._v__ast__InfixExpr).right; (*node.expr._v__ast__InfixExpr).right = subst_expr; } } g->inside_ternary++; if (g->pref->is_test) { v__gen__c__Gen_write(g, _S("if (")); int prev_inside_ternary = g->inside_ternary; g->inside_ternary = 0; v__gen__c__Gen_expr(g, node.expr); g->inside_ternary = prev_inside_ternary; v__gen__c__Gen_write(g, _S(")")); v__gen__c__Gen_decrement_inside_ternary(g); v__gen__c__Gen_writeln(g, _S(" {")); string metaname_ok = v__gen__c__Gen_gen_assert_metainfo(g, node, v__gen__c__AssertMetainfoKind__pass); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tmain__TestRunner_name_table[test_runner._typ]._method_assert_pass(test_runner._object, &"), 0xfe10, {.d_s = metaname_ok}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("} else {")); string metaname_fail = v__gen__c__Gen_gen_assert_metainfo(g, node, v__gen__c__AssertMetainfoKind__fail); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tmain__TestRunner_name_table[test_runner._typ]._method_assert_fail(test_runner._object, &"), 0xfe10, {.d_s = metaname_fail}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_gen_assert_postfailure_mode(g, node); v__gen__c__Gen_writeln(g, _S("}")); } else { v__gen__c__Gen_write(g, _S("if (!(")); int prev_inside_ternary = g->inside_ternary; g->inside_ternary = 0; v__gen__c__Gen_expr(g, node.expr); g->inside_ternary = prev_inside_ternary; v__gen__c__Gen_write(g, _S("))")); v__gen__c__Gen_decrement_inside_ternary(g); v__gen__c__Gen_writeln(g, _S(" {")); string metaname_panic = v__gen__c__Gen_gen_assert_metainfo(g, node, v__gen__c__AssertMetainfoKind__panic); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t__print_assert_failure(&"), 0xfe10, {.d_s = metaname_panic}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_gen_assert_postfailure_mode(g, node); v__gen__c__Gen_writeln(g, _S("}")); } if ((node.expr)._typ == 362 /* v.ast.InfixExpr */) { if (((*node.expr._v__ast__InfixExpr).left)._typ == 343 /* v.ast.CTempVar */) { (*node.expr._v__ast__InfixExpr).left = save_left; } if (((*node.expr._v__ast__InfixExpr).right)._typ == 343 /* v.ast.CTempVar */) { (*node.expr._v__ast__InfixExpr).right = save_right; } } } VV_LOC _result_v__ast__Expr v__gen__c__Gen_assert_subexpression_to_ctemp(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_type) { if (expr._typ == 344 /* v.ast.CallExpr */) { _result_v__ast__Expr _t1 = {0}; _result_ok(&(v__ast__Expr[]) { v__ast__CTempVar_to_sumtype_v__ast__Expr(ADDR(v__ast__CTempVar, (v__gen__c__Gen_new_ctemp_var_then_gen(g, v__ast__CallExpr_to_sumtype_v__ast__Expr(&(*expr._v__ast__CallExpr)), expr_type)))) }, (_result*)(&_t1), sizeof(v__ast__Expr)); return _t1; } else if (expr._typ == 374 /* v.ast.ParExpr */) { if (((*expr._v__ast__ParExpr).expr)._typ == 344 /* v.ast.CallExpr */) { _result_v__ast__Expr _t2 = {0}; _result_ok(&(v__ast__Expr[]) { v__ast__CTempVar_to_sumtype_v__ast__Expr(ADDR(v__ast__CTempVar, (v__gen__c__Gen_new_ctemp_var_then_gen(g, v__ast__CallExpr_to_sumtype_v__ast__Expr(&(*(*expr._v__ast__ParExpr).expr._v__ast__CallExpr)), expr_type)))) }, (_result*)(&_t2), sizeof(v__ast__Expr)); return _t2; } } else if (expr._typ == 379 /* v.ast.SelectorExpr */) { if (((*expr._v__ast__SelectorExpr).expr)._typ == 344 /* v.ast.CallExpr */) { v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, v__gen__c__Gen_unwrap_generic(g, (*(*expr._v__ast__SelectorExpr).expr._v__ast__CallExpr).return_type)); if (sym->kind == v__ast__Kind__struct) { if ((*(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518)).is_union) { return (_result_v__ast__Expr){ .is_error=true, .err=_const_v__gen__c__unsupported_ctemp_assert_transform, .data={E_STRUCT} }; } } _result_v__ast__Expr _t4 = {0}; _result_ok(&(v__ast__Expr[]) { v__ast__CTempVar_to_sumtype_v__ast__Expr(ADDR(v__ast__CTempVar, (v__gen__c__Gen_new_ctemp_var_then_gen(g, v__ast__SelectorExpr_to_sumtype_v__ast__Expr(&(*expr._v__ast__SelectorExpr)), expr_type)))) }, (_result*)(&_t4), sizeof(v__ast__Expr)); return _t4; } } else { } return (_result_v__ast__Expr){ .is_error=true, .err=_const_v__gen__c__unsupported_ctemp_assert_transform, .data={E_STRUCT} }; } VV_LOC void v__gen__c__Gen_gen_assert_postfailure_mode(v__gen__c__Gen* g, v__ast__AssertStmt node) { v__gen__c__Gen_write_v_source_line_info_stmt(g, v__ast__AssertStmt_to_sumtype_v__ast__Stmt(&node)); bool _t1 = (g->pref->assert_failure_mode == v__pref__AssertFailureMode__continues); bool _t2 = false; if (!_t1) { Array_v__ast__Attr _t2_orig = g->fn_decl->attrs; int _t2_len = _t2_orig.len; for (int _t3 = 0; _t3 < _t2_len; ++_t3) { v__ast__Attr it = ((v__ast__Attr*) _t2_orig.data)[_t3]; if (fast_string_eq(it.name, _S("assert_continues"))) { _t2 = true; break; } } } if ( _t1 ||_t2) { return; } bool _t4 = (g->pref->assert_failure_mode == v__pref__AssertFailureMode__aborts); bool _t5 = false; if (!_t4) { Array_v__ast__Attr _t5_orig = g->fn_decl->attrs; int _t5_len = _t5_orig.len; for (int _t6 = 0; _t6 < _t5_len; ++_t6) { v__ast__Attr it = ((v__ast__Attr*) _t5_orig.data)[_t6]; if (fast_string_eq(it.name, _S("assert_aborts"))) { _t5 = true; break; } } } if ( _t4 ||_t5) { v__gen__c__Gen_writeln(g, _S("\tabort();")); } bool _t7 = (g->pref->assert_failure_mode == v__pref__AssertFailureMode__backtraces); bool _t8 = false; if (!_t7) { Array_v__ast__Attr _t8_orig = g->fn_decl->attrs; int _t8_len = _t8_orig.len; for (int _t9 = 0; _t9 < _t8_len; ++_t9) { v__ast__Attr it = ((v__ast__Attr*) _t8_orig.data)[_t9]; if (fast_string_eq(it.name, _S("assert_backtraces"))) { _t8 = true; break; } } } if ( _t7 ||_t8) { v__ast__Fn* _t11 = (v__ast__Fn*)(map_get_check(ADDR(map, g->table->fns), &(string[]){_S("print_backtrace")})); _option_v__ast__Fn _t10 = {0}; if (_t11) { *((v__ast__Fn*)&_t10.data) = *((v__ast__Fn*)_t11); } else { _t10.state = 2; _t10.err = _v_error(_S("map key does not exist")); } if (_t10.state == 0) { v__ast__Fn _dummy_10 = (*(v__ast__Fn*)_t10.data); v__gen__c__Gen_writeln(g, _S("\tprint_backtrace();")); } } if (g->pref->is_test) { v__gen__c__Gen_writeln(g, _S("\tlongjmp(g_jump_buffer, 1);")); } v__gen__c__Gen_writeln2(g, _S("\t// TODO"), _S("\t// Maybe print all vars in a test function if it fails?")); if (g->pref->assert_failure_mode != v__pref__AssertFailureMode__continues) { v__gen__c__Gen_writeln(g, _S("\t_v_panic(_S(\"Assertion failed...\"));")); } } VV_LOC string v__gen__c__Gen_gen_assert_metainfo(v__gen__c__Gen* g, v__ast__AssertStmt node, v__gen__c__AssertMetainfoKind kind) { string mod_path = v__gen__c__cestring(g->file->path); string fn_name = g->fn_decl->name; int line_nr = node.pos.line_nr; string src = v__ast__Expr_str(&node.expr); if ((node.extra)._typ != 354 /* v.ast.EmptyExpr */) { src = string__plus(src, string__plus(_S(", "), v__ast__Expr_str(&node.extra))); } src = v__gen__c__cestring(src); string metaname = str_intp(2, _MOV((StrIntpData[]){{_S("v_assert_meta_info_"), 0xfe10, {.d_s = v__gen__c__Gen_new_tmp_var(g)}}, {_SLIT0, 0, { .d_c = 0 }}})); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tVAssertMetaInfo "), 0xfe10, {.d_s = metaname}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = metaname}}, {_S(".fpath = "), 0xfe10, {.d_s = v__gen__c__ctoslit(mod_path)}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = metaname}}, {_S(".line_nr = "), 0xfe07, {.d_i32 = line_nr}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = metaname}}, {_S(".fn_name = "), 0xfe10, {.d_s = v__gen__c__ctoslit(fn_name)}}, {_S(";"), 0, { .d_c = 0 }}}))); string metasrc = v__gen__c__cnewlines(v__gen__c__ctoslit(src)); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = metaname}}, {_S(".src = "), 0xfe10, {.d_s = metasrc}}, {_S(";"), 0, { .d_c = 0 }}}))); if (node.expr._typ == 362 /* v.ast.InfixExpr */) { string expr_op_str = v__gen__c__ctoslit(v__token__Kind_str((*node.expr._v__ast__InfixExpr).op)); string expr_left_str = v__gen__c__cnewlines(v__gen__c__ctoslit(v__ast__Expr_str(&(*node.expr._v__ast__InfixExpr).left))); string expr_right_str = v__gen__c__cnewlines(v__gen__c__ctoslit(v__ast__Expr_str(&(*node.expr._v__ast__InfixExpr).right))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = metaname}}, {_S(".op = "), 0xfe10, {.d_s = expr_op_str}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = metaname}}, {_S(".llabel = "), 0xfe10, {.d_s = expr_left_str}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = metaname}}, {_S(".rlabel = "), 0xfe10, {.d_s = expr_right_str}}, {_S(";"), 0, { .d_c = 0 }}}))); v__ast__Type left_type = ((*node.expr._v__ast__InfixExpr).left_ct_expr ? (v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, (*node.expr._v__ast__InfixExpr).left, (*node.expr._v__ast__InfixExpr).left_type)) : ((*node.expr._v__ast__InfixExpr).left_type)); v__ast__Type right_type = ((*node.expr._v__ast__InfixExpr).right_ct_expr ? (v__type_resolver__TypeResolver_get_type(&g->type_resolver, (*node.expr._v__ast__InfixExpr).right)) : ((*node.expr._v__ast__InfixExpr).right_type)); if (kind != v__gen__c__AssertMetainfoKind__pass) { { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, metaname); v__gen__c__Gen_write(g, _S(".lvalue = ")); } v__gen__c__Gen_gen_assert_single_expr(g, (*node.expr._v__ast__InfixExpr).left, left_type); v__gen__c__Gen_writeln(g, _S(";")); { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, metaname); v__gen__c__Gen_write(g, _S(".rvalue = ")); } v__gen__c__Gen_gen_assert_single_expr(g, (*node.expr._v__ast__InfixExpr).right, right_type); v__gen__c__Gen_writeln(g, _S(";")); } } else if (node.expr._typ == 344 /* v.ast.CallExpr */) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = metaname}}, {_S(".op = _S(\"call\");"), 0, { .d_c = 0 }}}))); } else { } if ((node.extra)._typ == 354 /* v.ast.EmptyExpr */) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = metaname}}, {_S(".has_msg = false;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = metaname}}, {_S(".message = _SLIT0;"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = metaname}}, {_S(".has_msg = true;"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, metaname); v__gen__c__Gen_write(g, _S(".message = ")); } v__gen__c__Gen_gen_assert_single_expr(g, node.extra, _const_v__ast__string_type); v__gen__c__Gen_writeln(g, _S(";")); } return metaname; } VV_LOC void v__gen__c__Gen_gen_assert_single_expr(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type typ) { string expr_str = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&expr)}}, {_SLIT0, 0, { .d_c = 0 }}})); if (expr._typ == 345 /* v.ast.CastExpr */) { if (v__ast__Type_is_float(typ) || v__ast__TypeSymbol_is_float(v__ast__Table_final_sym(g->table, typ))) { v__gen__c__Gen_gen_expr_to_string(g, (*expr._v__ast__CastExpr).expr, typ); } else { v__gen__c__Gen_write(g, v__gen__c__ctoslit(expr_str)); } } else if (expr._typ == 374 /* v.ast.ParExpr */) { v__gen__c__Gen_gen_assert_single_expr(g, (*expr._v__ast__ParExpr).expr, typ); } else if (expr._typ == 359 /* v.ast.IfExpr */) { v__gen__c__Gen_write(g, v__gen__c__ctoslit(expr_str)); } else if (expr._typ == 369 /* v.ast.MatchExpr */) { v__gen__c__Gen_write(g, v__gen__c__ctoslit(expr_str)); } else if (expr._typ == 377 /* v.ast.RangeExpr */) { v__gen__c__Gen_write(g, v__gen__c__ctoslit(expr_str)); } else if (expr._typ == 361 /* v.ast.IndexExpr */) { v__gen__c__Gen_gen_expr_to_string(g, expr, typ); } else if (expr._typ == 376 /* v.ast.PrefixExpr */) { if (((*expr._v__ast__PrefixExpr).right)._typ == 345 /* v.ast.CastExpr */) { v__gen__c__Gen_write(g, v__gen__c__ctoslit(expr_str)); } else if (((*expr._v__ast__PrefixExpr).right)._typ == 358 /* v.ast.Ident */) { v__gen__c__Gen_write(g, v__gen__c__ctoslit(expr_str)); } else { v__gen__c__Gen_gen_expr_to_string(g, expr, typ); } } else if (expr._typ == 386 /* v.ast.TypeNode */) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, typ)); v__gen__c__Gen_write(g, v__gen__c__ctoslit(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sym->name}}, {_SLIT0, 0, { .d_c = 0 }}})))); } else { bool should_clone = true; if (typ == _const_v__ast__string_type && ((expr)._typ == 361 /* v.ast.IndexExpr */ || (expr)._typ == 344 /* v.ast.CallExpr */ || (expr)._typ == 384 /* v.ast.StringLiteral */ || (expr)._typ == 383 /* v.ast.StringInterLiteral */)) { should_clone = false; } if ((expr)._typ == 343 /* v.ast.CTempVar */ && ((*(v__ast__CTempVar*)__as_cast((expr)._v__ast__CTempVar,(expr)._typ, 343)).orig)._typ == 344 /* v.ast.CallExpr */) { should_clone = false; if ((*(*expr._v__ast__CTempVar).orig._v__ast__CallExpr).or_block.kind == v__ast__OrKind__propagate_option) { should_clone = true; } if ((*(*expr._v__ast__CTempVar).orig._v__ast__CallExpr).is_method && (*(*expr._v__ast__CTempVar).orig._v__ast__CallExpr).args.len == 0 && fast_string_eq((*(*expr._v__ast__CTempVar).orig._v__ast__CallExpr).name, _S("type_name"))) { should_clone = true; } } if (should_clone) { v__gen__c__Gen_write(g, _S("string_clone(")); } v__gen__c__Gen_gen_expr_to_string(g, expr, typ); if (should_clone) { v__gen__c__Gen_write(g, _S(")")); } } } VV_LOC void v__gen__c__Gen_expr_with_opt_or_block(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_typ, v__ast__Expr var_expr, v__ast__Type ret_typ, bool in_heap) { bool v__gen__c__Gen_expr_with_opt_or_block_defer_0 = false; bool gen_or = (expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).or_expr.kind != v__ast__OrKind__absent; if (gen_or) { bool old_inside_opt_or_res = g->inside_opt_or_res; g->inside_opt_or_res = true; v__gen__c__Gen_expr_with_cast(g, expr, expr_typ, ret_typ); if (in_heap) { v__gen__c__Gen_write(g, _S("))")); } v__gen__c__Gen_writeln(g, _S(";")); string expr_var = ((expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).kind == v__ast__IdentKind__constant ? (v__gen__c__Gen_get_const_name(g, (*expr._v__ast__Ident))) : (expr)._typ == 358 /* v.ast.Ident */ && v__ast__Ident_is_auto_heap(((v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358))) ? (str_intp(2, _MOV((StrIntpData[]){{_S("(*"), 0xfe10, {.d_s = (*expr._v__ast__Ident).name}}, {_S(")"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&expr)}}, {_SLIT0, 0, { .d_c = 0 }}})))); string dot_or_ptr = (!v__ast__Type_has_flag(expr_typ, v__ast__TypeFlag__option_mut_param_t) ? (_S(".")) : (_S("-> "))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = v__gen__c__c_name(expr_var)}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("state != 0) { // assign"), 0, { .d_c = 0 }}}))); if ((expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).or_expr.kind == v__ast__OrKind__propagate_option) { v__gen__c__Gen_writeln(g, _S("\tpanic_option_not_set(_S(\"none\"));")); } else { g->inside_or_block = true; v__gen__c__Gen_expr_with_opt_or_block_defer_0 = true; Array_v__ast__Stmt stmts = (*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).or_expr.stmts; bool _t2 = (stmts.len > 0); bool _t1 = _t2 && ((*(v__ast__Stmt*)array_last(stmts)))._typ == 401 /* v.ast.ExprStmt */ && (({ v__ast__Stmt _t3 = (*(v__ast__Stmt*)array_last(stmts)); *(v__ast__ExprStmt*)__as_cast(_t3._v__ast__ExprStmt,_t3._typ, 401); })).typ != _const_v__ast__void_type; if (_t1) { v__gen__c__Gen_gen_or_block_stmts(g, v__gen__c__c_name(v__ast__Expr_str(&var_expr)), _S(""), stmts, ret_typ, false); } else { v__gen__c__Gen_stmts(g, stmts); bool _t4 = (stmts.len > 0); if ( _t4 && ((*(v__ast__Stmt*)array_last(stmts)))._typ == 401 /* v.ast.ExprStmt */) { v__gen__c__Gen_writeln(g, _S(";")); } } } v__gen__c__Gen_writeln(g, _S("}")); g->inside_opt_or_res = old_inside_opt_or_res; } else { v__gen__c__Gen_expr_with_opt(g, expr, expr_typ, ret_typ); } // Defer begin if (v__gen__c__Gen_expr_with_opt_or_block_defer_0) { g->inside_or_block = false; } // Defer end } VV_LOC string v__gen__c__Gen_expr_opt_with_alias(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_typ, v__ast__Type ret_typ) { string styp = v__gen__c__Gen_base_type(g, ret_typ); string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; string ret_var = v__gen__c__Gen_new_tmp_var(g); string ret_styp = string_replace(v__gen__c__Gen_styp(g, ret_typ), _S("*"), _S("_ptr")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_styp}}, {_S(" "), 0xfe10, {.d_s = ret_var}}, {_S(" = {.state=2, .err=_const_none__, .data={E_STRUCT}};"), 0, { .d_c = 0 }}}))); if ((expr)._typ != 371 /* v.ast.None */) { bool is_option_expr = v__ast__Type_has_flag(expr_typ, v__ast__TypeFlag__option); if (is_option_expr) { { v__gen__c__Gen_write(g, _S("_option_clone((")); v__gen__c__Gen_write(g, _const_v__gen__c__option_name); v__gen__c__Gen_write(g, _S("*)")); } } else { { v__gen__c__Gen_write(g, _S("_option_ok(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]){ ")); } } bool has_addr = is_option_expr && !((expr)._typ == 358 /* v.ast.Ident */ || (expr)._typ == 379 /* v.ast.SelectorExpr */); if (has_addr) { string expr_styp = string_replace(v__gen__c__Gen_styp(g, expr_typ), _S("*"), _S("_ptr")); { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, expr_styp); v__gen__c__Gen_write(g, _S(", ")); } } else if (is_option_expr) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, expr); if (has_addr) { v__gen__c__Gen_write(g, _S(")")); } if (!is_option_expr) { v__gen__c__Gen_write(g, _S(" }")); } v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(", ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = ret_var}}, {_S(", sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_write(g, line); if (g->inside_return) { v__gen__c__Gen_write(g, _S(" ")); } v__gen__c__Gen_write(g, ret_var); return ret_var; } VV_LOC string v__gen__c__Gen_expr_opt_with_cast(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_typ, v__ast__Type ret_typ) { bool v__gen__c__Gen_expr_opt_with_cast_defer_0 = false; v__gen__c__PastTmpVar past; if (!v__ast__Type_has_flag(expr_typ, v__ast__TypeFlag__option) || !v__ast__Type_has_flag(ret_typ, v__ast__TypeFlag__option)) { _v_panic(_S("cgen: expected expr_type and ret_typ to be options")); VUNREACHABLE(); } if (v__ast__Type_idx(expr_typ) == v__ast__Type_idx(ret_typ) && v__ast__Table_sym(g->table, expr_typ)->kind != v__ast__Kind__alias) { return v__gen__c__Gen_expr_with_opt(g, expr, expr_typ, ret_typ); } else { if ((expr)._typ == 344 /* v.ast.CallExpr */ && v__ast__Type_has_flag((*(v__ast__CallExpr*)__as_cast((expr)._v__ast__CallExpr,(expr)._typ, 344)).return_type, v__ast__TypeFlag__option)) { return v__gen__c__Gen_expr_opt_with_alias(g, v__ast__CallExpr_to_sumtype_v__ast__Expr(&(*expr._v__ast__CallExpr)), expr_typ, ret_typ); } else { past = v__gen__c__Gen_past_tmp_var_new(g); v__gen__c__Gen_expr_opt_with_cast_defer_0 = true; string styp = v__gen__c__Gen_base_type(g, ret_typ); string decl_styp = string_replace(v__gen__c__Gen_styp(g, ret_typ), _S("*"), _S("_ptr")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = decl_styp}}, {_S(" "), 0xfe10, {.d_s = past.tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); bool is_none = (expr)._typ == 345 /* v.ast.CastExpr */ && ((*(v__ast__CastExpr*)__as_cast((expr)._v__ast__CastExpr,(expr)._typ, 345)).expr)._typ == 371 /* v.ast.None */; if (is_none) { { v__gen__c__Gen_write(g, _S("_option_none(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) {")); } } else { { v__gen__c__Gen_write(g, _S("_option_ok(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) {")); } } if ((expr)._typ == 345 /* v.ast.CastExpr */ && v__ast__Type_has_flag(expr_typ, v__ast__TypeFlag__option)) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(g->table, ret_typ); if (ret_sym->kind == v__ast__Kind__sum_type) { v__ast__TypeSymbol* exp_sym = v__ast__Table_sym(g->table, expr_typ); string fname = v__gen__c__Gen_get_sumtype_casting_fn(g, expr_typ, ret_typ); v__gen__c__Gen_call_cfn_for_casting_expr(g, fname, expr, ret_typ, expr_typ, ret_sym->cname, v__ast__Type_is_ptr(expr_typ), exp_sym->kind == v__ast__Kind__function, v__gen__c__Gen_styp(g, expr_typ)); } else { { v__gen__c__Gen_write(g, _S("*((")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, expr_typ)); v__gen__c__Gen_write(g, _S("*)")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(".data)")); } } else { bool old_inside_opt_or_res = g->inside_opt_or_res; g->inside_opt_or_res = false; v__gen__c__Gen_expr_with_cast(g, expr, expr_typ, ret_typ); g->inside_opt_or_res = old_inside_opt_or_res; } v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)(&"), 0xfe10, {.d_s = past.tmp_var}}, {_S("), sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); string _t3 = past.tmp_var; // Defer begin if (v__gen__c__Gen_expr_opt_with_cast_defer_0) { v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } // Defer end return _t3; } } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC string v__gen__c__Gen_expr_with_opt(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_typ, v__ast__Type ret_typ) { bool v__gen__c__Gen_expr_with_opt_defer_0 = false; bool old_inside_opt_or_res; old_inside_opt_or_res = g->inside_opt_or_res; g->inside_opt_or_res = true; v__gen__c__Gen_expr_with_opt_defer_0 = true; if (v__ast__Type_has_flag(expr_typ, v__ast__TypeFlag__option) && v__ast__Type_has_flag(ret_typ, v__ast__TypeFlag__option) && !g->is_arraymap_set && ((expr)._typ == 379 /* v.ast.SelectorExpr */ || (expr)._typ == 353 /* v.ast.DumpExpr */ || (expr)._typ == 358 /* v.ast.Ident */ || (expr)._typ == 350 /* v.ast.ComptimeSelector */ || (expr)._typ == 339 /* v.ast.AsCast */ || (expr)._typ == 344 /* v.ast.CallExpr */ || (expr)._typ == 369 /* v.ast.MatchExpr */ || (expr)._typ == 359 /* v.ast.IfExpr */ || (expr)._typ == 361 /* v.ast.IndexExpr */ || (expr)._typ == 388 /* v.ast.UnsafeExpr */ || (expr)._typ == 345 /* v.ast.CastExpr */)) { if ((expr)._typ == 358 /* v.ast.Ident */ || (expr)._typ == 345 /* v.ast.CastExpr */) { if (v__ast__Type_idx(expr_typ) != v__ast__Type_idx(ret_typ)) { string _t1 = v__gen__c__Gen_expr_opt_with_cast(g, expr, expr_typ, ret_typ); // Defer begin if (v__gen__c__Gen_expr_with_opt_defer_0) { g->inside_opt_or_res = old_inside_opt_or_res; } // Defer end return _t1; } } v__gen__c__Gen_expr(g, expr); if ((expr)._typ == 350 /* v.ast.ComptimeSelector */) { string _t2 = v__gen__c__Gen_gen_comptime_selector(g, (*expr._v__ast__ComptimeSelector)); // Defer begin if (v__gen__c__Gen_expr_with_opt_defer_0) { g->inside_opt_or_res = old_inside_opt_or_res; } // Defer end return _t2; } else { string _t3 = v__ast__Expr_str(&expr); // Defer begin if (v__gen__c__Gen_expr_with_opt_defer_0) { g->inside_opt_or_res = old_inside_opt_or_res; } // Defer end return _t3; } } else { string tmp_out_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_expr_with_tmp_var(g, expr, expr_typ, ret_typ, tmp_out_var); string _t4 = tmp_out_var; // Defer begin if (v__gen__c__Gen_expr_with_opt_defer_0) { g->inside_opt_or_res = old_inside_opt_or_res; } // Defer end return _t4; } string _t5 = _S(""); // Defer begin if (v__gen__c__Gen_expr_with_opt_defer_0) { g->inside_opt_or_res = old_inside_opt_or_res; } // Defer end return _t5; } VV_LOC void v__gen__c__Gen_assign_stmt(v__gen__c__Gen* g, v__ast__AssignStmt node_) { bool v__gen__c__Gen_assign_stmt_defer_0 = false; bool v__gen__c__Gen_assign_stmt_defer_1 = false; bool af; string type_to_free; string sref_name; bool v__gen__c__Gen_assign_stmt_defer_2 = false; Array_string last_curr_var_name; bool v__gen__c__Gen_assign_stmt_defer_3 = false; bool v__gen__c__Gen_assign_stmt_defer_4 = false; bool old_inside_opt_or_res; bool v__gen__c__Gen_assign_stmt_defer_5 = false; bool old_is_auto_heap; v__ast__AssignStmt node = node_; if (node.is_static) { bool is_defer_var = ((*(v__ast__Expr*)array_get(node.left, 0)))._typ == 358 /* v.ast.Ident */ && (Array_string_contains(g->defer_vars, (*(v__ast__Ident*)__as_cast(((*(v__ast__Expr*)array_get(node.left, 0)))._v__ast__Ident,((*(v__ast__Expr*)array_get(node.left, 0)))._typ, 358)).name)); if (is_defer_var && node.op == v__token__Kind__decl_assign) { return; } if (!is_defer_var) { v__gen__c__Gen_write(g, _S("static ")); } } if (node.is_volatile && ((*(v__ast__Expr*)array_get(node.left, 0)))._typ == 358 /* v.ast.Ident */ && !(Array_string_contains(g->defer_vars, (*(v__ast__Ident*)__as_cast(((*(v__ast__Expr*)array_get(node.left, 0)))._v__ast__Ident,((*(v__ast__Expr*)array_get(node.left, 0)))._typ, 358)).name))) { v__gen__c__Gen_write(g, _S("volatile ")); } v__ast__Type return_type = _const_v__ast__void_type; bool is_decl = node.op == v__token__Kind__decl_assign; g->assign_op = node.op; g->inside_assign = true; g->assign_ct_type = 0; g->arraymap_set_pos = 0; g->is_arraymap_set = false; g->is_assign_lhs = false; g->is_shared = false; v__gen__c__Gen_assign_stmt_defer_0 = true; v__token__Kind op = (is_decl ? (v__token__Kind__assign) : (node.op)); v__ast__Expr right_expr = (*(v__ast__Expr*)array_get(node.right, 0)); if (right_expr._typ == 344 /* v.ast.CallExpr */) { return_type = (*right_expr._v__ast__CallExpr).return_type; } else if (right_expr._typ == 367 /* v.ast.LockExpr */) { return_type = (*right_expr._v__ast__LockExpr).typ; } else if (right_expr._typ == 369 /* v.ast.MatchExpr */) { return_type = (*right_expr._v__ast__MatchExpr).return_type; } else if (right_expr._typ == 359 /* v.ast.IfExpr */) { return_type = (*right_expr._v__ast__IfExpr).typ; } else { } af = g->is_autofree && !g->is_builtin_mod && node.op == v__token__Kind__assign && node.left_types.len == 1 && (((*(v__ast__Expr*)array_get(node.left, 0)))._typ == 358 /* v.ast.Ident */ || ((*(v__ast__Expr*)array_get(node.left, 0)))._typ == 379 /* v.ast.SelectorExpr */); sref_name = _S(""); type_to_free = _S(""); if (af) { v__ast__Type first_left_type = (*(v__ast__Type*)array_get(node.left_types, 0)); v__ast__TypeSymbol* first_left_sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get(node.left_types, 0))); if (first_left_type == _const_v__ast__string_type || first_left_sym->kind == v__ast__Kind__array) { type_to_free = (first_left_type == _const_v__ast__string_type ? (_S("string")) : (_S("array"))); bool ok = true; v__ast__Expr left0 = (*(v__ast__Expr*)array_get(node.left, 0)); if ((left0)._typ == 358 /* v.ast.Ident */) { if (fast_string_eq((*left0._v__ast__Ident).name, _S("_"))) { ok = false; } } if (ok) { sref_name = str_intp(2, _MOV((StrIntpData[]){{_S("_sref"), 0xfe07, {.d_i32 = node.pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}})); { v__gen__c__Gen_write(g, type_to_free); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, sref_name); v__gen__c__Gen_write(g, _S(" = (")); } v__gen__c__Gen_expr(g, left0); if (v__ast__Type_has_flag(first_left_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("->val")); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("); // free "), 0xfe10, {.d_s = type_to_free}}, {_S(" on re-assignment2"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_assign_stmt_defer_1 = true; } else { af = false; } } else { af = false; } } if (return_type != _const_v__ast__void_type && return_type != 0) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, return_type); if (sym->kind == v__ast__Kind__multi_return) { v__gen__c__Gen_gen_multi_return_assign(g, (voidptr)&node, return_type, *sym); // Defer begin if (v__gen__c__Gen_assign_stmt_defer_1) { if (af) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_to_free}}, {_S("_free(&"), 0xfe10, {.d_s = sref_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_0) { g->assign_op = v__token__Kind__unknown; g->inside_assign = false; g->assign_ct_type = 0; g->arraymap_set_pos = 0; g->is_arraymap_set = false; g->is_assign_lhs = false; g->is_shared = false; } // Defer end return; } } if (node.has_cross_var) { v__gen__c__Gen_gen_cross_var_assign(g, (voidptr)&node); } if (node.right.len < node.left.len) { v__gen__c__Gen_checker_bug(g, _S("node.right.len < node.left.len"), node.pos); } if (node.right_types.len < node.left.len) { v__gen__c__Gen_checker_bug(g, _S("node.right_types.len < node.left.len"), node.pos); } if (node.left_types.len < node.left.len) { v__gen__c__Gen_checker_bug(g, _S("node.left_types.len < node.left.len"), node.pos); } last_curr_var_name = array_clone_to_depth(&g->curr_var_name, 0); v__gen__c__Gen_assign_stmt_defer_2 = true; g->curr_var_name = __new_array_with_default(0, 0, sizeof(string), 0); for (int i = 0; i < node.left.len; ++i) { v__ast__Expr* left = ((v__ast__Expr*)node.left.data) + i; bool is_auto_heap = false; v__ast__Type var_type = (*(v__ast__Type*)array_get(node.left_types, i)); v__ast__Type val_type = (*(v__ast__Type*)array_get(node.right_types, i)); v__ast__Expr val = (*(v__ast__Expr*)array_get(node.right, i)); bool is_call = false; bool gen_or = false; bool blank_assign = false; bool is_va_list = false; v__ast__Ident ident = ((v__ast__Ident){.language = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comptime = 0,.scope = ((void*)0),.obj = _const_v__ast__empty_scope_object,.mod = (string){.str=(byteptr)"", .is_lit=1},.name = (string){.str=(byteptr)"", .is_lit=1},.full_name = (string){.str=(byteptr)"", .is_lit=1},.cached_name = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.info = (v__ast__IdentInfo){._v__ast__IdentFn=HEAP(v__ast__IdentFn, ((v__ast__IdentFn){.typ = 0,})),._typ=476},.is_mut = 0,.or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.ct_expr = 0,}); int cur_indexexpr = -1; v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, var_type)); is_va_list = left_sym->language == v__ast__Language__c && fast_string_eq(left_sym->name, _S("C.va_list")); if ((left)->_typ == 358 /* v.ast.Ident */) { ident = (*left->_v__ast__Ident); array_push((array*)&g->curr_var_name, _MOV((string[]){ string_clone(ident.name) })); blank_assign = (*left->_v__ast__Ident).kind == v__ast__IdentKind__blank_ident; v__ast__IdentInfo left_info = (*left->_v__ast__Ident).info; if ((left_info)._typ == 477 /* v.ast.IdentVar */) { v__ast__ShareType share = (*left_info._v__ast__IdentVar).share; if (share == v__ast__ShareType__shared_t) { var_type = v__ast__Type_set_flag(var_type, v__ast__TypeFlag__shared_f); } if (share == v__ast__ShareType__atomic_t) { var_type = v__ast__Type_set_flag(var_type, v__ast__TypeFlag__atomic_f); } } if (((*left->_v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { if (is_decl) { if ((val)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((val)._v__ast__Ident,(val)._typ, 358)).ct_expr) { v__ast__Type ctyp = v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, val)); if (ctyp != _const_v__ast__void_type) { var_type = ctyp; val_type = var_type; gen_or = (*val._v__ast__Ident).or_expr.kind != v__ast__OrKind__absent; if (gen_or) { var_type = v__ast__Type_clear_flag(val_type, v__ast__TypeFlag__option); } (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = var_type; g->assign_ct_type = var_type; } } else if ((val)._typ == 350 /* v.ast.ComptimeSelector */) { if (((*val._v__ast__ComptimeSelector).typ_key).len != 0) { if (is_decl) { var_type = v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, (*val._v__ast__ComptimeSelector).typ_key, var_type); val_type = var_type; (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = var_type; } else { val_type = v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, (*val._v__ast__ComptimeSelector).typ_key, var_type); } g->assign_ct_type = var_type; } } else if ((val)._typ == 349 /* v.ast.ComptimeCall */) { string key_str = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*val._v__ast__ComptimeCall).method_name}}, {_S(".return_type"), 0, { .d_c = 0 }}})); var_type = v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, key_str, var_type); (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = var_type; g->assign_ct_type = var_type; } else if ((val)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((val)._v__ast__Ident,(val)._typ, 358)).info)._typ == 477 /* v.ast.IdentVar */) { v__ast__IdentVar val_info = *(v__ast__IdentVar*)__as_cast((((*val._v__ast__Ident)).info)._v__ast__IdentVar,(((*val._v__ast__Ident)).info)._typ, 477); gen_or = (*val._v__ast__Ident).or_expr.kind != v__ast__OrKind__absent; if (val_info.is_option && gen_or) { var_type = v__ast__Type_clear_flag(val_type, v__ast__TypeFlag__option); (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = var_type; } } else if ((val)._typ == 353 /* v.ast.DumpExpr */) { if (((*val._v__ast__DumpExpr).expr)._typ == 350 /* v.ast.ComptimeSelector */) { if (((*(*val._v__ast__DumpExpr).expr._v__ast__ComptimeSelector).typ_key).len != 0) { var_type = v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, (*(*val._v__ast__DumpExpr).expr._v__ast__ComptimeSelector).typ_key, var_type); val_type = var_type; (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = var_type; } g->assign_ct_type = var_type; } } else if ((val)._typ == 361 /* v.ast.IndexExpr */ && (((*(v__ast__IndexExpr*)__as_cast((val)._v__ast__IndexExpr,(val)._typ, 361)).left)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*(v__ast__IndexExpr*)__as_cast((val)._v__ast__IndexExpr,(val)._typ, 361)).left)._v__ast__Ident,((*(v__ast__IndexExpr*)__as_cast((val)._v__ast__IndexExpr,(val)._typ, 361)).left)._typ, 358)).ct_expr)) { v__ast__Type ctyp = v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, val)); if (ctyp != _const_v__ast__void_type) { var_type = ctyp; val_type = var_type; (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = var_type; g->assign_ct_type = var_type; } } else if ((*(*left->_v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__generic_var && (val)._typ == 344 /* v.ast.CallExpr */) { if ((*val._v__ast__CallExpr).return_type_generic != 0 && v__ast__Type_has_flag((*val._v__ast__CallExpr).return_type_generic, v__ast__TypeFlag__generic)) { v__ast__Type fn_ret_type = v__gen__c__Gen_resolve_return_type(g, (*val._v__ast__CallExpr)); if (fn_ret_type != _const_v__ast__void_type) { var_type = fn_ret_type; val_type = var_type; (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = var_type; } } else if ((*val._v__ast__CallExpr).is_static_method && v__ast__Type_has_flag((*val._v__ast__CallExpr).left_type, v__ast__TypeFlag__generic)) { v__ast__Type fn_ret_type = v__gen__c__Gen_resolve_return_type(g, (*val._v__ast__CallExpr)); var_type = fn_ret_type; val_type = var_type; (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = var_type; g->assign_ct_type = var_type; } else if ((*val._v__ast__CallExpr).left_type != 0 && v__ast__Table_type_kind(g->table, (*val._v__ast__CallExpr).left_type) == v__ast__Kind__array && fast_string_eq((*val._v__ast__CallExpr).name, _S("map")) && (*val._v__ast__CallExpr).args.len > 0 && ((*(v__ast__CallArg*)array_get((*val._v__ast__CallExpr).args, 0)).expr)._typ == 339 /* v.ast.AsCast */ && v__ast__Type_has_flag((*(v__ast__AsCast*)__as_cast(((*(v__ast__CallArg*)array_get((*val._v__ast__CallExpr).args, 0)).expr)._v__ast__AsCast,((*(v__ast__CallArg*)array_get((*val._v__ast__CallExpr).args, 0)).expr)._typ, 339)).typ, v__ast__TypeFlag__generic)) { var_type = v__ast__Table_find_or_register_array(g->table, v__gen__c__Gen_unwrap_generic(g, ((*(*(v__ast__CallArg*)array_get((*val._v__ast__CallExpr).args, 0)).expr._v__ast__AsCast)).typ)); val_type = var_type; (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = var_type; g->assign_ct_type = var_type; } } else if ((val)._typ == 362 /* v.ast.InfixExpr */ && ((*(v__ast__InfixExpr*)__as_cast((val)._v__ast__InfixExpr,(val)._typ, 362)).op == v__token__Kind__plus || (*(v__ast__InfixExpr*)__as_cast((val)._v__ast__InfixExpr,(val)._typ, 362)).op == v__token__Kind__minus || (*(v__ast__InfixExpr*)__as_cast((val)._v__ast__InfixExpr,(val)._typ, 362)).op == v__token__Kind__mul || (*(v__ast__InfixExpr*)__as_cast((val)._v__ast__InfixExpr,(val)._typ, 362)).op == v__token__Kind__div || (*(v__ast__InfixExpr*)__as_cast((val)._v__ast__InfixExpr,(val)._typ, 362)).op == v__token__Kind__mod) && (*(v__ast__InfixExpr*)__as_cast((val)._v__ast__InfixExpr,(val)._typ, 362)).left_ct_expr) { v__ast__Type ctyp = v__type_resolver__TypeResolver_promote_type(&g->type_resolver, v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, (*val._v__ast__InfixExpr).left)), v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, (*val._v__ast__InfixExpr).right, (*val._v__ast__InfixExpr).right_type))); if (ctyp != _const_v__ast__void_type) { v__ast__ComptimeVarKind ct_type_var = v__type_resolver__ResolverInfo_get_ct_type_var(g->comptime, (*val._v__ast__InfixExpr).left); if (ct_type_var == v__ast__ComptimeVarKind__key_var || ct_type_var == v__ast__ComptimeVarKind__value_var) { v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, (*left->_v__ast__Ident).name, v__gen__c__Gen_unwrap_generic(g, ctyp)); } var_type = ctyp; val_type = var_type; (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = var_type; g->assign_ct_type = var_type; } } else if ((val)._typ == 375 /* v.ast.PostfixExpr */ && (*(v__ast__PostfixExpr*)__as_cast((val)._v__ast__PostfixExpr,(val)._typ, 375)).op == v__token__Kind__question && (((*(v__ast__PostfixExpr*)__as_cast((val)._v__ast__PostfixExpr,(val)._typ, 375)).expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*(v__ast__PostfixExpr*)__as_cast((val)._v__ast__PostfixExpr,(val)._typ, 375)).expr)._v__ast__Ident,((*(v__ast__PostfixExpr*)__as_cast((val)._v__ast__PostfixExpr,(val)._typ, 375)).expr)._typ, 358)).ct_expr)) { v__ast__Type ctyp = v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, val)); if (ctyp != _const_v__ast__void_type) { var_type = ctyp; val_type = var_type; (*(*left->_v__ast__Ident).obj._v__ast__Var).typ = var_type; g->assign_ct_type = var_type; v__ast__ComptimeVarKind ct_type_var = v__type_resolver__ResolverInfo_get_ct_type_var(g->comptime, (*val._v__ast__PostfixExpr).expr); if (ct_type_var == v__ast__ComptimeVarKind__field_var) { v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, (*left->_v__ast__Ident).name, ctyp); } } } } is_auto_heap = (*(*left->_v__ast__Ident).obj._v__ast__Var).is_auto_heap; } } else if ((left)->_typ == 350 /* v.ast.ComptimeSelector */) { if (((*left->_v__ast__ComptimeSelector).typ_key).len != 0) { var_type = v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, (*left->_v__ast__ComptimeSelector).typ_key, var_type); } g->assign_ct_type = var_type; if ((val)._typ == 350 /* v.ast.ComptimeSelector */) { if (((*val._v__ast__ComptimeSelector).typ_key).len != 0) { val_type = v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, (*val._v__ast__ComptimeSelector).typ_key, var_type); } } else if ((val)._typ == 344 /* v.ast.CallExpr */) { g->assign_ct_type = g->comptime->comptime_for_field_type; } } else if ((left)->_typ == 361 /* v.ast.IndexExpr */ && (val)._typ == 350 /* v.ast.ComptimeSelector */) { if (((*val._v__ast__ComptimeSelector).typ_key).len != 0) { val_type = v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, (*val._v__ast__ComptimeSelector).typ_key, var_type); } g->assign_ct_type = val_type; } string styp = v__gen__c__Gen_styp(g, var_type); bool is_fixed_array_init = false; bool has_val = false; if (val._typ == 338 /* v.ast.ArrayInit */) { is_fixed_array_init = (*val._v__ast__ArrayInit).is_fixed; has_val = (*val._v__ast__ArrayInit).has_val; } else if (val._typ == 344 /* v.ast.CallExpr */) { is_call = true; if ((*val._v__ast__CallExpr).comptime_ret_val) { return_type = g->comptime->comptime_for_field_type; styp = v__gen__c__Gen_styp(g, return_type); } else { return_type = (*val._v__ast__CallExpr).return_type; } } else if (val._typ == 336 /* v.ast.AnonFn */) { if (!v__ast__Type_has_option_or_result(var_type)) { if (blank_assign) { v__gen__c__Gen_write(g, _S("{")); } if ((is_decl || blank_assign) && (left)->_typ == 358 /* v.ast.Ident */) { Array_v__ast__Type _t2 = {0}; Array_v__ast__Param _t2_orig = (*val._v__ast__AnonFn).decl.params; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(v__ast__Type)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Param it = ((v__ast__Param*) _t2_orig.data)[_t4]; v__ast__Type _t3 = it.typ; array_push((array*)&_t2, &_t3); } string sig = v__gen__c__Gen_fn_var_signature(g, (*val._v__ast__AnonFn).decl.return_type,_t2, ident.name); v__gen__c__Gen_write(g, string__plus(sig, _S(" = "))); } else { g->is_assign_lhs = true; g->assign_op = node.op; v__gen__c__Gen_expr(g, *left); g->is_assign_lhs = false; g->is_arraymap_set = false; if ((left)->_typ == 361 /* v.ast.IndexExpr */) { v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, (*left->_v__ast__IndexExpr).left_type); if (sym->kind == v__ast__Kind__map || sym->kind == v__ast__Kind__array) { v__gen__c__Gen_expr(g, val); v__gen__c__Gen_writeln(g, _S("});")); continue; } } v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, val); v__gen__c__Gen_writeln(g, _S(";")); if (blank_assign) { v__gen__c__Gen_write(g, _S("}")); } continue; } } else { } v__ast__Type unwrapped_val_type = v__gen__c__Gen_unwrap_generic(g, val_type); v__ast__TypeSymbol* right_sym = v__ast__Table_sym(g->table, unwrapped_val_type); v__ast__TypeSymbol* unaliased_right_sym = v__ast__Table_final_sym(g->table, unwrapped_val_type); bool is_fixed_array_var = !g->pref->translated && unaliased_right_sym->kind == v__ast__Kind__array_fixed && (val)._typ != 338 /* v.ast.ArrayInit */ && (((val)._typ == 358 /* v.ast.Ident */ || (val)._typ == 361 /* v.ast.IndexExpr */ || (val)._typ == 344 /* v.ast.CallExpr */ || (val)._typ == 379 /* v.ast.SelectorExpr */ || (val)._typ == 353 /* v.ast.DumpExpr */ || (val)._typ == 362 /* v.ast.InfixExpr */) || ((val)._typ == 345 /* v.ast.CastExpr */ && ((*(v__ast__CastExpr*)__as_cast((val)._v__ast__CastExpr,(val)._typ, 345)).expr)._typ != 338 /* v.ast.ArrayInit */) || ((val)._typ == 376 /* v.ast.PrefixExpr */ && (*(v__ast__PrefixExpr*)__as_cast((val)._v__ast__PrefixExpr,(val)._typ, 376)).op == v__token__Kind__arrow) || ((val)._typ == 388 /* v.ast.UnsafeExpr */ && (((*(v__ast__UnsafeExpr*)__as_cast((val)._v__ast__UnsafeExpr,(val)._typ, 388)).expr)._typ == 379 /* v.ast.SelectorExpr */ || ((*(v__ast__UnsafeExpr*)__as_cast((val)._v__ast__UnsafeExpr,(val)._typ, 388)).expr)._typ == 358 /* v.ast.Ident */ || ((*(v__ast__UnsafeExpr*)__as_cast((val)._v__ast__UnsafeExpr,(val)._typ, 388)).expr)._typ == 344 /* v.ast.CallExpr */))); g->is_assign_lhs = true; g->assign_op = node.op; g->left_is_opt = v__ast__Type_has_option_or_result(var_type); g->right_is_opt = v__ast__Type_has_option_or_result(val_type); v__gen__c__Gen_assign_stmt_defer_3 = true; if (blank_assign) { if ((val)._typ == 361 /* v.ast.IndexExpr */) { g->assign_op = v__token__Kind__decl_assign; } g->is_assign_lhs = false; if (is_call) { bool old_is_void_expr_stmt = g->is_void_expr_stmt; g->is_void_expr_stmt = true; v__gen__c__Gen_expr(g, val); g->is_void_expr_stmt = old_is_void_expr_stmt; } else if (g->inside_for_c_stmt) { v__gen__c__Gen_expr(g, val); } else if (v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_opt(g, val, val_type, var_type); } else { if (left_sym->kind == v__ast__Kind__function) { v__gen__c__Gen_write(g, _S("{void* _ = ")); } else { { v__gen__c__Gen_write(g, _S("{")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" _ = ")); } } if (((val)._typ == 369 /* v.ast.MatchExpr */ || (val)._typ == 359 /* v.ast.IfExpr */) && (unaliased_right_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { string tmp_var = v__gen__c__Gen_expr_with_var(g, val, var_type, false); v__gen__c__Gen_fixed_array_var_init(g, tmp_var, false, (*unaliased_right_sym->info._v__ast__ArrayFixed).elem_type, (*unaliased_right_sym->info._v__ast__ArrayFixed).size); } else { v__gen__c__Gen_expr(g, val); } v__gen__c__Gen_writeln(g, _S(";}")); } } else if (node.op == v__token__Kind__assign && !g->pref->translated && (is_fixed_array_init || (unaliased_right_sym->kind == v__ast__Kind__array_fixed && ((val)._typ == 358 /* v.ast.Ident */ || (val)._typ == 345 /* v.ast.CastExpr */)))) { if (is_fixed_array_init && v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr(g, *left); v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_expr_with_opt(g, val, val_type, var_type); } else if (unaliased_right_sym->kind == v__ast__Kind__array_fixed && (val)._typ == 345 /* v.ast.CastExpr */) { if (v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr(g, *left); v__gen__c__Gen_writeln(g, _S(".state = 0;")); v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_expr(g, *left); v__gen__c__Gen_write(g, _S(".data, ")); v__gen__c__Gen_expr(g, val); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(var_type, v__ast__TypeFlag__option))}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_expr(g, *left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, val); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, var_type)}}, {_S("));"), 0, { .d_c = 0 }}}))); } } else { string v_var = _S(""); string arr_typ = string_trim(styp, _S("*")); if (is_fixed_array_init) { v__ast__ArrayInit right = *(v__ast__ArrayInit*)__as_cast((val)._v__ast__ArrayInit,(val)._typ, 338); v_var = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, arr_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, v_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, v__ast__ArrayInit_to_sumtype_v__ast__Expr(&right)); v__gen__c__Gen_writeln(g, _S(";")); } else { v__ast__Ident right = *(v__ast__Ident*)__as_cast((val)._v__ast__Ident,(val)._typ, 358); v_var = right.name; } int pos = g->out.len; v__gen__c__Gen_expr(g, *left); if (g->is_arraymap_set && g->arraymap_set_pos >= 0) { if (g->arraymap_set_pos > 0) { v__gen__c__Gen_go_back_to(g, g->arraymap_set_pos); } { v__gen__c__Gen_write(g, _S(", &")); v__gen__c__Gen_write(g, v_var); v__gen__c__Gen_write(g, _S(")")); } g->is_arraymap_set = false; g->arraymap_set_pos = 0; } else { v__gen__c__Gen_go_back_to(g, pos); bool is_var_mut = !is_decl && v__ast__Expr_is_auto_deref_var(*left); string addr_left = (is_var_mut ? (_S("")) : (_S("&"))); v__gen__c__Gen_writeln(g, _S("")); { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, addr_left); } v__gen__c__Gen_expr(g, *left); string addr_val = (is_fixed_array_var ? (_S("")) : (_S("&"))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(", "), 0xfe10, {.d_s = addr_val}}, {_SLIT0, 0xfe10, {.d_s = v_var}}, {_S(", sizeof("), 0xfe10, {.d_s = arr_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } g->is_assign_lhs = false; } } else { bool is_inside_ternary = g->inside_ternary != 0; string _t5; /* if prepend */ if (is_inside_ternary && is_decl) { v__gen__c__Gen_register_ternary_name(g, ident.name); g->empty_line = false; _t5 = v__gen__c__Gen_go_before_ternary(g); } else { _t5 = _S(""); } string cur_line = _t5; bool str_add = false; bool op_overloaded = false; v__ast__Type op_expected_left = _const_v__ast__no_type; v__ast__Type op_expected_right = _const_v__ast__no_type; bool is_shared_re_assign = !is_decl && v__ast__Type_has_flag((*(v__ast__Type*)array_get(node.left_types, i)), v__ast__TypeFlag__shared_f) && (left)->_typ == 358 /* v.ast.Ident */ && (left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__map || left_sym->kind == v__ast__Kind__struct); if (node.op == v__token__Kind__plus_assign && unaliased_right_sym->kind == v__ast__Kind__string) { if ((left)->_typ == 361 /* v.ast.IndexExpr */) { if (v__ast__Table_sym(g->table, (*left->_v__ast__IndexExpr).left_type)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_expr(g, v__ast__IndexExpr_to_sumtype_v__ast__Expr(&(*left->_v__ast__IndexExpr))); v__gen__c__Gen_write(g, _S(" = string__plus(")); } else { v__gen__c__Gen_expr(g, v__ast__IndexExpr_to_sumtype_v__ast__Expr(&(*left->_v__ast__IndexExpr))); v__gen__c__Gen_write(g, _S("string__plus(")); } } else { if (v__ast__Expr_is_auto_deref_var(*left)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, *left); v__gen__c__Gen_write(g, _S(" = string__plus(")); } g->is_assign_lhs = false; str_add = true; } if (((left_sym->kind == v__ast__Kind__struct && right_sym->kind == v__ast__Kind__struct) || (left_sym->kind == v__ast__Kind__alias && right_sym->kind == v__ast__Kind__alias)) && (node.op == v__token__Kind__plus_assign || node.op == v__token__Kind__minus_assign || node.op == v__token__Kind__div_assign || node.op == v__token__Kind__mult_assign || node.op == v__token__Kind__mod_assign)) { string _t6 = (string){.str=(byteptr)"", .is_lit=1}; if (node.op == (v__token__Kind__plus_assign)) { _t6 = _S("+"); } else if (node.op == (v__token__Kind__minus_assign)) { _t6 = _S("-"); } else if (node.op == (v__token__Kind__div_assign)) { _t6 = _S("/"); } else if (node.op == (v__token__Kind__mod_assign)) { _t6 = _S("%"); } else if (node.op == (v__token__Kind__mult_assign)) { _t6 = _S("*"); } else { _t6 = _S("unknown op"); }string extracted_op = _t6; int pos = g->out.len; v__gen__c__Gen_expr(g, *left); if ((left_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((left_sym->info)._v__ast__Struct,(left_sym->info)._typ, 518)).generic_types.len > 0) { Array_v__ast__Type concrete_types = (*left_sym->info._v__ast__Struct).concrete_types; string method_name = string__plus(string__plus(left_sym->cname, _S("_")), v__util__replace_op(extracted_op)); method_name = v__gen__c__Gen_generic_fn_name(g, concrete_types, method_name); { v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_write(g, method_name); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_expr(g, *left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, val); v__gen__c__Gen_writeln(g, _S(");")); // Defer begin if (v__gen__c__Gen_assign_stmt_defer_3) { g->left_is_opt = false; g->right_is_opt = false; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_2) { g->curr_var_name = last_curr_var_name; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_1) { if (af) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_to_free}}, {_S("_free(&"), 0xfe10, {.d_s = sref_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_0) { g->assign_op = v__token__Kind__unknown; g->inside_assign = false; g->assign_ct_type = 0; g->arraymap_set_pos = 0; g->is_arraymap_set = false; g->is_assign_lhs = false; g->is_shared = false; } // Defer end return; } else if (left_sym->kind == v__ast__Kind__alias && v__ast__TypeSymbol_is_number(v__ast__Table_final_sym(g->table, v__gen__c__Gen_unwrap_generic(g, var_type))) && !v__ast__TypeSymbol_has_method(left_sym, extracted_op)) { v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_expr(g, *left); { v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, extracted_op); v__gen__c__Gen_write(g, _S(" ")); } v__gen__c__Gen_expr(g, val); if (!g->inside_for_c_stmt) { v__gen__c__Gen_write(g, _S(";")); } // Defer begin if (v__gen__c__Gen_assign_stmt_defer_3) { g->left_is_opt = false; g->right_is_opt = false; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_2) { g->curr_var_name = last_curr_var_name; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_1) { if (af) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_to_free}}, {_S("_free(&"), 0xfe10, {.d_s = sref_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_0) { g->assign_op = v__token__Kind__unknown; g->inside_assign = false; g->assign_ct_type = 0; g->arraymap_set_pos = 0; g->is_arraymap_set = false; g->is_assign_lhs = false; g->is_shared = false; } // Defer end return; } else if (left_sym->kind == v__ast__Kind__alias && v__ast__Table_final_sym(g->table, var_type)->kind == v__ast__Kind__struct) { v__ast__TypeSymbol* struct_info = v__ast__Table_final_sym(g->table, var_type); if ((struct_info->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((struct_info->info)._v__ast__Struct,(struct_info->info)._typ, 518)).generic_types.len > 0) { string method_name = string__plus(string__plus(struct_info->cname, _S("_")), v__util__replace_op(extracted_op)); method_name = v__gen__c__Gen_generic_fn_name(g, (*struct_info->info._v__ast__Struct).concrete_types, method_name); { v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_write(g, method_name); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_expr(g, *left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, val); v__gen__c__Gen_writeln(g, _S(");")); // Defer begin if (v__gen__c__Gen_assign_stmt_defer_3) { g->left_is_opt = false; g->right_is_opt = false; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_2) { g->curr_var_name = last_curr_var_name; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_1) { if (af) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_to_free}}, {_S("_free(&"), 0xfe10, {.d_s = sref_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_0) { g->assign_op = v__token__Kind__unknown; g->inside_assign = false; g->assign_ct_type = 0; g->arraymap_set_pos = 0; g->is_arraymap_set = false; g->is_assign_lhs = false; g->is_shared = false; } // Defer end return; } } else { if (v__ast__Table_final_sym(g->table, v__gen__c__Gen_unwrap_generic(g, var_type))->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_go_back_to(g, pos); g->empty_line = true; v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_expr(g, *left); { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, v__util__replace_op(extracted_op)); v__gen__c__Gen_write(g, _S("(")); } } else { { v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, v__util__replace_op(extracted_op)); v__gen__c__Gen_write(g, _S("(")); } } _result_v__ast__Fn _t7 = v__ast__Table_find_method(g->table, left_sym, extracted_op); if (_t7.is_error) { IError err = _t7.err; v__gen__c__Gen_error(g, str_intp(3, _MOV((StrIntpData[]){{_S("assignment operator `"), 0xfe10, {.d_s = extracted_op}}, {_S("=` used but no `"), 0xfe10, {.d_s = extracted_op}}, {_S("` method defined"), 0, { .d_c = 0 }}})), node.pos); VUNREACHABLE(); *(v__ast__Fn*) _t7.data = ((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); } v__ast__Fn method = (*(v__ast__Fn*)_t7.data); op_expected_left = (*(v__ast__Param*)array_get(method.params, 0)).typ; op_expected_right = (*(v__ast__Param*)array_get(method.params, 1)).typ; op_overloaded = true; } } v__ast__TypeSymbol* final_left_sym = v__ast__Table_final_sym(g->table, v__gen__c__Gen_unwrap_generic(g, var_type)); v__ast__TypeSymbol* final_right_sym = v__ast__Table_final_sym(g->table, unwrapped_val_type); int aligned = 0; if ((final_left_sym->info)._typ == 518 /* v.ast.Struct */) { _option_v__ast__Attr _t8; if (_t8 = Array_v__ast__Attr_find_first((*final_left_sym->info._v__ast__Struct).attrs, _S("aligned")), _t8.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t8.data; aligned = ((attr.arg).len == 0 ? (0) : (string_int(attr.arg))); } } if (final_left_sym->kind == v__ast__Kind__bool && final_right_sym->kind == v__ast__Kind__bool && (node.op == v__token__Kind__boolean_or_assign || node.op == v__token__Kind__boolean_and_assign)) { string extracted_op = ((node.op == (v__token__Kind__boolean_or_assign))? (_S("||")) : (node.op == (v__token__Kind__boolean_and_assign))? (_S("&&")) : (_S("unknown op"))); v__gen__c__Gen_expr(g, *left); v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_expr(g, *left); { v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, extracted_op); v__gen__c__Gen_write(g, _S(" ")); } v__gen__c__Gen_expr(g, val); v__gen__c__Gen_writeln(g, _S(";")); // Defer begin if (v__gen__c__Gen_assign_stmt_defer_3) { g->left_is_opt = false; g->right_is_opt = false; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_2) { g->curr_var_name = last_curr_var_name; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_1) { if (af) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_to_free}}, {_S("_free(&"), 0xfe10, {.d_s = sref_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_0) { g->assign_op = v__token__Kind__unknown; g->inside_assign = false; g->assign_ct_type = 0; g->arraymap_set_pos = 0; g->is_arraymap_set = false; g->is_assign_lhs = false; g->is_shared = false; } // Defer end return; } if ((right_sym->info)._typ == 553 /* v.ast.FnType */ && is_decl) { if (is_inside_ternary) { strings__Builder_write_string(&g->out, v__util__tabs((int)(g->indent - g->inside_ternary))); } string fn_name = v__gen__c__c_fn_name(v__gen__c__Gen_get_ternary_name(g, ident.name)); if (v__ast__Type_has_flag(val_type, v__ast__TypeFlag__option)) { string ret_styp = v__gen__c__Gen_styp(g, v__gen__c__Gen_unwrap_generic(g, val_type)); { v__gen__c__Gen_write(g, ret_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, fn_name); } } else { string ret_styp = v__gen__c__Gen_styp(g, (*right_sym->info._v__ast__FnType).func.return_type); string call_conv = _S(""); string msvc_call_conv = _S(""); for (int _t9 = 0; _t9 < (*right_sym->info._v__ast__FnType).func.attrs.len; ++_t9) { v__ast__Attr attr = ((v__ast__Attr*)(*right_sym->info._v__ast__FnType).func.attrs.data)[_t9]; if (_SLIT_EQ(attr.name.str, attr.name.len, "callconv")) { if (g->is_cc_msvc) { msvc_call_conv = str_intp(2, _MOV((StrIntpData[]){{_S("__"), 0xfe10, {.d_s = attr.arg}}, {_S(" "), 0, { .d_c = 0 }}})); } else { call_conv = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = attr.arg}}, {_SLIT0, 0, { .d_c = 0 }}})); } } else { } } string call_conv_attribute_suffix = (call_conv.len != 0 ? (str_intp(2, _MOV((StrIntpData[]){{_S("__attribute__(("), 0xfe10, {.d_s = call_conv}}, {_S("))"), 0, { .d_c = 0 }}}))) : (_S(""))); { v__gen__c__Gen_write(g, ret_styp); v__gen__c__Gen_write(g, _S(" (")); v__gen__c__Gen_write(g, msvc_call_conv); v__gen__c__Gen_write(g, _S("*")); v__gen__c__Gen_write(g, fn_name); v__gen__c__Gen_write(g, _S(") (")); } int def_pos = g->definitions.len; v__gen__c__Gen_fn_decl_params(g, (*right_sym->info._v__ast__FnType).func.params, ((void*)0), false, false); strings__Builder_go_back(&g->definitions, (int)(g->definitions.len - def_pos)); { v__gen__c__Gen_write(g, _S(")")); v__gen__c__Gen_write(g, call_conv_attribute_suffix); } } } else { if (is_decl) { if (is_inside_ternary) { strings__Builder_write_string(&g->out, v__util__tabs((int)(g->indent - g->inside_ternary))); } bool is_used_var_styp = false; if (!(Array_string_contains(g->defer_vars, ident.name))) { v__ast__TypeSymbol* val_sym = v__ast__Table_sym(g->table, val_type); if ((val_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((val_sym->info)._v__ast__Struct,(val_sym->info)._typ, 518)).generic_types.len > 0) { if ((val)._typ == 385 /* v.ast.StructInit */) { string var_styp = v__gen__c__Gen_styp(g, (*val._v__ast__StructInit).typ); if (v__ast__Type_has_flag(var_type, v__ast__TypeFlag__shared_f)) { { v__gen__c__Gen_write(g, _S("__shared__")); v__gen__c__Gen_write(g, var_styp); v__gen__c__Gen_write(g, _S("* ")); } } else { { v__gen__c__Gen_write(g, var_styp); v__gen__c__Gen_write(g, _S(" ")); } } is_used_var_styp = true; } else if ((val)._typ == 376 /* v.ast.PrefixExpr */) { if ((*val._v__ast__PrefixExpr).op == v__token__Kind__amp && ((*val._v__ast__PrefixExpr).right)._typ == 385 /* v.ast.StructInit */) { string var_styp = v__gen__c__Gen_styp(g, v__ast__Type_ref((*(*val._v__ast__PrefixExpr).right._v__ast__StructInit).typ)); if (v__ast__Type_has_flag(var_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("__shared__")); } { v__gen__c__Gen_write(g, var_styp); v__gen__c__Gen_write(g, _S(" ")); } is_used_var_styp = true; } } } if (!is_used_var_styp) { if (!v__ast__Type_has_flag(val_type, v__ast__TypeFlag__option) && v__ast__TypeSymbol_is_array_fixed(left_sym)) { if ((left_sym->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* parent_sym = v__ast__Table_final_sym(g->table, (*left_sym->info._v__ast__Alias).parent_type); styp = v__gen__c__Gen_styp(g, (*left_sym->info._v__ast__Alias).parent_type); if (!v__ast__TypeSymbol_is_array_fixed_ret(parent_sym)) { { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); } } else { { v__gen__c__Gen_write(g, string_substr(styp, 3, 2147483647)); v__gen__c__Gen_write(g, _S(" ")); } } } else { if (!v__ast__TypeSymbol_is_array_fixed_ret(left_sym)) { { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); } } else { { v__gen__c__Gen_write(g, string_substr(styp, 3, 2147483647)); v__gen__c__Gen_write(g, _S(" ")); } } } } else { { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); } } } if (is_auto_heap && !(v__ast__Type_is_ptr(val_type) && v__ast__Type_has_flag(val_type, v__ast__TypeFlag__option))) { v__gen__c__Gen_write(g, _S("*")); } } } if ((left)->_typ == 358 /* v.ast.Ident */ || (left)->_typ == 379 /* v.ast.SelectorExpr */) { g->prevent_sum_type_unwrapping_once = true; } if (!is_fixed_array_var || is_decl || is_shared_re_assign) { if (op_overloaded) { v__gen__c__Gen_op_arg(g, *left, op_expected_left, var_type); } else { if (!is_decl && !is_shared_re_assign && v__ast__Expr_is_auto_deref_var(*left) && !v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_write(g, _S("*")); } if (node_.op == v__token__Kind__assign && v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option_mut_param_t)) { v__gen__c__Gen_write(g, _S("memcpy(&")); v__gen__c__Gen_expr(g, *left); { v__gen__c__Gen_write(g, _S("->data, *(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, val_type)); v__gen__c__Gen_write(g, _S("**)&")); } } else if (v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option_mut_param_t)) { v__gen__c__Gen_expr(g, *left); v__gen__c__Gen_write(g, _S(" = ")); } else { v__gen__c__Gen_expr(g, *left); } if (!is_decl && v__ast__Type_has_flag(var_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("->val")); } } } } if (is_inside_ternary && is_decl) { { v__gen__c__Gen_write(g, _S(";\n")); v__gen__c__Gen_write(g, cur_line); } strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); v__gen__c__Gen_expr(g, *left); } g->is_assign_lhs = false; if ((left)->_typ == 361 /* v.ast.IndexExpr */ && g->cur_indexexpr.len > 0) { cur_indexexpr = Array_int_index(g->cur_indexexpr, v__ast__Expr_pos(*left).pos); } if (is_fixed_array_var || is_va_list) { if (is_decl) { v__gen__c__Gen_writeln(g, _S(";")); if (is_va_list) { continue; } } } else if (!v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option_mut_param_t) && cur_indexexpr == -1 && !str_add && !op_overloaded) { v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = v__token__Kind_str(op)}}, {_S(" "), 0, { .d_c = 0 }}}))); } else if (str_add || op_overloaded) { v__gen__c__Gen_write(g, _S(", ")); } bool cloned = false; if (g->is_autofree) { if ((right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__string) && !v__ast__Type_has_flag(unwrapped_val_type, v__ast__TypeFlag__shared_f)) { if (v__gen__c__Gen_gen_clone_assignment(g, var_type, val, unwrapped_val_type, false)) { cloned = true; } } else if ((right_sym->info)._typ == 542 /* v.ast.Interface */ && var_type != _const_v__ast__error_type) { v__gen__c__Gen_register_free_method(g, var_type); } } if (!cloned) { if ((g->comptime->comptime_for_field_var).len == 0 && ((v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option) && !v__ast__Type_has_flag(val_type, v__ast__TypeFlag__option)) || (v__ast__Type_has_flag(var_type, v__ast__TypeFlag__result) && !v__ast__Type_has_flag(val_type, v__ast__TypeFlag__result)))) { old_inside_opt_or_res = g->inside_opt_or_res; v__gen__c__Gen_assign_stmt_defer_4 = true; g->inside_opt_or_res = true; if (is_auto_heap && v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_write(g, _S("&")); } string tmp_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_expr_with_tmp_var(g, val, val_type, var_type, tmp_var); } else if (is_fixed_array_var) { string typ_str = string_trim(v__gen__c__Gen_styp(g, val_type), _S("*")); string final_typ_str = (is_fixed_array_var ? (_S("")) : (str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = typ_str}}, {_S("*)"), 0, { .d_c = 0 }}})))); string final_ref_str = (is_fixed_array_var ? (_S("")) : v__ast__Type_is_ptr(val_type) ? (_S("(byte*)")) : (_S("(byte*)&"))); if (v__ast__Type_has_flag(val_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr(g, *left); v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_expr(g, val); } else { if (op_overloaded) { v__gen__c__Gen_expr(g, *left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, val); { v__gen__c__Gen_write(g, _S(").ret_arr, sizeof(")); v__gen__c__Gen_write(g, typ_str); v__gen__c__Gen_write(g, _S(")")); } } else { { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, final_typ_str); } v__gen__c__Gen_expr(g, *left); { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, final_ref_str); } v__gen__c__Gen_expr(g, val); { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, typ_str); v__gen__c__Gen_write(g, _S("))")); } } } } else if (is_decl) { g->is_shared = v__ast__Type_has_flag(var_type, v__ast__TypeFlag__shared_f); if (is_fixed_array_init && !has_val) { if ((val)._typ == 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_array_init(g, (*val._v__ast__ArrayInit), v__gen__c__c_name(ident.name)); } else { v__gen__c__Gen_write(g, _S("{0}")); } } else { bool is_option_unwrapped = (val)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((val)._v__ast__Ident,(val)._typ, 358)).or_expr.kind != v__ast__OrKind__absent; bool is_option_auto_heap = is_auto_heap && is_option_unwrapped; if (is_auto_heap) { if (aligned != 0) { { v__gen__c__Gen_write(g, _S("HEAP_align(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(", (")); } } else { { v__gen__c__Gen_write(g, _S("HEAP(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(", (")); } } } if (v__ast__Expr_is_auto_deref_var(val) && !is_option_unwrapped) { v__gen__c__Gen_write(g, _S("*")); } if ((v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option) && !((val)._typ == 358 /* v.ast.Ident */ || (val)._typ == 379 /* v.ast.SelectorExpr */)) || gen_or) { v__gen__c__Gen_expr_with_opt_or_block(g, val, val_type, *left, var_type, is_option_auto_heap); } else if ((val)._typ == 338 /* v.ast.ArrayInit */) { string cvar_name = v__gen__c__c_name(ident.name); if ((*val._v__ast__ArrayInit).is_fixed && (Array_string_contains(g->defer_vars, ident.name))) { v__gen__c__Gen_go_before_last_stmt(g); g->empty_line = true; { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, cvar_name); v__gen__c__Gen_write(g, _S(", ")); } { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(")")); } v__gen__c__Gen_array_init(g, (*val._v__ast__ArrayInit), cvar_name); { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("))")); } } else { v__gen__c__Gen_array_init(g, (*val._v__ast__ArrayInit), cvar_name); } } else if (v__ast__Type_has_flag(val_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_expr_with_cast(g, val, val_type, var_type); } else if (((val)._typ == 369 /* v.ast.MatchExpr */ || (val)._typ == 359 /* v.ast.IfExpr */) && (unaliased_right_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { string tmp_var = v__gen__c__Gen_expr_with_var(g, val, var_type, false); v__gen__c__Gen_fixed_array_var_init(g, tmp_var, false, (*unaliased_right_sym->info._v__ast__ArrayFixed).elem_type, (*unaliased_right_sym->info._v__ast__ArrayFixed).size); } else { v__gen__c__Gen_expr(g, val); } if (is_auto_heap && !is_option_auto_heap) { if (aligned != 0) { { v__gen__c__Gen_write(g, _S("), ")); v__gen__c__Gen_write_decimal(g, aligned); v__gen__c__Gen_write(g, _S(")")); } } else { v__gen__c__Gen_write(g, _S("))")); } } } } else { old_is_auto_heap = g->is_option_auto_heap; v__gen__c__Gen_assign_stmt_defer_5 = true; if ((val)._typ == 358 /* v.ast.Ident */ && v__ast__Ident_is_mut(((v__ast__Ident*)__as_cast((val)._v__ast__Ident,(val)._typ, 358))) && v__ast__Type_is_ptr(var_type)) { if (v__ast__Type_nr_muls(var_type) < v__ast__Type_nr_muls(val_type)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(var_type))); } } g->is_option_auto_heap = v__ast__Type_has_flag(val_type, v__ast__TypeFlag__option) && (val)._typ == 376 /* v.ast.PrefixExpr */ && ((*(v__ast__PrefixExpr*)__as_cast((val)._v__ast__PrefixExpr,(val)._typ, 376)).right)._typ == 358 /* v.ast.Ident */ && v__ast__Ident_is_auto_heap(((v__ast__Ident*)__as_cast((((v__ast__PrefixExpr*)__as_cast((val)._v__ast__PrefixExpr,(val)._typ, 376))->right)._v__ast__Ident,(((v__ast__PrefixExpr*)__as_cast((val)._v__ast__PrefixExpr,(val)._typ, 376))->right)._typ, 358))); if (v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option) || gen_or) { v__gen__c__Gen_expr_with_opt_or_block(g, val, val_type, *left, var_type, false); } else if (node.has_cross_var) { v__gen__c__Gen_gen_cross_tmp_variable(g, node.left, val); } else { if (op_overloaded) { v__gen__c__Gen_op_arg(g, val, op_expected_right, val_type); } else { v__ast__Type exp_type = v__ast__Type_clear_flag((v__ast__Type_is_ptr(var_type) && (v__ast__Expr_is_auto_deref_var(*left) || v__ast__Type_has_flag(var_type, v__ast__TypeFlag__shared_f)) ? (v__ast__Type_deref(var_type)) : (var_type)), v__ast__TypeFlag__shared_f); v__gen__c__Gen_expr_with_cast(g, val, val_type, exp_type); } } } } if (str_add || op_overloaded) { v__gen__c__Gen_write(g, _S(")")); } if (node_.op == v__token__Kind__assign && v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option_mut_param_t)) { { v__gen__c__Gen_write(g, _S(".data, sizeof(")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, val_type)); v__gen__c__Gen_write(g, _S("))")); } } if (cur_indexexpr != -1) { array_delete(&g->cur_indexexpr, cur_indexexpr); v__gen__c__Gen_write(g, _S(" })")); g->is_arraymap_set = g->cur_indexexpr.len > 0; } g->is_shared = false; } g->right_is_opt = false; if (g->inside_ternary == 0 && (node.left.len > 1 || !node.is_simple)) { v__gen__c__Gen_writeln(g, _S(";")); } } // Defer begin if (v__gen__c__Gen_assign_stmt_defer_5) { g->is_option_auto_heap = old_is_auto_heap; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_4) { g->inside_opt_or_res = old_inside_opt_or_res; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_3) { g->left_is_opt = false; g->right_is_opt = false; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_2) { g->curr_var_name = last_curr_var_name; } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_1) { if (af) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_to_free}}, {_S("_free(&"), 0xfe10, {.d_s = sref_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } } // Defer end // Defer begin if (v__gen__c__Gen_assign_stmt_defer_0) { g->assign_op = v__token__Kind__unknown; g->inside_assign = false; g->assign_ct_type = 0; g->arraymap_set_pos = 0; g->is_arraymap_set = false; g->is_assign_lhs = false; g->is_shared = false; } // Defer end } VV_LOC void v__gen__c__Gen_gen_multi_return_assign(v__gen__c__Gen* g, v__ast__AssignStmt* node, v__ast__Type return_type, v__ast__TypeSymbol return_sym) { string mr_var_name = str_intp(2, _MOV((StrIntpData[]){{_S("mr_"), 0xfe07, {.d_i32 = node->pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}})); bool is_option = v__ast__Type_has_flag(return_type, v__ast__TypeFlag__option); string mr_styp = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(return_type, v__ast__TypeFlag__result)); if (((*(v__ast__Expr*)array_get(node->right, 0)))._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast(((*(v__ast__Expr*)array_get(node->right, 0)))._v__ast__CallExpr,((*(v__ast__Expr*)array_get(node->right, 0)))._typ, 344)).or_block.kind != v__ast__OrKind__absent) { is_option = false; mr_styp = v__gen__c__Gen_styp(g, v__ast__Type_clear_option_and_result(return_type)); } { v__gen__c__Gen_write(g, mr_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, mr_var_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, (*(v__ast__Expr*)array_get(node->right, 0))); v__gen__c__Gen_writeln(g, _S(";")); Array_v__ast__Type mr_types = (*(v__ast__MultiReturn*)__as_cast((return_sym.info)._v__ast__MultiReturn,(return_sym.info)._typ, 552)).types; for (int i = 0; i < node->left.len; ++i) { v__ast__Expr lx = ((v__ast__Expr*)node->left.data)[i]; int cur_indexexpr = -1; bool is_auto_heap = false; v__ast__Ident ident = ((v__ast__Ident){.language = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comptime = 0,.scope = ((void*)0),.obj = _const_v__ast__empty_scope_object,.mod = (string){.str=(byteptr)"", .is_lit=1},.name = (string){.str=(byteptr)"", .is_lit=1},.full_name = (string){.str=(byteptr)"", .is_lit=1},.cached_name = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.info = (v__ast__IdentInfo){._v__ast__IdentFn=HEAP(v__ast__IdentFn, ((v__ast__IdentFn){.typ = 0,})),._typ=476},.is_mut = 0,.or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.ct_expr = 0,}); if ((lx)._typ == 358 /* v.ast.Ident */) { ident = (*lx._v__ast__Ident); if ((*lx._v__ast__Ident).kind == v__ast__IdentKind__blank_ident) { continue; } if (((*lx._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { is_auto_heap = (*(*lx._v__ast__Ident).obj._v__ast__Var).is_auto_heap; } } if ((lx)._typ == 361 /* v.ast.IndexExpr */ && g->cur_indexexpr.len > 0) { cur_indexexpr = Array_int_index(g->cur_indexexpr, (*lx._v__ast__IndexExpr).pos.pos); } string styp = ((Array_string_contains(g->defer_vars, ident.name)) ? (_S("")) : (v__gen__c__Gen_styp(g, (*(v__ast__Type*)array_get(node->left_types, i))))); if (node->op == v__token__Kind__decl_assign) { { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); } } if (v__ast__Expr_is_auto_deref_var(lx)) { v__gen__c__Gen_write(g, _S("*")); } string noscan = (is_auto_heap ? (v__gen__c__Gen_check_noscan(g, return_type)) : (_S(""))); int aligned = 0; v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, (*(v__ast__Type*)array_get(node->left_types, i))); if ((sym->info)._typ == 518 /* v.ast.Struct */) { _option_v__ast__Attr _t1; if (_t1 = Array_v__ast__Attr_find_first((*sym->info._v__ast__Struct).attrs, _S("aligned")), _t1.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t1.data; aligned = ((attr.arg).len == 0 ? (0) : (string_int(attr.arg))); } } if (v__ast__Type_has_flag((*(v__ast__Type*)array_get(node->left_types, i)), v__ast__TypeFlag__option)) { string base_typ = v__gen__c__Gen_base_type(g, (*(v__ast__Type*)array_get(node->left_types, i))); string tmp_var = (is_auto_heap ? ((aligned != 0 ? (str_intp(5, _MOV((StrIntpData[]){{_S("HEAP_align("), 0xfe10, {.d_s = styp}}, {_S(", "), 0xfe10, {.d_s = mr_var_name}}, {_S(".arg"), 0xfe07, {.d_i32 = i}}, {_S(", "), 0xfe07, {.d_i32 = aligned}}, {_S(")"), 0, { .d_c = 0 }}}))) : (str_intp(5, _MOV((StrIntpData[]){{_S("HEAP"), 0xfe10, {.d_s = noscan}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(", "), 0xfe10, {.d_s = mr_var_name}}, {_S(".arg"), 0xfe07, {.d_i32 = i}}, {_S(")"), 0, { .d_c = 0 }}}))))) : is_option ? (str_intp(4, _MOV((StrIntpData[]){{_S("(*(("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, return_type)}}, {_S("*)"), 0xfe10, {.d_s = mr_var_name}}, {_S(".data)).arg"), 0xfe07, {.d_i32 = i}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mr_var_name}}, {_S(".arg"), 0xfe07, {.d_i32 = i}}, {_SLIT0, 0, { .d_c = 0 }}})))); if (v__ast__Type_has_flag((*(v__ast__Type*)array_get(mr_types, i)), v__ast__TypeFlag__option)) { bool old_left_is_opt = g->left_is_opt; g->left_is_opt = true; v__gen__c__Gen_expr(g, lx); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(" = "), 0xfe10, {.d_s = tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); g->left_is_opt = old_left_is_opt; } else { { v__gen__c__Gen_write(g, _S("_option_ok(&(")); v__gen__c__Gen_write(g, base_typ); v__gen__c__Gen_write(g, _S("[]) { ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" }, (")); v__gen__c__Gen_write(g, _const_v__gen__c__option_name); v__gen__c__Gen_write(g, _S("*)(&")); } bool tmp_left_is_opt = g->left_is_opt; g->left_is_opt = true; v__gen__c__Gen_expr(g, lx); g->left_is_opt = tmp_left_is_opt; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("), sizeof("), 0xfe10, {.d_s = base_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } } else { v__gen__c__Gen_expr(g, lx); if (sym->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_writeln2(g, _S(";"), str_intp(5, _MOV((StrIntpData[]){{_S("memcpy(&"), 0xfe10, {.d_s = v__gen__c__Gen_expr_string(g, lx)}}, {_S(", &"), 0xfe10, {.d_s = mr_var_name}}, {_S(".arg"), 0xfe07, {.d_i32 = i}}, {_S(", sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { if (cur_indexexpr != -1) { if (is_auto_heap) { if (aligned != 0) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("HEAP_align("), 0xfe10, {.d_s = styp}}, {_S(", "), 0xfe10, {.d_s = mr_var_name}}, {_S(".arg"), 0xfe07, {.d_i32 = i}}, {_S(", "), 0xfe07, {.d_i32 = aligned}}, {_S(") });"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("HEAP"), 0xfe10, {.d_s = noscan}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(", "), 0xfe10, {.d_s = mr_var_name}}, {_S(".arg"), 0xfe07, {.d_i32 = i}}, {_S(") });"), 0, { .d_c = 0 }}}))); } } else if (is_option) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("(*(("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, return_type)}}, {_S("*)"), 0xfe10, {.d_s = mr_var_name}}, {_S(".data)).arg"), 0xfe07, {.d_i32 = i}}, {_S(" });"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mr_var_name}}, {_S(".arg"), 0xfe07, {.d_i32 = i}}, {_S(" });"), 0, { .d_c = 0 }}}))); } array_delete(&g->cur_indexexpr, cur_indexexpr); } else { if (is_auto_heap) { if (aligned != 0) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S(" = HEAP_align("), 0xfe10, {.d_s = styp}}, {_S(", "), 0xfe10, {.d_s = mr_var_name}}, {_S(".arg"), 0xfe07, {.d_i32 = i}}, {_S(", "), 0xfe07, {.d_i32 = aligned}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S(" = HEAP"), 0xfe10, {.d_s = noscan}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(", "), 0xfe10, {.d_s = mr_var_name}}, {_S(".arg"), 0xfe07, {.d_i32 = i}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else if (is_option) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" = (*(("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, return_type)}}, {_S("*)"), 0xfe10, {.d_s = mr_var_name}}, {_S(".data)).arg"), 0xfe07, {.d_i32 = i}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(" = "), 0xfe10, {.d_s = mr_var_name}}, {_S(".arg"), 0xfe07, {.d_i32 = i}}, {_S(";"), 0, { .d_c = 0 }}}))); } } } } } if (g->is_arraymap_set) { g->is_arraymap_set = false; } } VV_LOC void v__gen__c__Gen_gen_cross_var_assign(v__gen__c__Gen* g, v__ast__AssignStmt* node) { for (int i = 0; i < node->left.len; ++i) { v__ast__Expr left = ((v__ast__Expr*)node->left.data)[i]; bool left_is_auto_deref_var = v__ast__Expr_is_auto_deref_var(left); if (left._typ == 358 /* v.ast.Ident */) { v__ast__Type left_typ = (*(v__ast__Type*)array_get(node->left_types, i)); v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, left_typ); string anon_ctx = _S(""); if (g->anon_fn) { _option_v__ast__Var_ptr _t1; if (_t1 = v__ast__Scope_find_var((*left._v__ast__Ident).scope, (*left._v__ast__Ident).name), _t1.state == 0) { v__ast__Var* obj = *(v__ast__Var**)_t1.data; if (obj->is_inherited) { anon_ctx = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__closure_ctx}}, {_S("->"), 0, { .d_c = 0 }}})); } } } if ((left_sym->info)._typ == 553 /* v.ast.FnType */) { v__gen__c__Gen_write_fn_ptr_decl(g, &(*left_sym->info._v__ast__FnType), str_intp(2, _MOV((StrIntpData[]){{_S("_var_"), 0xfe07, {.d_i32 = (*left._v__ast__Ident).pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(" = "), 0xfe10, {.d_s = anon_ctx}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name((*left._v__ast__Ident).name)}}, {_S(";"), 0, { .d_c = 0 }}}))); } else if (left_is_auto_deref_var) { string styp = string_trim(v__gen__c__Gen_styp(g, left_typ), _S("*")); if (left_sym->kind == v__ast__Kind__array) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" _var_"), 0xfe07, {.d_i32 = (*left._v__ast__Ident).pos.pos}}, {_S(" = array_clone("), 0xfe10, {.d_s = anon_ctx}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name((*left._v__ast__Ident).name)}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" _var_"), 0xfe07, {.d_i32 = (*left._v__ast__Ident).pos.pos}}, {_S(" = *"), 0xfe10, {.d_s = anon_ctx}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name((*left._v__ast__Ident).name)}}, {_S(";"), 0, { .d_c = 0 }}}))); } } else { string styp = v__gen__c__Gen_styp(g, left_typ); if (left_sym->kind == v__ast__Kind__array) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" _var_"), 0xfe07, {.d_i32 = (*left._v__ast__Ident).pos.pos}}, {_S(" = array_clone(&"), 0xfe10, {.d_s = anon_ctx}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name((*left._v__ast__Ident).name)}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" _var_"), 0xfe07, {.d_i32 = (*left._v__ast__Ident).pos.pos}}, {_S(" = "), 0xfe10, {.d_s = anon_ctx}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name((*left._v__ast__Ident).name)}}, {_S(";"), 0, { .d_c = 0 }}}))); } } } else if (left._typ == 361 /* v.ast.IndexExpr */) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__ast__Table_unaliased_type(g->table, (*left._v__ast__IndexExpr).left_type)); if (sym->kind == v__ast__Kind__array) { v__ast__Array info = *(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513); v__ast__TypeSymbol* elem_typ = v__ast__Table_sym(g->table, info.elem_type); bool needs_clone = info.elem_type == _const_v__ast__string_type && g->is_autofree; if (elem_typ->kind == v__ast__Kind__function) { v__ast__Type left_typ = (*(v__ast__Type*)array_get(node->left_types, i)); v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, left_typ); v__gen__c__Gen_write_fn_ptr_decl(g, (v__ast__FnType*)__as_cast((left_sym->info)._v__ast__FnType,(left_sym->info)._typ, 553), str_intp(2, _MOV((StrIntpData[]){{_S("_var_"), 0xfe07, {.d_i32 = (*left._v__ast__IndexExpr).pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__gen__c__Gen_write(g, _S(" = *(voidptr*)array_get(")); } else { string styp = v__gen__c__Gen_styp(g, info.elem_type); string string_clone = (needs_clone ? (_S("string_clone(")) : (_S(""))); { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" _var_")); v__gen__c__Gen_write_decimal(g, (*left._v__ast__IndexExpr).pos.pos); v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_write(g, string_clone); v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)array_get(")); } } if (v__ast__Type_is_ptr((*left._v__ast__IndexExpr).left_type)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, (*left._v__ast__IndexExpr).left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, (*left._v__ast__IndexExpr).index); if (needs_clone) { v__gen__c__Gen_write(g, _S(")")); } v__gen__c__Gen_writeln(g, _S(");")); } else if (sym->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549); v__ast__TypeSymbol* elem_typ = v__ast__Table_sym(g->table, info.elem_type); if (elem_typ->kind == v__ast__Kind__function) { v__ast__Type left_typ = (*(v__ast__Type*)array_get(node->left_types, i)); v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, left_typ); v__gen__c__Gen_write_fn_ptr_decl(g, (v__ast__FnType*)__as_cast((left_sym->info)._v__ast__FnType,(left_sym->info)._typ, 553), str_intp(2, _MOV((StrIntpData[]){{_S("_var_"), 0xfe07, {.d_i32 = (*left._v__ast__IndexExpr).pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__gen__c__Gen_write(g, _S(" = *(voidptr*)")); } else { string styp = v__gen__c__Gen_styp(g, info.elem_type); { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" _var_")); v__gen__c__Gen_write_decimal(g, (*left._v__ast__IndexExpr).pos.pos); v__gen__c__Gen_write(g, _S(" = ")); } } if (v__ast__Type_is_ptr((*left._v__ast__IndexExpr).left_type)) { v__gen__c__Gen_write(g, _S("*")); } bool needs_clone = info.elem_type == _const_v__ast__string_type && g->is_autofree; if (needs_clone) { v__gen__c__Gen_write(g, _S("string_clone(")); } v__gen__c__Gen_expr(g, left); if (needs_clone) { v__gen__c__Gen_write(g, _S(")")); } v__gen__c__Gen_writeln(g, _S(";")); } else if (sym->kind == v__ast__Kind__map) { v__ast__Map info = *(v__ast__Map*)__as_cast((sym->info)._v__ast__Map,(sym->info)._typ, 514); string skeytyp = v__gen__c__Gen_styp(g, info.key_type); string styp = v__gen__c__Gen_styp(g, info.value_type); string zero = v__gen__c__Gen_type_default(g, info.value_type); v__ast__TypeSymbol* val_typ = v__ast__Table_sym(g->table, info.value_type); if (val_typ->kind == v__ast__Kind__function) { v__ast__Type left_type = (*(v__ast__Type*)array_get(node->left_types, i)); v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, left_type); v__gen__c__Gen_write_fn_ptr_decl(g, (v__ast__FnType*)__as_cast((left_sym->info)._v__ast__FnType,(left_sym->info)._typ, 553), str_intp(2, _MOV((StrIntpData[]){{_S("_var_"), 0xfe07, {.d_i32 = (*left._v__ast__IndexExpr).pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__gen__c__Gen_write(g, _S(" = *(voidptr*)map_get(")); } else { { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" _var_")); v__gen__c__Gen_write_decimal(g, (*left._v__ast__IndexExpr).pos.pos); v__gen__c__Gen_write(g, _S(" = *(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)map_get(")); } } if (!v__ast__Type_is_ptr((*left._v__ast__IndexExpr).left_type)) { v__gen__c__Gen_write(g, _S("ADDR(map, ")); v__gen__c__Gen_expr(g, (*left._v__ast__IndexExpr).left); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_expr(g, (*left._v__ast__IndexExpr).left); } { v__gen__c__Gen_write(g, _S(", &(")); v__gen__c__Gen_write(g, skeytyp); v__gen__c__Gen_write(g, _S("[]){")); } v__gen__c__Gen_expr(g, (*left._v__ast__IndexExpr).index); v__gen__c__Gen_write(g, _S("}")); if (val_typ->kind == v__ast__Kind__function) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", &(voidptr[]){ "), 0xfe10, {.d_s = zero}}, {_S(" });"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(", &("), 0xfe10, {.d_s = styp}}, {_S("[]){ "), 0xfe10, {.d_s = zero}}, {_S(" });"), 0, { .d_c = 0 }}}))); } } } else if (left._typ == 379 /* v.ast.SelectorExpr */) { string styp = v__gen__c__Gen_styp(g, (*left._v__ast__SelectorExpr).typ); { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" _var_")); v__gen__c__Gen_write_decimal(g, (*left._v__ast__SelectorExpr).pos.pos); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, (*left._v__ast__SelectorExpr).expr); string sel = v__gen__c__Gen_dot_or_ptr(g, (*left._v__ast__SelectorExpr).expr_type); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sel}}, {_SLIT0, 0xfe10, {.d_s = (*left._v__ast__SelectorExpr).field_name}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { } } } VV_LOC void v__gen__c__Gen_gen_cross_tmp_variable(v__gen__c__Gen* g, Array_v__ast__Expr left, v__ast__Expr val) { v__ast__Expr val_ = val; if (val._typ == 358 /* v.ast.Ident */) { bool has_var = false; for (int _t1 = 0; _t1 < left.len; ++_t1) { v__ast__Expr lx = ((v__ast__Expr*)left.data)[_t1]; if ((lx)._typ == 358 /* v.ast.Ident */) { if (string__eq((*val._v__ast__Ident).name, (*lx._v__ast__Ident).name)) { v__gen__c__Gen_write2(g, _S("_var_"), int_str((*lx._v__ast__Ident).pos.pos)); has_var = true; break; } } } if (!has_var) { v__gen__c__Gen_expr(g, val_); } } else if (val._typ == 361 /* v.ast.IndexExpr */) { bool has_var = false; for (int _t2 = 0; _t2 < left.len; ++_t2) { v__ast__Expr lx = ((v__ast__Expr*)left.data)[_t2]; if (string__eq(v__ast__Expr_str(&val_), v__ast__Expr_str(&lx))) { v__gen__c__Gen_write2(g, _S("_var_"), int_str(v__ast__Expr_pos(lx).pos)); has_var = true; break; } } if (!has_var) { v__gen__c__Gen_expr(g, val_); } } else if (val._typ == 362 /* v.ast.InfixExpr */) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, (*val._v__ast__InfixExpr).left_type); string svalop = v__token__Kind_str((*val._v__ast__InfixExpr).op); _result_v__ast__Fn _t3; if (_t3 = v__ast__Table_find_method(g->table, sym, svalop), !_t3.is_error) { string left_styp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls((*val._v__ast__InfixExpr).left_type, 0)); v__gen__c__Gen_write2(g, left_styp, _S("_")); v__gen__c__Gen_write2(g, v__util__replace_op(svalop), _S("(")); v__gen__c__Gen_gen_cross_tmp_variable(g, left, (*val._v__ast__InfixExpr).left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_gen_cross_tmp_variable(g, left, (*val._v__ast__InfixExpr).right); v__gen__c__Gen_write(g, _S(")")); } else { IError err = _t3.err; v__gen__c__Gen_gen_cross_tmp_variable(g, left, (*val._v__ast__InfixExpr).left); v__gen__c__Gen_write(g, svalop); v__gen__c__Gen_gen_cross_tmp_variable(g, left, (*val._v__ast__InfixExpr).right); } } else if (val._typ == 374 /* v.ast.ParExpr */) { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_gen_cross_tmp_variable(g, left, (*val._v__ast__ParExpr).expr); v__gen__c__Gen_write(g, _S(")")); } else if (val._typ == 344 /* v.ast.CallExpr */) { if ((*val._v__ast__CallExpr).is_method) { multi_return_v__ast__Type_ref_v__ast__TypeSymbol mr_42117 = v__gen__c__Gen_unwrap_receiver_type(g, (*val._v__ast__CallExpr)); v__ast__Type unwrapped_rec_type = mr_42117.arg0; v__ast__TypeSymbol* typ_sym = mr_42117.arg1; v__ast__Type left_type = v__gen__c__Gen_unwrap_generic(g, (*val._v__ast__CallExpr).left_type); v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, left_type); v__ast__TypeSymbol* final_left_sym = v__ast__Table_final_sym(g->table, left_type); string rec_typ_name = v__gen__c__Gen_resolve_receiver_name(g, (*val._v__ast__CallExpr), unwrapped_rec_type, *final_left_sym, *left_sym, *typ_sym); string fn_name = v__util__no_dots(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = rec_typ_name}}, {_S("_"), 0xfe10, {.d_s = (*val._v__ast__CallExpr).name}}, {_SLIT0, 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, fn_name); v__gen__c__Gen_write(g, _S("(&")); } v__gen__c__Gen_gen_cross_tmp_variable(g, left, (*val._v__ast__CallExpr).left); for (int i = 0; i < (*val._v__ast__CallExpr).args.len; ++i) { v__ast__CallArg arg = ((v__ast__CallArg*)(*val._v__ast__CallExpr).args.data)[i]; v__gen__c__Gen_gen_cross_tmp_variable(g, left, arg.expr); if (i != (int)((*val._v__ast__CallExpr).args.len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } } v__gen__c__Gen_write(g, _S(")")); } else { string fn_name = string_replace((*val._v__ast__CallExpr).name, _S("."), _S("__")); if ((*val._v__ast__CallExpr).concrete_types.len > 0) { fn_name = v__gen__c__Gen_generic_fn_name(g, (*val._v__ast__CallExpr).concrete_types, fn_name); } { v__gen__c__Gen_write(g, fn_name); v__gen__c__Gen_write(g, _S("(")); } for (int i = 0; i < (*val._v__ast__CallExpr).args.len; ++i) { v__ast__CallArg arg = ((v__ast__CallArg*)(*val._v__ast__CallExpr).args.data)[i]; v__gen__c__Gen_gen_cross_tmp_variable(g, left, arg.expr); if (i != (int)((*val._v__ast__CallExpr).args.len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } } v__gen__c__Gen_write(g, _S(")")); } } else if (val._typ == 376 /* v.ast.PrefixExpr */) { v__gen__c__Gen_write(g, v__token__Kind_str((*val._v__ast__PrefixExpr).op)); v__gen__c__Gen_gen_cross_tmp_variable(g, left, (*val._v__ast__PrefixExpr).right); } else if (val._typ == 375 /* v.ast.PostfixExpr */) { v__gen__c__Gen_gen_cross_tmp_variable(g, left, (*val._v__ast__PostfixExpr).expr); v__gen__c__Gen_write(g, v__token__Kind_str((*val._v__ast__PostfixExpr).op)); } else if (val._typ == 379 /* v.ast.SelectorExpr */) { bool has_var = false; for (int _t4 = 0; _t4 < left.len; ++_t4) { v__ast__Expr lx = ((v__ast__Expr*)left.data)[_t4]; if (string__eq(v__ast__Expr_str(&val_), v__ast__Expr_str(&lx))) { v__gen__c__Gen_write2(g, _S("_var_"), int_str(v__ast__Expr_pos(lx).pos)); has_var = true; break; } } if (!has_var) { v__gen__c__Gen_expr(g, val_); } } else { v__gen__c__Gen_expr(g, val_); } } VV_LOC string v__gen__c__Gen_equality_fn(v__gen__c__Gen* g, v__ast__Type typ) { array_push((array*)&g->needed_equality_fns, _MOV((v__ast__Type[]){ v__ast__Type_set_nr_muls(typ, 0) })); v__ast__Type t1 = v__gen__c__Gen_unwrap_generic(g, typ); v__ast__Type t2 = v__ast__Type_set_nr_muls(t1, 0); string st2 = v__gen__c__Gen_styp(g, t2); string res = string_replace(st2, _S("struct "), _S("")); return res; } VV_LOC void v__gen__c__Gen_gen_equality_fns(v__gen__c__Gen* g) { for (int _t1 = 0; _t1 < g->needed_equality_fns.len; ++_t1) { v__ast__Type needed_typ = ((v__ast__Type*)g->needed_equality_fns.data)[_t1]; if ((Array_v__ast__Type_contains(g->generated_eq_fns, needed_typ))) { continue; } v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, needed_typ); if (sym->kind == (v__ast__Kind__sum_type)) { v__gen__c__Gen_gen_sumtype_equality_fn(g, needed_typ); } else if (sym->kind == (v__ast__Kind__struct)) { v__gen__c__Gen_gen_struct_equality_fn(g, needed_typ); } else if (sym->kind == (v__ast__Kind__array)) { v__gen__c__Gen_gen_array_equality_fn(g, needed_typ); } else if (sym->kind == (v__ast__Kind__array_fixed)) { v__gen__c__Gen_gen_fixed_array_equality_fn(g, needed_typ); } else if (sym->kind == (v__ast__Kind__map)) { v__gen__c__Gen_gen_map_equality_fn(g, needed_typ); } else if (sym->kind == (v__ast__Kind__alias)) { v__gen__c__Gen_gen_alias_equality_fn(g, needed_typ); } else if (sym->kind == (v__ast__Kind__interface)) { v__gen__c__Gen_gen_interface_equality_fn(g, needed_typ); } else { v__gen__c__verror(str_intp(2, _MOV((StrIntpData[]){{_S("could not generate equality function for type "), 0xfe10, {.d_s = v__ast__Kind_str(sym->kind)}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } } } VV_LOC string v__gen__c__Gen_gen_sumtype_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type) { v__gen__c__Type left = v__gen__c__Gen_unwrap(g, left_type); string ptr_styp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(left.typ, 0)); v__ast__Type left_no_ptr = v__ast__Type_set_nr_muls(left_type, 0); if ((Array_v__ast__Type_contains(g->generated_eq_fns, left_no_ptr))) { return ptr_styp; } array_push((array*)&g->generated_eq_fns, _MOV((v__ast__Type[]){ left_no_ptr })); v__ast__SumType info = v__ast__TypeSymbol_sumtype_info(left.sym); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_S("bool "), 0xfe10, {.d_s = ptr_styp}}, {_S("_sumtype_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b);"), 0, { .d_c = 0 }}}))); string left_typ = v__gen__c__Gen_read_field(g, left_type, _S("_typ"), _S("a")); string right_typ = v__gen__c__Gen_read_field(g, left_type, _S("_typ"), _S("b")); strings__Builder fn_builder = strings__new_builder(512); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("inline bool "), 0xfe10, {.d_s = ptr_styp}}, {_S("_sumtype_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = left_typ}}, {_S(" != "), 0xfe10, {.d_s = right_typ}}, {_S(") { return false; }"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = left_typ}}, {_S(" == "), 0xfe10, {.d_s = right_typ}}, {_S(" && "), 0xfe10, {.d_s = right_typ}}, {_S(" == 0) { return true; } // uninitialized"), 0, { .d_c = 0 }}}))); for (int _t3 = 0; _t3 < info.variants.len; ++_t3) { v__ast__Type typ = ((v__ast__Type*)info.variants.data)[_t3]; v__gen__c__Type variant = v__gen__c__Gen_unwrap(g, typ); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = left_typ}}, {_S(" == "), 0xfe07, {.d_i32 = ((int)(variant.typ))}}, {_S(") {"), 0, { .d_c = 0 }}}))); string name = str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = v__gen__c__Gen_get_sumtype_variant_name(g, variant.typ, *variant.sym)}}, {_SLIT0, 0, { .d_c = 0 }}})); string left_arg = v__gen__c__Gen_read_field(g, left_type, name, _S("a")); string right_arg = v__gen__c__Gen_read_field(g, left_type, name, _S("b")); if (v__ast__Type_has_flag(variant.typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&fn_builder, str_intp(6, _MOV((StrIntpData[]){{_S("\t\treturn ((*"), 0xfe10, {.d_s = left_arg}}, {_S(").state == 2 && (*"), 0xfe10, {.d_s = right_arg}}, {_S(").state == 2) || !memcmp(&(*"), 0xfe10, {.d_s = left_arg}}, {_S(").data, &(*"), 0xfe10, {.d_s = right_arg}}, {_S(").data, sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, variant.typ)}}, {_S("));"), 0, { .d_c = 0 }}}))); } else if (variant.sym->kind == v__ast__Kind__string) { strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\treturn string__eq(*"), 0xfe10, {.d_s = left_arg}}, {_S(", *"), 0xfe10, {.d_s = right_arg}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (variant.sym->kind == v__ast__Kind__sum_type && !v__ast__Type_is_ptr(typ)) { string eq_fn = v__gen__c__Gen_gen_sumtype_equality_fn(g, typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_sumtype_eq(*"), 0xfe10, {.d_s = left_arg}}, {_S(", *"), 0xfe10, {.d_s = right_arg}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (variant.sym->kind == v__ast__Kind__struct && !v__ast__Type_is_ptr(typ)) { string eq_fn = v__gen__c__Gen_gen_struct_equality_fn(g, typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_struct_eq(*"), 0xfe10, {.d_s = left_arg}}, {_S(", *"), 0xfe10, {.d_s = right_arg}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (variant.sym->kind == v__ast__Kind__array && !v__ast__Type_is_ptr(typ)) { string eq_fn = v__gen__c__Gen_gen_array_equality_fn(g, typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_arr_eq(*"), 0xfe10, {.d_s = left_arg}}, {_S(", *"), 0xfe10, {.d_s = right_arg}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (variant.sym->kind == v__ast__Kind__array_fixed && !v__ast__Type_is_ptr(typ)) { string eq_fn = v__gen__c__Gen_gen_fixed_array_equality_fn(g, typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_arr_eq(*"), 0xfe10, {.d_s = left_arg}}, {_S(", *"), 0xfe10, {.d_s = right_arg}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (variant.sym->kind == v__ast__Kind__map && !v__ast__Type_is_ptr(typ)) { string eq_fn = v__gen__c__Gen_gen_map_equality_fn(g, typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_map_eq(*"), 0xfe10, {.d_s = left_arg}}, {_S(", *"), 0xfe10, {.d_s = right_arg}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (variant.sym->kind == v__ast__Kind__alias && !v__ast__Type_is_ptr(typ)) { if ((*(bool*)map_get(ADDR(map, g->no_eq_method_types), &(v__ast__Type[]){typ}, &(bool[]){ 0 }))) { strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\treturn *"), 0xfe10, {.d_s = left_arg}}, {_S(" == *"), 0xfe10, {.d_s = right_arg}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { string eq_fn = v__gen__c__Gen_gen_alias_equality_fn(g, typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_alias_eq(*"), 0xfe10, {.d_s = left_arg}}, {_S(", *"), 0xfe10, {.d_s = right_arg}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else if (variant.sym->kind == v__ast__Kind__function) { strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\treturn *((voidptr*)(*"), 0xfe10, {.d_s = left_arg}}, {_S(")) == *((voidptr*)(*"), 0xfe10, {.d_s = right_arg}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\treturn *"), 0xfe10, {.d_s = left_arg}}, {_S(" == *"), 0xfe10, {.d_s = right_arg}}, {_S(";"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&fn_builder, _S("\t}")); } strings__Builder_writeln(&fn_builder, _S("\treturn false;")); strings__Builder_writeln(&fn_builder, _S("}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); return ptr_styp; } inline VV_LOC string v__gen__c__Gen_read_opt(v__gen__c__Gen* g, v__ast__Type typ, string var_name) { return str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, typ)}}, {_S("*)"), 0xfe10, {.d_s = var_name}}, {_S(".data"), 0, { .d_c = 0 }}})); } inline VV_LOC string v__gen__c__Gen_read_field(v__gen__c__Gen* g, v__ast__Type struct_type, string field_name, string var_name) { return (v__ast__Type_has_flag(struct_type, v__ast__TypeFlag__option) ? (str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__gen__c__Gen_read_opt(g, struct_type, var_name)}}, {_S(")->"), 0xfe10, {.d_s = field_name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = var_name}}, {_S("."), 0xfe10, {.d_s = field_name}}, {_SLIT0, 0, { .d_c = 0 }}})))); } inline VV_LOC string v__gen__c__Gen_read_map_from_option(v__gen__c__Gen* g, v__ast__Type typ, string var_name) { string _t2; /* if prepend */ if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { return str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, typ)}}, {_S("*)&"), 0xfe10, {.d_s = var_name}}, {_S(".data"), 0, { .d_c = 0 }}})); } else { _t2 = var_name; } return _t2; } inline VV_LOC string v__gen__c__Gen_read_map_field_from_option(v__gen__c__Gen* g, v__ast__Type typ, string field_name, string var_name) { return (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option) ? (str_intp(4, _MOV((StrIntpData[]){{_S("(*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, typ)}}, {_S("*)"), 0xfe10, {.d_s = var_name}}, {_S(".data)."), 0xfe10, {.d_s = field_name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = var_name}}, {_S("."), 0xfe10, {.d_s = field_name}}, {_SLIT0, 0, { .d_c = 0 }}})))); } inline VV_LOC string v__gen__c__Gen_read_opt_field(v__gen__c__Gen* g, v__ast__Type struct_type, string field_name, string var_name, v__ast__Type field_typ) { return (v__ast__Type_has_flag(field_typ, v__ast__TypeFlag__option) ? (str_intp(3, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, field_typ)}}, {_S("*)"), 0xfe10, {.d_s = v__gen__c__Gen_read_field(g, struct_type, field_name, var_name)}}, {_S(".data"), 0, { .d_c = 0 }}}))) : (v__gen__c__Gen_read_field(g, struct_type, field_name, var_name))); } VV_LOC string v__gen__c__Gen_gen_struct_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type) { bool v__gen__c__Gen_gen_struct_equality_fn_defer_0 = false; strings__Builder fn_builder; v__gen__c__Type left = v__gen__c__Gen_unwrap(g, left_type); string ptr_styp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(left.typ, 0)); string fn_name = string_replace(ptr_styp, _S("struct "), _S("")); v__ast__Type left_no_ptr = v__ast__Type_set_nr_muls(left_type, 0); if ((Array_v__ast__Type_contains(g->generated_eq_fns, left_no_ptr))) { return fn_name; } array_push((array*)&g->generated_eq_fns, _MOV((v__ast__Type[]){ left_no_ptr })); v__ast__Struct info = v__ast__TypeSymbol_struct_info(left.sym); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_S("bool "), 0xfe10, {.d_s = fn_name}}, {_S("_struct_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b);"), 0, { .d_c = 0 }}}))); fn_builder = strings__new_builder(512); v__gen__c__Gen_gen_struct_equality_fn_defer_0 = true; strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("inline bool "), 0xfe10, {.d_s = fn_name}}, {_S("_struct_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b) {"), 0, { .d_c = 0 }}}))); if (v__ast__TypeSymbol_has_method(left.sym, _S("=="))) { if (v__ast__Type_has_flag(left.typ, v__ast__TypeFlag__option)) { string opt_ptr_styp = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(v__ast__Type_set_nr_muls(left.typ, 0), v__ast__TypeFlag__option)); string opt_fn_name = string_replace(opt_ptr_styp, _S("struct "), _S("")); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\treturn (a.state == b.state && b.state == 2) || "), 0xfe10, {.d_s = opt_fn_name}}, {_S("__eq(*("), 0xfe10, {.d_s = opt_ptr_styp}}, {_S("*)a.data, *("), 0xfe10, {.d_s = opt_ptr_styp}}, {_S("*)b.data);"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = fn_name}}, {_S("__eq(a, b);"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&fn_builder, _S("}")); string _t3 = fn_name; // Defer begin if (v__gen__c__Gen_gen_struct_equality_fn_defer_0) { array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } // Defer end return _t3; } strings__Builder_write_string(&fn_builder, _S("\treturn ")); if (info.fields.len > 0) { for (int i = 0; i < info.fields.len; ++i) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[i]; if (i > 0) { strings__Builder_write_string(&fn_builder, _S("\n\t\t&& ")); } v__gen__c__Type field_type = v__gen__c__Gen_unwrap(g, field.typ); string field_name = v__gen__c__c_name(field.name); string left_arg = v__gen__c__Gen_read_field(g, left_type, field_name, _S("a")); string right_arg = v__gen__c__Gen_read_field(g, left_type, field_name, _S("b")); if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { { strings__Builder_write_string(&fn_builder, _S("((")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(".state == ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(".state && ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(".state == 2) || ")); } } if (field_type.sym->kind == v__ast__Kind__string) { if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { string left_arg_opt = v__gen__c__Gen_read_opt_field(g, left_type, field_name, _S("a"), field.typ); string right_arg_opt = v__gen__c__Gen_read_opt_field(g, left_type, field_name, _S("b"), field.typ); { strings__Builder_write_string(&fn_builder, _S("(((")); strings__Builder_write_string(&fn_builder, left_arg_opt); strings__Builder_write_string(&fn_builder, _S(").len == (")); strings__Builder_write_string(&fn_builder, right_arg_opt); strings__Builder_write_string(&fn_builder, _S(").len && (")); strings__Builder_write_string(&fn_builder, left_arg_opt); strings__Builder_write_string(&fn_builder, _S(").len == 0) || fast_string_eq(")); strings__Builder_write_string(&fn_builder, left_arg_opt); strings__Builder_write_string(&fn_builder, _S(", ")); strings__Builder_write_string(&fn_builder, right_arg_opt); strings__Builder_write_string(&fn_builder, _S("))")); } } else if (v__ast__Type_is_ptr(field.typ)) { { strings__Builder_write_string(&fn_builder, _S("((")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S("->len == ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S("->len && ")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S("->len == 0) || fast_string_eq(*(")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S("), *(")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(")))")); } } else { { strings__Builder_write_string(&fn_builder, _S("((")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(".len == ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(".len && ")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(".len == 0) || fast_string_eq(")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(", ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S("))")); } } } else if (field_type.sym->kind == v__ast__Kind__sum_type && !v__ast__Type_is_ptr(field.typ)) { string eq_fn = v__gen__c__Gen_gen_sumtype_equality_fn(g, field.typ); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_sumtype_eq(")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(", ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(")")); } } else if (field_type.sym->kind == v__ast__Kind__struct && !v__ast__Type_is_ptr(field.typ)) { string eq_fn = v__gen__c__Gen_gen_struct_equality_fn(g, field.typ); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_struct_eq(")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(", ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(")")); } } else if (field_type.sym->kind == v__ast__Kind__array && !v__ast__Type_is_ptr(field.typ)) { string eq_fn = v__gen__c__Gen_gen_array_equality_fn(g, field.typ); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_arr_eq(")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(", ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(")")); } } else if (field_type.sym->kind == v__ast__Kind__array_fixed && !v__ast__Type_is_ptr(field.typ)) { string eq_fn = v__gen__c__Gen_gen_fixed_array_equality_fn(g, field.typ); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_arr_eq(")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(", ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(")")); } } else if (field_type.sym->kind == v__ast__Kind__map && !v__ast__Type_is_ptr(field.typ)) { string eq_fn = v__gen__c__Gen_gen_map_equality_fn(g, field.typ); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_map_eq(")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(", ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(")")); } } else if (field_type.sym->kind == v__ast__Kind__alias && !v__ast__Type_is_ptr(field.typ)) { if ((*(bool*)map_get(ADDR(map, g->no_eq_method_types), &(v__ast__Type[]){field.typ}, &(bool[]){ 0 }))) { { strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(" == ")); strings__Builder_write_string(&fn_builder, right_arg); } } else { string eq_fn = v__gen__c__Gen_gen_alias_equality_fn(g, field.typ); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_alias_eq(")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(", ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(")")); } } } else if (field_type.sym->kind == v__ast__Kind__function && !v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { { strings__Builder_write_string(&fn_builder, _S("*((voidptr*)(")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(")) == *((voidptr*)(")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S("))")); } } else if (field_type.sym->kind == v__ast__Kind__interface && (!v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option) || !v__ast__Type_is_ptr(field.typ))) { string ptr = (v__ast__Type_is_ptr(field.typ) ? (string_repeat(_S("*"), v__ast__Type_nr_muls(field.typ))) : (_S(""))); string eq_fn = v__gen__c__Gen_gen_interface_equality_fn(g, field.typ); if ((ptr).len != 0) { { strings__Builder_write_string(&fn_builder, _S("((")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(" == (void*)0 && ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(" == (void*)0) || (")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(" != (void*)0 && ")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(" != (void*)0 && ")); } } { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_interface_eq(")); strings__Builder_write_string(&fn_builder, ptr); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(", ")); strings__Builder_write_string(&fn_builder, ptr); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(")")); } if ((ptr).len != 0) { strings__Builder_write_string(&fn_builder, _S("))")); } } else if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { { strings__Builder_write_string(&fn_builder, _S("!memcmp(&")); strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(".data, &")); strings__Builder_write_string(&fn_builder, right_arg); strings__Builder_write_string(&fn_builder, _S(".data, sizeof(")); strings__Builder_write_string(&fn_builder, v__gen__c__Gen_base_type(g, field.typ)); strings__Builder_write_string(&fn_builder, _S("))")); } } else { { strings__Builder_write_string(&fn_builder, left_arg); strings__Builder_write_string(&fn_builder, _S(" == ")); strings__Builder_write_string(&fn_builder, right_arg); } } if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { strings__Builder_write_string(&fn_builder, _S(")")); } } } else { strings__Builder_write_string(&fn_builder, _S("true")); } strings__Builder_writeln(&fn_builder, _S(";")); strings__Builder_writeln(&fn_builder, _S("}")); string _t5 = fn_name; // Defer begin if (v__gen__c__Gen_gen_struct_equality_fn_defer_0) { array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } // Defer end return _t5; } VV_LOC string v__gen__c__Gen_gen_alias_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type) { v__gen__c__Type left = v__gen__c__Gen_unwrap(g, left_type); string ptr_styp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(left.typ, 0)); v__ast__Type left_no_ptr = v__ast__Type_set_nr_muls(left_type, 0); if ((Array_v__ast__Type_contains(g->generated_eq_fns, left_no_ptr))) { return ptr_styp; } array_push((array*)&g->generated_eq_fns, _MOV((v__ast__Type[]){ left_no_ptr })); v__ast__Alias info = *(v__ast__Alias*)__as_cast((left.sym->info)._v__ast__Alias,(left.sym->info)._typ, 539); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_S("bool "), 0xfe10, {.d_s = ptr_styp}}, {_S("_alias_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b);"), 0, { .d_c = 0 }}}))); strings__Builder fn_builder = strings__new_builder(512); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("inline bool "), 0xfe10, {.d_s = ptr_styp}}, {_S("_alias_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b) {"), 0, { .d_c = 0 }}}))); bool is_option = v__ast__Type_has_flag(left.typ, v__ast__TypeFlag__option); string left_var = (is_option ? (string__plus(_S("*"), v__gen__c__Gen_read_opt(g, info.parent_type, _S("a")))) : (_S("a"))); string right_var = (is_option ? (string__plus(_S("*"), v__gen__c__Gen_read_opt(g, info.parent_type, _S("b")))) : (_S("b"))); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, info.parent_type); if (sym->kind == v__ast__Kind__string) { if (v__ast__Type_has_flag(info.parent_type, v__ast__TypeFlag__option)) { left_var = string__plus(_S("*"), v__gen__c__Gen_read_opt(g, info.parent_type, _S("a"))); right_var = string__plus(_S("*"), v__gen__c__Gen_read_opt(g, info.parent_type, _S("b"))); strings__Builder_writeln(&fn_builder, str_intp(6, _MOV((StrIntpData[]){{_S("\treturn (("), 0xfe10, {.d_s = left_var}}, {_S(").len == ("), 0xfe10, {.d_s = right_var}}, {_S(").len && ("), 0xfe10, {.d_s = left_var}}, {_S(").len == 0) || fast_string_eq("), 0xfe10, {.d_s = left_var}}, {_S(", "), 0xfe10, {.d_s = right_var}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, _S("\treturn string__eq(a, b);")); } } else if (sym->kind == v__ast__Kind__sum_type && !v__ast__Type_is_ptr(left.typ)) { string eq_fn = v__gen__c__Gen_gen_sumtype_equality_fn(g, info.parent_type); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_sumtype_eq("), 0xfe10, {.d_s = left_var}}, {_S(", "), 0xfe10, {.d_s = right_var}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__struct && !v__ast__Type_is_ptr(left.typ)) { string eq_fn = v__gen__c__Gen_gen_struct_equality_fn(g, info.parent_type); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_struct_eq("), 0xfe10, {.d_s = left_var}}, {_S(", "), 0xfe10, {.d_s = right_var}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__interface && !v__ast__Type_is_ptr(left.typ)) { string eq_fn = v__gen__c__Gen_gen_interface_equality_fn(g, info.parent_type); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_interface_eq("), 0xfe10, {.d_s = left_var}}, {_S(", "), 0xfe10, {.d_s = right_var}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__array && !v__ast__Type_is_ptr(left.typ)) { string eq_fn = v__gen__c__Gen_gen_array_equality_fn(g, info.parent_type); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_arr_eq("), 0xfe10, {.d_s = left_var}}, {_S(", "), 0xfe10, {.d_s = right_var}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__array_fixed && !v__ast__Type_is_ptr(left.typ)) { string eq_fn = v__gen__c__Gen_gen_fixed_array_equality_fn(g, info.parent_type); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_arr_eq("), 0xfe10, {.d_s = left_var}}, {_S(", "), 0xfe10, {.d_s = right_var}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__map && !v__ast__Type_is_ptr(left.typ)) { string eq_fn = v__gen__c__Gen_gen_map_equality_fn(g, info.parent_type); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = eq_fn}}, {_S("_map_eq("), 0xfe10, {.d_s = left_var}}, {_S(", "), 0xfe10, {.d_s = right_var}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__function && !v__ast__Type_has_flag(left.typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&fn_builder, _S("\treturn *((voidptr*)(a)) == *((voidptr*)(b));")); } else if (v__ast__Type_has_flag(info.parent_type, v__ast__TypeFlag__option) || v__ast__Type_has_flag(left.typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn a.state == b.state && !memcmp(&a.data, &b.data, sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, info.parent_type)}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, _S("\treturn a == b;")); } strings__Builder_writeln(&fn_builder, _S("}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); return ptr_styp; } VV_LOC string v__gen__c__Gen_gen_array_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type) { v__gen__c__Type left = v__gen__c__Gen_unwrap(g, left_type); string ptr_styp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(left.typ, 0)); v__ast__Type left_no_ptr = v__ast__Type_set_nr_muls(left_type, 0); if ((Array_v__ast__Type_contains(g->generated_eq_fns, left_no_ptr))) { return ptr_styp; } array_push((array*)&g->generated_eq_fns, _MOV((v__ast__Type[]){ left_no_ptr })); v__gen__c__Type elem = v__gen__c__Gen_unwrap(g, v__ast__TypeSymbol_array_info(left.sym).elem_type); string ptr_elem_styp = v__gen__c__Gen_styp(g, elem.typ); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_S("bool "), 0xfe10, {.d_s = ptr_styp}}, {_S("_arr_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b);"), 0, { .d_c = 0 }}}))); strings__Builder fn_builder = strings__new_builder(512); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("inline bool "), 0xfe10, {.d_s = ptr_styp}}, {_S("_arr_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b) {"), 0, { .d_c = 0 }}}))); string left_len = v__gen__c__Gen_read_field(g, left_type, _S("len"), _S("a")); string right_len = v__gen__c__Gen_read_field(g, left_type, _S("len"), _S("b")); string left_data = v__gen__c__Gen_read_field(g, left_type, _S("data"), _S("a")); string right_data = v__gen__c__Gen_read_field(g, left_type, _S("data"), _S("b")); string left_elem = v__gen__c__Gen_read_field(g, left_type, _S("element_size"), _S("a")); string right_elem = v__gen__c__Gen_read_field(g, left_type, _S("element_size"), _S("b")); if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option)) { strings__Builder_writeln(&fn_builder, _S("\tif (a.state != b.state) return false;")); strings__Builder_writeln(&fn_builder, _S("\tif (a.state == 2 && a.state == b.state) return true;")); } strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = left_len}}, {_S(" != "), 0xfe10, {.d_s = right_len}}, {_S(") {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\t\treturn false;")); strings__Builder_writeln(&fn_builder, _S("\t}")); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tfor (int i = 0; i < "), 0xfe10, {.d_s = left_len}}, {_S("; ++i) {"), 0, { .d_c = 0 }}}))); if (elem.sym->kind == v__ast__Kind__string) { strings__Builder_writeln(&fn_builder, str_intp(7, _MOV((StrIntpData[]){{_S("\t\tif (!string__eq(*(("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)((byte*)"), 0xfe10, {.d_s = left_data}}, {_S("+(i*"), 0xfe10, {.d_s = left_elem}}, {_S("))), *(("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)((byte*)"), 0xfe10, {.d_s = right_data}}, {_S("+(i*"), 0xfe10, {.d_s = right_elem}}, {_S("))))) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__sum_type && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_sumtype_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(6, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_sumtype_eq((("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = left_data}}, {_S(")[i], (("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = right_data}}, {_S(")[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__struct && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_struct_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(6, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_struct_eq((("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = left_data}}, {_S(")[i], (("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = right_data}}, {_S(")[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__interface && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_interface_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(6, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_interface_eq((("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = left_data}}, {_S(")[i], (("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = right_data}}, {_S(")[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__array && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_array_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(6, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_arr_eq((("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = left_data}}, {_S(")[i], (("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = right_data}}, {_S(")[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__array_fixed && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_fixed_array_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(6, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_arr_eq((("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = left_data}}, {_S(")[i], (("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = right_data}}, {_S(")[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__map && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_map_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(6, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_map_eq((("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = left_data}}, {_S(")[i], (("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = right_data}}, {_S(")[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__alias && !v__ast__Type_is_ptr(elem.typ)) { if ((*(bool*)map_get(ADDR(map, g->no_eq_method_types), &(v__ast__Type[]){elem.typ}, &(bool[]){ 0 }))) { strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tif ((("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = left_data}}, {_S(")[i] != (("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = right_data}}, {_S(")[i]) {"), 0, { .d_c = 0 }}}))); } else { string eq_fn = v__gen__c__Gen_gen_alias_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(6, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_alias_eq((("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = left_data}}, {_S(")[i], (("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = right_data}}, {_S(")[i])) {"), 0, { .d_c = 0 }}}))); } } else if (elem.sym->kind == v__ast__Kind__function) { strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tif (*((voidptr*)((byte*)"), 0xfe10, {.d_s = left_data}}, {_S("+(i*"), 0xfe10, {.d_s = left_elem}}, {_S("))) != *((voidptr*)((byte*)"), 0xfe10, {.d_s = right_data}}, {_S("+(i*"), 0xfe10, {.d_s = right_elem}}, {_S(")))) {"), 0, { .d_c = 0 }}}))); } else { if (v__ast__Type_has_flag(elem.typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("* left = (("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = left_data}}, {_S(")+(i*"), 0xfe10, {.d_s = left_elem}}, {_S(");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("* right = (("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)"), 0xfe10, {.d_s = right_data}}, {_S(")+(i*"), 0xfe10, {.d_s = right_elem}}, {_S(");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif (!(left->state == 2 && left->state == right->state) && memcmp(left->data, right->data, sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, elem.typ)}}, {_S("))) {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, str_intp(7, _MOV((StrIntpData[]){{_S("\t\tif (*(("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)((byte*)"), 0xfe10, {.d_s = left_data}}, {_S("+(i*"), 0xfe10, {.d_s = left_elem}}, {_S("))) != *(("), 0xfe10, {.d_s = ptr_elem_styp}}, {_S("*)((byte*)"), 0xfe10, {.d_s = right_data}}, {_S("+(i*"), 0xfe10, {.d_s = right_elem}}, {_S(")))) {"), 0, { .d_c = 0 }}}))); } } strings__Builder_writeln(&fn_builder, _S("\t\t\treturn false;")); strings__Builder_writeln(&fn_builder, _S("\t\t}")); strings__Builder_writeln(&fn_builder, _S("\t}")); strings__Builder_writeln(&fn_builder, _S("\treturn true;")); strings__Builder_writeln(&fn_builder, _S("}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); return ptr_styp; } VV_LOC string v__gen__c__Gen_gen_fixed_array_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type) { v__gen__c__Type left_typ = v__gen__c__Gen_unwrap(g, left_type); string ptr_styp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(left_typ.typ, 0)); v__ast__Type left_no_ptr = v__ast__Type_set_nr_muls(left_type, 0); if ((Array_v__ast__Type_contains(g->generated_eq_fns, left_no_ptr))) { return ptr_styp; } array_push((array*)&g->generated_eq_fns, _MOV((v__ast__Type[]){ left_no_ptr })); v__ast__ArrayFixed elem_info = v__ast__TypeSymbol_array_fixed_info(left_typ.sym); v__gen__c__Type elem = v__gen__c__Gen_unwrap(g, elem_info.elem_type); int size = elem_info.size; string arg_styp = ptr_styp; if (elem_info.is_fn_ret) { arg_styp = string_substr(ptr_styp, 3, 2147483647); } strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_S("bool "), 0xfe10, {.d_s = ptr_styp}}, {_S("_arr_eq("), 0xfe10, {.d_s = arg_styp}}, {_S(" a, "), 0xfe10, {.d_s = arg_styp}}, {_S(" b);"), 0, { .d_c = 0 }}}))); bool is_option = v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option); string left = (is_option ? (_S("a.data")) : (_S("a"))); string right = (is_option ? (_S("b.data")) : (_S("b"))); strings__Builder fn_builder = strings__new_builder(512); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("inline bool "), 0xfe10, {.d_s = ptr_styp}}, {_S("_arr_eq("), 0xfe10, {.d_s = arg_styp}}, {_S(" a, "), 0xfe10, {.d_s = arg_styp}}, {_S(" b) {"), 0, { .d_c = 0 }}}))); if (is_option) { strings__Builder_writeln(&fn_builder, _S("\tif (a.state != b.state) return false;")); strings__Builder_writeln(&fn_builder, _S("\tif (a.state == 2 && a.state == b.state) return true;")); } if (v__ast__TypeSymbol_is_primitive_fixed_array(left_typ.sym)) { string suffix = (is_option ? (_S(".data")) : (_S("[0]"))); string size_styp = (is_option ? (v__gen__c__Gen_base_type(g, v__ast__Type_set_nr_muls(left_typ.typ, 0))) : (arg_styp)); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\tif (!memcmp(&a"), 0xfe10, {.d_s = suffix}}, {_S(", &b"), 0xfe10, {.d_s = suffix}}, {_S(", sizeof("), 0xfe10, {.d_s = size_styp}}, {_S("))) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\t\treturn true;")); strings__Builder_writeln(&fn_builder, _S("\t}")); } strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tfor (int i = 0; i < "), 0xfe07, {.d_i32 = size}}, {_S("; ++i) {"), 0, { .d_c = 0 }}}))); if (elem.sym->kind == v__ast__Kind__string) { strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tif (!string__eq(((string*)"), 0xfe10, {.d_s = left}}, {_S(")[i], ((string*)"), 0xfe10, {.d_s = right}}, {_S(")[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__sum_type && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_sumtype_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_sumtype_eq("), 0xfe10, {.d_s = left}}, {_S("[i], "), 0xfe10, {.d_s = right}}, {_S("[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__struct && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_struct_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_struct_eq("), 0xfe10, {.d_s = left}}, {_S("[i], "), 0xfe10, {.d_s = right}}, {_S("[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__interface && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_interface_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_interface_eq("), 0xfe10, {.d_s = left}}, {_S("[i], "), 0xfe10, {.d_s = right}}, {_S("[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__array && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_array_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_arr_eq("), 0xfe10, {.d_s = left}}, {_S("[i], "), 0xfe10, {.d_s = right}}, {_S("[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__array_fixed && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_fixed_array_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_arr_eq("), 0xfe10, {.d_s = left}}, {_S("[i], "), 0xfe10, {.d_s = right}}, {_S("[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__map && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_map_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_map_eq("), 0xfe10, {.d_s = left}}, {_S("[i], "), 0xfe10, {.d_s = right}}, {_S("[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__alias && !v__ast__Type_is_ptr(elem.typ)) { string eq_fn = v__gen__c__Gen_gen_alias_equality_fn(g, elem.typ); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_alias_eq("), 0xfe10, {.d_s = left}}, {_S("[i], "), 0xfe10, {.d_s = right}}, {_S("[i])) {"), 0, { .d_c = 0 }}}))); } else if (elem.sym->kind == v__ast__Kind__function) { strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = left}}, {_S("[i] != "), 0xfe10, {.d_s = right}}, {_S("[i]) {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = left}}, {_S("[i] != "), 0xfe10, {.d_s = right}}, {_S("[i]) {"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&fn_builder, _S("\t\t\treturn false;")); strings__Builder_writeln(&fn_builder, _S("\t\t}")); strings__Builder_writeln(&fn_builder, _S("\t}")); strings__Builder_writeln(&fn_builder, _S("\treturn true;")); strings__Builder_writeln(&fn_builder, _S("}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); return ptr_styp; } VV_LOC string v__gen__c__Gen_gen_map_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type) { v__gen__c__Type left = v__gen__c__Gen_unwrap(g, left_type); string ptr_styp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(left.typ, 0)); v__ast__Type left_no_ptr = v__ast__Type_set_nr_muls(left_type, 0); if ((Array_v__ast__Type_contains(g->generated_eq_fns, left_no_ptr))) { return ptr_styp; } array_push((array*)&g->generated_eq_fns, _MOV((v__ast__Type[]){ left_no_ptr })); v__gen__c__Type value = v__gen__c__Gen_unwrap(g, v__ast__TypeSymbol_map_info(left.sym).value_type); string ptr_value_styp = v__gen__c__Gen_styp(g, value.typ); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_S("bool "), 0xfe10, {.d_s = ptr_styp}}, {_S("_map_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b);"), 0, { .d_c = 0 }}}))); string left_len = v__gen__c__Gen_read_map_field_from_option(g, left.typ, _S("len"), _S("a")); string right_len = v__gen__c__Gen_read_map_field_from_option(g, left.typ, _S("len"), _S("b")); string key_values = v__gen__c__Gen_read_map_field_from_option(g, left.typ, _S("key_values"), _S("a")); string a = (v__ast__Type_has_flag(left.typ, v__ast__TypeFlag__option) ? (v__gen__c__Gen_read_map_from_option(g, left.typ, _S("a"))) : (_S("&a"))); string b = (v__ast__Type_has_flag(left.typ, v__ast__TypeFlag__option) ? (v__gen__c__Gen_read_map_from_option(g, left.typ, _S("b"))) : (_S("&b"))); strings__Builder fn_builder = strings__new_builder(512); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("inline bool "), 0xfe10, {.d_s = ptr_styp}}, {_S("_map_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = left_len}}, {_S(" != "), 0xfe10, {.d_s = right_len}}, {_S(") {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\t\treturn false;")); strings__Builder_writeln(&fn_builder, _S("\t}")); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tfor (int i = 0; i < "), 0xfe10, {.d_s = key_values}}, {_S(".len; ++i) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif (!DenseArray_has_index(&"), 0xfe10, {.d_s = key_values}}, {_S(", i)) continue;"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tvoidptr k = DenseArray_key(&"), 0xfe10, {.d_s = key_values}}, {_S(", i);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif (!map_exists("), 0xfe10, {.d_s = b}}, {_S(", k)) return false;"), 0, { .d_c = 0 }}}))); v__ast__Kind kind = v__ast__Table_type_kind(g->table, value.typ); if (kind == v__ast__Kind__function) { v__ast__FnType info = *(v__ast__FnType*)__as_cast((value.sym->info)._v__ast__FnType,(value.sym->info)._typ, 553); Array_v__ast__Type _t3 = {0}; Array_v__ast__Param _t3_orig = info.func.params; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__Type)); for (int _t5 = 0; _t5 < _t3_len; ++_t5) { v__ast__Param it = ((v__ast__Param*) _t3_orig.data)[_t5]; v__ast__Type _t4 = it.typ; array_push((array*)&_t3, &_t4); } string sig = v__gen__c__Gen_fn_var_signature(g, info.func.return_type,_t3, _S("v")); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = sig}}, {_S(" = *(voidptr*)map_get("), 0xfe10, {.d_s = a}}, {_S(", k, &(voidptr[]){ 0 });"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = ptr_value_styp}}, {_S(" v = *("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("*)map_get("), 0xfe10, {.d_s = a}}, {_S(", k, &("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("[]){ 0 });"), 0, { .d_c = 0 }}}))); } switch (kind) { case v__ast__Kind__string: { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif (!fast_string_eq(*(string*)map_get("), 0xfe10, {.d_s = b}}, {_S(", k, &(string[]){_S(\"\")}), v)) {"), 0, { .d_c = 0 }}}))); break; } case v__ast__Kind__sum_type: { string eq_fn = v__gen__c__Gen_gen_sumtype_equality_fn(g, value.typ); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_sumtype_eq(*("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("*)map_get("), 0xfe10, {.d_s = b}}, {_S(", k, &("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("[]){ 0 }), v)) {"), 0, { .d_c = 0 }}}))); break; } case v__ast__Kind__struct: { string eq_fn = v__gen__c__Gen_gen_struct_equality_fn(g, value.typ); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_struct_eq(*("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("*)map_get("), 0xfe10, {.d_s = b}}, {_S(", k, &("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("[]){ 0 }), v)) {"), 0, { .d_c = 0 }}}))); break; } case v__ast__Kind__interface: { string eq_fn = v__gen__c__Gen_gen_interface_equality_fn(g, value.typ); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_interface_eq(*("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("*)map_get("), 0xfe10, {.d_s = b}}, {_S(", k, &("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("[]){ 0 }), v)) {"), 0, { .d_c = 0 }}}))); break; } case v__ast__Kind__array: { string eq_fn = v__gen__c__Gen_gen_array_equality_fn(g, value.typ); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_arr_eq(*("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("*)map_get("), 0xfe10, {.d_s = b}}, {_S(", k, &("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("[]){ 0 }), v)) {"), 0, { .d_c = 0 }}}))); break; } case v__ast__Kind__array_fixed: { string eq_fn = v__gen__c__Gen_gen_fixed_array_equality_fn(g, value.typ); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_arr_eq(*("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("*)map_get("), 0xfe10, {.d_s = b}}, {_S(", k, &("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("[]){ 0 }), v)) {"), 0, { .d_c = 0 }}}))); break; } case v__ast__Kind__map: { string eq_fn = v__gen__c__Gen_gen_map_equality_fn(g, value.typ); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_map_eq(*("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("*)map_get("), 0xfe10, {.d_s = b}}, {_S(", k, &("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("[]){ 0 }), v)) {"), 0, { .d_c = 0 }}}))); break; } case v__ast__Kind__alias: { string eq_fn = v__gen__c__Gen_gen_alias_equality_fn(g, value.typ); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tif (!"), 0xfe10, {.d_s = eq_fn}}, {_S("_alias_eq(*("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("*)map_get("), 0xfe10, {.d_s = b}}, {_S(", k, &("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("[]){ 0 }), v)) {"), 0, { .d_c = 0 }}}))); break; } case v__ast__Kind__function: { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif (*(voidptr*)map_get("), 0xfe10, {.d_s = b}}, {_S(", k, &(voidptr[]){ 0 }) != v) {"), 0, { .d_c = 0 }}}))); break; } case v__ast__Kind__placeholder: case v__ast__Kind__void: case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__i32: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__isize: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__usize: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__bool: case v__ast__Kind__none: case v__ast__Kind__chan: case v__ast__Kind__any: case v__ast__Kind__generic_inst: case v__ast__Kind__multi_return: case v__ast__Kind__enum: case v__ast__Kind__float_literal: case v__ast__Kind__int_literal: case v__ast__Kind__aggregate: case v__ast__Kind__thread: default: { { if (v__ast__Type_has_flag(value.typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tif (memcmp(v.data, (("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("*)map_get("), 0xfe10, {.d_s = b}}, {_S(", k, &("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("[]){ 0 }))->data, sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, value.typ)}}, {_S(")) != 0) {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tif (*("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("*)map_get("), 0xfe10, {.d_s = b}}, {_S(", k, &("), 0xfe10, {.d_s = ptr_value_styp}}, {_S("[]){ 0 }) != v) {"), 0, { .d_c = 0 }}}))); } break; } } } strings__Builder_writeln(&fn_builder, _S("\t\t\treturn false;")); strings__Builder_writeln(&fn_builder, _S("\t\t}")); strings__Builder_writeln(&fn_builder, _S("\t}")); strings__Builder_writeln(&fn_builder, _S("\treturn true;")); strings__Builder_writeln(&fn_builder, _S("}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); return ptr_styp; } VV_LOC string v__gen__c__Gen_gen_interface_equality_fn(v__gen__c__Gen* g, v__ast__Type left_type) { bool v__gen__c__Gen_gen_interface_equality_fn_defer_0 = false; strings__Builder fn_builder; v__gen__c__Type left = v__gen__c__Gen_unwrap(g, left_type); string ptr_styp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(left.typ, 0)); string idx_fn = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(v__ast__Type_set_nr_muls(left.typ, 0), v__ast__TypeFlag__option)); string fn_name = string_replace(ptr_styp, _S("interface "), _S("")); v__ast__Type left_no_ptr = v__ast__Type_set_nr_muls(left_type, 0); if ((Array_v__ast__Type_contains(g->generated_eq_fns, left_no_ptr))) { return fn_name; } array_push((array*)&g->generated_eq_fns, _MOV((v__ast__Type[]){ left_no_ptr })); v__ast__TypeInfo info = left.sym->info; strings__Builder_writeln(&g->definitions, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("bool "), 0xfe10, {.d_s = ptr_styp}}, {_S("_interface_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b);"), 0, { .d_c = 0 }}}))); fn_builder = strings__new_builder(512); v__gen__c__Gen_gen_interface_equality_fn_defer_0 = true; string left_arg = v__gen__c__Gen_read_field(g, left_type, _S("_typ"), _S("a")); string right_arg = v__gen__c__Gen_read_field(g, left_type, _S("_typ"), _S("b")); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("inline bool "), 0xfe10, {.d_s = fn_name}}, {_S("_interface_eq("), 0xfe10, {.d_s = ptr_styp}}, {_S(" a, "), 0xfe10, {.d_s = ptr_styp}}, {_S(" b) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = left_arg}}, {_S(" == "), 0xfe10, {.d_s = right_arg}}, {_S(") {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tint idx = v_typeof_interface_idx_"), 0xfe10, {.d_s = idx_fn}}, {_S("("), 0xfe10, {.d_s = left_arg}}, {_S(");"), 0, { .d_c = 0 }}}))); if ((info)._typ == 542 /* v.ast.Interface */) { for (int _t3 = 0; _t3 < (*info._v__ast__Interface).types.len; ++_t3) { v__ast__Type typ = ((v__ast__Type*)(*info._v__ast__Interface).types.data)[_t3]; v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__ast__Type_set_nr_muls(typ, 0)); if (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif (idx == "), 0xfe07, {.d_i32 = v__ast__Type_idx(typ)}}, {_S(") {"), 0, { .d_c = 0 }}}))); strings__Builder_write_string(&fn_builder, _S("\t\t\treturn ")); if (sym->kind == (v__ast__Kind__struct)) { string eq_fn = v__gen__c__Gen_gen_struct_equality_fn(g, typ); string l_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("a")); string r_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("b")); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_struct_eq(*(")); strings__Builder_write_string(&fn_builder, l_eqfn); strings__Builder_write_string(&fn_builder, _S("), *(")); strings__Builder_write_string(&fn_builder, r_eqfn); strings__Builder_write_string(&fn_builder, _S("))")); } } else if (sym->kind == (v__ast__Kind__string)) { string l_str = v__gen__c__Gen_read_field(g, left_type, _S("_string"), _S("a")); string r_str = v__gen__c__Gen_read_field(g, left_type, _S("_string"), _S("b")); { strings__Builder_write_string(&fn_builder, _S("string__eq(*(")); strings__Builder_write_string(&fn_builder, l_str); strings__Builder_write_string(&fn_builder, _S("), *(")); strings__Builder_write_string(&fn_builder, r_str); strings__Builder_write_string(&fn_builder, _S("))")); } } else if (sym->kind == (v__ast__Kind__sum_type)) { string eq_fn = v__gen__c__Gen_gen_sumtype_equality_fn(g, typ); string l_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("a")); string r_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("b")); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_sumtype_eq(*(")); strings__Builder_write_string(&fn_builder, l_eqfn); strings__Builder_write_string(&fn_builder, _S("), *(")); strings__Builder_write_string(&fn_builder, r_eqfn); strings__Builder_write_string(&fn_builder, _S("))")); } } else if (sym->kind == (v__ast__Kind__array)) { string eq_fn = v__gen__c__Gen_gen_array_equality_fn(g, typ); string l_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("a")); string r_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("b")); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_arr_eq(*(")); strings__Builder_write_string(&fn_builder, l_eqfn); strings__Builder_write_string(&fn_builder, _S("), *(")); strings__Builder_write_string(&fn_builder, r_eqfn); strings__Builder_write_string(&fn_builder, _S("))")); } } else if (sym->kind == (v__ast__Kind__array_fixed)) { string eq_fn = v__gen__c__Gen_gen_fixed_array_equality_fn(g, typ); string l_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("a")); string r_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("b")); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_arr_eq(*(")); strings__Builder_write_string(&fn_builder, l_eqfn); strings__Builder_write_string(&fn_builder, _S("), *(")); strings__Builder_write_string(&fn_builder, r_eqfn); strings__Builder_write_string(&fn_builder, _S("))")); } } else if (sym->kind == (v__ast__Kind__map)) { string eq_fn = v__gen__c__Gen_gen_map_equality_fn(g, typ); string l_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("a")); string r_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("b")); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_map_eq(*(")); strings__Builder_write_string(&fn_builder, l_eqfn); strings__Builder_write_string(&fn_builder, _S("), *(")); strings__Builder_write_string(&fn_builder, r_eqfn); strings__Builder_write_string(&fn_builder, _S("))")); } } else if (sym->kind == (v__ast__Kind__alias)) { string eq_fn = v__gen__c__Gen_gen_alias_equality_fn(g, typ); string l_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("a")); string r_eqfn = v__gen__c__Gen_read_field(g, left_type, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = eq_fn}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("b")); { strings__Builder_write_string(&fn_builder, eq_fn); strings__Builder_write_string(&fn_builder, _S("_alias_eq(*(")); strings__Builder_write_string(&fn_builder, l_eqfn); strings__Builder_write_string(&fn_builder, _S("), *(")); strings__Builder_write_string(&fn_builder, r_eqfn); strings__Builder_write_string(&fn_builder, _S("))")); } } else { strings__Builder_write_string(&fn_builder, _S("true")); } strings__Builder_writeln(&fn_builder, _S(";")); strings__Builder_writeln(&fn_builder, _S("\t\t}")); } } strings__Builder_writeln(&fn_builder, _S("\t}")); strings__Builder_writeln(&fn_builder, _S("\treturn false;")); strings__Builder_writeln(&fn_builder, _S("}")); string _t4 = fn_name; // Defer begin if (v__gen__c__Gen_gen_interface_equality_fn_defer_0) { array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } // Defer end return _t4; } inline VV_LOC void v__gen__c__Gen_register_free_method(v__gen__c__Gen* g, v__ast__Type typ) { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_get_free_method(g, v__ast__Type_set_nr_muls(v__ast__Type_clear_flag(typ, v__ast__TypeFlag__shared_f), 0)); } else { v__gen__c__Gen_get_free_method(g, typ); } } VV_LOC string v__gen__c__Gen_get_free_method(v__gen__c__Gen* g, v__ast__Type typ) { if (_IN_MAP(ADDR(v__ast__Type, typ), ADDR(map, g->autofree_methods))) { return (*(string*)map_get(ADDR(map, g->autofree_methods), &(v__ast__Type[]){typ}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })); } v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, typ)); if ((sym->info)._typ == 539 /* v.ast.Alias */) { if ((*sym->info._v__ast__Alias).is_import) { sym = v__ast__Table_sym(g->table, (*sym->info._v__ast__Alias).parent_type); } } string styp = string_replace(v__gen__c__Gen_styp(g, typ), _S("*"), _S("")); string fn_name = v__gen__c__styp_to_free_fn_name(styp); if (v__ast__TypeSymbol_has_method_with_generic_parent(sym, _S("free"))) { map_set(&g->autofree_methods, &(v__ast__Type[]){typ}, &(string[]) { fn_name }); return fn_name; } map_set(&g->autofree_methods, &(v__ast__Type[]){typ}, &(string[]) { fn_name }); return fn_name; } VV_LOC void v__gen__c__Gen_gen_free_methods(v__gen__c__Gen* g) { Map_v__ast__Type_string _t1 = g->autofree_methods; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} v__ast__Type typ = *(v__ast__Type*)DenseArray_key(&_t1.key_values, _t2); v__gen__c__Gen_gen_free_method(g, typ); } } VV_LOC string v__gen__c__Gen_gen_free_method(v__gen__c__Gen* g, v__ast__Type typ) { string styp = string_replace(v__gen__c__Gen_styp(g, typ), _S("*"), _S("")); string fn_name = v__gen__c__styp_to_free_fn_name(styp); v__ast__Type deref_typ = (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option) ? (typ) : (v__ast__Type_set_nr_muls(typ, 0))); if (_IN_MAP(ADDR(v__ast__Type, deref_typ), ADDR(map, g->generated_free_methods))) { return fn_name; } map_set(&g->generated_free_methods, &(v__ast__Type[]){deref_typ}, &(bool[]) { true }); v__ast__Type objtyp = v__gen__c__Gen_unwrap_generic(g, typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, objtyp); if ((sym->info)._typ == 539 /* v.ast.Alias */) { if ((*sym->info._v__ast__Alias).is_import) { sym = v__ast__Table_sym(g->table, (*sym->info._v__ast__Alias).parent_type); } } if (sym->kind != v__ast__Kind__interface && v__ast__TypeSymbol_has_method_with_generic_parent(sym, _S("free"))) { return fn_name; } if (sym->info._typ == 518 /* v.ast.Struct */) { v__gen__c__Gen_gen_free_for_struct(g, objtyp, (*sym->info._v__ast__Struct), styp, fn_name); } else if (sym->info._typ == 513 /* v.ast.Array */) { v__gen__c__Gen_gen_free_for_array(g, (*sym->info._v__ast__Array), styp, fn_name); } else if (sym->info._typ == 514 /* v.ast.Map */) { v__gen__c__Gen_gen_free_for_map(g, objtyp, styp, fn_name); } else if (sym->info._typ == 542 /* v.ast.Interface */) { v__gen__c__Gen_gen_free_for_interface(g, *sym, (*sym->info._v__ast__Interface), styp, fn_name); } else { println(v__ast__Table_type_str(g->table, typ)); println(str_intp(3, _MOV((StrIntpData[]){{_S("could not generate free method '"), 0xfe10, {.d_s = fn_name}}, {_S("' for type '"), 0xfe10, {.d_s = styp}}, {_S("'"), 0, { .d_c = 0 }}}))); } return fn_name; } VV_LOC void v__gen__c__Gen_gen_free_for_interface(v__gen__c__Gen* g, v__ast__TypeSymbol sym, v__ast__Interface info, string styp, string fn_name) { bool v__gen__c__Gen_gen_free_for_interface_defer_0 = false; strings__Builder fn_builder; strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("void "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S("* it);"), 0, { .d_c = 0 }}}))); fn_builder = strings__new_builder(128); v__gen__c__Gen_gen_free_for_interface_defer_0 = true; strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("void "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S("* it) {"), 0, { .d_c = 0 }}}))); for (int _t1 = 0; _t1 < info.types.len; ++_t1) { v__ast__Type t = ((v__ast__Type*)info.types.data)[_t1]; v__ast__Type typ_ = v__gen__c__Gen_unwrap_generic(g, t); v__ast__TypeSymbol* sub_sym = v__ast__Table_sym(g->table, typ_); if (!(sub_sym->kind == v__ast__Kind__string || sub_sym->kind == v__ast__Kind__array || sub_sym->kind == v__ast__Kind__map || sub_sym->kind == v__ast__Kind__struct)) { continue; } if (!v__ast__TypeSymbol_has_method_with_generic_parent(sub_sym, _S("free"))) { continue; } string type_styp = v__gen__c__Gen_gen_type_name_for_free_call(g, typ_); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\tif (it->_typ == _"), 0xfe10, {.d_s = sym.cname}}, {_S("_"), 0xfe10, {.d_s = sub_sym->cname}}, {_S("_index) { "), 0xfe10, {.d_s = type_styp}}, {_S("_free(it->_"), 0xfe10, {.d_s = sub_sym->cname}}, {_S("); return; }"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&fn_builder, _S("}")); // Defer begin if (v__gen__c__Gen_gen_free_for_interface_defer_0) { array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } // Defer end } VV_LOC void v__gen__c__Gen_gen_free_for_struct(v__gen__c__Gen* g, v__ast__Type typ, v__ast__Struct info, string styp, string fn_name) { bool v__gen__c__Gen_gen_free_for_struct_defer_0 = false; strings__Builder fn_builder; strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("void "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S("* it);"), 0, { .d_c = 0 }}}))); fn_builder = strings__new_builder(128); v__gen__c__Gen_gen_free_for_struct_defer_0 = true; strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("void "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S("* it) {"), 0, { .d_c = 0 }}}))); for (int _t1 = 0; _t1 < info.fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[_t1]; string field_name = v__gen__c__c_name(field.name); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, field.typ)); if (!(sym->kind == v__ast__Kind__string || sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__map || sym->kind == v__ast__Kind__struct)) { continue; } string field_styp = v__gen__c__Gen_gen_type_name_for_free_call(g, field.typ); bool is_struct_option = v__ast__Type_has_flag(typ, v__ast__TypeFlag__option); string field_styp_fn_name = (v__ast__TypeSymbol_has_method(sym, _S("free")) ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = field_styp}}, {_S("_free"), 0, { .d_c = 0 }}}))) : (v__gen__c__Gen_gen_free_method(g, field.typ))); bool is_field_option = v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option); bool expects_opt = string_starts_with(field_styp_fn_name, _S("_option_")); if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__shared_f)) { strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = field_styp_fn_name}}, {_S("(&(it->"), 0xfe10, {.d_s = field_name}}, {_S("->val));"), 0, { .d_c = 0 }}}))); } else if (is_struct_option) { string opt_styp = v__gen__c__Gen_base_type(g, typ); string prefix = (v__ast__Type_is_ptr(field.typ) ? (_S("")) : (_S("&"))); if (is_field_option) { string opt_field_styp = (expects_opt ? (v__gen__c__Gen_styp(g, field.typ)) : (v__gen__c__Gen_base_type(g, field.typ))); string suffix = (expects_opt ? (_S("")) : (_S(".data"))); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\tif ((("), 0xfe10, {.d_s = opt_styp}}, {_S("*)&it->data)->"), 0xfe10, {.d_s = field_name}}, {_S(".state != 2) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(7, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = field_styp_fn_name}}, {_S("(("), 0xfe10, {.d_s = opt_field_styp}}, {_S("*)"), 0xfe10, {.d_s = prefix}}, {_S("(("), 0xfe10, {.d_s = opt_styp}}, {_S("*)&it->data)->"), 0xfe10, {.d_s = field_name}}, {_SLIT0, 0xfe10, {.d_s = suffix}}, {_S(");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\t}")); } else { strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = field_styp_fn_name}}, {_S("("), 0xfe10, {.d_s = prefix}}, {_S("(("), 0xfe10, {.d_s = opt_styp}}, {_S("*)&it->data)->"), 0xfe10, {.d_s = field_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else { if (is_field_option) { string opt_field_styp = (expects_opt ? (v__gen__c__Gen_styp(g, field.typ)) : (v__gen__c__Gen_base_type(g, field.typ))); string suffix = (expects_opt ? (_S("")) : (_S(".data"))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tif (it->"), 0xfe10, {.d_s = field_name}}, {_S(".state != 2) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = field_styp_fn_name}}, {_S("(("), 0xfe10, {.d_s = opt_field_styp}}, {_S("*)&(it->"), 0xfe10, {.d_s = field_name}}, {_SLIT0, 0xfe10, {.d_s = suffix}}, {_S("));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\t}")); } else { strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = field_styp_fn_name}}, {_S("(&(it->"), 0xfe10, {.d_s = field_name}}, {_S("));"), 0, { .d_c = 0 }}}))); } } } strings__Builder_writeln(&fn_builder, _S("}")); // Defer begin if (v__gen__c__Gen_gen_free_for_struct_defer_0) { array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } // Defer end } VV_LOC string v__gen__c__Gen_gen_type_name_for_free_call(v__gen__c__Gen* g, v__ast__Type typ) { string styp = string_replace(v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(v__ast__Type_set_nr_muls(typ, 0), v__ast__TypeFlag__option)), _S("*"), _S("")); if (string_starts_with(styp, _S("__shared"))) { styp = string_all_after(styp, _S("__shared__")); } return styp; } VV_LOC void v__gen__c__Gen_gen_free_for_array(v__gen__c__Gen* g, v__ast__Array info, string styp, string fn_name) { bool v__gen__c__Gen_gen_free_for_array_defer_0 = false; strings__Builder fn_builder; strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("void "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S("* it);"), 0, { .d_c = 0 }}}))); fn_builder = strings__new_builder(128); v__gen__c__Gen_gen_free_for_array_defer_0 = true; strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("void "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S("* it) {"), 0, { .d_c = 0 }}}))); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, info.elem_type)); if (sym->kind == v__ast__Kind__string || sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__map || sym->kind == v__ast__Kind__struct) { strings__Builder_writeln(&fn_builder, _S("\tfor (int i = 0; i < it->len; i++) {")); string elem_styp = string_replace(v__gen__c__Gen_styp(g, info.elem_type), _S("*"), _S("")); string elem_styp_fn_name = (v__ast__TypeSymbol_has_method(sym, _S("free")) ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = elem_styp}}, {_S("_free"), 0, { .d_c = 0 }}}))) : (v__gen__c__Gen_gen_free_method(g, info.elem_type))); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = elem_styp_fn_name}}, {_S("(&((("), 0xfe10, {.d_s = elem_styp}}, {_S("*)it->data)[i]));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\t}")); } strings__Builder_writeln(&fn_builder, _S("\tarray_free(it);")); strings__Builder_writeln(&fn_builder, _S("}")); // Defer begin if (v__gen__c__Gen_gen_free_for_array_defer_0) { array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } // Defer end } VV_LOC void v__gen__c__Gen_gen_free_for_map(v__gen__c__Gen* g, v__ast__Type typ, string styp, string fn_name) { bool v__gen__c__Gen_gen_free_for_map_defer_0 = false; strings__Builder fn_builder; strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("void "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S("* it);"), 0, { .d_c = 0 }}}))); fn_builder = strings__new_builder(128); v__gen__c__Gen_gen_free_for_map_defer_0 = true; strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("void "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S("* it) {"), 0, { .d_c = 0 }}}))); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&fn_builder, _S("\tif (it->state != 2) {")); strings__Builder_writeln(&fn_builder, _S("\t\tmap_free((map*)&it->data);")); strings__Builder_writeln(&fn_builder, _S("\t}")); } else { strings__Builder_writeln(&fn_builder, _S("\tmap_free(it);")); } strings__Builder_writeln(&fn_builder, _S("}")); // Defer begin if (v__gen__c__Gen_gen_free_for_map_defer_0) { array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } // Defer end } inline VV_LOC string v__gen__c__styp_to_free_fn_name(string styp) { return string__plus(string_replace_each(styp, new_array_from_c_array(6, 6, sizeof(string), _MOV((string[6]){_S("*"), _S(""), _S("."), _S("__"), _S(" "), _S("__")}))), _S("_free")); } VV_LOC void v__gen__c__Gen_gen_str_default(v__gen__c__Gen* g, v__ast__TypeSymbol sym, string styp, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("> gen_str_default: "), 0xfe10, {.d_s = sym.name}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | str_fn_name"), 0, { .d_c = 0 }}}))); } #endif string convertor = _S(""); string typename_ = _S(""); bool got_int_str = false; if ((Array_int_contains(_const_v__ast__integer_type_idxs, sym.parent_idx))) { convertor = _S("int"); typename_ = _S("int"); #if defined(CUSTOM_DEFINE_new_int) { if (_SLIT_EQ(str_fn_name.str, str_fn_name.len, "i64_str")) { if (got_int_str) { return; } else { got_int_str = true; } } } #endif } else if (sym.parent_idx == 16) { convertor = _S("float"); typename_ = _S("f32"); } else if (sym.parent_idx == 17) { convertor = _S("double"); typename_ = _S("f64"); } else if (sym.parent_idx == 19) { convertor = _S("bool"); typename_ = _S("bool"); } else { v__gen__c__verror(str_intp(2, _MOV((StrIntpData[]){{_S("could not generate string method for type `"), 0xfe10, {.d_s = styp}}, {_S("`"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } strings__Builder_writeln(&g->definitions, str_intp(3, _MOV((StrIntpData[]){{_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it) {"), 0, { .d_c = 0 }}}))); if (_SLIT_EQ(convertor.str, convertor.len, "bool")) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\tstring tmp1 = string__plus(_S(\""), 0xfe10, {.d_s = styp}}, {_S("(\"), ("), 0xfe10, {.d_s = convertor}}, {_S(")it ? _S(\"true\") : _S(\"false\"));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_S("\tstring tmp1 = string__plus(_S(\""), 0xfe10, {.d_s = styp}}, {_S("(\"), tos3("), 0xfe10, {.d_s = typename_}}, {_S("_str(("), 0xfe10, {.d_s = convertor}}, {_S(")it).str));"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->auto_str_funcs, _S("\tstring tmp2 = string__plus(tmp1, _S(\")\"));")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstring_free(&tmp1);")); strings__Builder_writeln(&g->auto_str_funcs, _S("\treturn tmp2;")); strings__Builder_writeln(&g->auto_str_funcs, _S("}")); } VV_LOC string v__gen__c__Gen_get_str_fn(v__gen__c__Gen* g, v__ast__Type typ) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> get_str_fn: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(typ))}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__ast__Type unwrapped = (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option) ? (v__ast__Type_clear_flag(v__gen__c__Gen_unwrap_generic(g, typ), v__ast__TypeFlag__variadic)) : (v__ast__Type_clear_flag(v__ast__Type_set_nr_muls(v__gen__c__Gen_unwrap_generic(g, typ), 0), v__ast__TypeFlag__variadic))); if (g->pref->nofloat) { if (typ == _const_v__ast__f32_type) { unwrapped = _const_v__ast__u32_type; } else if (typ == _const_v__ast__f64_type) { unwrapped = _const_v__ast__u64_type; } } string styp = v__gen__c__Gen_styp(g, unwrapped); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, unwrapped); string str_fn_name = v__gen__c__styp_to_str_fn_name(styp); if ((sym->info)._typ == 539 /* v.ast.Alias */ && !v__ast__TypeSymbol_has_method(sym, _S("str"))) { if ((*sym->info._v__ast__Alias).is_import) { sym = v__ast__Table_sym(g->table, (*sym->info._v__ast__Alias).parent_type); str_fn_name = v__gen__c__styp_to_str_fn_name(sym->name); } } if (v__ast__TypeSymbol_has_method_with_generic_parent(sym, _S("str"))) { if (sym->info._typ == 518 /* v.ast.Struct */) { str_fn_name = v__gen__c__Gen_generic_fn_name(g, (*sym->info._v__ast__Struct).concrete_types, str_fn_name); } else if (sym->info._typ == 544 /* v.ast.SumType */) { str_fn_name = v__gen__c__Gen_generic_fn_name(g, (*sym->info._v__ast__SumType).concrete_types, str_fn_name); } else if (sym->info._typ == 542 /* v.ast.Interface */) { str_fn_name = v__gen__c__Gen_generic_fn_name(g, (*sym->info._v__ast__Interface).concrete_types, str_fn_name); } else { } } if (sym->language == v__ast__Language__c && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__option) && v__ast__TypeSymbol_has_method(sym, _S("str"))) { str_fn_name = string__plus(v__util__no_dots(v__gen__c__Gen_cc_type(g, unwrapped, false)), _S("_str")); } array_push((array*)&g->str_types, _MOV((v__gen__c__StrType[]){ ((v__gen__c__StrType){.styp = styp,.typ = unwrapped,}) })); return str_fn_name; } VV_LOC void v__gen__c__Gen_final_gen_str(v__gen__c__Gen* g, v__gen__c__StrType typ) { if ((Array_v__gen__c__StrType_contains(g->generated_str_fns, typ))) { return; } #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> final_gen_str: "), 0xfe10, {.d_s = v__gen__c__StrType_str(typ)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif array_push((array*)&g->generated_str_fns, _MOV((v__gen__c__StrType[]){ typ })); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ.typ); if (v__ast__TypeSymbol_has_method_with_generic_parent(sym, _S("str")) && !(v__ast__Type_has_flag(typ.typ, v__ast__TypeFlag__option) || v__ast__Type_has_flag(typ.typ, v__ast__TypeFlag__result))) { return; } string styp = typ.styp; string str_fn_name = v__gen__c__styp_to_str_fn_name(styp); if ((Array_string_contains(g->str_fn_names->val, str_fn_name))) { return; } sync__RwMutex_lock(&g->str_fn_names->mtx); /*lock*/ { array_push((array*)&g->str_fn_names->val, _MOV((string[]){ string_clone(str_fn_name) })); } sync__RwMutex_unlock(&g->str_fn_names->mtx);; if (v__ast__Type_has_flag(typ.typ, v__ast__TypeFlag__option)) { string opt_typ = (v__ast__Type_has_flag(typ.typ, v__ast__TypeFlag__option_mut_param_t) ? (string_replace(styp, _S("*"), _S(""))) : (styp)); v__gen__c__Gen_gen_str_for_option(g, typ.typ, opt_typ, str_fn_name); return; } if (v__ast__Type_has_flag(typ.typ, v__ast__TypeFlag__result)) { v__gen__c__Gen_gen_str_for_result(g, typ.typ, styp, str_fn_name); return; } if (sym->info._typ == 539 /* v.ast.Alias */) { if ((*sym->info._v__ast__Alias).is_import) { v__gen__c__Gen_gen_str_default(g, *sym, styp, str_fn_name); } else { v__gen__c__Gen_gen_str_for_alias(g, (*sym->info._v__ast__Alias), styp, str_fn_name); } } else if (sym->info._typ == 513 /* v.ast.Array */) { v__gen__c__Gen_gen_str_for_array(g, (*sym->info._v__ast__Array), styp, str_fn_name); } else if (sym->info._typ == 549 /* v.ast.ArrayFixed */) { v__gen__c__Gen_gen_str_for_array_fixed(g, (*sym->info._v__ast__ArrayFixed), styp, str_fn_name); } else if (sym->info._typ == 548 /* v.ast.Enum */) { v__gen__c__Gen_gen_str_for_enum(g, (*sym->info._v__ast__Enum), styp, str_fn_name); } else if (sym->info._typ == 553 /* v.ast.FnType */) { v__gen__c__Gen_gen_str_for_fn_type(g, (*sym->info._v__ast__FnType), styp, str_fn_name); } else if (sym->info._typ == 518 /* v.ast.Struct */) { v__gen__c__Gen_gen_str_for_struct(g, (*sym->info._v__ast__Struct), sym->language, styp, v__ast__Table_type_to_str(g->table, typ.typ), str_fn_name); } else if (sym->info._typ == 514 /* v.ast.Map */) { v__gen__c__Gen_gen_str_for_map(g, (*sym->info._v__ast__Map), styp, str_fn_name); } else if (sym->info._typ == 552 /* v.ast.MultiReturn */) { v__gen__c__Gen_gen_str_for_multi_return(g, (*sym->info._v__ast__MultiReturn), styp, str_fn_name); } else if (sym->info._typ == 544 /* v.ast.SumType */) { v__gen__c__Gen_gen_str_for_union_sum_type(g, (*sym->info._v__ast__SumType), styp, v__ast__Table_type_to_str(g->table, typ.typ), str_fn_name); } else if (sym->info._typ == 542 /* v.ast.Interface */) { v__gen__c__Gen_gen_str_for_interface(g, (*sym->info._v__ast__Interface), styp, v__ast__Table_type_to_str(g->table, typ.typ), str_fn_name); } else if (sym->info._typ == 550 /* v.ast.Chan */) { v__gen__c__Gen_gen_str_for_chan(g, (*sym->info._v__ast__Chan), styp, str_fn_name); } else if (sym->info._typ == 551 /* v.ast.Thread */) { v__gen__c__Gen_gen_str_for_thread(g, (*sym->info._v__ast__Thread), styp, str_fn_name); } else { if (!fast_string_eq(sym->name, _S("nil"))) { v__gen__c__verror(str_intp(3, _MOV((StrIntpData[]){{_S("could not generate string method `"), 0xfe10, {.d_s = str_fn_name}}, {_S("` for type `"), 0xfe10, {.d_s = styp}}, {_S("`"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } } } VV_LOC void v__gen__c__Gen_gen_str_for_option(v__gen__c__Gen* g, v__ast__Type typ, string styp, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_option: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(typ))}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__ast__Type parent_type = v__ast__Type_clear_flag(typ, v__ast__TypeFlag__option); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, parent_type); multi_return_bool_bool_int mr_5423 = v__ast__TypeSymbol_str_method_info(sym); bool sym_has_str_method = mr_5423.arg0; bool expects_ptr = mr_5423.arg1; string parent_str_fn_name = v__gen__c__Gen_get_str_fn(g, parent_type); strings__Builder_writeln(&g->definitions, str_intp(3, _MOV((StrIntpData[]){{_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it) { return indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("(it, 0); }"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, str_intp(3, _MOV((StrIntpData[]){{_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it, int indent_count);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it, int indent_count) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstring res;")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tif (it.state == 0) {")); string _t2; /* if prepend */ if (v__ast__Type_is_ptr(typ) && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__option_mut_param_t)) { string dot = (expects_ptr ? (string_repeat(_S("*"), v__ast__Type_nr_muls(typ))) : (string_repeat(_S("*"), (int)(v__ast__Type_nr_muls(typ) + 1)))); _t2 = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = dot}}, {_S("("), 0xfe10, {.d_s = sym->cname}}, {_S("**)&"), 0, { .d_c = 0 }}})); } else if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option_mut_param_t)) { _t2 = str_intp(2, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = sym->cname}}, {_S("*)"), 0, { .d_c = 0 }}})); } else if (expects_ptr) { _t2 = str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = sym->cname}}, {_S("*)"), 0, { .d_c = 0 }}})); } else { _t2 = str_intp(2, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = sym->cname}}, {_S("*)"), 0, { .d_c = 0 }}})); } string deref = _t2; if (sym->kind == v__ast__Kind__string) { if (v__ast__Type_nr_muls(typ) > 1) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tres = ptr_str(*("), 0xfe10, {.d_s = sym->cname}}, {_S("**)&it.data);"), 0, { .d_c = 0 }}}))); } else { string tmp_res = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = parent_str_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("it.data)"), 0, { .d_c = 0 }}})); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tres = "), 0xfe10, {.d_s = str_intp_sq(tmp_res)}}, {_S(";"), 0, { .d_c = 0 }}}))); } } else if (v__gen__c__should_use_indent_func(sym->kind) && !sym_has_str_method) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tres = indent_"), 0xfe10, {.d_s = parent_str_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("it.data, indent_count);"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__function) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tres = "), 0xfe10, {.d_s = parent_str_fn_name}}, {_S("();"), 0, { .d_c = 0 }}}))); } else { if (v__ast__Type_nr_muls(typ) > 1) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tres = ptr_str(*("), 0xfe10, {.d_s = sym->cname}}, {_S("**)&it.data);"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tres = "), 0xfe10, {.d_s = parent_str_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("it.data);"), 0, { .d_c = 0 }}}))); } } strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\treturn "), 0xfe10, {.d_s = str_intp_sub(_S("Option(%%)"), _S("res"))}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\t}")); strings__Builder_writeln(&g->auto_str_funcs, _S("\treturn _S(\"Option(none)\");")); strings__Builder_writeln(&g->auto_str_funcs, _S("}")); } VV_LOC void v__gen__c__Gen_gen_str_for_result(v__gen__c__Gen* g, v__ast__Type typ, string styp, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_result: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(typ))}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__ast__Type parent_type = v__ast__Type_clear_flag(typ, v__ast__TypeFlag__result); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, parent_type); multi_return_bool_bool_int mr_7512 = v__ast__TypeSymbol_str_method_info(sym); bool sym_has_str_method = mr_7512.arg0; string parent_str_fn_name = v__gen__c__Gen_get_str_fn(g, parent_type); strings__Builder_writeln(&g->definitions, str_intp(3, _MOV((StrIntpData[]){{_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it) { return indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("(it, 0); }"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, str_intp(3, _MOV((StrIntpData[]){{_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it, int indent_count);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it, int indent_count) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstring res;")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tif (!it.is_error) {")); if (sym->kind == v__ast__Kind__string) { string tmp_res = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = parent_str_fn_name}}, {_S("(*("), 0xfe10, {.d_s = sym->cname}}, {_S("*)it.data)"), 0, { .d_c = 0 }}})); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tres = "), 0xfe10, {.d_s = str_intp_sq(tmp_res)}}, {_S(";"), 0, { .d_c = 0 }}}))); } else if (v__gen__c__should_use_indent_func(sym->kind) && !sym_has_str_method) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tres = indent_"), 0xfe10, {.d_s = parent_str_fn_name}}, {_S("(*("), 0xfe10, {.d_s = sym->cname}}, {_S("*)it.data, indent_count);"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tres = "), 0xfe10, {.d_s = parent_str_fn_name}}, {_S("(*("), 0xfe10, {.d_s = sym->cname}}, {_S("*)it.data);"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->auto_str_funcs, _S("\t} else {")); string tmp_str = str_intp_sub(_S("error: %%"), _S("IError_str(it.err)")); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tres = "), 0xfe10, {.d_s = tmp_str}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\t}")); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = str_intp_sub(_S("Result(%%)"), _S("res"))}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("}")); } VV_LOC void v__gen__c__Gen_gen_str_for_alias(v__gen__c__Gen* g, v__ast__Alias info, string styp, string str_fn_name) { bool v__gen__c__Gen_gen_str_for_alias_defer_0 = false; int old; string parent_str_fn_name = v__gen__c__Gen_get_str_fn(g, info.parent_type); v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(g->table, info.parent_type); multi_return_bool_bool_int mr_8963 = v__ast__TypeSymbol_str_method_info(parent_sym); bool str_method_expects_ptr = mr_8963.arg1; #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_alias: "), 0xfe10, {.d_s = parent_str_fn_name}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif string clean_type_v_type_name = v__util__strip_main_name(string_replace(styp, _S("__"), _S("."))); bool is_c_struct = v__ast__TypeSymbol_is_c_struct(parent_sym) && str_method_expects_ptr; string arg_def = (is_c_struct ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S("* it"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" it"), 0, { .d_c = 0 }}})))); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = arg_def}}, {_S(");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = arg_def}}, {_S(") { return indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("(it, 0); }"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = arg_def}}, {_S(", int indent_count);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = arg_def}}, {_S(", int indent_count) {"), 0, { .d_c = 0 }}}))); old = v__gen__c__Gen_reset_tmp_count(g); v__gen__c__Gen_gen_str_for_alias_defer_0 = true; strings__Builder_writeln(&g->auto_str_funcs, _S("\tstring indents = string_repeat(_S(\" \"), indent_count);")); if (str_method_expects_ptr) { string it_arg = (is_c_struct ? (_S("it")) : (_S("&it"))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\tstring tmp_ds = "), 0xfe10, {.d_s = parent_str_fn_name}}, {_S("("), 0xfe10, {.d_s = it_arg}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { multi_return_string_string mr_10085 = v__gen__c__deref_kind(str_method_expects_ptr, v__ast__Type_is_ptr(info.parent_type), info.parent_type); string deref = mr_10085.arg0; strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\tstring tmp_ds = "), 0xfe10, {.d_s = parent_str_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("it);"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_S("\tstring res = str_intp(3, _MOV((StrIntpData[]){\n\011\011{_SLIT0, "), 0xfe10, {.d_s = _const_v__gen__c__si_s_code}}, {_S(", {.d_s = indents }},\n\011\011{_S(\""), 0xfe10, {.d_s = clean_type_v_type_name}}, {_S("(\"), "), 0xfe10, {.d_s = _const_v__gen__c__si_s_code}}, {_S(", {.d_s = tmp_ds }},\n\011\011{_S(\")\"), 0, {.d_c = 0 }}\n\011}));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstring_free(&indents);")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstring_free(&tmp_ds);")); strings__Builder_writeln(&g->auto_str_funcs, _S("\treturn res;")); strings__Builder_writeln(&g->auto_str_funcs, _S("}")); // Defer begin if (v__gen__c__Gen_gen_str_for_alias_defer_0) { g->tmp_count = old; } // Defer end } VV_LOC void v__gen__c__Gen_gen_str_for_multi_return(v__gen__c__Gen* g, v__ast__MultiReturn info, string styp, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_multi_return: "), 0xfe10, {.d_s = Array_v__ast__Type_str(info.types)}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" a);"), 0, { .d_c = 0 }}}))); strings__Builder fn_builder = strings__new_builder(512); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" a) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tstrings__Builder sb = strings__new_builder(2 + "), 0xfe07, {.d_i32 = info.types.len}}, {_S(" * 10);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\tstrings__Builder_write_string(&sb, _S(\"(\"));")); for (int i = 0; i < info.types.len; ++i) { v__ast__Type typ = ((v__ast__Type*)info.types.data)[i]; v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); bool is_arg_ptr = v__ast__Type_is_ptr(typ); multi_return_bool_bool_int mr_11379 = v__ast__TypeSymbol_str_method_info(sym); bool sym_has_str_method = mr_11379.arg0; bool str_method_expects_ptr = mr_11379.arg1; string arg_str_fn_name = v__gen__c__Gen_get_str_fn(g, typ); if (v__gen__c__should_use_indent_func(sym->kind) && !sym_has_str_method) { strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = arg_str_fn_name}}, {_S("(a.arg"), 0xfe07, {.d_i32 = i}}, {_S("));"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__f32 || sym->kind == v__ast__Kind__f64) { if (sym->kind == v__ast__Kind__f32) { string tmp_val = str_intp_g32(str_intp(2, _MOV((StrIntpData[]){{_S("a.arg"), 0xfe07, {.d_i32 = i}}, {_SLIT0, 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = tmp_val}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { string tmp_val = str_intp_g64(str_intp(2, _MOV((StrIntpData[]){{_S("a.arg"), 0xfe07, {.d_i32 = i}}, {_SLIT0, 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = tmp_val}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else if (sym->kind == v__ast__Kind__string) { string tmp_str = str_intp_sq(str_intp(2, _MOV((StrIntpData[]){{_S("a.arg"), 0xfe07, {.d_i32 = i}}, {_SLIT0, 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = tmp_str}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__function) { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = arg_str_fn_name}}, {_S("());"), 0, { .d_c = 0 }}}))); } else { multi_return_string_string mr_12218 = v__gen__c__deref_kind(str_method_expects_ptr, is_arg_ptr, typ); string deref = mr_12218.arg0; string deref_label = mr_12218.arg1; strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, _S(\""), 0xfe10, {.d_s = deref_label}}, {_S("\"));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_S("\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = arg_str_fn_name}}, {_S("( "), 0xfe10, {.d_s = deref}}, {_S(" a.arg"), 0xfe07, {.d_i32 = i}}, {_S("));"), 0, { .d_c = 0 }}}))); } if (i != (int)(info.types.len - 1)) { strings__Builder_writeln(&fn_builder, _S("\tstrings__Builder_write_string(&sb, _S(\", \"));")); } } strings__Builder_writeln(&fn_builder, _S("\tstrings__Builder_write_string(&sb, _S(\")\"));")); strings__Builder_writeln(&fn_builder, _S("\tstring res = strings__Builder_str(&sb);")); strings__Builder_writeln(&fn_builder, _S("\tstrings__Builder_free(&sb);")); strings__Builder_writeln(&fn_builder, _S("\treturn res;")); strings__Builder_writeln(&fn_builder, _S("}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } VV_LOC void v__gen__c__Gen_gen_str_for_enum(v__gen__c__Gen* g, v__ast__Enum info, string styp, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_enum: "), 0xfe10, {.d_s = v__ast__Enum_str(info)}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif string s = v__util__no_dots(styp); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" it) { /* gen_str_for_enum */"), 0, { .d_c = 0 }}}))); if (info.is_flag) { string clean_name = v__util__strip_main_name(string_replace(styp, _S("__"), _S("."))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\tstring ret = _S(\""), 0xfe10, {.d_s = clean_name}}, {_S("{\");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\tint first = 1;")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tu64 zit = (u64)it;")); for (int i = 0; i < info.vals.len; ++i) { string val = ((string*)info.vals.data)[i]; u64 mask = (((u64)(1U)) << i); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\tif (zit & 0x"), 0xf020fe28, {.d_u64 = mask}}, {_S("U) {if (!first) {ret = string__plus(ret, _S(\" | \"));} ret = string__plus(ret, _S(\"."), 0xfe10, {.d_s = val}}, {_S("\")); first = 0;}"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->auto_str_funcs, _S("\tret = string__plus(ret, _S(\"}\"));")); strings__Builder_writeln(&g->auto_str_funcs, _S("\treturn ret;")); } else { strings__Builder_writeln(&g->auto_str_funcs, _S("\tswitch(it) {")); Array_string seen = __new_array_with_default(info.vals.len, 0, sizeof(string), &(string[]){_S("")}); for (int _t2 = 0; _t2 < info.vals.len; ++_t2) { string val = ((string*)info.vals.data)[_t2]; if (info.is_multi_allowed && (Array_string_contains(seen, val))) { continue; } else if (info.is_multi_allowed) { array_push((array*)&seen, _MOV((string[]){ string_clone(val) })); } strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tcase "), 0xfe10, {.d_s = s}}, {_S("__"), 0xfe10, {.d_s = val}}, {_S(": return _S(\""), 0xfe10, {.d_s = val}}, {_S("\");"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tdefault: return _S(\"unknown enum value\");")); strings__Builder_writeln(&g->auto_str_funcs, _S("\t}")); } strings__Builder_writeln(&g->auto_str_funcs, _S("}")); } VV_LOC void v__gen__c__Gen_gen_str_for_interface(v__gen__c__Gen* g, v__ast__Interface info, string styp, string typ_str, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_interface: "), 0xfe10, {.d_s = Array_v__ast__Type_str(info.types)}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x) { return indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("(x, 0); }"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x, int indent_count);"), 0, { .d_c = 0 }}}))); strings__Builder fn_builder = strings__new_builder(512); string clean_interface_v_type_name = v__util__strip_main_name(typ_str); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x, int indent_count) { /* gen_str_for_interface */"), 0, { .d_c = 0 }}}))); for (int _t2 = 0; _t2 < info.types.len; ++_t2) { v__ast__Type typ = ((v__ast__Type*)info.types.data)[_t2]; v__ast__TypeSymbol* sub_sym = v__ast__Table_sym(g->table, v__ast__mktyp(typ)); if (g->pref->skip_unused && !_IN_MAP(ADDR(int, sub_sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } string func_name = v__gen__c__Gen_get_str_fn(g, typ); multi_return_bool_bool_int mr_15553 = v__ast__TypeSymbol_str_method_info(sub_sym); bool sym_has_str_method = mr_15553.arg0; bool str_method_expects_ptr = mr_15553.arg1; if (v__gen__c__should_use_indent_func(sub_sym->kind) && !sym_has_str_method) { func_name = str_intp(2, _MOV((StrIntpData[]){{_S("indent_"), 0xfe10, {.d_s = func_name}}, {_SLIT0, 0, { .d_c = 0 }}})); } string deref = (sym_has_str_method && str_method_expects_ptr ? (_S(" ")) : (_S("*"))); if (typ == _const_v__ast__string_type) { string val = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = func_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("("), 0xfe10, {.d_s = sub_sym->cname}}, {_S("*)x._"), 0xfe10, {.d_s = sub_sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}})); if (v__gen__c__should_use_indent_func(sub_sym->kind) && !sym_has_str_method) { val = string__plus(val, _S(", indent_count")); } val = string__plus(val, _S(")")); string res = str_intp(4, _MOV((StrIntpData[]){{_S("str_intp(2, _MOV((StrIntpData[]){\n\011\011\011\011{_S(\""), 0xfe10, {.d_s = clean_interface_v_type_name}}, {_S("(\'\"), "), 0xfe10, {.d_s = _const_v__gen__c__si_s_code}}, {_S(", {.d_s = "), 0xfe10, {.d_s = val}}, {_S("}},\n\011\011\011\011{_S(\"\')\"), 0, {.d_c = 0 }}\n\011\011\011}))"), 0, { .d_c = 0 }}})); strings__Builder_write_string2(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\tif (x._typ == _"), 0xfe10, {.d_s = styp}}, {_S("_"), 0xfe10, {.d_s = sub_sym->cname}}, {_S("_index)"), 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S(" return "), 0xfe10, {.d_s = res}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { if (!(sub_sym->kind == v__ast__Kind__array && string__eq(v__ast__Table_sym(g->table, v__ast__Table_value_type(g->table, typ))->cname, styp))) { string val = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = func_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("("), 0xfe10, {.d_s = sub_sym->cname}}, {_S("*)x._"), 0xfe10, {.d_s = sub_sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}})); if (v__gen__c__should_use_indent_func(sub_sym->kind) && !sym_has_str_method) { val = string__plus(val, _S(", indent_count")); } val = string__plus(val, _S(")")); string res = str_intp(4, _MOV((StrIntpData[]){{_S("str_intp(2, _MOV((StrIntpData[]){\n\011\011\011\011\011{_S(\""), 0xfe10, {.d_s = clean_interface_v_type_name}}, {_S("(\"), "), 0xfe10, {.d_s = _const_v__gen__c__si_s_code}}, {_S(", {.d_s = "), 0xfe10, {.d_s = val}}, {_S("}},\n\011\011\011\011\011{_S(\")\"), 0, {.d_c = 0 }}\n\011\011\011\011}))"), 0, { .d_c = 0 }}})); strings__Builder_write_string2(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\tif (x._typ == _"), 0xfe10, {.d_s = styp}}, {_S("_"), 0xfe10, {.d_s = sub_sym->cname}}, {_S("_index)"), 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S(" return "), 0xfe10, {.d_s = res}}, {_S(";\n"), 0, { .d_c = 0 }}}))); } else { strings__Builder_write_string2(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\tif (x._typ == _"), 0xfe10, {.d_s = styp}}, {_S("_"), 0xfe10, {.d_s = sub_sym->cname}}, {_S("_index)"), 0, { .d_c = 0 }}})), _S(" return _S(\"\");\n")); } } } strings__Builder_writeln(&fn_builder, _S("\treturn _S(\"unknown interface value\");")); strings__Builder_writeln(&fn_builder, _S("}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } VV_LOC void v__gen__c__Gen_gen_str_for_union_sum_type(v__gen__c__Gen* g, v__ast__SumType info, string styp, string typ_str, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_union_sum_type: "), 0xfe10, {.d_s = Array_v__ast__Type_str(info.variants)}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x) { return indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("(x, 0); }"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x, int indent_count);"), 0, { .d_c = 0 }}}))); strings__Builder fn_builder = strings__new_builder(512); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x, int indent_count) {"), 0, { .d_c = 0 }}}))); string clean_sum_type_v_type_name = _S(""); if (info.is_anon) { Array_string _t2 = {0}; Array_v__ast__Type _t2_orig = info.variants; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Type it = ((v__ast__Type*) _t2_orig.data)[_t4]; string _t3 = v__util__strip_main_name(v__ast__Table_sym(g->table, it)->name); array_push((array*)&_t2, &_t3); } Array_string variant_names =_t2; clean_sum_type_v_type_name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = Array_string_join(variant_names, _S("|"))}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { clean_sum_type_v_type_name = v__util__strip_main_name(typ_str); } strings__Builder_writeln(&fn_builder, _S("\tswitch(x._typ) {")); Array_int idxs = __new_array_with_default(0, 0, sizeof(int), 0); for (int _t5 = 0; _t5 < info.variants.len; ++_t5) { v__ast__Type typ = ((v__ast__Type*)info.variants.data)[_t5]; if ((Array_int_contains(idxs, typ))) { continue; } array_push((array*)&idxs, _MOV((int[]){ typ })); string typ_name = v__gen__c__Gen_styp(g, typ); string func_name = v__gen__c__Gen_get_str_fn(g, typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); bool is_c_struct = v__ast__TypeSymbol_is_c_struct(sym); multi_return_bool_bool_int mr_18470 = v__ast__TypeSymbol_str_method_info(sym); bool sym_has_str_method = mr_18470.arg0; bool str_method_expects_ptr = mr_18470.arg1; string deref = (is_c_struct || (sym_has_str_method && str_method_expects_ptr) ? (_S(" ")) : (_S("*"))); if (v__gen__c__should_use_indent_func(sym->kind) && !sym_has_str_method) { func_name = str_intp(2, _MOV((StrIntpData[]){{_S("indent_"), 0xfe10, {.d_s = func_name}}, {_SLIT0, 0, { .d_c = 0 }}})); } if (typ == _const_v__ast__string_type) { string val = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = func_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("("), 0xfe10, {.d_s = typ_name}}, {_S("*)x._"), 0xfe10, {.d_s = sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}})); if (v__gen__c__should_use_indent_func(sym->kind) && !sym_has_str_method) { val = string__plus(val, _S(", indent_count")); } val = string__plus(val, _S(")")); string res = str_intp(4, _MOV((StrIntpData[]){{_S("str_intp(2, _MOV((StrIntpData[]){\n\011\011\011\011{_S(\""), 0xfe10, {.d_s = clean_sum_type_v_type_name}}, {_S("(\'\"), "), 0xfe10, {.d_s = _const_v__gen__c__si_s_code}}, {_S(", {.d_s = "), 0xfe10, {.d_s = val}}, {_S("}},\n\011\011\011\011{_S(\"\')\"), 0, {.d_c = 0 }}\n\011\011\011}))"), 0, { .d_c = 0 }}})); { strings__Builder_write_string(&fn_builder, _S("\t\tcase ")); strings__Builder_write_decimal(&fn_builder, ((int)(typ))); strings__Builder_write_string(&fn_builder, _S(": return ")); strings__Builder_write_string(&fn_builder, res); strings__Builder_write_string(&fn_builder, _S(";\n")); } } else { string val = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = func_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("("), 0xfe10, {.d_s = typ_name}}, {_S("*)x._"), 0xfe10, {.d_s = v__gen__c__Gen_get_sumtype_variant_name(g, typ, *sym)}}, {_SLIT0, 0, { .d_c = 0 }}})); if (v__gen__c__should_use_indent_func(sym->kind) && !sym_has_str_method) { val = string__plus(val, _S(", indent_count")); } val = string__plus(val, _S(")")); string res = str_intp(4, _MOV((StrIntpData[]){{_S("str_intp(2, _MOV((StrIntpData[]){\n\011\011\011\011{_S(\""), 0xfe10, {.d_s = clean_sum_type_v_type_name}}, {_S("(\"), "), 0xfe10, {.d_s = _const_v__gen__c__si_s_code}}, {_S(", {.d_s = "), 0xfe10, {.d_s = val}}, {_S("}},\n\011\011\011\011{_S(\")\"), 0, {.d_c = 0 }}\n\011\011\011}))"), 0, { .d_c = 0 }}})); { strings__Builder_write_string(&fn_builder, _S("\t\tcase ")); strings__Builder_write_decimal(&fn_builder, ((int)(typ))); strings__Builder_write_string(&fn_builder, _S(": return ")); strings__Builder_write_string(&fn_builder, res); strings__Builder_write_string(&fn_builder, _S(";\n")); } } } strings__Builder_writeln(&fn_builder, _S("\t\tdefault: return _S(\"unknown sum type value\");")); strings__Builder_writeln(&fn_builder, _S("\t}")); strings__Builder_writeln(&fn_builder, _S("}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } VV_LOC string v__gen__c__Gen_fn_decl_str(v__gen__c__Gen* g, v__ast__FnType info) { string fn_str = _S("fn ("); for (int i = 0; i < info.func.params.len; ++i) { v__ast__Param arg = ((v__ast__Param*)info.func.params.data)[i]; if (arg.is_mut) { fn_str = string__plus(fn_str, _S("mut ")); } if (i > 0) { fn_str = string__plus(fn_str, _S(", ")); } if (v__ast__Type_has_flag(arg.typ, v__ast__TypeFlag__option)) { fn_str = string__plus(fn_str, _S("?")); } fn_str = string__plus(fn_str, v__util__strip_main_name(v__ast__Table_get_type_name(g->table, v__gen__c__Gen_unwrap_generic(g, arg.typ)))); } fn_str = string__plus(fn_str, _S(")")); if (info.func.return_type == _const_v__ast__ovoid_type) { fn_str = string__plus(fn_str, _S(" ?")); } else if (info.func.return_type == _const_v__ast__rvoid_type) { fn_str = string__plus(fn_str, _S(" !")); } else if (info.func.return_type != _const_v__ast__void_type) { string x = v__util__strip_main_name(v__ast__Table_get_type_name(g->table, v__gen__c__Gen_unwrap_generic(g, info.func.return_type))); if (v__ast__Type_has_flag(info.func.return_type, v__ast__TypeFlag__option)) { fn_str = string__plus(fn_str, str_intp(2, _MOV((StrIntpData[]){{_S(" ?"), 0xfe10, {.d_s = x}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else if (v__ast__Type_has_flag(info.func.return_type, v__ast__TypeFlag__result)) { fn_str = string__plus(fn_str, str_intp(2, _MOV((StrIntpData[]){{_S(" !"), 0xfe10, {.d_s = x}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else { fn_str = string__plus(fn_str, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = x}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } return fn_str; } VV_LOC void v__gen__c__Gen_gen_str_for_fn_type(v__gen__c__Gen* g, v__ast__FnType info, string styp, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_fn_type: "), 0xfe10, {.d_s = info.func.name}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif strings__Builder_writeln(&g->definitions, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("();"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("() { return _S(\""), 0xfe10, {.d_s = v__gen__c__Gen_fn_decl_str(g, info)}}, {_S("\");}"), 0, { .d_c = 0 }}}))); } VV_LOC void v__gen__c__Gen_gen_str_for_chan(v__gen__c__Gen* g, v__ast__Chan info, string styp, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_chan: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(info.elem_type))}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif string elem_type_name = v__util__strip_main_name(v__ast__Table_get_type_name(g->table, v__gen__c__Gen_unwrap_generic(g, info.elem_type))); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x) { return sync__Channel_auto_str(x, _S(\""), 0xfe10, {.d_s = elem_type_name}}, {_S("\")); }"), 0, { .d_c = 0 }}}))); } VV_LOC void v__gen__c__Gen_gen_str_for_thread(v__gen__c__Gen* g, v__ast__Thread info, string styp, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_thread: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(info.return_type))}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif string ret_type_name = v__util__strip_main_name(v__ast__Table_get_type_name(g->table, info.return_type)); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" _); // auto}"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" _) { return _S(\"thread("), 0xfe10, {.d_s = ret_type_name}}, {_S(")\");}"), 0, { .d_c = 0 }}}))); } inline VV_LOC string v__gen__c__styp_to_str_fn_name(string styp) { return string__plus(string_replace_each(styp, new_array_from_c_array(6, 6, sizeof(string), _MOV((string[6]){_S("*"), _S(""), _S("."), _S("__"), _S(" "), _S("__")}))), _S("_str")); } VV_LOC multi_return_string_string v__gen__c__deref_kind(bool str_method_expects_ptr, bool is_elem_ptr, v__ast__Type typ) { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { return (multi_return_string_string){.arg0=_S(""), .arg1=_S("")}; } if (str_method_expects_ptr != is_elem_ptr) { if (is_elem_ptr) { return (multi_return_string_string){.arg0=string_repeat(_S("*"), v__ast__Type_nr_muls(typ)), .arg1=string_repeat(_S("&"), v__ast__Type_nr_muls(typ))}; } else { return (multi_return_string_string){.arg0=_S("&"), .arg1=_S("")}; } } return (multi_return_string_string){.arg0=_S(""), .arg1=_S("")}; } VV_LOC void v__gen__c__Gen_gen_str_for_array(v__gen__c__Gen* g, v__ast__Array info, string styp, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_array: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(info.elem_type))}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__ast__Type typ = info.elem_type; v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, info.elem_type); bool is_option = v__ast__Type_has_flag(typ, v__ast__TypeFlag__option); if (!is_option && (sym->info)._typ == 539 /* v.ast.Alias */) { typ = (*sym->info._v__ast__Alias).parent_type; sym = v__ast__Table_sym(g->table, typ); } string field_styp = v__gen__c__Gen_styp(g, typ); bool is_elem_ptr = v__ast__Type_is_ptr(typ); multi_return_bool_bool_int mr_23025 = v__ast__TypeSymbol_str_method_info(sym); bool sym_has_str_method = mr_23025.arg0; bool str_method_expects_ptr = mr_23025.arg1; string elem_str_fn_name = v__gen__c__Gen_get_str_fn(g, typ); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" a);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" a) { return indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("(a, 0);}"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" a, int indent_count);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" a, int indent_count) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstrings__Builder sb = strings__new_builder(2 + a.len * 10);")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstrings__Builder_write_string(&sb, _S(\"[\"));")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tfor (int i = 0; i < a.len; ++i) {")); if (sym->kind == v__ast__Kind__function) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstring x = "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("();"), 0, { .d_c = 0 }}}))); } else { if (!v__ast__Type_has_flag(typ, v__ast__TypeFlag__option) && sym->kind == v__ast__Kind__array_fixed) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = field_styp}}, {_S(" it;"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tmemcpy(*("), 0xfe10, {.d_s = field_styp}}, {_S("*)it, (byte*)array_get(a, i), sizeof("), 0xfe10, {.d_s = field_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = field_styp}}, {_S(" it = *("), 0xfe10, {.d_s = field_styp}}, {_S("*)array_get(a, i);"), 0, { .d_c = 0 }}}))); } if (v__gen__c__should_use_indent_func(sym->kind) && !sym_has_str_method) { if (is_elem_ptr) { multi_return_string_string mr_24290 = v__gen__c__deref_kind(str_method_expects_ptr, is_elem_ptr, typ); string deref = mr_24290.arg0; string deref_label = mr_24290.arg1; strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tstring x = _S(\"nil\");")); if (!v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tif (it != 0) {")); } strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tstrings__Builder_write_string(&sb, _S(\""), 0xfe10, {.d_s = deref_label}}, {_S("\"));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t\tx = "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("it);"), 0, { .d_c = 0 }}}))); if (!v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&g->auto_str_funcs, _S("\t\t}")); } } else { string prefix = (!is_option && v__ast__TypeSymbol_is_c_struct(sym) && str_method_expects_ptr ? (_S("&")) : (_S(""))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tstring x = indent_"), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("("), 0xfe10, {.d_s = prefix}}, {_S("it, indent_count);"), 0, { .d_c = 0 }}}))); } } else if (sym->kind == v__ast__Kind__f32 || sym->kind == v__ast__Kind__f64) { if (sym->kind == v__ast__Kind__f32) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstring x = "), 0xfe10, {.d_s = str_intp_g32(_S("it"))}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstring x = "), 0xfe10, {.d_s = str_intp_g64(_S("it"))}}, {_S(";"), 0, { .d_c = 0 }}}))); } } else if (sym->kind == v__ast__Kind__rune) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tstring x = str_intp(2, _MOV((StrIntpData[]){{_S(\"`\"), "), 0xfe10, {.d_s = _const_v__gen__c__si_s_code}}, {_S(", {.d_s = "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("(it) }}, {_S(\"`\"), 0, {.d_c = 0 }}}));\n"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__string) { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { string func = v__gen__c__Gen_get_str_fn(g, typ); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstring x = "), 0xfe10, {.d_s = func}}, {_S("(it);\n"), 0, { .d_c = 0 }}}))); } else if (is_elem_ptr) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstring x = str_intp(2, _MOV((StrIntpData[]){{_S(\"&\'\"), "), 0xfe10, {.d_s = _const_v__gen__c__si_s_code}}, {_S(", {.d_s = *it }}, {_S(\"\'\"), 0, {.d_c = 0 }}}));\n"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstring x = str_intp(2, _MOV((StrIntpData[]){{_S(\"\'\"), "), 0xfe10, {.d_s = _const_v__gen__c__si_s_code}}, {_S(", {.d_s = it }}, {_S(\"\'\"), 0, {.d_c = 0 }}}));\n"), 0, { .d_c = 0 }}}))); } } else { multi_return_string_string mr_26185 = v__gen__c__deref_kind(str_method_expects_ptr, is_elem_ptr, typ); string deref = mr_26185.arg0; string deref_label = mr_26185.arg1; if (is_elem_ptr) { strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tstring x = _S(\"nil\");")); if (!v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tif (it != 0) {")); } strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tstrings__Builder_write_string(&sb, _S(\""), 0xfe10, {.d_s = deref_label}}, {_S("\"));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t\tx = "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("it);"), 0, { .d_c = 0 }}}))); if (!v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&g->auto_str_funcs, _S("\t\t}")); } } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, _S(\""), 0xfe10, {.d_s = deref_label}}, {_S("\"));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tstring x = "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("it);"), 0, { .d_c = 0 }}}))); } } } strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tstrings__Builder_write_string(&sb, x);")); if (g->is_autofree && typ != _const_v__ast__bool_type) { strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tstring_free(&x);")); } strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tif (i < a.len-1) {")); strings__Builder_writeln(&g->auto_str_funcs, _S("\t\t\tstrings__Builder_write_string(&sb, _S(\", \"));")); strings__Builder_writeln(&g->auto_str_funcs, _S("\t\t}")); strings__Builder_writeln(&g->auto_str_funcs, _S("\t}")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstrings__Builder_write_string(&sb, _S(\"]\"));")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstring res = strings__Builder_str(&sb);")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstrings__Builder_free(&sb);")); strings__Builder_writeln(&g->auto_str_funcs, _S("\treturn res;")); strings__Builder_writeln(&g->auto_str_funcs, _S("}")); } VV_LOC void v__gen__c__Gen_gen_str_for_array_fixed(v__gen__c__Gen* g, v__ast__ArrayFixed info, string styp, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_array_fixed: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(info.elem_type))}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__ast__Type typ = info.elem_type; v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, info.elem_type); if ((sym->info)._typ == 539 /* v.ast.Alias */) { typ = (*sym->info._v__ast__Alias).parent_type; sym = v__ast__Table_sym(g->table, typ); } bool is_elem_ptr = v__ast__Type_is_ptr(typ); multi_return_bool_bool_int mr_28001 = v__ast__TypeSymbol_str_method_info(sym); bool sym_has_str_method = mr_28001.arg0; bool str_method_expects_ptr = mr_28001.arg1; string elem_str_fn_name = v__gen__c__Gen_get_str_fn(g, typ); string def_arg = (info.is_fn_ret ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, typ)}}, {_S(" a["), 0xfe07, {.d_i32 = info.size}}, {_S("]"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" a"), 0, { .d_c = 0 }}})))); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = def_arg}}, {_S(");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = def_arg}}, {_S(") { return indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("(a, 0);}"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = def_arg}}, {_S(", int indent_count);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = def_arg}}, {_S(", int indent_count) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\tstrings__Builder sb = strings__new_builder(2 + "), 0xfe07, {.d_i32 = info.size}}, {_S(" * 10);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstrings__Builder_write_string(&sb, _S(\"[\"));")); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\tfor (int i = 0; i < "), 0xfe07, {.d_i32 = info.size}}, {_S("; ++i) {"), 0, { .d_c = 0 }}}))); if (sym->kind == v__ast__Kind__function) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstring x = "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("();"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tstrings__Builder_write_string(&sb, x);")); } else { multi_return_string_string mr_29035 = v__gen__c__deref_kind(str_method_expects_ptr, is_elem_ptr, typ); string deref = mr_29035.arg0; string deref_label = mr_29035.arg1; if (v__gen__c__should_use_indent_func(sym->kind) && !sym_has_str_method) { if (is_elem_ptr) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, _S(\""), 0xfe10, {.d_s = deref_label}}, {_S("\"));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tif ( 0 == a[i] ) {")); strings__Builder_writeln(&g->auto_str_funcs, _S("\t\t\tstrings__Builder_write_string(&sb, _S(\"0\"));")); strings__Builder_writeln(&g->auto_str_funcs, _S("\t\t}else{")); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("a[i]));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\t\t}")); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("a[i]));"), 0, { .d_c = 0 }}}))); } } else if ((sym->kind == v__ast__Kind__f32 || sym->kind == v__ast__Kind__f64) && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { if (sym->kind == v__ast__Kind__f32) { string field_str = str_intp_g32(_S("a[i]")); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = field_str}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { string field_str = str_intp_g64(_S("a[i]")); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = field_str}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else if (sym->kind == v__ast__Kind__string && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { string field_str = str_intp_sq(_S("a[i]")); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = field_str}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__rune && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { string tmp_str = str_intp_rune(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = elem_str_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("a[i])"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = tmp_str}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("a[i]));"), 0, { .d_c = 0 }}}))); } } strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif (i < "), 0xfe07, {.d_i32 = (int)(info.size - 1)}}, {_S(") {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\t\t\tstrings__Builder_write_string(&sb, _S(\", \"));")); strings__Builder_writeln(&g->auto_str_funcs, _S("\t\t}")); strings__Builder_writeln(&g->auto_str_funcs, _S("\t}")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstrings__Builder_write_string(&sb, _S(\"]\"));")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstring res = strings__Builder_str(&sb);")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstrings__Builder_free(&sb);")); strings__Builder_writeln(&g->auto_str_funcs, _S("\treturn res;")); strings__Builder_writeln(&g->auto_str_funcs, _S("}")); } VV_LOC void v__gen__c__Gen_gen_str_for_map(v__gen__c__Gen* g, v__ast__Map info, string styp, string str_fn_name) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(5, _MOV((StrIntpData[]){{_S("> gen_str_for_map: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(info.key_type))}}, {_S(" -> "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(info.value_type))}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__ast__Type key_typ = info.key_type; v__ast__TypeSymbol* key_sym = v__ast__Table_sym(g->table, key_typ); if ((key_sym->info)._typ == 539 /* v.ast.Alias */) { key_typ = (*key_sym->info._v__ast__Alias).parent_type; key_sym = v__ast__Table_sym(g->table, key_typ); } string key_styp = v__gen__c__Gen_styp(g, key_typ); string key_str_fn_name = v__gen__c__styp_to_str_fn_name(key_styp); if (!v__ast__TypeSymbol_has_method(key_sym, _S("str"))) { v__gen__c__Gen_get_str_fn(g, key_typ); } v__ast__Type val_typ = info.value_type; v__ast__TypeSymbol* val_sym = v__ast__Table_sym(g->table, val_typ); bool is_option = v__ast__Type_has_flag(val_typ, v__ast__TypeFlag__option); if (!is_option && (val_sym->info)._typ == 539 /* v.ast.Alias */) { val_typ = (*val_sym->info._v__ast__Alias).parent_type; val_sym = v__ast__Table_sym(g->table, val_typ); } string val_styp = v__gen__c__Gen_styp(g, val_typ); string elem_str_fn_name = v__gen__c__styp_to_str_fn_name(val_styp); bool receiver_is_ptr = false; _option_v__ast__Fn _t2 = v__ast__TypeSymbol_find_method_with_generic_parent(val_sym, _S("str")); if (_t2.state != 0) { IError err = _t2.err; *(v__ast__Fn*) _t2.data = ((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); } v__ast__Fn fn_str = (*(v__ast__Fn*)_t2.data); if (fast_string_eq(fn_str.name, _S("str"))) { receiver_is_ptr = v__ast__Type_is_ptr(fn_str.receiver_type); if (val_sym->info._typ == 518 /* v.ast.Struct */) { if ((*val_sym->info._v__ast__Struct).generic_types.len > 0) { elem_str_fn_name = v__gen__c__Gen_generic_fn_name(g, (*val_sym->info._v__ast__Struct).concrete_types, elem_str_fn_name); } } else if (val_sym->info._typ == 542 /* v.ast.Interface */) { if ((*val_sym->info._v__ast__Interface).generic_types.len > 0) { elem_str_fn_name = v__gen__c__Gen_generic_fn_name(g, (*val_sym->info._v__ast__Interface).concrete_types, elem_str_fn_name); } } else if (val_sym->info._typ == 544 /* v.ast.SumType */) { if ((*val_sym->info._v__ast__SumType).generic_types.len > 0) { elem_str_fn_name = v__gen__c__Gen_generic_fn_name(g, (*val_sym->info._v__ast__SumType).concrete_types, elem_str_fn_name); } } else { } } else { v__gen__c__Gen_get_str_fn(g, val_typ); } strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" m);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" m) { return indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("(m, 0);}"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" m, int indent_count);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" m, int indent_count) { /* gen_str_for_map */"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstrings__Builder sb = strings__new_builder(2 + m.key_values.len * 10);")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstrings__Builder_write_string(&sb, _S(\"{\"));")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tbool is_first = true;")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tfor (int i = 0; i < m.key_values.len; ++i) {")); strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tif (!DenseArray_has_index(&m.key_values, i)) { continue; }")); strings__Builder_writeln(&g->auto_str_funcs, _S("\t\telse if (!is_first) { strings__Builder_write_string(&sb, _S(\", \")); }")); if (key_sym->kind == v__ast__Kind__string) { strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tstring key = *(string*)DenseArray_key(&m.key_values, i);")); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = key_styp}}, {_S(" key = *("), 0xfe10, {.d_s = key_styp}}, {_S("*)DenseArray_key(&m.key_values, i);"), 0, { .d_c = 0 }}}))); } if (key_sym->kind == v__ast__Kind__string) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = str_intp_sq(_S("key"))}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (key_sym->kind == v__ast__Kind__rune) { string tmp_str = str_intp_rune(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = key_str_fn_name}}, {_S("(key)"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = tmp_str}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = key_str_fn_name}}, {_S("(key));"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tstrings__Builder_write_string(&sb, _S(\": \"));")); multi_return_bool_bool_int mr_34091 = v__ast__TypeSymbol_str_method_info(val_sym); bool str_method_expects_ptr = mr_34091.arg1; multi_return_string_string mr_34136 = v__gen__c__deref_kind(str_method_expects_ptr, v__ast__Type_is_ptr(val_typ), val_typ); string deref_label = mr_34136.arg1; if ((deref_label).len != 0) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tstrings__Builder_write_string(&sb, _S(\""), 0xfe10, {.d_s = deref_label}}, {_S("\"));"), 0, { .d_c = 0 }}}))); } if (val_sym->kind == v__ast__Kind__function) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("());"), 0, { .d_c = 0 }}}))); } else if (val_sym->kind == v__ast__Kind__string) { if (v__ast__Type_has_flag(val_typ, v__ast__TypeFlag__option)) { string func = v__gen__c__Gen_get_str_fn(g, val_typ); strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = func}}, {_S("(*("), 0xfe10, {.d_s = val_styp}}, {_S("*)DenseArray_value(&m.key_values, i)));"), 0, { .d_c = 0 }}}))); } else { string tmp_str = str_intp_sq(str_intp(2, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = val_styp}}, {_S("*)DenseArray_value(&m.key_values, i)"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = tmp_str}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else if (v__gen__c__should_use_indent_func(val_sym->kind) && !fast_string_eq(fn_str.name, _S("str"))) { string ptr_str = (!is_option && v__ast__TypeSymbol_is_c_struct(val_sym) && str_method_expects_ptr ? (_S("")) : (string_repeat(_S("*"), (int)(v__ast__Type_nr_muls(val_typ) + 1)))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, indent_"), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("("), 0xfe10, {.d_s = ptr_str}}, {_S("("), 0xfe10, {.d_s = val_styp}}, {_S("*)DenseArray_value(&m.key_values, i), indent_count));"), 0, { .d_c = 0 }}}))); } else if (val_sym->kind == v__ast__Kind__f32 || val_sym->kind == v__ast__Kind__f64) { string tmp_val = str_intp(2, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = val_styp}}, {_S("*)DenseArray_value(&m.key_values, i)"), 0, { .d_c = 0 }}})); if (v__ast__Type_has_flag(val_typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = v__gen__c__Gen_get_str_fn(g, val_typ)}}, {_S("(*("), 0xfe10, {.d_s = val_styp}}, {_S("*)DenseArray_value(&m.key_values, i)));"), 0, { .d_c = 0 }}}))); } else { if (val_sym->kind == v__ast__Kind__f32) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = str_intp_g32(tmp_val)}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = str_intp_g64(tmp_val)}}, {_S(");"), 0, { .d_c = 0 }}}))); } } } else if (val_sym->kind == v__ast__Kind__rune) { string tmp_str = str_intp_rune(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = elem_str_fn_name}}, {_S("(*("), 0xfe10, {.d_s = val_styp}}, {_S("*)DenseArray_value(&m.key_values, i))"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = tmp_str}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { string ptr_str = string_repeat(_S("*"), v__ast__Type_nr_muls(val_typ)); if (v__ast__Type_has_flag(val_typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = v__gen__c__Gen_get_str_fn(g, val_typ)}}, {_S("(*"), 0xfe10, {.d_s = ptr_str}}, {_S("("), 0xfe10, {.d_s = val_styp}}, {_S("*)DenseArray_value(&m.key_values, i)));"), 0, { .d_c = 0 }}}))); } else if (receiver_is_ptr) { strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("("), 0xfe10, {.d_s = ptr_str}}, {_S("("), 0xfe10, {.d_s = val_styp}}, {_S("*)DenseArray_value(&m.key_values, i)));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->auto_str_funcs, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tstrings__Builder_write_string(&sb, "), 0xfe10, {.d_s = elem_str_fn_name}}, {_S("(*"), 0xfe10, {.d_s = ptr_str}}, {_S("("), 0xfe10, {.d_s = val_styp}}, {_S("*)DenseArray_value(&m.key_values, i)));"), 0, { .d_c = 0 }}}))); } } strings__Builder_writeln(&g->auto_str_funcs, _S("\t\tis_first = false;")); strings__Builder_writeln(&g->auto_str_funcs, _S("\t}")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstrings__Builder_write_string(&sb, _S(\"}\"));")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstring res = strings__Builder_str(&sb);")); strings__Builder_writeln(&g->auto_str_funcs, _S("\tstrings__Builder_free(&sb);")); strings__Builder_writeln(&g->auto_str_funcs, _S("\treturn res;")); strings__Builder_writeln(&g->auto_str_funcs, _S("}")); } VV_LOC StrIntpType v__gen__c__Gen_type_to_fmt(v__gen__c__Gen* g, v__ast__Type typ) { if (typ == 11) { return StrIntpType__si_u8; } if (typ == 18) { return StrIntpType__si_c; } if ((Array_v__ast__Type_contains(_const_v__ast__voidptr_types, typ)) || typ == _const_v__ast__nil_type || (Array_v__ast__Type_contains(_const_v__ast__byteptr_types, typ))) { return StrIntpType__si_p; } if ((Array_v__ast__Type_contains(_const_v__ast__charptr_types, typ))) { return StrIntpType__si_s; } int typ_nr_muls = v__ast__Type_nr_muls(typ); if (typ_nr_muls > 1) { return StrIntpType__si_p; } v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); if (v__ast__Type_is_int_valptr(typ) || v__ast__Type_is_float_valptr(typ)) { return StrIntpType__si_s; } else if (sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__array_fixed || sym->kind == v__ast__Kind__map || sym->kind == v__ast__Kind__bool || sym->kind == v__ast__Kind__enum || sym->kind == v__ast__Kind__interface || sym->kind == v__ast__Kind__sum_type || sym->kind == v__ast__Kind__function || sym->kind == v__ast__Kind__alias || sym->kind == v__ast__Kind__chan || sym->kind == v__ast__Kind__thread) { return StrIntpType__si_s; } else if (sym->kind == v__ast__Kind__string) { return StrIntpType__si_s; } else if (sym->kind == v__ast__Kind__f32 || sym->kind == v__ast__Kind__f64) { if (sym->kind == v__ast__Kind__f32) { return StrIntpType__si_g32; } return StrIntpType__si_g64; } else if (sym->kind == v__ast__Kind__int) { return StrIntpType__si_i32; } else if (sym->kind == v__ast__Kind__u32) { return StrIntpType__si_u32; } else if (sym->kind == v__ast__Kind__u64) { return StrIntpType__si_u64; } else if (sym->kind == v__ast__Kind__i64) { return StrIntpType__si_i64; } else if (sym->kind == v__ast__Kind__usize) { return StrIntpType__si_u64; } else if (sym->kind == v__ast__Kind__isize) { return StrIntpType__si_i64; } return StrIntpType__si_i32; } VV_LOC void v__gen__c__Gen_gen_str_for_struct(v__gen__c__Gen* g, v__ast__Struct info, v__ast__Language lang, string styp, string typ_str, string str_fn_name) { bool v__gen__c__Gen_gen_str_for_struct_defer_0 = false; strings__Builder fn_builder; bool v__gen__c__Gen_gen_str_for_struct_defer_1 = false; int old; bool v__gen__c__Gen_gen_str_for_struct_defer_2 = false; v__util__Surrounder fn_body_surrounder; strings__Builder fn_body; #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("> gen_str_for_struct: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(info.parent_type))}}, {_S(" | "), 0xfe10, {.d_s = styp}}, {_S(" | "), 0xfe10, {.d_s = str_fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif bool is_c_struct = lang == v__ast__Language__c; string arg_def = (is_c_struct ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S("* it"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" it"), 0, { .d_c = 0 }}})))); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = arg_def}}, {_S(");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->auto_str_funcs, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string "), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = arg_def}}, {_S(") { return indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("(it, 0);}"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = arg_def}}, {_S(", int indent_count);"), 0, { .d_c = 0 }}}))); fn_builder = strings__new_builder(512); v__gen__c__Gen_gen_str_for_struct_defer_0 = true; strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("string indent_"), 0xfe10, {.d_s = str_fn_name}}, {_S("("), 0xfe10, {.d_s = arg_def}}, {_S(", int indent_count) {"), 0, { .d_c = 0 }}}))); old = v__gen__c__Gen_reset_tmp_count(g); v__gen__c__Gen_gen_str_for_struct_defer_1 = true; string clean_struct_v_type_name = (info.is_anon ? (_S("struct ")) : (v__util__strip_main_name(typ_str))); if (info.fields.len == 0) { strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn _S(\""), 0xfe10, {.d_s = clean_struct_v_type_name}}, {_S("{}\");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("}")); // Defer begin if (v__gen__c__Gen_gen_str_for_struct_defer_1) { g->tmp_count = old; } // Defer end // Defer begin if (v__gen__c__Gen_gen_str_for_struct_defer_0) { array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } // Defer end return; } strings__Builder_writeln(&fn_builder, _S("\tstring indents = string_repeat(_S(\" \"), indent_count);")); fn_body_surrounder = v__util__new_surrounder(info.fields.len); fn_body = strings__new_builder((int)(info.fields.len * 256)); v__gen__c__Gen_gen_str_for_struct_defer_2 = true; Array_int field_skips = __new_array_with_default(0, 0, sizeof(int), 0); for (int i = 0; i < info.fields.len; ++i) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[i]; _option_v__ast__Attr _t3; if (_t3 = Array_v__ast__Attr_find_first(field.attrs, _S("str")), _t3.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t3.data; if (fast_string_eq(attr.arg, _S("skip"))) { array_push((array*)&field_skips, _MOV((int[]){ i })); } } } if (g->pref->hide_auto_str) { strings__Builder_writeln(&fn_body, _S("\tstring res = { .str =\"str() used with -hide-auto-str\", .len=30 }; return res;")); // Defer begin if (v__gen__c__Gen_gen_str_for_struct_defer_2) { v__util__Surrounder_builder_write_befores(&fn_body_surrounder, (voidptr)&fn_builder); _PUSH_MANY(&fn_builder, (fn_body), _t5, strings__Builder); v__util__Surrounder_builder_write_afters(&fn_body_surrounder, (voidptr)&fn_builder); strings__Builder_writeln(&fn_builder, _S("\tstring_free(&indents);")); strings__Builder_writeln(&fn_builder, _S("\treturn res;")); strings__Builder_writeln(&fn_builder, _S("}")); } // Defer end // Defer begin if (v__gen__c__Gen_gen_str_for_struct_defer_1) { g->tmp_count = old; } // Defer end // Defer begin if (v__gen__c__Gen_gen_str_for_struct_defer_0) { array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } // Defer end return; } strings__Builder_writeln(&fn_body, str_intp(2, _MOV((StrIntpData[]){{_S("\tstring res = str_intp( "), 0xfe07, {.d_i32 = (int)((int)(((int)(info.fields.len - field_skips.len)) * 4) + 3)}}, {_S(", _MOV((StrIntpData[]){"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_body, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t{_S(\""), 0xfe10, {.d_s = clean_struct_v_type_name}}, {_S("{\\n\"), 0, {.d_c=0}},"), 0, { .d_c = 0 }}}))); bool _t7 = false; Array_v__ast__Attr _t7_orig = info.attrs; int _t7_len = _t7_orig.len; for (int _t8 = 0; _t8 < _t7_len; ++_t8) { v__ast__Attr it = ((v__ast__Attr*) _t7_orig.data)[_t8]; if (fast_string_eq(it.name, _S("autostr")) && fast_string_eq(it.arg, _S("allowrecurse"))) { _t7 = true; break; } } bool allow_circular =_t7; bool is_first = true; for (int i = 0; i < info.fields.len; ++i) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[i]; if ((Array_int_contains(field_skips, i))) { continue; } v__ast__Type ftyp_noshared = (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__shared_f) ? (v__ast__Type_clear_flag(v__ast__Type_deref(field.typ), v__ast__TypeFlag__shared_f)) : (field.typ)); string ptr_amp = (v__ast__Type_is_ptr(ftyp_noshared) ? (_S("&")) : (_S(""))); v__ast__Type base_typ = v__gen__c__Gen_unwrap_generic(g, field.typ); if (v__ast__Type_has_flag(base_typ, v__ast__TypeFlag__shared_f)) { base_typ = v__ast__Type_deref(v__ast__Type_clear_flag(base_typ, v__ast__TypeFlag__shared_f)); } StrIntpType base_fmt = v__gen__c__Gen_type_to_fmt(g, base_typ); bool is_opt_field = v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option); string quote_str = _S(""); string prefix = _S(""); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, field.typ)); if (!is_opt_field) { if (sym->kind == v__ast__Kind__string) { quote_str = _S("'"); } else if ((Array_v__ast__Type_contains(_const_v__ast__charptr_types, field.typ))) { quote_str = _S("\\\""); prefix = _S("C"); } } if (is_first) { { strings__Builder_write_string(&fn_body, _S("\t\t{_SLIT0, ")); strings__Builder_write_string(&fn_body, _const_v__gen__c__si_s_code); strings__Builder_write_string(&fn_body, _S(", {.d_s=indents}}, {_S(\" ")); strings__Builder_write_string(&fn_body, field.name); strings__Builder_write_string(&fn_body, _S(": ")); strings__Builder_write_string(&fn_body, ptr_amp); strings__Builder_write_string(&fn_body, prefix); strings__Builder_write_string(&fn_body, _S("\"), 0, {.d_c=0}}, ")); } is_first = false; } else { { strings__Builder_write_string(&fn_body, _S("\t\t{_S(\"\\n\"), ")); strings__Builder_write_string(&fn_body, _const_v__gen__c__si_s_code); strings__Builder_write_string(&fn_body, _S(", {.d_s=indents}}, {_S(\" ")); strings__Builder_write_string(&fn_body, field.name); strings__Builder_write_string(&fn_body, _S(": ")); strings__Builder_write_string(&fn_body, ptr_amp); strings__Builder_write_string(&fn_body, prefix); strings__Builder_write_string(&fn_body, _S("\"), 0, {.d_c=0}}, ")); } } multi_return_bool_bool_int mr_41805 = v__ast__TypeSymbol_str_method_info(sym); bool sym_has_str_method = mr_41805.arg0; bool str_method_expects_ptr = mr_41805.arg1; string sftyp = v__gen__c__Gen_styp(g, ftyp_noshared); string field_styp = string_replace(sftyp, _S("*"), _S("")); string _t9; /* if prepend */ if (sym_has_str_method) { string _t10; /* if prepend */ if (v__ast__Type_has_flag(ftyp_noshared, v__ast__TypeFlag__option)) { _t10 = v__gen__c__Gen_get_str_fn(g, ftyp_noshared); } else { string left_cc_type = v__gen__c__Gen_cc_type(g, ftyp_noshared, false); string left_fn_name = v__util__no_dots(left_cc_type); _t10 = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = left_fn_name}}, {_S("_str"), 0, { .d_c = 0 }}})); } string field_fn_name = _t10; if ((sym->info)._typ == 518 /* v.ast.Struct */) { field_fn_name = v__gen__c__Gen_generic_fn_name(g, (*sym->info._v__ast__Struct).concrete_types, field_fn_name); } _t9 = field_fn_name; } else { _t9 = v__gen__c__Gen_get_str_fn(g, ftyp_noshared); } string field_styp_fn_name = _t9; if (is_opt_field) { { strings__Builder_write_string(&fn_body, _S("{_S(\"")); strings__Builder_write_string(&fn_body, quote_str); strings__Builder_write_string(&fn_body, _S("\"), ")); strings__Builder_write_string(&fn_body, _const_v__gen__c__si_s_code); strings__Builder_write_string(&fn_body, _S(", {.d_s=")); } } else if (!(sym->kind == v__ast__Kind__f32 || sym->kind == v__ast__Kind__f64)) { { strings__Builder_write_string(&fn_body, _S("{_S(\"")); strings__Builder_write_string(&fn_body, quote_str); strings__Builder_write_string(&fn_body, _S("\"), ")); strings__Builder_write_decimal(&fn_body, ((int)(base_fmt))); strings__Builder_write_string(&fn_body, _S(", {.")); strings__Builder_write_string(&fn_body, v__gen__c__data_str(base_fmt)); strings__Builder_write_string(&fn_body, _S("=")); } } else { string g_fmt = string__plus(_S("0x"), u32_hex(((((u32)(base_fmt)) | (((u32)(0x7FU)) << 9U))))); { strings__Builder_write_string(&fn_body, _S("{_S(\"")); strings__Builder_write_string(&fn_body, quote_str); strings__Builder_write_string(&fn_body, _S("\"), ")); strings__Builder_write_string(&fn_body, g_fmt); strings__Builder_write_string(&fn_body, _S(", {.")); strings__Builder_write_string(&fn_body, v__gen__c__data_str(base_fmt)); strings__Builder_write_string(&fn_body, _S("=")); } } string funcprefix = _S(""); multi_return_string_bool mr_42854 = v__gen__c__struct_auto_str_func(sym, lang, field.typ, field_styp_fn_name, field.name, sym_has_str_method, str_method_expects_ptr); string func = mr_42854.arg0; bool caller_should_free = mr_42854.arg1; int ftyp_nr_muls = v__ast__Type_nr_muls(field.typ); string field_name = (lang == v__ast__Language__c ? (field.name) : (v__gen__c__c_name(field.name))); string op = (is_c_struct ? (_S("->")) : (_S("."))); string it_field_name = str_intp(3, _MOV((StrIntpData[]){{_S("it"), 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = field_name}}, {_SLIT0, 0, { .d_c = 0 }}})); if (ftyp_nr_muls > 1 || (Array_v__ast__Type_contains(_const_v__ast__cptr_types, field.typ))) { if (is_opt_field) { } else { func = str_intp(2, _MOV((StrIntpData[]){{_S("(voidptr) "), 0xfe10, {.d_s = it_field_name}}, {_SLIT0, 0, { .d_c = 0 }}})); caller_should_free = false; } } else if (v__ast__Type_is_ptr(ftyp_noshared)) { if (v__ast__Type_has_flag(ftyp_noshared, v__ast__TypeFlag__option)) { funcprefix = string__plus(funcprefix, str_intp(3, _MOV((StrIntpData[]){{_S("isnil(&"), 0xfe10, {.d_s = it_field_name}}, {_S(") || isnil(&"), 0xfe10, {.d_s = it_field_name}}, {_S(".data)"), 0, { .d_c = 0 }}}))); } else { funcprefix = string__plus(funcprefix, str_intp(2, _MOV((StrIntpData[]){{_S("isnil("), 0xfe10, {.d_s = it_field_name}}, {_S(")"), 0, { .d_c = 0 }}}))); } funcprefix = string__plus(funcprefix, _S(" ? _S(\"nil\") : ")); if (!v__ast__Type_has_flag(ftyp_noshared, v__ast__TypeFlag__option) && !(sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__alias || sym->kind == v__ast__Kind__enum || sym->kind == v__ast__Kind__sum_type || sym->kind == v__ast__Kind__map || sym->kind == v__ast__Kind__interface) && !v__ast__Type_is_int_valptr(field.typ) && !v__ast__Type_is_float_valptr(field.typ)) { funcprefix = string__plus(funcprefix, _S("*")); } } bool is_field_array = false; if ((sym->info)._typ == 513 /* v.ast.Array */) { field_styp = string_trim(v__gen__c__Gen_styp(g, (*sym->info._v__ast__Array).elem_type), _S("*")); is_field_array = true; } else if ((sym->info)._typ == 549 /* v.ast.ArrayFixed */) { field_styp = string_trim(v__gen__c__Gen_styp(g, (*sym->info._v__ast__ArrayFixed).elem_type), _S("*")); is_field_array = true; } if (string__eq(styp, field_styp) && !allow_circular) { if (is_field_array) { if (is_opt_field) { string arr_styp = v__gen__c__Gen_base_type(g, field.typ); { strings__Builder_write_string(&fn_body, it_field_name); strings__Builder_write_string(&fn_body, _S(".state != 2 && (*(")); strings__Builder_write_string(&fn_body, arr_styp); strings__Builder_write_string(&fn_body, _S("*)")); strings__Builder_write_string(&fn_body, it_field_name); strings__Builder_write_string(&fn_body, _S(".data).len > 0 ? ")); strings__Builder_write_string(&fn_body, funcprefix); strings__Builder_write_string(&fn_body, _S("_S(\"[]\") : ")); strings__Builder_write_string(&fn_body, funcprefix); strings__Builder_write_string(&fn_body, _S("_S(\"[]\")")); } } else { { strings__Builder_write_string(&fn_body, it_field_name); strings__Builder_write_string(&fn_body, _S(".len > 0 ? ")); strings__Builder_write_string(&fn_body, funcprefix); strings__Builder_write_string(&fn_body, _S("_S(\"[]\") : ")); strings__Builder_write_string(&fn_body, funcprefix); strings__Builder_write_string(&fn_body, _S("_S(\"[]\")")); } } } else { { strings__Builder_write_string(&fn_body, funcprefix); strings__Builder_write_string(&fn_body, _S("_S(\"\")")); } } } else { if ((Array_v__ast__Type_contains(_const_v__ast__charptr_types, field.typ))) { { strings__Builder_write_string(&fn_body, _S("tos4((byteptr)")); strings__Builder_write_string(&fn_body, func); strings__Builder_write_string(&fn_body, _S(")")); } } else { if (v__ast__Type_is_ptr(field.typ) && (sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__interface)) { funcprefix = string__plus(funcprefix, _S("(indent_count > 25)? _S(\"\") : ")); } if (caller_should_free) { string tmpvar = v__gen__c__Gen_new_tmp_var(g); v__util__Surrounder_add(&fn_body_surrounder, str_intp(4, _MOV((StrIntpData[]){{_S("\tstring "), 0xfe10, {.d_s = tmpvar}}, {_S(" = "), 0xfe10, {.d_s = funcprefix}}, {_SLIT0, 0xfe10, {.d_s = func}}, {_S(";"), 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S("\tstring_free(&"), 0xfe10, {.d_s = tmpvar}}, {_S(");"), 0, { .d_c = 0 }}}))); strings__Builder_write_string(&fn_body, tmpvar); } else { strings__Builder_write_string2(&fn_body, funcprefix, func); } } } strings__Builder_writeln(&fn_body, str_intp(2, _MOV((StrIntpData[]){{_S("}}, {_S(\""), 0xfe10, {.d_s = quote_str}}, {_S("\"), 0, {.d_c=0}},"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&fn_body, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t{_S(\"\\n\"), "), 0xfe10, {.d_s = _const_v__gen__c__si_s_code}}, {_S(", {.d_s=indents}}, {_S(\"}\"), 0, {.d_c=0}},"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_body, _S("\t}));")); // Defer begin if (v__gen__c__Gen_gen_str_for_struct_defer_2) { v__util__Surrounder_builder_write_befores(&fn_body_surrounder, (voidptr)&fn_builder); _PUSH_MANY(&fn_builder, (fn_body), _t11, strings__Builder); v__util__Surrounder_builder_write_afters(&fn_body_surrounder, (voidptr)&fn_builder); strings__Builder_writeln(&fn_builder, _S("\tstring_free(&indents);")); strings__Builder_writeln(&fn_builder, _S("\treturn res;")); strings__Builder_writeln(&fn_builder, _S("}")); } // Defer end // Defer begin if (v__gen__c__Gen_gen_str_for_struct_defer_1) { g->tmp_count = old; } // Defer end // Defer begin if (v__gen__c__Gen_gen_str_for_struct_defer_0) { array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } // Defer end } VV_LOC string v__gen__c__c_struct_ptr(v__ast__TypeSymbol* sym, v__ast__Type typ, bool expects_ptr) { if (v__ast__TypeSymbol_is_c_struct(sym)) { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { return _S(""); } if (v__ast__Type_nr_muls(typ) >= 1) { if (expects_ptr) { return string_repeat(_S("*"), (int)(v__ast__Type_nr_muls(typ) - 1)); } else { return string_repeat(_S("*"), v__ast__Type_nr_muls(typ)); } } return (expects_ptr ? (_S("&")) : (_S(""))); } return _S(""); } VV_LOC multi_return_string_bool v__gen__c__struct_auto_str_func(v__ast__TypeSymbol* sym, v__ast__Language lang, v__ast__Type _field_type, string fn_name, string field_name, bool has_custom_str, bool expects_ptr) { #if defined(CUSTOM_DEFINE_trace_autostr) { eprintln(str_intp(6, _MOV((StrIntpData[]){{_S("> struct_auto_str_func: "), 0xfe10, {.d_s = sym->name}}, {_S(" | field_type.debug() | "), 0xfe10, {.d_s = fn_name}}, {_S(" | "), 0xfe10, {.d_s = field_name}}, {_S(" | "), 0xfe10, {.d_s = has_custom_str ? _S("true") : _S("false")}}, {_S(" | "), 0xfe10, {.d_s = expects_ptr ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__ast__Type field_type = (v__ast__Type_has_flag(_field_type, v__ast__TypeFlag__shared_f) ? (v__ast__Type_deref(_field_type)) : (_field_type)); string sufix = (v__ast__Type_has_flag(field_type, v__ast__TypeFlag__shared_f) ? (_S("->val")) : (_S(""))); multi_return_string_string mr_46516 = v__gen__c__deref_kind(expects_ptr, v__ast__Type_is_ptr(field_type), field_type); string deref = mr_46516.arg0; string final_field_name = (lang == v__ast__Language__c ? (field_name) : (v__gen__c__c_name(field_name))); string op = (lang == v__ast__Language__c ? (_S("->")) : (_S("."))); string prefix = (v__ast__TypeSymbol_is_c_struct(sym) ? (v__gen__c__c_struct_ptr(sym, _field_type, expects_ptr)) : (deref)); if (sym->kind == v__ast__Kind__enum) { return (multi_return_string_bool){.arg0=str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("(it"), 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = final_field_name}}, {_S("))"), 0, { .d_c = 0 }}})), .arg1=true}; } else if (v__ast__Type_has_flag(_field_type, v__ast__TypeFlag__option) || v__gen__c__should_use_indent_func(sym->kind)) { string obj = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = prefix}}, {_S("it"), 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = final_field_name}}, {_SLIT0, 0xfe10, {.d_s = sufix}}, {_SLIT0, 0, { .d_c = 0 }}})); if (has_custom_str) { if (sym->kind == v__ast__Kind__interface && v__ast__Interface_defines_method((*(v__ast__Interface*)__as_cast((sym->info)._v__ast__Interface,(sym->info)._typ, 542)), _S("str"))) { string iface_obj = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = prefix}}, {_S("it"), 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = final_field_name}}, {_SLIT0, 0xfe10, {.d_s = sufix}}, {_SLIT0, 0, { .d_c = 0 }}})); string dot = (v__ast__Type_is_ptr(field_type) ? (_S("->")) : (_S("."))); return (multi_return_string_bool){.arg0=str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = string_trim_string_right(fn_name, _S("_str"))}}, {_S("_name_table["), 0xfe10, {.d_s = iface_obj}}, {_SLIT0, 0xfe10, {.d_s = dot}}, {_S("_typ]._method_str("), 0xfe10, {.d_s = iface_obj}}, {_SLIT0, 0xfe10, {.d_s = dot}}, {_S("_object)"), 0, { .d_c = 0 }}})), .arg1=true}; } return (multi_return_string_bool){.arg0=str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = obj}}, {_S(")"), 0, { .d_c = 0 }}})), .arg1=true}; } return (multi_return_string_bool){.arg0=str_intp(3, _MOV((StrIntpData[]){{_S("indent_"), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = obj}}, {_S(", indent_count + 1)"), 0, { .d_c = 0 }}})), .arg1=true}; } else if (sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__array_fixed || sym->kind == v__ast__Kind__map || sym->kind == v__ast__Kind__sum_type) { string obj = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = prefix}}, {_S("it"), 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = final_field_name}}, {_SLIT0, 0xfe10, {.d_s = sufix}}, {_SLIT0, 0, { .d_c = 0 }}})); if (has_custom_str) { return (multi_return_string_bool){.arg0=str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = obj}}, {_S(")"), 0, { .d_c = 0 }}})), .arg1=true}; } return (multi_return_string_bool){.arg0=str_intp(3, _MOV((StrIntpData[]){{_S("indent_"), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = obj}}, {_S(", indent_count + 1)"), 0, { .d_c = 0 }}})), .arg1=true}; } else if (sym->kind == v__ast__Kind__function) { return (multi_return_string_bool){.arg0=str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_name}}, {_S("()"), 0, { .d_c = 0 }}})), .arg1=true}; } else if (sym->kind == v__ast__Kind__chan) { return (multi_return_string_bool){.arg0=str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("it"), 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = final_field_name}}, {_SLIT0, 0xfe10, {.d_s = sufix}}, {_S(")"), 0, { .d_c = 0 }}})), .arg1=true}; } else if (sym->kind == v__ast__Kind__thread) { return (multi_return_string_bool){.arg0=str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("it"), 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = final_field_name}}, {_SLIT0, 0xfe10, {.d_s = sufix}}, {_S(")"), 0, { .d_c = 0 }}})), .arg1=false}; } else { string method_str = _S(""); if (!v__ast__Type_is_ptr(field_type) && v__ast__Type_has_option_or_result(field_type)) { method_str = str_intp(4, _MOV((StrIntpData[]){{_S("(*("), 0xfe10, {.d_s = sym->name}}, {_S("*)it"), 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = final_field_name}}, {_S(".data)"), 0, { .d_c = 0 }}})); } else { method_str = str_intp(4, _MOV((StrIntpData[]){{_S("it"), 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = final_field_name}}, {_SLIT0, 0xfe10, {.d_s = sufix}}, {_SLIT0, 0, { .d_c = 0 }}})); } if (sym->kind == v__ast__Kind__bool) { return (multi_return_string_bool){.arg0=str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = method_str}}, {_S(" ? _S(\"true\") : _S(\"false\")"), 0, { .d_c = 0 }}})), .arg1=false}; } else if ((v__ast__Type_is_int_valptr(field_type) || v__ast__Type_is_float_valptr(field_type)) && !expects_ptr) { if (sym->kind == v__ast__Kind__f32) { return (multi_return_string_bool){.arg0=str_intp(3, _MOV((StrIntpData[]){{_S("str_intp(1, _MOV((StrIntpData[]){\n\011\011\011\011\011{_SLIT0, "), 0xfe10, {.d_s = _const_si_g32_code}}, {_S(", {.d_f32 = *"), 0xfe10, {.d_s = method_str}}, {_S(" }}\n\011\011\011\011}))"), 0, { .d_c = 0 }}})), .arg1=true}; } else if (sym->kind == v__ast__Kind__f64) { return (multi_return_string_bool){.arg0=str_intp(3, _MOV((StrIntpData[]){{_S("str_intp(1, _MOV((StrIntpData[]){\n\011\011\011\011\011{_SLIT0, "), 0xfe10, {.d_s = _const_si_g64_code}}, {_S(", {.d_f64 = *"), 0xfe10, {.d_s = method_str}}, {_S(" }}\n\011\011\011\011}))"), 0, { .d_c = 0 }}})), .arg1=true}; } else if (sym->kind == v__ast__Kind__u64 || sym->kind == v__ast__Kind__usize) { StrIntpType fmt_type = StrIntpType__si_u64; return (multi_return_string_bool){.arg0=str_intp(3, _MOV((StrIntpData[]){{_S("str_intp(1, _MOV((StrIntpData[]){{_SLIT0, "), 0xfe06, {.d_u32 = (((u32)(fmt_type)) | 0xfe00U)}}, {_S(", {.d_u64 = *"), 0xfe10, {.d_s = method_str}}, {_S(" }}}))"), 0, { .d_c = 0 }}})), .arg1=true}; } else if (sym->kind == v__ast__Kind__i64 || sym->kind == v__ast__Kind__isize) { StrIntpType fmt_type = StrIntpType__si_i64; return (multi_return_string_bool){.arg0=str_intp(3, _MOV((StrIntpData[]){{_S("str_intp(1, _MOV((StrIntpData[]){{_SLIT0, "), 0xfe06, {.d_u32 = (((u32)(fmt_type)) | 0xfe00U)}}, {_S(", {.d_i64 = *"), 0xfe10, {.d_s = method_str}}, {_S(" }}}))"), 0, { .d_c = 0 }}})), .arg1=true}; } StrIntpType fmt_type = StrIntpType__si_i32; return (multi_return_string_bool){.arg0=str_intp(3, _MOV((StrIntpData[]){{_S("str_intp(1, _MOV((StrIntpData[]){{_SLIT0, "), 0xfe06, {.d_u32 = (((u32)(fmt_type)) | 0xfe00U)}}, {_S(", {.d_i32 = *"), 0xfe10, {.d_s = method_str}}, {_S(" }}}))"), 0, { .d_c = 0 }}})), .arg1=true}; } return (multi_return_string_bool){.arg0=method_str, .arg1=false}; } return (multi_return_string_bool){0}; } VV_LOC string v__gen__c__data_str(StrIntpType x) { string _t2 = (string){.str=(byteptr)"", .is_lit=1}; switch (x) { case StrIntpType__si_no_str: { _t2 = _S("no_str"); break; } case StrIntpType__si_c: { _t2 = _S("d_c"); break; } case StrIntpType__si_u8: { _t2 = _S("d_u8"); break; } case StrIntpType__si_i8: { _t2 = _S("d_i8"); break; } case StrIntpType__si_u16: { _t2 = _S("d_u16"); break; } case StrIntpType__si_i16: { _t2 = _S("d_i16"); break; } case StrIntpType__si_u32: { _t2 = _S("d_u32"); break; } case StrIntpType__si_i32: { _t2 = _S("d_i32"); break; } case StrIntpType__si_u64: { _t2 = _S("d_u64"); break; } case StrIntpType__si_i64: { _t2 = _S("d_i64"); break; } case StrIntpType__si_f32: { _t2 = _S("d_f32"); break; } case StrIntpType__si_f64: { _t2 = _S("d_f64"); break; } case StrIntpType__si_g32: { _t2 = _S("d_f32"); break; } case StrIntpType__si_g64: { _t2 = _S("d_f64"); break; } case StrIntpType__si_e32: { _t2 = _S("d_f32"); break; } case StrIntpType__si_e64: { _t2 = _S("d_f64"); break; } case StrIntpType__si_s: { _t2 = _S("d_s"); break; } case StrIntpType__si_r: { _t2 = _S("d_r"); break; } case StrIntpType__si_p: { _t2 = _S("d_p"); break; } case StrIntpType__si_vp: { _t2 = _S("d_vp"); break; } } return _t2; } VV_LOC bool v__gen__c__should_use_indent_func(v__ast__Kind kind) { return (kind == v__ast__Kind__struct || kind == v__ast__Kind__alias || kind == v__ast__Kind__array || kind == v__ast__Kind__array_fixed || kind == v__ast__Kind__map || kind == v__ast__Kind__sum_type || kind == v__ast__Kind__interface); } VV_LOC multi_return_string_int v__gen__c__Gen_get_enum_type_idx_from_fn_name(v__gen__c__Gen* g, string fn_name) { string enum_name = string_all_before(fn_name, _S("__static__")); string mod_enum_name = (!string_contains(enum_name, _S(".")) ? (string__plus(string__plus(g->cur_mod.name, _S(".")), enum_name)) : (enum_name)); int idx = (*(int*)map_get(ADDR(map, g->table->type_idxs), &(string[]){mod_enum_name}, &(int[]){ 0 })); if (idx == 0 && (string_contains(enum_name, _S(".")) || u8_is_capital(string_at(enum_name, 0)))) { for (int _t1 = 0; _t1 < g->file->imports.len; ++_t1) { v__ast__Import import_sym = ((v__ast__Import*)g->file->imports.data)[_t1]; mod_enum_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = import_sym.mod}}, {_S("."), 0xfe10, {.d_s = enum_name}}, {_SLIT0, 0, { .d_c = 0 }}})); idx = (*(int*)map_get(ADDR(map, g->table->type_idxs), &(string[]){mod_enum_name}, &(int[]){ 0 })); if (idx > 0) { break; } } } return (multi_return_string_int){.arg0=mod_enum_name, .arg1=idx}; } VV_LOC void v__gen__c__Gen_gen_enum_static_from_string(v__gen__c__Gen* g, string fn_name, string mod_enum_name, int idx) { v__ast__Type enum_typ = v__ast__idx_to_type(idx); string enum_styp = v__gen__c__Gen_styp(g, enum_typ); v__ast__Type option_enum_typ = v__ast__Type_set_flag(enum_typ, v__ast__TypeFlag__option); string option_enum_styp = v__gen__c__Gen_styp(g, option_enum_typ); Array_string enum_field_names = v__ast__Table_get_enum_field_names(g->table, mod_enum_name); Array_i64 enum_field_vals = v__ast__Table_get_enum_field_vals(g->table, mod_enum_name); strings__Builder fn_builder = strings__new_builder(512); strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_SLIT0, 0xfe10, {.d_s = option_enum_styp}}, {_S(" "), 0xfe10, {.d_s = fn_name}}, {_S("(string name);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_SLIT0, 0xfe10, {.d_s = option_enum_styp}}, {_S(" "), 0xfe10, {.d_s = fn_name}}, {_S("(string name) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = option_enum_styp}}, {_S(" t1;"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\tbool exists = false;")); strings__Builder_writeln(&fn_builder, _S("\tint inx = 0;")); strings__Builder_writeln(&fn_builder, _S("\tarray field_names = __new_array_with_default(0, 0, sizeof(string), 0);")); for (int _t1 = 0; _t1 < enum_field_names.len; ++_t1) { string field_name = ((string*)enum_field_names.data)[_t1]; strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tarray_push((array*)&field_names, _MOV((string[]){ _S(\""), 0xfe10, {.d_s = field_name}}, {_S("\") }));"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&fn_builder, _S("\tarray field_vals = __new_array_with_default(0, 0, sizeof(i64), 0);")); for (int _t2 = 0; _t2 < enum_field_vals.len; ++_t2) { i64 field_val = ((i64*)enum_field_vals.data)[_t2]; strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tarray_push((array*)&field_vals, _MOV((i64[]){ "), 0xfe09, {.d_i64 = field_val}}, {_S(" }));"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\tfor (int i = 0; i < "), 0xfe07, {.d_i32 = enum_field_names.len}}, {_S("; ++i) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\t\tif (fast_string_eq(name, (*(string*)array_get(field_names, i)))) {")); strings__Builder_writeln(&fn_builder, _S("\t\t\texists = true;")); strings__Builder_writeln(&fn_builder, _S("\t\t\tinx = i;")); strings__Builder_writeln(&fn_builder, _S("\t\t\tbreak;")); strings__Builder_writeln(&fn_builder, _S("\t\t}")); strings__Builder_writeln(&fn_builder, _S("\t}")); strings__Builder_writeln(&fn_builder, _S("\tif (exists) {")); strings__Builder_writeln(&fn_builder, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t_option_ok(&("), 0xfe10, {.d_s = enum_styp}}, {_S("[]){ (*(i64*)array_get(field_vals, inx)) }, (_option*)&t1, sizeof("), 0xfe10, {.d_s = enum_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\t\treturn t1;")); strings__Builder_writeln(&fn_builder, _S("\t} else {")); strings__Builder_writeln(&fn_builder, str_intp(2, _MOV((StrIntpData[]){{_S("\t\treturn ("), 0xfe10, {.d_s = option_enum_styp}}, {_S("){ .state=2, .err=_const_none__, .data={E_STRUCT} };"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&fn_builder, _S("\t}")); strings__Builder_writeln(&fn_builder, _S("}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&fn_builder) })); } VV_LOC void v__gen__c__Gen_autofree_scope_vars(v__gen__c__Gen* g, int pos, int line_nr, bool free_parent_scopes) { if (!g->is_autofree) { return; } v__gen__c__Gen_autofree_scope_vars_stop(g, pos, line_nr, free_parent_scopes, -1); } VV_LOC void v__gen__c__Gen_autofree_scope_vars_stop(v__gen__c__Gen* g, int pos, int line_nr, bool free_parent_scopes, int stop_pos) { if (!g->is_autofree) { return; } if (g->is_builtin_mod) { return; } if (pos == -1) { return; } v__ast__Scope* scope = v__ast__Scope_innermost(g->file->scope, pos); if (scope->start_pos == 0) { return; } ; v__gen__c__Gen_autofree_scope_vars2(g, scope, scope->start_pos, scope->end_pos, line_nr, free_parent_scopes, stop_pos); } VV_LOC void v__gen__c__Gen_print_autofree_var(v__gen__c__Gen* g, v__ast__Var var, string comment) { if (!g->pref->print_autofree_vars && (g->pref->print_autofree_vars_in_fn).len == 0) { return; } println(str_intp(6, _MOV((StrIntpData[]){{_S("autofree: "), 0xfe10, {.d_s = g->file->path}}, {_S(":"), 0xfe07, {.d_i32 = var.pos.line_nr}}, {_S(": skipping `"), 0xfe10, {.d_s = var.name}}, {_S("` in fn `"), 0xfe10, {.d_s = g->last_fn_c_name}}, {_S("`. "), 0xfe10, {.d_s = comment}}, {_SLIT0, 0, { .d_c = 0 }}}))); } VV_LOC void v__gen__c__Gen_autofree_scope_vars2(v__gen__c__Gen* g, v__ast__Scope* scope, int start_pos, int end_pos, int line_nr, bool free_parent_scopes, int stop_pos) { if (scope == ((void*)0)) { return; } ; Map_string_v__ast__ScopeObject _t1 = scope->objects; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} v__ast__ScopeObject obj = (*(v__ast__ScopeObject*)DenseArray_value(&_t1.key_values, _t2)); if (obj._typ == 422 /* v.ast.Var */) { ; if (string__eq((*obj._v__ast__Var).name, g->returned_var_name)) { v__gen__c__Gen_print_autofree_var(g, (*obj._v__ast__Var), _S("returned from function")); ; continue; } if ((*obj._v__ast__Var).is_or) { ; continue; } if ((*obj._v__ast__Var).is_tmp) { v__gen__c__Gen_print_autofree_var(g, (*obj._v__ast__Var), _S("tmp var (loop?)")); ; continue; } if ((*obj._v__ast__Var).is_inherited) { v__gen__c__Gen_print_autofree_var(g, (*obj._v__ast__Var), _S("inherited")); ; continue; } if ((*obj._v__ast__Var).pos.pos > end_pos || ((*obj._v__ast__Var).pos.pos < start_pos && (*obj._v__ast__Var).pos.line_nr == line_nr) || (end_pos < scope->end_pos && ((*obj._v__ast__Var).expr)._typ == 359 /* v.ast.IfExpr */)) { continue; } if (((*obj._v__ast__Var).expr)._typ == 360 /* v.ast.IfGuardExpr */) { continue; } v__gen__c__Gen_autofree_variable(g, (*obj._v__ast__Var)); } else { } } for (;;) { if (!(g->autofree_scope_stmts.len > 0)) break; v__gen__c__Gen_write(g, (*(string*)array_pop(&g->autofree_scope_stmts))); } if (free_parent_scopes && scope->parent != ((void*)0) && !scope->detached_from_parent && (stop_pos == -1 || scope->parent->start_pos >= stop_pos)) { ; v__gen__c__Gen_autofree_scope_vars2(g, scope->parent, start_pos, end_pos, line_nr, true, stop_pos); } } VV_LOC void v__gen__c__Gen_autofree_variable(v__gen__c__Gen* g, v__ast__Var v) { if (v.typ == 0) { return; } v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v.typ); if (g->is_autofree) { } string free_fn = string__plus(v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(v.typ, 0)), _S("_free")); if (sym->kind == v__ast__Kind__array) { if (v__ast__TypeSymbol_has_method(sym, _S("free"))) { v__gen__c__Gen_autofree_var_call(g, free_fn, v); return; } v__gen__c__Gen_autofree_var_call(g, _S("array_free"), v); return; } if (sym->kind == v__ast__Kind__string) { if (v.expr._typ == 384 /* v.ast.StringLiteral */) { v__gen__c__Gen_print_autofree_var(g, v, _S("string literal")); ; } else { } v__gen__c__Gen_autofree_var_call(g, _S("string_free"), v); return; } bool is_user_ref = v__ast__Type_is_ptr(v.typ) && u8_is_capital(string_at(string_after(sym->name, _S(".")), 0)); if (is_user_ref) { if (g->pref->experimental) { v__gen__c__Gen_autofree_var_call(g, _S("free"), v); } else { v__gen__c__Gen_print_autofree_var(g, v, _S("user reference type, use -experimental to autofree those")); } } if (v__ast__TypeSymbol_has_method(sym, _S("free"))) { v__gen__c__Gen_autofree_var_call(g, free_fn, v); } } VV_LOC void v__gen__c__Gen_autofree_var_call(v__gen__c__Gen* g, string free_fn_name, v__ast__Var v) { if (v.is_arg) { return; } if (v.is_used && v.is_autofree_tmp) { return; } if (g->is_builtin_mod) { return; } if (!g->is_autofree) { return; } if (string_contains(v.name, _S("expr_write_string_1_"))) { return; } strings__Builder af = strings__new_builder(128); if (v__ast__Type_is_ptr(v.typ) && v__ast__Type_idx(v.typ) != 11) { strings__Builder_write_string(&af, _S("\t")); if (v__ast__Type_share(v.typ) == v__ast__ShareType__shared_t) { strings__Builder_write_string(&af, string_replace_each(free_fn_name, new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("__shared__"), _S("")})))); } else { strings__Builder_write_string(&af, free_fn_name); } strings__Builder_write_string(&af, _S("(")); if (v__ast__Type_has_flag(v.typ, v__ast__TypeFlag__option)) { string base_type = v__gen__c__Gen_base_type(g, v.typ); { strings__Builder_write_string(&af, _S("(")); strings__Builder_write_string(&af, base_type); strings__Builder_write_string(&af, _S("*)")); } } if (v__ast__Type_share(v.typ) == v__ast__ShareType__shared_t) { strings__Builder_write_string(&af, _S("&")); } strings__Builder_write_string(&af, strings__repeat('*', (int)(v__ast__Type_nr_muls(v.typ) - 1))); strings__Builder_write_string(&af, v__gen__c__c_name(v.name)); if (v__ast__Type_share(v.typ) == v__ast__ShareType__shared_t) { strings__Builder_write_string(&af, _S("->val")); } if (v__ast__Type_has_flag(v.typ, v__ast__TypeFlag__option)) { strings__Builder_write_string(&af, _S(".data)")); } strings__Builder_writeln(&af, _S("); // autofreed ptr var")); } else { if (v.typ == _const_v__ast__error_type && !v.is_autofree_tmp) { return; } if (v.is_auto_heap) { strings__Builder_writeln(&af, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = free_fn_name}}, {_S("("), 0xfe10, {.d_s = v__gen__c__c_name(v.name)}}, {_S("); // autofreed heap var "), 0xfe10, {.d_s = g->cur_mod.name}}, {_S(" "), 0xfe10, {.d_s = g->is_builtin_mod ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else if (v__ast__Type_has_flag(v.typ, v__ast__TypeFlag__option)) { string base_type = v__gen__c__Gen_base_type(g, v.typ); strings__Builder_writeln(&af, str_intp(2, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = v__gen__c__c_name(v.name)}}, {_S(".state != 2) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&af, str_intp(6, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = free_fn_name}}, {_S("(("), 0xfe10, {.d_s = base_type}}, {_S("*)"), 0xfe10, {.d_s = v__gen__c__c_name(v.name)}}, {_S(".data); // autofreed option var "), 0xfe10, {.d_s = g->cur_mod.name}}, {_S(" "), 0xfe10, {.d_s = g->is_builtin_mod ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); strings__Builder_writeln(&af, _S("\t}")); } else if (v__ast__Type_idx(v.typ) != 11) { strings__Builder_writeln(&af, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = free_fn_name}}, {_S("(&"), 0xfe10, {.d_s = v__gen__c__c_name(v.name)}}, {_S("); // autofreed var "), 0xfe10, {.d_s = g->cur_mod.name}}, {_S(" "), 0xfe10, {.d_s = g->is_builtin_mod ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } array_push((array*)&g->autofree_scope_stmts, _MOV((string[]){ strings__Builder_str(&af) })); } v__gen__c__GenOutput v__gen__c__gen(Array_v__ast__File_ptr files, v__ast__Table* table, v__pref__Preferences* pref_) { string module_built = _S(""); if (pref_->build_mode == v__pref__BuildMode__build_module) { for (int _t1 = 0; _t1 < files.len; ++_t1) { v__ast__File* file = ((v__ast__File**)files.data)[_t1]; if (string_contains(file->path, pref_->path) && string__eq(file->mod.short_name, string_trim_right(string_all_after_last(pref_->path, _const_os__path_separator), _const_os__path_separator))) { module_built = file->mod.name; break; } } } bool timers_should_print = false; #if defined(CUSTOM_DEFINE_time_cgening) { timers_should_print = true; } #endif Map_string_int *reflection_strings = HEAP(Map_string_int, (new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) )); v__gen__c__Gen *global_g = HEAP(v__gen__c__Gen, (((v__gen__c__Gen){ .pref = pref_, .field_data_type = v__ast__Table_find_type(table, _S("FieldData")), .enum_data_type = v__ast__Table_find_type(table, _S("EnumData")), .variant_data_type = v__ast__Table_find_type(table, _S("VariantData")), .module_built = module_built, .timers_should_print = timers_should_print, .out = strings__new_builder(512000), .extern_out = __new_array(0, 0, sizeof(u8)), .cheaders = strings__new_builder(15000), .preincludes = strings__new_builder(100), .postincludes = strings__new_builder(100), .includes = strings__new_builder(100), .typedefs = strings__new_builder(100), .enum_typedefs = strings__new_builder(100), .definitions = strings__new_builder(100), .type_definitions = strings__new_builder(100), .sort_fn_definitions = strings__new_builder(100), .alias_definitions = strings__new_builder(100), .hotcode_definitions = strings__new_builder(100), .channel_definitions = strings__new_builder(100), .thread_definitions = strings__new_builder(100), .comptime_definitions = strings__new_builder(100), .type_default_vars = __new_array(0, 0, sizeof(u8)), .cleanup = __new_array(0, 0, sizeof(u8)), .cleanups = new_map(sizeof(string), sizeof(strings__Builder), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .gowrappers = strings__new_builder(100), .waiter_fn_definitions = __new_array(0, 0, sizeof(u8)), .auto_str_funcs = strings__new_builder(100), .dump_funcs = strings__new_builder(100), .pcs_declarations = strings__new_builder(100), .cov_declarations = strings__new_builder(100), .embedded_data = strings__new_builder(1000), .shared_types = strings__new_builder(100), .shared_functions = strings__new_builder(100), .out_options_forward = strings__new_builder(100), .out_options = strings__new_builder(100), .out_results_forward = strings__new_builder(100), .out_results = strings__new_builder(100), .json_forward_decls = strings__new_builder(100), .sql_buf = strings__new_builder(100), .global_const_defs = new_map(sizeof(string), sizeof(v__gen__c__GlobalConstDef), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .vsafe_arithmetic_ops = new_map(sizeof(string), sizeof(v__gen__c__VSafeArithmeticOp), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .sorted_global_const_names = __new_array(0, 0, sizeof(string)), .file = ((void*)0), .table = table, .styp_cache = new_map(sizeof(v__ast__Type), sizeof(string), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .no_eq_method_types = new_map(sizeof(v__ast__Type), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .unique_file_path_hash = 0, .fn_decl = ((void*)0), .last_fn_c_name = (string){.str=(byteptr)"", .is_lit=1}, .tmp_count = 0, .tmp_count_af = 0, .tmp_count_declarations = 0, .global_tmp_count = 0, .discard_or_result = 0, .is_direct_array_access = 0, .is_assign_lhs = 0, .is_void_expr_stmt = 0, .is_arraymap_set = 0, .is_amp = 0, .is_sql = 0, .is_shared = 0, .is_vlines_enabled = 0, .is_autofree = pref_->autofree, .is_builtin_mod = 0, .is_json_fn = 0, .is_js_call = 0, .is_fn_index_call = 0, .is_cc_msvc = fast_string_eq(pref_->ccompiler, _S("msvc")), .is_option_auto_heap = 0, .vlines_path = (string){.str=(byteptr)"", .is_lit=1}, .options_pos_forward = 0, .options_forward = __new_array(0, 0, sizeof(string)), .options = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .results_forward = __new_array(0, 0, sizeof(string)), .results = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .done_options = (__shared__Array_string*)__dup__shared__Array_string(&(__shared__Array_string){.mtx= {0}, .val=__new_array(0, 0, sizeof(string))}, sizeof(__shared__Array_string)), .done_results = (__shared__Array_string*)__dup__shared__Array_string(&(__shared__Array_string){.mtx= {0}, .val=__new_array(0, 0, sizeof(string))}, sizeof(__shared__Array_string)), .chan_pop_options = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .chan_push_options = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .mtxs = (string){.str=(byteptr)"", .is_lit=1}, .tmp_var_ptr = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .labeled_loops = new_map(sizeof(string), sizeof(v__ast__Stmt*), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .contains_ptr_cache = new_map(sizeof(v__ast__Type), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .inner_loop = &_const_v__ast__empty_stmt, .cur_indexexpr = __new_array(0, 0, sizeof(int)), .shareds = new_map(sizeof(int), sizeof(string), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .coverage_files = new_map(sizeof(u64), sizeof(v__gen__c__CoverageInfo*), &map_hash_int_8, &map_eq_int_8, &map_clone_int_8, &map_free_nop), .inside_smartcast = 0, .inside_ternary = 0, .inside_map_postfix = 0, .inside_map_infix = 0, .inside_assign = 0, .inside_map_index = 0, .inside_array_index = 0, .inside_array_fixed_struct = 0, .inside_opt_or_res = 0, .inside_opt_data = 0, .inside_if_option = 0, .inside_if_result = 0, .inside_match_option = 0, .inside_match_result = 0, .inside_vweb_tmpl = 0, .inside_return = 0, .inside_return_tmpl = 0, .inside_struct_init = 0, .inside_or_block = 0, .inside_call = 0, .inside_curry_call = 0, .inside_dump_fn = 0, .inside_c_extern = 0, .expected_fixed_arr = 0, .inside_for_c_stmt = 0, .inside_cast_in_heap = 0, .inside_cast = 0, .inside_selector = 0, .inside_selector_deref = 0, .inside_memset = 0, .inside_const = 0, .inside_array_item = 0, .inside_const_opt_or_res = 0, .inside_lambda = 0, .inside_cinit = 0, .inside_global_decl = 0, .inside_interface_deref = 0, .last_tmp_call_var = __new_array(0, 0, sizeof(string)), .last_if_option_type = 0, .loop_depth = 0, .ternary_names = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .ternary_level_names = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .arraymap_set_pos = 0, .stmt_path_pos = __new_array(0, 0, sizeof(int)), .skip_stmt_pos = 0, .left_is_opt = 0, .right_is_opt = 0, .assign_ct_type = 0, .indent = -1, .empty_line = 0, .assign_op = 0, .defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)), .defer_ifdef = (string){.str=(byteptr)"", .is_lit=1}, .defer_profile_code = (string){.str=(byteptr)"", .is_lit=1}, .defer_vars = __new_array(0, 0, sizeof(string)), .closure_structs = __new_array(0, 0, sizeof(string)), .str_types = __new_array(0, 0, sizeof(v__gen__c__StrType)), .generated_str_fns = __new_array(0, 0, sizeof(v__gen__c__StrType)), .str_fn_names = (__shared__Array_string*)__dup__shared__Array_string(&(__shared__Array_string){.mtx= {0}, .val=__new_array(0, 0, sizeof(string))}, sizeof(__shared__Array_string)), .threaded_fns = (__shared__Array_string*)__dup__shared__Array_string(&(__shared__Array_string){.mtx= {0}, .val=__new_array(0, 0, sizeof(string))}, sizeof(__shared__Array_string)), .waiter_fns = (__shared__Array_string*)__dup__shared__Array_string(&(__shared__Array_string){.mtx= {0}, .val=__new_array(0, 0, sizeof(string))}, sizeof(__shared__Array_string)), .needed_equality_fns = __new_array(0, 0, sizeof(v__ast__Type)), .generated_eq_fns = __new_array(0, 0, sizeof(v__ast__Type)), .array_sort_fn = (__shared__Array_string*)__dup__shared__Array_string(&(__shared__Array_string){.mtx= {0}, .val=__new_array(0, 0, sizeof(string))}, sizeof(__shared__Array_string)), .array_contains_types = __new_array(0, 0, sizeof(v__ast__Type)), .array_index_types = __new_array(0, 0, sizeof(v__ast__Type)), .auto_fn_definitions = __new_array(0, 0, sizeof(string)), .sumtype_casting_fns = __new_array(0, 0, sizeof(v__gen__c__SumtypeCastingFn)), .anon_fn_definitions = __new_array(0, 0, sizeof(string)), .anon_fns = (__shared__Array_string*)__dup__shared__Array_string(&(__shared__Array_string){.mtx= {0}, .val=__new_array(0, 0, sizeof(string))}, sizeof(__shared__Array_string)), .sumtype_definitions = new_map(sizeof(int), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .trace_fn_definitions = __new_array(0, 0, sizeof(string)), .json_types = __new_array(0, 0, sizeof(v__ast__Type)), .pcs = __new_array(0, 0, sizeof(v__gen__c__ProfileCounterMeta)), .hotcode_fn_names = __new_array(0, 0, sizeof(string)), .hotcode_fpaths = __new_array(0, 0, sizeof(string)), .embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)), .sql_i = 0, .sql_stmt_name = (string){.str=(byteptr)"", .is_lit=1}, .sql_bind_name = (string){.str=(byteptr)"", .is_lit=1}, .sql_idents = __new_array(0, 0, sizeof(string)), .sql_idents_types = __new_array(0, 0, sizeof(v__ast__Type)), .sql_left_type = 0, .sql_table_name = (string){.str=(byteptr)"", .is_lit=1}, .sql_fkey = (string){.str=(byteptr)"", .is_lit=1}, .sql_parent_id = (string){.str=(byteptr)"", .is_lit=1}, .sql_side = 0, .sql_last_stmt_out_len = 0, .strs_to_free0 = __new_array(0, 0, sizeof(string)), .type_resolver = ((v__type_resolver__TypeResolver){.resolver = I_v__type_resolver__DummyResolver_to_Interface_v__type_resolver__IResolverType(((v__type_resolver__DummyResolver*)memdup(&(v__type_resolver__DummyResolver){.file = ((void*)0),}, sizeof(v__type_resolver__DummyResolver)))),.table = ((void*)0),.info = ((v__type_resolver__ResolverInfo){.saved_type_map = new_map(sizeof(string), sizeof(v__ast__Type), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.comptime_loop_id = 0,.inside_comptime_for = 0,.inside_comptime_if = 0,.has_different_types = 0,.comptime_for_variant_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_field_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_field_type = 0,.comptime_for_field_value = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.comptime_for_enum_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_attr_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_method_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_method = ((void*)0),.comptime_for_method_ret_type = 0,.comptime_for_method_param_var = (string){.str=(byteptr)"", .is_lit=1},}),.info_stack = __new_array(0, 0, sizeof(v__type_resolver__ResolverInfo)),.type_map = new_map(sizeof(string), sizeof(v__ast__Type), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}), .comptime = ((void*)0), .prevent_sum_type_unwrapping_once = 0, .aggregate_type_idx = 0, .arg_no_auto_deref = 0, .branch_parent_pos = 0, .returned_var_name = (string){.str=(byteptr)"", .is_lit=1}, .infix_left_var_name = (string){.str=(byteptr)"", .is_lit=1}, .curr_var_name = __new_array(0, 0, sizeof(string)), .called_fn_name = (string){.str=(byteptr)"", .is_lit=1}, .timers = v__util__new_timers(((v__util__TimerParams){.should_print = timers_should_print,.label = _S("global_cgen"),})), .force_main_console = 0, .as_cast_type_names = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .obf_table = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .referenced_fns = (__shared__Map_string_bool*)__dup__shared__Map_string_bool(&(__shared__Map_string_bool){.mtx= {0}, .val=new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string)}, sizeof(__shared__Map_string_bool)), .nr_closures = 0, .expected_cast_type = 0, .expected_arg_mut = 0, .or_expr_return_type = 0, .anon_fn = 0, .tests_inited = 0, .has_main = 0, .cur_mod = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}), .cur_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .cur_fn = ((void*)0), .cur_lock = ((v__ast__LockExpr){.is_rlock = __new_array(0, 0, sizeof(bool)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.lockeds = __new_array(0, 0, sizeof(v__ast__Expr)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_expr = 0,.typ = 0,.scope = ((void*)0),}), .cur_struct_init_typ = 0, .autofree_methods = new_map(sizeof(v__ast__Type), sizeof(string), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .generated_free_methods = new_map(sizeof(v__ast__Type), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .autofree_scope_stmts = __new_array(0, 0, sizeof(string)), .use_segfault_handler = v__pref__Preferences_should_use_segfault_handler(pref_), .test_function_names = __new_array(0, 0, sizeof(string)), .out_fn_start_pos = __new_array(0, 0, sizeof(int)), .static_modifier = (pref_->parallel_cc ? (_S("static ")) : (_S(""))), .static_non_parallel = (!pref_->parallel_cc ? (_S("static ")) : (_S(""))), .has_reflection = (Array_string_contains(table->modules, _S("v.reflection"))), .has_debugger = (Array_string_contains(table->modules, _S("v.debug"))), .reflection_strings = &(*(reflection_strings)), .defer_return_tmp_var = (string){.str=(byteptr)"", .is_lit=1}, .vweb_filter_fn_name = (string){.str=(byteptr)"", .is_lit=1}, .export_funcs = __new_array(0, 0, sizeof(string)), .type_default_impl_level = 0, }))); (*(global_g)).type_resolver = *v__type_resolver__TypeResolver__static__new(table, HEAP(v__type_resolver__IResolverType, I_v__gen__c__Gen_to_Interface_v__type_resolver__IResolverType(&(*(global_g))))); (*(global_g)).comptime = &(*(global_g)).type_resolver.info; if (pref_->is_test) { v__gen__c__Gen_write_tests_definitions(&(*(global_g))); } v__util__timing_start(_S("cgen init")); for (int _t3 = 0; _t3 < (*(global_g)).table->modules.len; ++_t3) { string mod = ((string*)(*(global_g)).table->modules.data)[_t3]; map_set(&(*(global_g)).cleanups, &(string[]){mod}, &(strings__Builder[]) { strings__new_builder(100) }); } v__gen__c__Gen_init(&(*(global_g))); v__util__timing_measure(_S("cgen init")); (*(global_g)).tests_inited = false; (*(global_g)).file = (*(v__ast__File**)array_last(files)); if (!pref_->no_parallel) { v__util__timing_start(_S("cgen parallel processing")); sync__pool__PoolProcessor* pp = sync__pool__new_pool_processor(((sync__pool__PoolProcessorConfig){.maxjobs = 0,.callback = (voidptr)v__gen__c__cgen_process_one_file_cb,})); sync__pool__PoolProcessor_set_shared_context(pp, (voidptr)&(*(global_g))); sync__pool__PoolProcessor_work_on_items_T___ptr__v__ast__File(pp, files); v__util__timing_measure(_S("cgen parallel processing")); v__util__timing_start(_S("cgen unification")); Array_v__gen__c__Gen_ptr _t4 = sync__pool__PoolProcessor_get_results_ref_T_v__gen__c__Gen(pp); for (int _t5 = 0; _t5 < _t4.len; ++_t5) { v__gen__c__Gen* g = ((v__gen__c__Gen**)_t4.data)[_t5]; _PUSH_MANY(&(*(global_g)).embedded_files, (g->embedded_files), _t6, Array_v__ast__EmbeddedFile); _PUSH_MANY(&(*(global_g)).out, (g->out), _t7, strings__Builder); _PUSH_MANY(&(*(global_g)).cheaders, (g->cheaders), _t8, strings__Builder); _PUSH_MANY(&(*(global_g)).preincludes, (g->preincludes), _t9, strings__Builder); _PUSH_MANY(&(*(global_g)).postincludes, (g->postincludes), _t10, strings__Builder); _PUSH_MANY(&(*(global_g)).includes, (g->includes), _t11, strings__Builder); _PUSH_MANY(&(*(global_g)).typedefs, (g->typedefs), _t12, strings__Builder); _PUSH_MANY(&(*(global_g)).type_definitions, (g->type_definitions), _t13, strings__Builder); _PUSH_MANY(&(*(global_g)).sort_fn_definitions, (g->sort_fn_definitions), _t14, strings__Builder); _PUSH_MANY(&(*(global_g)).alias_definitions, (g->alias_definitions), _t15, strings__Builder); _PUSH_MANY(&(*(global_g)).definitions, (g->definitions), _t16, strings__Builder); _PUSH_MANY(&(*(global_g)).gowrappers, (g->gowrappers), _t17, strings__Builder); _PUSH_MANY(&(*(global_g)).waiter_fn_definitions, (g->waiter_fn_definitions), _t18, strings__Builder); _PUSH_MANY(&(*(global_g)).auto_str_funcs, (g->auto_str_funcs), _t19, strings__Builder); _PUSH_MANY(&(*(global_g)).dump_funcs, (g->auto_str_funcs), _t20, strings__Builder); _PUSH_MANY(&(*(global_g)).comptime_definitions, (g->comptime_definitions), _t21, strings__Builder); _PUSH_MANY(&(*(global_g)).pcs_declarations, (g->pcs_declarations), _t22, strings__Builder); _PUSH_MANY(&(*(global_g)).cov_declarations, (g->cov_declarations), _t23, strings__Builder); _PUSH_MANY(&(*(global_g)).hotcode_definitions, (g->hotcode_definitions), _t24, strings__Builder); _PUSH_MANY(&(*(global_g)).embedded_data, (g->embedded_data), _t25, strings__Builder); _PUSH_MANY(&(*(global_g)).shared_types, (g->shared_types), _t26, strings__Builder); _PUSH_MANY(&(*(global_g)).shared_functions, (g->channel_definitions), _t27, strings__Builder); _PUSH_MANY(&(*(global_g)).export_funcs, (g->export_funcs), _t28, Array_string); (*(global_g)).force_main_console = (*(global_g)).force_main_console || g->force_main_console; Map_string_v__gen__c__VSafeArithmeticOp _t29 = g->vsafe_arithmetic_ops; int _t31 = _t29.key_values.len; for (int _t30 = 0; _t30 < _t31; ++_t30 ) { int _t32 = _t29.key_values.len - _t31; _t31 = _t29.key_values.len; if (_t32 < 0) { _t30 = -1; continue; } if (!DenseArray_has_index(&_t29.key_values, _t30)) {continue;} string k = *(string*)DenseArray_key(&_t29.key_values, _t30); k = string_clone(k); v__gen__c__VSafeArithmeticOp v = (*(v__gen__c__VSafeArithmeticOp*)DenseArray_value(&_t29.key_values, _t30)); (*(v__gen__c__VSafeArithmeticOp*)map_get_and_set((map*)&(*(global_g)).vsafe_arithmetic_ops, &(string[]){k}, &(v__gen__c__VSafeArithmeticOp[]){ (v__gen__c__VSafeArithmeticOp){.typ = 0,.op = 0,} })) = v; } Map_string_v__gen__c__GlobalConstDef _t33 = g->global_const_defs; int _t35 = _t33.key_values.len; for (int _t34 = 0; _t34 < _t35; ++_t34 ) { int _t36 = _t33.key_values.len - _t35; _t35 = _t33.key_values.len; if (_t36 < 0) { _t34 = -1; continue; } if (!DenseArray_has_index(&_t33.key_values, _t34)) {continue;} string k = *(string*)DenseArray_key(&_t33.key_values, _t34); k = string_clone(k); v__gen__c__GlobalConstDef v = (*(v__gen__c__GlobalConstDef*)DenseArray_value(&_t33.key_values, _t34)); (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&(*(global_g)).global_const_defs, &(string[]){k}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = v; } Map_int_string _t37 = g->shareds; int _t39 = _t37.key_values.len; for (int _t38 = 0; _t38 < _t39; ++_t38 ) { int _t40 = _t37.key_values.len - _t39; _t39 = _t37.key_values.len; if (_t40 < 0) { _t38 = -1; continue; } if (!DenseArray_has_index(&_t37.key_values, _t38)) {continue;} int k = *(int*)DenseArray_key(&_t37.key_values, _t38); string v = (*(string*)DenseArray_value(&_t37.key_values, _t38)); map_set(&(*(global_g)).shareds, &(int[]){k}, &(string[]) { v }); } Map_string_string _t41 = g->chan_pop_options; int _t43 = _t41.key_values.len; for (int _t42 = 0; _t42 < _t43; ++_t42 ) { int _t44 = _t41.key_values.len - _t43; _t43 = _t41.key_values.len; if (_t44 < 0) { _t42 = -1; continue; } if (!DenseArray_has_index(&_t41.key_values, _t42)) {continue;} string k = *(string*)DenseArray_key(&_t41.key_values, _t42); k = string_clone(k); string v = (*(string*)DenseArray_value(&_t41.key_values, _t42)); map_set(&(*(global_g)).chan_pop_options, &(string[]){k}, &(string[]) { v }); } Map_string_string _t45 = g->chan_push_options; int _t47 = _t45.key_values.len; for (int _t46 = 0; _t46 < _t47; ++_t46 ) { int _t48 = _t45.key_values.len - _t47; _t47 = _t45.key_values.len; if (_t48 < 0) { _t46 = -1; continue; } if (!DenseArray_has_index(&_t45.key_values, _t46)) {continue;} string k = *(string*)DenseArray_key(&_t45.key_values, _t46); k = string_clone(k); string v = (*(string*)DenseArray_value(&_t45.key_values, _t46)); map_set(&(*(global_g)).chan_push_options, &(string[]){k}, &(string[]) { v }); } Map_string_string _t49 = g->options; int _t51 = _t49.key_values.len; for (int _t50 = 0; _t50 < _t51; ++_t50 ) { int _t52 = _t49.key_values.len - _t51; _t51 = _t49.key_values.len; if (_t52 < 0) { _t50 = -1; continue; } if (!DenseArray_has_index(&_t49.key_values, _t50)) {continue;} string k = *(string*)DenseArray_key(&_t49.key_values, _t50); k = string_clone(k); string v = (*(string*)DenseArray_value(&_t49.key_values, _t50)); map_set(&(*(global_g)).options, &(string[]){k}, &(string[]) { v }); } Map_string_string _t53 = g->results; int _t55 = _t53.key_values.len; for (int _t54 = 0; _t54 < _t55; ++_t54 ) { int _t56 = _t53.key_values.len - _t55; _t55 = _t53.key_values.len; if (_t56 < 0) { _t54 = -1; continue; } if (!DenseArray_has_index(&_t53.key_values, _t54)) {continue;} string k = *(string*)DenseArray_key(&_t53.key_values, _t54); k = string_clone(k); string v = (*(string*)DenseArray_value(&_t53.key_values, _t54)); map_set(&(*(global_g)).results, &(string[]){k}, &(string[]) { v }); } Map_string_string _t57 = g->as_cast_type_names; int _t59 = _t57.key_values.len; for (int _t58 = 0; _t58 < _t59; ++_t58 ) { int _t60 = _t57.key_values.len - _t59; _t59 = _t57.key_values.len; if (_t60 < 0) { _t58 = -1; continue; } if (!DenseArray_has_index(&_t57.key_values, _t58)) {continue;} string k = *(string*)DenseArray_key(&_t57.key_values, _t58); k = string_clone(k); string v = (*(string*)DenseArray_value(&_t57.key_values, _t58)); map_set(&(*(global_g)).as_cast_type_names, &(string[]){k}, &(string[]) { v }); } Map_int_bool _t61 = g->sumtype_definitions; int _t63 = _t61.key_values.len; for (int _t62 = 0; _t62 < _t63; ++_t62 ) { int _t64 = _t61.key_values.len - _t63; _t63 = _t61.key_values.len; if (_t64 < 0) { _t62 = -1; continue; } if (!DenseArray_has_index(&_t61.key_values, _t62)) {continue;} int k = *(int*)DenseArray_key(&_t61.key_values, _t62); bool v = (*(bool*)DenseArray_value(&_t61.key_values, _t62)); map_set(&(*(global_g)).sumtype_definitions, &(int[]){k}, &(bool[]) { v }); } Map_u64_v__gen__c__CoverageInfo_ptr _t65 = g->coverage_files; int _t67 = _t65.key_values.len; for (int _t66 = 0; _t66 < _t67; ++_t66 ) { int _t68 = _t65.key_values.len - _t67; _t67 = _t65.key_values.len; if (_t68 < 0) { _t66 = -1; continue; } if (!DenseArray_has_index(&_t65.key_values, _t66)) {continue;} u64 k = *(u64*)DenseArray_key(&_t65.key_values, _t66); v__gen__c__CoverageInfo* v = (*(v__gen__c__CoverageInfo**)DenseArray_value(&_t65.key_values, _t66)); (*(v__gen__c__CoverageInfo**)map_get_and_set((map*)&(*(global_g)).coverage_files, &(u64[]){k}, &(v__gen__c__CoverageInfo*[]){ 0 })) = v; } _PUSH_MANY(&(*(global_g)).json_forward_decls, (g->json_forward_decls), _t69, strings__Builder); _PUSH_MANY(&(*(global_g)).enum_typedefs, (g->enum_typedefs), _t70, strings__Builder); _PUSH_MANY(&(*(global_g)).channel_definitions, (g->channel_definitions), _t71, strings__Builder); _PUSH_MANY(&(*(global_g)).thread_definitions, (g->thread_definitions), _t72, strings__Builder); _PUSH_MANY(&(*(global_g)).sql_buf, (g->sql_buf), _t73, strings__Builder); _PUSH_MANY(&(*(strings__Builder*)map_get_and_set((map*)&(*(global_g)).cleanups, &(string[]){g->file->mod.name}, &(strings__Builder[]){ __new_array(0, 0, sizeof(u8)) })), (g->cleanup), _t74, strings__Builder); for (int _t75 = 0; _t75 < g->str_types.len; ++_t75) { v__gen__c__StrType str_type = ((v__gen__c__StrType*)g->str_types.data)[_t75]; array_push((array*)&(*(global_g)).str_types, _MOV((v__gen__c__StrType[]){ str_type })); } for (int _t77 = 0; _t77 < g->sumtype_casting_fns.len; ++_t77) { v__gen__c__SumtypeCastingFn scf = ((v__gen__c__SumtypeCastingFn*)g->sumtype_casting_fns.data)[_t77]; if (!(Array_v__gen__c__SumtypeCastingFn_contains((*(global_g)).sumtype_casting_fns, scf))) { array_push((array*)&(*(global_g)).sumtype_casting_fns, _MOV((v__gen__c__SumtypeCastingFn[]){ scf })); } } (*(global_g)).nr_closures += g->nr_closures; (*(global_g)).has_main = (*(global_g)).has_main || g->has_main; _PUSH_MANY(&(*(global_g)).auto_fn_definitions, (g->auto_fn_definitions), _t79, Array_string); _PUSH_MANY(&(*(global_g)).anon_fn_definitions, (g->anon_fn_definitions), _t80, Array_string); _PUSH_MANY(&(*(global_g)).needed_equality_fns, (g->needed_equality_fns), _t81, Array_v__ast__Type); _PUSH_MANY(&(*(global_g)).array_contains_types, (g->array_contains_types), _t82, Array_v__ast__Type); _PUSH_MANY(&(*(global_g)).array_index_types, (g->array_index_types), _t83, Array_v__ast__Type); _PUSH_MANY(&(*(global_g)).pcs, (g->pcs), _t84, Array_v__gen__c__ProfileCounterMeta); _PUSH_MANY(&(*(global_g)).json_types, (g->json_types), _t85, Array_v__ast__Type); _PUSH_MANY(&(*(global_g)).hotcode_fn_names, (g->hotcode_fn_names), _t86, Array_string); _PUSH_MANY(&(*(global_g)).hotcode_fpaths, (g->hotcode_fpaths), _t87, Array_string); _PUSH_MANY(&(*(global_g)).test_function_names, (g->test_function_names), _t88, Array_string); Map_v__ast__Type_string _t89 = g->autofree_methods; int _t91 = _t89.key_values.len; for (int _t90 = 0; _t90 < _t91; ++_t90 ) { int _t92 = _t89.key_values.len - _t91; _t91 = _t89.key_values.len; if (_t92 < 0) { _t90 = -1; continue; } if (!DenseArray_has_index(&_t89.key_values, _t90)) {continue;} v__ast__Type k = *(v__ast__Type*)DenseArray_key(&_t89.key_values, _t90); string v = (*(string*)DenseArray_value(&_t89.key_values, _t90)); map_set(&(*(global_g)).autofree_methods, &(v__ast__Type[]){k}, &(string[]) { v }); } Map_v__ast__Type_bool _t93 = g->no_eq_method_types; int _t95 = _t93.key_values.len; for (int _t94 = 0; _t94 < _t95; ++_t94 ) { int _t96 = _t93.key_values.len - _t95; _t95 = _t93.key_values.len; if (_t96 < 0) { _t94 = -1; continue; } if (!DenseArray_has_index(&_t93.key_values, _t94)) {continue;} v__ast__Type k = *(v__ast__Type*)DenseArray_key(&_t93.key_values, _t94); bool v = (*(bool*)DenseArray_value(&_t93.key_values, _t94)); map_set(&(*(global_g)).no_eq_method_types, &(v__ast__Type[]){k}, &(bool[]) { v }); } v__gen__c__Gen_free_builders(g); } } else { v__util__timing_start(_S("cgen serial processing")); for (int _t97 = 0; _t97 < files.len; ++_t97) { v__ast__File* file = ((v__ast__File**)files.data)[_t97]; (*(global_g)).file = file; v__gen__c__Gen_gen_file(&(*(global_g))); strings__Builder_drain_builder(&(*(strings__Builder*)map_get(ADDR(map, (*(global_g)).cleanups), &(string[]){file->mod.name}, &(strings__Builder[]){ __new_array(0, 0, sizeof(u8)) })), (voidptr)&(*(global_g)).cleanup, 100); (*(global_g)).global_tmp_count = 0; (*(global_g)).tmp_count = 0; } v__util__timing_measure(_S("cgen serial processing")); v__util__timing_start(_S("cgen unification")); } v__gen__c__Gen_gen_jsons(&(*(global_g))); v__gen__c__Gen_dump_expr_definitions(&(*(global_g))); for (int i = 0; i < (*(global_g)).str_types.len; i++) { v__gen__c__Gen_final_gen_str(&(*(global_g)), (*(v__gen__c__StrType*)array_get((*(global_g)).str_types, i))); } for (int _t98 = 0; _t98 < (*(global_g)).sumtype_casting_fns.len; ++_t98) { v__gen__c__SumtypeCastingFn sumtype_casting_fn = ((v__gen__c__SumtypeCastingFn*)(*(global_g)).sumtype_casting_fns.data)[_t98]; v__gen__c__Gen_write_sumtype_casting_fn(&(*(global_g)), sumtype_casting_fn); } v__gen__c__Gen_write_shareds(&(*(global_g))); v__gen__c__Gen_write_chan_pop_option_fns(&(*(global_g))); v__gen__c__Gen_write_chan_push_option_fns(&(*(global_g))); v__gen__c__Gen_gen_array_contains_methods(&(*(global_g))); v__gen__c__Gen_gen_array_index_methods(&(*(global_g))); v__gen__c__Gen_gen_equality_fns(&(*(global_g))); v__gen__c__Gen_gen_free_methods(&(*(global_g))); v__gen__c__Gen_register_iface_return_types(&(*(global_g))); v__gen__c__Gen_write_results(&(*(global_g))); v__gen__c__Gen_write_options(&(*(global_g))); v__gen__c__Gen_sort_globals_consts(&(*(global_g))); v__util__timing_measure(_S("cgen unification")); v__gen__c__Gen *g = HEAP(v__gen__c__Gen, ((*(global_g)))); v__util__timing_start(_S("cgen common")); if ((*(g)).pref->build_mode == v__pref__BuildMode__build_module) { bool is_toml = string_contains((*(g)).pref->path, _S("/toml")); for (int idx = 0; idx < (*(g)).table->type_symbols.len; ++idx) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)(*(g)).table->type_symbols.data)[idx]; if (idx == 0 || idx == 31) { continue; } if (is_toml && string_contains(sym->cname, _S("map[string]"))) { continue; } strings__Builder_writeln(&(*(g)).definitions, str_intp(3, _MOV((StrIntpData[]){{_S("int _v_type_idx_"), 0xfe10, {.d_s = sym->cname}}, {_S("(); // 1build module "), 0xfe10, {.d_s = (*(g)).pref->path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } else if ((*(g)).pref->use_cache) { bool is_toml = string_contains((*(g)).pref->path, _S("/toml")); for (int idx = 0; idx < (*(g)).table->type_symbols.len; ++idx) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)(*(g)).table->type_symbols.data)[idx]; if (idx == 0 || idx == 31) { continue; } if (is_toml && string_contains(sym->cname, _S("map[string]"))) { continue; } strings__Builder_writeln(&(*(g)).definitions, str_intp(4, _MOV((StrIntpData[]){{_S("int _v_type_idx_"), 0xfe10, {.d_s = sym->cname}}, {_S("() { return "), 0xfe07, {.d_i32 = idx}}, {_S("; }; //lol "), 0xfe10, {.d_s = (*(g)).pref->path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } v__gen__c__Gen_gen_vlines_reset(&(*(g))); if ((*(g)).pref->build_mode != v__pref__BuildMode__build_module) { v__gen__c__Gen_write_init_function(&(*(g))); } if ((*(g)).pref->is_coverage) { int total_code_points = 0; Map_u64_v__gen__c__CoverageInfo_ptr _t99 = (*(g)).coverage_files; int _t101 = _t99.key_values.len; for (int _t100 = 0; _t100 < _t101; ++_t100 ) { int _t102 = _t99.key_values.len - _t101; _t101 = _t99.key_values.len; if (_t102 < 0) { _t100 = -1; continue; } if (!DenseArray_has_index(&_t99.key_values, _t100)) {continue;} u64 k = *(u64*)DenseArray_key(&_t99.key_values, _t100); v__gen__c__CoverageInfo* cov = (*(v__gen__c__CoverageInfo**)DenseArray_value(&_t99.key_values, _t100)); strings__Builder_writeln(&(*(g)).cheaders, str_intp(3, _MOV((StrIntpData[]){{_S("#define _v_cov_file_offset_"), 0xfe08, {.d_u64 = k}}, {_S(" "), 0xfe07, {.d_i32 = total_code_points}}, {_SLIT0, 0, { .d_c = 0 }}}))); total_code_points += cov->points.len; } strings__Builder_writeln(&(*(g)).cheaders, str_intp(2, _MOV((StrIntpData[]){{_S("long int _v_cov["), 0xfe07, {.d_i32 = total_code_points}}, {_S("] = {0};"), 0, { .d_c = 0 }}}))); } if ((*(g)).out_options_forward.len > 0 || (*(g)).out_results_forward.len > 0) { string tail = strings__Builder_cut_to(&(*(g)).type_definitions, (*(g)).options_pos_forward); if ((*(g)).out_options_forward.len > 0) { strings__Builder_writeln(&(*(g)).type_definitions, _S("// #start V forward option_xxx definitions:")); strings__Builder_writeln(&(*(g)).type_definitions, strings__Builder_str(&(*(g)).out_options_forward)); strings__Builder_writeln(&(*(g)).type_definitions, _S("// #end V forward option_xxx definitions\n")); } if ((*(g)).out_results_forward.len > 0) { strings__Builder_writeln(&(*(g)).type_definitions, _S("// #start V forward result_xxx definitions:")); strings__Builder_writeln(&(*(g)).type_definitions, strings__Builder_str(&(*(g)).out_results_forward)); strings__Builder_writeln(&(*(g)).type_definitions, _S("// #end V forward result_xxx definitions\n")); } strings__Builder_writeln(&(*(g)).type_definitions, tail); } v__gen__c__Gen_finish(&(*(g))); strings__Builder b = strings__new_builder((int)((*(g)).out.len + 600000)); strings__Builder_write_string(&b, v__gen__c__Gen_hashes(&(*(g)))); if ((*(g)).use_segfault_handler || (*(g)).pref->is_prof) { strings__Builder_writeln(&b, _S("\n#define V_USE_SIGNAL_H")); } strings__Builder_write_string2(&b, _S("\n// V comptime_definitions:\n"), strings__Builder_str(&(*(g)).comptime_definitions)); strings__Builder_write_string2(&b, _S("\n// V typedefs:\n"), strings__Builder_str(&(*(g)).typedefs)); strings__Builder_write_string2(&b, _S("\n // V preincludes:\n"), strings__Builder_str(&(*(g)).preincludes)); strings__Builder_write_string2(&b, _S("\n// V cheaders:\n"), strings__Builder_str(&(*(g)).cheaders)); if ((*(g)).pcs_declarations.len > 0) { strings__Builder_writeln(&(*(g)).pcs_declarations, _S("// V profile thread local:")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("#if defined(__cplusplus) && __cplusplus >= 201103L")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("\t#define PROF_THREAD_LOCAL thread_local")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("#elif defined(__GNUC__) && __GNUC__ < 5")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("\t#define PROF_THREAD_LOCAL __thread")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("#elif defined(_MSC_VER)")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("\t#define PROF_THREAD_LOCAL __declspec(thread)")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("\t#define PROF_THREAD_LOCAL _Thread_local")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("#endif")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("#ifndef PROF_THREAD_LOCAL")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("\t#if defined(__GNUC__)")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("\t\t#define PROF_THREAD_LOCAL __thread")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("\t#endif")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("#endif")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("#ifdef PROF_THREAD_LOCAL")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("\tstatic PROF_THREAD_LOCAL double prof_measured_time = 0.0;")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("#else")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("\tdouble prof_measured_time = 0.0; // multithreaded: wrong values for func times without its children")); strings__Builder_writeln(&(*(g)).pcs_declarations, _S("#endif")); strings__Builder_write_string2(&b, _S("\n// V profile counters:\n"), strings__Builder_str(&(*(g)).pcs_declarations)); } strings__Builder_write_string2(&b, _S("\n// V includes:\n"), strings__Builder_str(&(*(g)).includes)); strings__Builder_writeln(&b, _S("\n// V global/const #define ... :")); for (int _t103 = 0; _t103 < (*(g)).sorted_global_const_names.len; ++_t103) { string var_name = ((string*)(*(g)).sorted_global_const_names.data)[_t103]; v__gen__c__GlobalConstDef* _t105 = (v__gen__c__GlobalConstDef*)(map_get_check(ADDR(map, (*(g)).global_const_defs), &(string[]){var_name})); _option_v__gen__c__GlobalConstDef _t104 = {0}; if (_t105) { *((v__gen__c__GlobalConstDef*)&_t104.data) = *((v__gen__c__GlobalConstDef*)_t105); } else { _t104.state = 2; _t104.err = _v_error(_S("map key does not exist")); } if (_t104.state == 0) { v__gen__c__GlobalConstDef var = (*(v__gen__c__GlobalConstDef*)_t104.data); if (string_starts_with(var.def, _S("#define"))) { strings__Builder_writeln(&b, var.def); } } } if ((*(g)).enum_typedefs.len > 0) { strings__Builder_write_string2(&b, _S("\n// Enum definitions:\n"), strings__Builder_str(&(*(g)).enum_typedefs)); } if ((*(g)).thread_definitions.len > 0) { strings__Builder_write_string2(&b, _S("\n// Thread definitions:\n"), strings__Builder_str(&(*(g)).thread_definitions)); } if ((*(g)).type_definitions.len > 0) { strings__Builder_write_string2(&b, _S("\n// V type definitions:\n"), strings__Builder_str(&(*(g)).type_definitions)); } if ((*(g)).alias_definitions.len > 0) { strings__Builder_write_string2(&b, _S("\n// V alias definitions:\n"), strings__Builder_str(&(*(g)).alias_definitions)); } if ((*(g)).shared_types.len > 0) { strings__Builder_write_string2(&b, _S("\n// V shared types:\n"), strings__Builder_str(&(*(g)).shared_types)); } if ((*(g)).out_options.len > 0) { strings__Builder_write_string2(&b, _S("\n// V Option_xxx definitions:\n"), strings__Builder_str(&(*(g)).out_options)); } if ((*(g)).out_results.len > 0) { strings__Builder_write_string2(&b, _S("\n// V result_xxx definitions:\n"), strings__Builder_str(&(*(g)).out_results)); } strings__Builder_write_string2(&b, _S("\n// V definitions:\n"), strings__Builder_str(&(*(g)).definitions)); if (!pref_->parallel_cc) { strings__Builder_writeln(&b, _S("\n// V global/const non-precomputed definitions:")); for (int _t106 = 0; _t106 < (*(g)).sorted_global_const_names.len; ++_t106) { string var_name = ((string*)(*(g)).sorted_global_const_names.data)[_t106]; v__gen__c__GlobalConstDef* _t108 = (v__gen__c__GlobalConstDef*)(map_get_check(ADDR(map, (*(g)).global_const_defs), &(string[]){var_name})); _option_v__gen__c__GlobalConstDef _t107 = {0}; if (_t108) { *((v__gen__c__GlobalConstDef*)&_t107.data) = *((v__gen__c__GlobalConstDef*)_t108); } else { _t107.state = 2; _t107.err = _v_error(_S("map key does not exist")); } if (_t107.state == 0) { v__gen__c__GlobalConstDef var = (*(v__gen__c__GlobalConstDef*)_t107.data); if (!string_starts_with(var.def, _S("#define"))) { strings__Builder_writeln(&b, var.def); } } } } string interface_table = v__gen__c__Gen_interface_table(&(*(g))); if (interface_table.len > 0) { strings__Builder_write_string2(&b, _S("\n// V interface table:\n"), interface_table); } if ((*(g)).sort_fn_definitions.len > 0) { strings__Builder_write_string2(&b, _S("\n// V sort fn definitions:\n"), strings__Builder_str(&(*(g)).sort_fn_definitions)); } if ((*(g)).hotcode_definitions.len > 0) { strings__Builder_write_string2(&b, _S("\n// V hotcode definitions:\n"), strings__Builder_str(&(*(g)).hotcode_definitions)); } if ((*(g)).shared_functions.len > 0) { strings__Builder_writeln(&b, _S("\n// V shared type functions:\n")); strings__Builder_write_string2(&b, strings__Builder_str(&(*(g)).shared_functions), _const_v__gen__c__c_concurrency_helpers); } if ((*(g)).channel_definitions.len > 0) { strings__Builder_write_string2(&b, _S("\n// V channel code:\n"), strings__Builder_str(&(*(g)).channel_definitions)); } if ((*(g)).vsafe_arithmetic_ops.len > 0) { Map_string_v__gen__c__VSafeArithmeticOp _t109 = (*(g)).vsafe_arithmetic_ops; int _t111 = _t109.key_values.len; for (int _t110 = 0; _t110 < _t111; ++_t110 ) { int _t112 = _t109.key_values.len - _t111; _t111 = _t109.key_values.len; if (_t112 < 0) { _t110 = -1; continue; } if (!DenseArray_has_index(&_t109.key_values, _t110)) {continue;} string vsafe_fn_name = *(string*)DenseArray_key(&_t109.key_values, _t110); vsafe_fn_name = string_clone(vsafe_fn_name); v__gen__c__VSafeArithmeticOp val = (*(v__gen__c__VSafeArithmeticOp*)DenseArray_value(&_t109.key_values, _t110)); string styp = v__gen__c__Gen_styp(&(*(g)), val.typ); if (val.op == v__token__Kind__div) { strings__Builder_writeln(&b, str_intp(5, _MOV((StrIntpData[]){{_S("static inline "), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = vsafe_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x, "), 0xfe10, {.d_s = styp}}, {_S(" y) { if (_unlikely_(0 == y)) { return 0; } else { return x / y; } }"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&b, str_intp(5, _MOV((StrIntpData[]){{_S("static inline "), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = vsafe_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" x, "), 0xfe10, {.d_s = styp}}, {_S(" y) { if (_unlikely_(0 == y)) { return x; } else { return x % y; } }"), 0, { .d_c = 0 }}}))); } } } if ((*(g)).pref->is_coverage) { strings__Builder_write_string2(&b, _S("\n// V coverage:\n"), strings__Builder_str(&(*(g)).cov_declarations)); } strings__Builder_writeln(&b, _S("\n// end of V out (header)")); string header = strings__Builder_last_n(&b, b.len); header = string__plus(_S("#ifndef V_HEADER_FILE\n#define V_HEADER_FILE"), header); header = string__plus(header, _S("\n#endif\n")); strings__Builder helpers = strings__new_builder(300000); if ((*(g)).embedded_data.len > 0) { strings__Builder_write_string2(&helpers, _S("\n// V embedded data:\n"), strings__Builder_str(&(*(g)).embedded_data)); } if ((*(g)).pref->parallel_cc) { strings__Builder_writeln(&helpers, _S("\n// V global/const non-precomputed definitions:")); for (int _t113 = 0; _t113 < (*(g)).sorted_global_const_names.len; ++_t113) { string var_name = ((string*)(*(g)).sorted_global_const_names.data)[_t113]; v__gen__c__GlobalConstDef* _t115 = (v__gen__c__GlobalConstDef*)(map_get_check(ADDR(map, (*(g)).global_const_defs), &(string[]){var_name})); _option_v__gen__c__GlobalConstDef _t114 = {0}; if (_t115) { *((v__gen__c__GlobalConstDef*)&_t114.data) = *((v__gen__c__GlobalConstDef*)_t115); } else { _t114.state = 2; _t114.err = _v_error(_S("map key does not exist")); } if (_t114.state == 0) { v__gen__c__GlobalConstDef var = (*(v__gen__c__GlobalConstDef*)_t114.data); if (!string_starts_with(var.def, _S("#define"))) { strings__Builder_writeln(&helpers, var.def); if (string_contains(var.def, _S(" = "))) { strings__Builder_writeln(&(*(g)).extern_out, str_intp(2, _MOV((StrIntpData[]){{_S("extern "), 0xfe10, {.d_s = string_all_before(var.def, _S(" = "))}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&(*(g)).extern_out, str_intp(2, _MOV((StrIntpData[]){{_S("extern "), 0xfe10, {.d_s = var.def}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } } } } if ((*(g)).waiter_fn_definitions.len > 0) { if ((*(g)).pref->parallel_cc) { strings__Builder_write_string2(&(*(g)).extern_out, _S("\n// V gowrappers waiter fns:\n"), Array_u8_bytestr((*(g)).waiter_fn_definitions)); } strings__Builder_write_string2(&helpers, _S("\n// V gowrappers waiter fns:\n"), strings__Builder_str(&(*(g)).waiter_fn_definitions)); } if ((*(g)).auto_str_funcs.len > 0) { strings__Builder_write_string2(&helpers, _S("\n// V auto str functions:\n"), strings__Builder_str(&(*(g)).auto_str_funcs)); } if ((*(g)).auto_fn_definitions.len > 0) { strings__Builder_writeln(&helpers, _S("\n// V auto functions:")); for (int _t116 = 0; _t116 < (*(g)).auto_fn_definitions.len; ++_t116) { string fn_def = ((string*)(*(g)).auto_fn_definitions.data)[_t116]; strings__Builder_writeln(&helpers, fn_def); } } if ((*(g)).json_forward_decls.len > 0) { strings__Builder_write_string2(&helpers, _S("\n// V json forward decls:\n"), Array_u8_bytestr((*(g)).json_forward_decls)); if ((*(g)).pref->parallel_cc) { strings__Builder_write_string2(&(*(g)).extern_out, _S("\n// V json forward decls:\n"), strings__Builder_str(&(*(g)).json_forward_decls)); } } if ((*(g)).gowrappers.len > 0) { strings__Builder_write_string2(&helpers, _S("\n// V gowrappers:\n"), strings__Builder_str(&(*(g)).gowrappers)); } if ((*(g)).dump_funcs.len > 0) { strings__Builder_write_string2(&helpers, _S("\n// V dump functions:\n"), strings__Builder_str(&(*(g)).dump_funcs)); } if ((*(g)).anon_fn_definitions.len > 0) { strings__Builder_writeln(&helpers, _S("\n// V anon functions:")); for (int _t117 = 0; _t117 < (*(g)).anon_fn_definitions.len; ++_t117) { string fn_def = ((string*)(*(g)).anon_fn_definitions.data)[_t117]; strings__Builder_writeln(&helpers, fn_def); } } if ((*(g)).pref->is_shared && (*(g)).pref->os == v__pref__OS__windows && (*(g)).export_funcs.len > 0) { string def_name = _S(""); string dll_name = _S(""); if (string_ends_with((*(g)).pref->out_name, _S(".dll"))) { def_name = string__plus(string_substr((*(g)).pref->out_name, 0, (int)((*(g)).pref->out_name.len - 4)), _S(".def")); dll_name = string_all_after_last((*(g)).pref->out_name, _S("\\")); } else { def_name = string__plus((*(g)).pref->out_name, _S(".def")); dll_name = string__plus(string_all_after_last((*(g)).pref->out_name, _S("\\")), _S(".dll")); } string file_content = string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("LIBRARY "), 0xfe10, {.d_s = dll_name}}, {_S("\n\nEXPORTS\n"), 0, { .d_c = 0 }}})), Array_string_join((*(g)).export_funcs, _S("\n"))); _result_void _t118 = os__write_file(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = def_name}}, {_SLIT0, 0, { .d_c = 0 }}})), file_content); if (_t118.is_error) { IError err = _t118.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; } string shelpers = strings__Builder_str(&helpers); if (!(*(g)).pref->parallel_cc) { strings__Builder_write_string(&b, shelpers); } string out_str = strings__Builder_str(&(*(g)).out); string extern_out_str = strings__Builder_str(&(*(g)).extern_out); strings__Builder_write_string(&b, out_str); strings__Builder_writeln(&b, _S("// THE END.")); string postincludes_str = strings__Builder_str(&(*(g)).postincludes); if ((postincludes_str).len != 0) { strings__Builder_write_string2(&b, _S("\n // V postincludes:\n"), postincludes_str); } v__util__timing_measure(_S("cgen common")); #if defined(CUSTOM_DEFINE_trace_all_generic_fn_keys) { Array_string gkeys = map_keys(&(*(g)).table->fn_generic_types); for (int _t120 = 0; _t120 < gkeys.len; ++_t120) { string gkey = ((string*)gkeys.data)[_t120]; eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">> g.table.fn_generic_types key: "), 0xfe10, {.d_s = gkey}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } #endif Array_int out_fn_start_pos = array_clone_to_depth(&(*(g)).out_fn_start_pos, 0); strings__Builder_free(&helpers); v__gen__c__Gen_free_builders(&(*(g))); return ((v__gen__c__GenOutput){ .header = header, .res_builder = b, .out_str = out_str, .out0_str = shelpers, .extern_str = extern_out_str, .out_fn_start_pos = out_fn_start_pos, }); } VV_LOC v__gen__c__Gen* v__gen__c__cgen_process_one_file_cb(sync__pool__PoolProcessor* p, int idx, int wid) { bool v__gen__c__cgen_process_one_file_cb_defer_0 = false; string timing_label_for_thread; v__ast__File* file = sync__pool__PoolProcessor_get_item_T___ptr__v__ast__File(p, idx); timing_label_for_thread = str_intp(2, _MOV((StrIntpData[]){{_S("C GEN thread "), 0xfe07, {.d_i32 = wid}}, {_SLIT0, 0, { .d_c = 0 }}})); v__util__timing_start(timing_label_for_thread); v__gen__c__cgen_process_one_file_cb_defer_0 = true; v__gen__c__Gen* global_g = ((v__gen__c__Gen*)(sync__pool__PoolProcessor_get_shared_context(p))); v__gen__c__Gen* g = ((v__gen__c__Gen*)memdup(&(v__gen__c__Gen){.pref = global_g->pref, .field_data_type = v__ast__Table_find_type(global_g->table, _S("FieldData")), .enum_data_type = v__ast__Table_find_type(global_g->table, _S("EnumData")), .variant_data_type = v__ast__Table_find_type(global_g->table, _S("VariantData")), .module_built = global_g->module_built, .timers_should_print = 0, .out = strings__new_builder(512000), .extern_out = __new_array(0, 0, sizeof(u8)), .cheaders = strings__new_builder(15000), .preincludes = __new_array(0, 0, sizeof(u8)), .postincludes = __new_array(0, 0, sizeof(u8)), .includes = strings__new_builder(100), .typedefs = strings__new_builder(100), .enum_typedefs = strings__new_builder(100), .definitions = strings__new_builder(100), .type_definitions = strings__new_builder(100), .sort_fn_definitions = strings__new_builder(100), .alias_definitions = strings__new_builder(100), .hotcode_definitions = strings__new_builder(100), .channel_definitions = strings__new_builder(100), .thread_definitions = strings__new_builder(100), .comptime_definitions = strings__new_builder(100), .type_default_vars = __new_array(0, 0, sizeof(u8)), .cleanup = strings__new_builder(100), .cleanups = new_map(sizeof(string), sizeof(strings__Builder), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .gowrappers = strings__new_builder(100), .waiter_fn_definitions = strings__new_builder(100), .auto_str_funcs = strings__new_builder(100), .dump_funcs = __new_array(0, 0, sizeof(u8)), .pcs_declarations = strings__new_builder(100), .cov_declarations = strings__new_builder(100), .embedded_data = strings__new_builder(1000), .shared_types = strings__new_builder(100), .shared_functions = strings__new_builder(100), .out_options_forward = strings__new_builder(100), .out_options = strings__new_builder(100), .out_results_forward = strings__new_builder(100), .out_results = strings__new_builder(100), .json_forward_decls = strings__new_builder(100), .sql_buf = strings__new_builder(100), .global_const_defs = new_map(sizeof(string), sizeof(v__gen__c__GlobalConstDef), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .vsafe_arithmetic_ops = new_map(sizeof(string), sizeof(v__gen__c__VSafeArithmeticOp), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .sorted_global_const_names = __new_array(0, 0, sizeof(string)), .file = file, .table = global_g->table, .styp_cache = new_map(sizeof(v__ast__Type), sizeof(string), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .no_eq_method_types = new_map(sizeof(v__ast__Type), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .unique_file_path_hash = 0, .fn_decl = ((void*)0), .last_fn_c_name = (string){.str=(byteptr)"", .is_lit=1}, .tmp_count = 0, .tmp_count_af = 0, .tmp_count_declarations = 0, .global_tmp_count = 0, .discard_or_result = 0, .is_direct_array_access = 0, .is_assign_lhs = 0, .is_void_expr_stmt = 0, .is_arraymap_set = 0, .is_amp = 0, .is_sql = 0, .is_shared = 0, .is_vlines_enabled = 0, .is_autofree = global_g->pref->autofree, .is_builtin_mod = 0, .is_json_fn = 0, .is_js_call = 0, .is_fn_index_call = 0, .is_cc_msvc = global_g->is_cc_msvc, .is_option_auto_heap = 0, .vlines_path = (string){.str=(byteptr)"", .is_lit=1}, .options_pos_forward = 0, .options_forward = global_g->options_forward, .options = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .results_forward = global_g->results_forward, .results = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .done_options = global_g->done_options, .done_results = global_g->done_results, .chan_pop_options = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .chan_push_options = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .mtxs = (string){.str=(byteptr)"", .is_lit=1}, .tmp_var_ptr = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .labeled_loops = new_map(sizeof(string), sizeof(v__ast__Stmt*), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .contains_ptr_cache = new_map(sizeof(v__ast__Type), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .inner_loop = &_const_v__ast__empty_stmt, .cur_indexexpr = __new_array(0, 0, sizeof(int)), .shareds = new_map(sizeof(int), sizeof(string), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .coverage_files = new_map(sizeof(u64), sizeof(v__gen__c__CoverageInfo*), &map_hash_int_8, &map_eq_int_8, &map_clone_int_8, &map_free_nop), .inside_smartcast = 0, .inside_ternary = 0, .inside_map_postfix = 0, .inside_map_infix = 0, .inside_assign = 0, .inside_map_index = 0, .inside_array_index = 0, .inside_array_fixed_struct = 0, .inside_opt_or_res = 0, .inside_opt_data = 0, .inside_if_option = 0, .inside_if_result = 0, .inside_match_option = 0, .inside_match_result = 0, .inside_vweb_tmpl = 0, .inside_return = 0, .inside_return_tmpl = 0, .inside_struct_init = 0, .inside_or_block = 0, .inside_call = 0, .inside_curry_call = 0, .inside_dump_fn = 0, .inside_c_extern = 0, .expected_fixed_arr = 0, .inside_for_c_stmt = 0, .inside_cast_in_heap = 0, .inside_cast = 0, .inside_selector = 0, .inside_selector_deref = 0, .inside_memset = 0, .inside_const = 0, .inside_array_item = 0, .inside_const_opt_or_res = 0, .inside_lambda = 0, .inside_cinit = 0, .inside_global_decl = 0, .inside_interface_deref = 0, .last_tmp_call_var = __new_array(0, 0, sizeof(string)), .last_if_option_type = 0, .loop_depth = 0, .ternary_names = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .ternary_level_names = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .arraymap_set_pos = 0, .stmt_path_pos = __new_array(0, 0, sizeof(int)), .skip_stmt_pos = 0, .left_is_opt = 0, .right_is_opt = 0, .assign_ct_type = 0, .indent = -1, .empty_line = 0, .assign_op = 0, .defer_stmts = __new_array(0, 0, sizeof(v__ast__DeferStmt)), .defer_ifdef = (string){.str=(byteptr)"", .is_lit=1}, .defer_profile_code = (string){.str=(byteptr)"", .is_lit=1}, .defer_vars = __new_array(0, 0, sizeof(string)), .closure_structs = __new_array(0, 0, sizeof(string)), .str_types = __new_array(0, 0, sizeof(v__gen__c__StrType)), .generated_str_fns = __new_array(0, 0, sizeof(v__gen__c__StrType)), .str_fn_names = global_g->str_fn_names, .threaded_fns = global_g->threaded_fns, .waiter_fns = global_g->waiter_fns, .needed_equality_fns = __new_array(0, 0, sizeof(v__ast__Type)), .generated_eq_fns = __new_array(0, 0, sizeof(v__ast__Type)), .array_sort_fn = global_g->array_sort_fn, .array_contains_types = __new_array(0, 0, sizeof(v__ast__Type)), .array_index_types = __new_array(0, 0, sizeof(v__ast__Type)), .auto_fn_definitions = __new_array(0, 0, sizeof(string)), .sumtype_casting_fns = __new_array(0, 0, sizeof(v__gen__c__SumtypeCastingFn)), .anon_fn_definitions = __new_array(0, 0, sizeof(string)), .anon_fns = global_g->anon_fns, .sumtype_definitions = new_map(sizeof(int), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .trace_fn_definitions = __new_array(0, 0, sizeof(string)), .json_types = __new_array(0, 0, sizeof(v__ast__Type)), .pcs = __new_array(0, 0, sizeof(v__gen__c__ProfileCounterMeta)), .hotcode_fn_names = __new_array(0, 0, sizeof(string)), .hotcode_fpaths = __new_array(0, 0, sizeof(string)), .embedded_files = __new_array(0, 0, sizeof(v__ast__EmbeddedFile)), .sql_i = 0, .sql_stmt_name = (string){.str=(byteptr)"", .is_lit=1}, .sql_bind_name = (string){.str=(byteptr)"", .is_lit=1}, .sql_idents = __new_array(0, 0, sizeof(string)), .sql_idents_types = __new_array(0, 0, sizeof(v__ast__Type)), .sql_left_type = 0, .sql_table_name = (string){.str=(byteptr)"", .is_lit=1}, .sql_fkey = (string){.str=(byteptr)"", .is_lit=1}, .sql_parent_id = (string){.str=(byteptr)"", .is_lit=1}, .sql_side = 0, .sql_last_stmt_out_len = 0, .strs_to_free0 = __new_array(0, 0, sizeof(string)), .type_resolver = ((v__type_resolver__TypeResolver){.resolver = I_v__type_resolver__DummyResolver_to_Interface_v__type_resolver__IResolverType(((v__type_resolver__DummyResolver*)memdup(&(v__type_resolver__DummyResolver){.file = ((void*)0),}, sizeof(v__type_resolver__DummyResolver)))),.table = ((void*)0),.info = ((v__type_resolver__ResolverInfo){.saved_type_map = new_map(sizeof(string), sizeof(v__ast__Type), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),.comptime_loop_id = 0,.inside_comptime_for = 0,.inside_comptime_if = 0,.has_different_types = 0,.comptime_for_variant_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_field_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_field_type = 0,.comptime_for_field_value = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.comptime_for_enum_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_attr_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_method_var = (string){.str=(byteptr)"", .is_lit=1},.comptime_for_method = ((void*)0),.comptime_for_method_ret_type = 0,.comptime_for_method_param_var = (string){.str=(byteptr)"", .is_lit=1},}),.info_stack = __new_array(0, 0, sizeof(v__type_resolver__ResolverInfo)),.type_map = new_map(sizeof(string), sizeof(v__ast__Type), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}), .comptime = ((void*)0), .prevent_sum_type_unwrapping_once = 0, .aggregate_type_idx = 0, .arg_no_auto_deref = 0, .branch_parent_pos = 0, .returned_var_name = (string){.str=(byteptr)"", .is_lit=1}, .infix_left_var_name = (string){.str=(byteptr)"", .is_lit=1}, .curr_var_name = __new_array(0, 0, sizeof(string)), .called_fn_name = (string){.str=(byteptr)"", .is_lit=1}, .timers = v__util__new_timers(((v__util__TimerParams){.should_print = global_g->timers_should_print,.label = str_intp(3, _MOV((StrIntpData[]){{_S("cgen_process_one_file_cb idx: "), 0xfe07, {.d_i32 = idx}}, {_S(", wid: "), 0xfe07, {.d_i32 = wid}}, {_SLIT0, 0, { .d_c = 0 }}})),})), .force_main_console = 0, .as_cast_type_names = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .obf_table = global_g->obf_table, .referenced_fns = global_g->referenced_fns, .nr_closures = 0, .expected_cast_type = 0, .expected_arg_mut = 0, .or_expr_return_type = 0, .anon_fn = 0, .tests_inited = 0, .has_main = 0, .cur_mod = ((v__ast__Module){.name = (string){.str=(byteptr)"", .is_lit=1},.short_name = (string){.str=(byteptr)"", .is_lit=1},.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_skipped = 0,}), .cur_concrete_types = __new_array(0, 0, sizeof(v__ast__Type)), .cur_fn = ((void*)0), .cur_lock = ((v__ast__LockExpr){.is_rlock = __new_array(0, 0, sizeof(bool)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.lockeds = __new_array(0, 0, sizeof(v__ast__Expr)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_expr = 0,.typ = 0,.scope = ((void*)0),}), .cur_struct_init_typ = 0, .autofree_methods = new_map(sizeof(v__ast__Type), sizeof(string), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .generated_free_methods = new_map(sizeof(v__ast__Type), sizeof(bool), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .autofree_scope_stmts = __new_array(0, 0, sizeof(string)), .use_segfault_handler = global_g->use_segfault_handler, .test_function_names = __new_array(0, 0, sizeof(string)), .out_fn_start_pos = __new_array(0, 0, sizeof(int)), .static_modifier = (string){.str=(byteptr)"", .is_lit=1}, .static_non_parallel = (string){.str=(byteptr)"", .is_lit=1}, .has_reflection = (Array_string_contains(global_g->table->modules, _S("v.reflection"))), .has_debugger = (Array_string_contains(global_g->table->modules, _S("v.debug"))), .reflection_strings = global_g->reflection_strings, .defer_return_tmp_var = (string){.str=(byteptr)"", .is_lit=1}, .vweb_filter_fn_name = (string){.str=(byteptr)"", .is_lit=1}, .export_funcs = __new_array(0, 0, sizeof(string)), .type_default_impl_level = 0, }, sizeof(v__gen__c__Gen))); g->type_resolver = *v__type_resolver__TypeResolver__static__new(global_g->table, HEAP(v__type_resolver__IResolverType, I_v__gen__c__Gen_to_Interface_v__type_resolver__IResolverType(g))); g->comptime = &g->type_resolver.info; v__gen__c__Gen_gen_file(g); v__gen__c__Gen* _t1 = g; // Defer begin if (v__gen__c__cgen_process_one_file_cb_defer_0) { v__util__timing_measure_cumulative(timing_label_for_thread); } // Defer end return _t1; } void v__gen__c__Gen_free_builders(v__gen__c__Gen* g) { { // Unsafe block strings__Builder_free(&g->out); strings__Builder_free(&g->cheaders); strings__Builder_free(&g->includes); strings__Builder_free(&g->typedefs); strings__Builder_free(&g->type_definitions); strings__Builder_free(&g->sort_fn_definitions); strings__Builder_free(&g->alias_definitions); strings__Builder_free(&g->definitions); strings__Builder_free(&g->cleanup); strings__Builder_free(&g->gowrappers); strings__Builder_free(&g->waiter_fn_definitions); strings__Builder_free(&g->auto_str_funcs); strings__Builder_free(&g->dump_funcs); strings__Builder_free(&g->comptime_definitions); strings__Builder_free(&g->pcs_declarations); strings__Builder_free(&g->cov_declarations); strings__Builder_free(&g->hotcode_definitions); strings__Builder_free(&g->embedded_data); strings__Builder_free(&g->shared_types); strings__Builder_free(&g->shared_functions); strings__Builder_free(&g->channel_definitions); strings__Builder_free(&g->thread_definitions); strings__Builder_free(&g->out_options_forward); strings__Builder_free(&g->out_options); strings__Builder_free(&g->out_results_forward); strings__Builder_free(&g->out_results); strings__Builder_free(&g->json_forward_decls); strings__Builder_free(&g->enum_typedefs); strings__Builder_free(&g->sql_buf); Map_string_strings__Builder _t1 = g->cleanups; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} strings__Builder* v = &(*(strings__Builder*)DenseArray_value(&_t1.key_values, _t2)); strings__Builder_free(v); } } } void v__gen__c__Gen_gen_file(v__gen__c__Gen* g) { v__util__Timers_start(g->timers, str_intp(2, _MOV((StrIntpData[]){{_S("cgen_file "), 0xfe10, {.d_s = g->file->path}}, {_SLIT0, 0, { .d_c = 0 }}}))); g->unique_file_path_hash = hash__fnv1a__sum64_string(g->file->path); if (g->pref->is_vlines) { g->vlines_path = v__util__vlines_escape_path(g->file->path, g->pref->ccompiler); g->is_vlines_enabled = true; g->inside_ternary = 0; } v__gen__c__Gen_stmts(g, g->file->stmts); for (int _t1 = 0; _t1 < g->file->embedded_files.len; ++_t1) { v__ast__EmbeddedFile path = ((v__ast__EmbeddedFile*)g->file->embedded_files.data)[_t1]; if (!(Array_v__ast__EmbeddedFile_contains(g->embedded_files, path))) { array_push((array*)&g->embedded_files, _MOV((v__ast__EmbeddedFile[]){ path })); } } v__util__Timers_show(g->timers, str_intp(2, _MOV((StrIntpData[]){{_S("cgen_file "), 0xfe10, {.d_s = g->file->path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } string v__gen__c__Gen_hashes(v__gen__c__Gen* g) { return string_replace(_const_v__gen__c__c_commit_hash_default, _S("@@@"), v__util__version__vhash()); } void v__gen__c__Gen_init(v__gen__c__Gen* g) { if ((g->pref->custom_prelude).len != 0) { strings__Builder_writeln(&g->cheaders, g->pref->custom_prelude); } else if (!g->pref->no_preludes) { strings__Builder_writeln(&g->cheaders, _S("// Generated by the V compiler")); if (g->pref->relaxed_gcc14) { strings__Builder_writeln(&g->cheaders, _S("\n#if defined __GNUC__ && __GNUC__ >= 14\n#pragma GCC diagnostic warning \"-Wimplicit-function-declaration\"\n#pragma GCC diagnostic warning \"-Wincompatible-pointer-types\"\n#pragma GCC diagnostic warning \"-Wint-conversion\"\n#pragma GCC diagnostic warning \"-Wreturn-mismatch\"\n#endif\n")); } if (g->pref->os == v__pref__OS__linux) { strings__Builder_writeln(&g->cheaders, _S("#define _GNU_SOURCE")); } if (g->pref->os == v__pref__OS__wasm32) { strings__Builder_writeln(&g->cheaders, _S("#define VWASM 1")); strings__Builder_writeln(&g->cheaders, _S("#include ")); strings__Builder_writeln(&g->cheaders, _S("#include ")); } else { string tcc_undef_has_include = _S("\n#if defined(__TINYC__) && defined(__has_include)\n// tcc does not support has_include properly yet, turn it off completely\n#undef __has_include\n#endif"); strings__Builder_writeln(&g->preincludes, tcc_undef_has_include); strings__Builder_writeln(&g->cheaders, tcc_undef_has_include); strings__Builder_writeln(&g->includes, tcc_undef_has_include); if (g->pref->os == v__pref__OS__freebsd) { strings__Builder_writeln(&g->cheaders, _S("#include ")); strings__Builder_writeln(&g->cheaders, _S("#include ")); } else { string install_compiler_msg = _S(" Please install the package `build-essential`."); strings__Builder_writeln(&g->cheaders, v__gen__c__get_guarded_include_text(_S(""), str_intp(2, _MOV((StrIntpData[]){{_S("The C compiler can not find ."), 0xfe10, {.d_s = install_compiler_msg}}, {_SLIT0, 0, { .d_c = 0 }}})))); if (g->pref->os == v__pref__OS__ios) { strings__Builder_writeln(&g->cheaders, v__gen__c__get_guarded_include_text(_S(""), str_intp(2, _MOV((StrIntpData[]){{_S("The C compiler can not find ."), 0xfe10, {.d_s = install_compiler_msg}}, {_SLIT0, 0, { .d_c = 0 }}})))); } strings__Builder_writeln(&g->cheaders, v__gen__c__get_guarded_include_text(_S(""), str_intp(2, _MOV((StrIntpData[]){{_S("The C compiler can not find ."), 0xfe10, {.d_s = install_compiler_msg}}, {_SLIT0, 0, { .d_c = 0 }}})))); } } if (g->pref->nofloat) { strings__Builder_writeln(&g->cheaders, _S("#define VNOFLOAT 1")); } strings__Builder_writeln(&g->cheaders, _const_v__gen__c__c_builtin_types); if (!g->pref->skip_unused || g->table->used_features->used_maps > 0) { strings__Builder_writeln(&g->cheaders, _const_v__gen__c__c_mapfn_callback_types); } if (g->pref->is_bare) { strings__Builder_writeln(&g->cheaders, _const_v__gen__c__c_bare_headers); } else { strings__Builder_writeln(&g->cheaders, _const_v__gen__c__c_headers); } if (!g->pref->skip_unused || g->table->used_features->used_maps > 0) { strings__Builder_writeln(&g->cheaders, _const_v__gen__c__c_wyhash_headers); } } if (g->pref->os == v__pref__OS__ios) { strings__Builder_writeln(&g->cheaders, _S("#define __TARGET_IOS__ 1")); strings__Builder_writeln(&g->cheaders, _S("#include ")); } if (g->pref->os == v__pref__OS__linux) { strings__Builder_writeln(&g->cheaders, _S("#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30")); strings__Builder_writeln(&g->cheaders, _S("#include ")); strings__Builder_writeln(&g->cheaders, _S("#define gettid() syscall(SYS_gettid)")); strings__Builder_writeln(&g->cheaders, _S("#endif")); } v__gen__c__Gen_write_builtin_types(g); g->options_pos_forward = g->type_definitions.len; v__gen__c__Gen_write_typedef_types(g); v__gen__c__Gen_write_typeof_functions(g); v__gen__c__Gen_write_sorted_types(g); v__gen__c__Gen_write_array_fixed_return_types(g); v__gen__c__Gen_write_multi_return_types(g); strings__Builder_writeln(&g->definitions, _S("// end of definitions #endif")); if (g->pref->compile_defines_all.len > 0) { strings__Builder_writeln(&g->comptime_definitions, _S("// V compile time defines by -d or -define flags:")); strings__Builder_writeln(&g->comptime_definitions, string__plus(_S("// All custom defines : "), Array_string_join(g->pref->compile_defines_all, _S(",")))); strings__Builder_writeln(&g->comptime_definitions, string__plus(_S("// Turned ON custom defines: "), Array_string_join(g->pref->compile_defines, _S(",")))); for (int _t1 = 0; _t1 < g->pref->compile_defines.len; ++_t1) { string cdefine = ((string*)g->pref->compile_defines.data)[_t1]; strings__Builder_writeln(&g->comptime_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("#define CUSTOM_DEFINE_"), 0xfe10, {.d_s = cdefine}}, {_SLIT0, 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->comptime_definitions, _S("")); } if (g->table->gostmts > 0) { strings__Builder_writeln(&g->comptime_definitions, _S("#define __VTHREADS__ (1)")); } if (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full_opt || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_leak) { strings__Builder_writeln(&g->comptime_definitions, _S("#define _VGCBOEHM (1)")); } if (g->pref->is_debug || (Array_string_contains(g->pref->compile_defines, _S("debug")))) { strings__Builder_writeln(&g->comptime_definitions, _S("#define _VDEBUG (1)")); } if (g->pref->is_prod || (Array_string_contains(g->pref->compile_defines, _S("prod")))) { strings__Builder_writeln(&g->comptime_definitions, _S("#define _VPROD (1)")); } if (g->pref->is_test || (Array_string_contains(g->pref->compile_defines, _S("test")))) { strings__Builder_writeln(&g->comptime_definitions, _S("#define _VTEST (1)")); } if (g->pref->is_prof || (Array_string_contains(g->pref->compile_defines, _S("profile")))) { strings__Builder_writeln(&g->comptime_definitions, _S("#define _VPROFILE (1)")); } if (g->pref->autofree) { strings__Builder_writeln(&g->comptime_definitions, _S("#define _VAUTOFREE (1)")); } if (g->pref->prealloc) { strings__Builder_writeln(&g->comptime_definitions, _S("#define _VPREALLOC (1)")); } if (g->pref->use_cache) { strings__Builder_writeln(&g->comptime_definitions, _S("#define _VUSECACHE (1)")); } if (g->pref->build_mode == v__pref__BuildMode__build_module) { strings__Builder_writeln(&g->comptime_definitions, _S("#define _VBUILDMODULE (1)")); } if (g->pref->is_livemain || g->pref->is_liveshared) { v__gen__c__Gen_generate_hotcode_reloading_declarations(g); } v__ast__Table* muttable = ((v__ast__Table*)(g->table)); if (g->use_segfault_handler) { map_set(&muttable->used_features->used_fns, &(string[]){_S("v_segmentation_fault_handler")}, &(bool[]) { true }); } map_set(&muttable->used_features->used_fns, &(string[]){_S("eprintln")}, &(bool[]) { true }); map_set(&muttable->used_features->used_fns, &(string[]){_S("print_backtrace")}, &(bool[]) { true }); map_set(&muttable->used_features->used_fns, &(string[]){_S("exit")}, &(bool[]) { true }); } void v__gen__c__Gen_finish(v__gen__c__Gen* g) { if (g->pref->is_prof && g->pref->build_mode != v__pref__BuildMode__build_module) { v__gen__c__Gen_gen_vprint_profile_stats(g); } if (g->pref->is_livemain || g->pref->is_liveshared) { v__gen__c__Gen_generate_hotcode_reloader_code(g); } v__gen__c__Gen_handle_embedded_files_finish(g); if (g->pref->is_test) { v__gen__c__Gen_gen_c_main_for_tests(g); } else if ((g->pref->is_shared || g->pref->is_liveshared) && g->pref->os == v__pref__OS__windows) { v__gen__c__Gen_gen_dll_main(g); } else { v__gen__c__Gen_gen_c_main(g); } } inline string v__gen__c__Gen_get_sumtype_variant_type_name(v__gen__c__Gen* g, v__ast__Type typ, v__ast__TypeSymbol sym) { return (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option) ? (str_intp(2, _MOV((StrIntpData[]){{_S("_option_"), 0xfe10, {.d_s = sym.cname}}, {_SLIT0, 0, { .d_c = 0 }}}))) : v__ast__TypeSymbol_is_c_struct(&sym) ? (v__gen__c__Gen_cc_type(g, typ, true)) : (sym.cname)); } inline string v__gen__c__Gen_get_sumtype_variant_name(v__gen__c__Gen* g, v__ast__Type typ, v__ast__TypeSymbol sym) { return (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option) ? (str_intp(2, _MOV((StrIntpData[]){{_S("_option_"), 0xfe10, {.d_s = sym.cname}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (sym.cname)); } void v__gen__c__Gen_write_typeof_functions(v__gen__c__Gen* g) { v__gen__c__Gen_writeln(g, _S("")); v__gen__c__Gen_writeln(g, _S("// >> typeof() support for sum types / interfaces")); for (int ityp = 0; ityp < g->table->type_symbols.len; ++ityp) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)g->table->type_symbols.data)[ityp]; if (sym->kind == v__ast__Kind__sum_type) { if (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } string static_prefix = (g->pref->build_mode == v__pref__BuildMode__build_module ? (_S("static ")) : (_S(""))); v__ast__SumType sum_info = *(v__ast__SumType*)__as_cast((sym->info)._v__ast__SumType,(sym->info)._typ, 544); if (sum_info.is_generic) { continue; } v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = static_prefix}}, {_S("char * v_typeof_sumtype_"), 0xfe10, {.d_s = sym->cname}}, {_S("(int sidx) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = static_prefix}}, {_S("char * v_typeof_sumtype_"), 0xfe10, {.d_s = sym->cname}}, {_S("(int);"), 0, { .d_c = 0 }}}))); if (g->pref->build_mode == v__pref__BuildMode__build_module) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tif( sidx == _v_type_idx_"), 0xfe10, {.d_s = sym->cname}}, {_S("() ) return \""), 0xfe10, {.d_s = v__util__strip_main_name(sym->name)}}, {_S("\";"), 0, { .d_c = 0 }}}))); for (int _t1 = 0; _t1 < sum_info.variants.len; ++_t1) { v__ast__Type v = ((v__ast__Type*)sum_info.variants.data)[_t1]; v__ast__TypeSymbol* subtype = v__ast__Table_sym(g->table, v); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\tif( sidx == _v_type_idx_"), 0xfe10, {.d_s = v__gen__c__Gen_get_sumtype_variant_name(g, v, *subtype)}}, {_S("() ) return \""), 0xfe10, {.d_s = v__util__strip_main_name(subtype->name)}}, {_S("\";"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn \"unknown "), 0xfe10, {.d_s = v__util__strip_main_name(sym->name)}}, {_S("\";"), 0, { .d_c = 0 }}}))); } else { int tidx = v__ast__Table_find_type_idx(g->table, sym->name); v__gen__c__Gen_writeln(g, _S("\tswitch(sidx) {")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tcase "), 0xfe07, {.d_i32 = tidx}}, {_S(": return \""), 0xfe10, {.d_s = v__util__strip_main_name(sym->name)}}, {_S("\";"), 0, { .d_c = 0 }}}))); Array_int idxs = __new_array_with_default(0, 0, sizeof(int), 0); for (int _t2 = 0; _t2 < sum_info.variants.len; ++_t2) { v__ast__Type v = ((v__ast__Type*)sum_info.variants.data)[_t2]; if ((Array_int_contains(idxs, v))) { continue; } v__ast__TypeSymbol* subtype = v__ast__Table_sym(g->table, v); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tcase "), 0xfe07, {.d_i32 = ((int)(v))}}, {_S(": return \""), 0xfe10, {.d_s = v__util__strip_main_name(subtype->name)}}, {_S("\";"), 0, { .d_c = 0 }}}))); array_push((array*)&idxs, _MOV((int[]){ v })); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tdefault: return \"unknown "), 0xfe10, {.d_s = v__util__strip_main_name(sym->name)}}, {_S("\";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\t}")); } v__gen__c__Gen_writeln2(g, _S("}"), _S("")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = static_prefix}}, {_S("int v_typeof_sumtype_idx_"), 0xfe10, {.d_s = sym->cname}}, {_S("(int sidx) {"), 0, { .d_c = 0 }}}))); if (g->pref->build_mode == v__pref__BuildMode__build_module) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tif( sidx == _v_type_idx_"), 0xfe10, {.d_s = sym->cname}}, {_S("() ) return "), 0xfe07, {.d_i32 = ((int)(ityp))}}, {_S(";"), 0, { .d_c = 0 }}}))); for (int _t4 = 0; _t4 < sum_info.variants.len; ++_t4) { v__ast__Type v = ((v__ast__Type*)sum_info.variants.data)[_t4]; v__ast__TypeSymbol* subtype = v__ast__Table_sym(g->table, v); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\tif( sidx == _v_type_idx_"), 0xfe10, {.d_s = subtype->cname}}, {_S("() ) return "), 0xfe07, {.d_i32 = ((int)(v))}}, {_S(";"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe07, {.d_i32 = ((int)(ityp))}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { int tidx = v__ast__Table_find_type_idx(g->table, sym->name); v__gen__c__Gen_writeln2(g, _S("\tswitch(sidx) {"), str_intp(3, _MOV((StrIntpData[]){{_S("\t\tcase "), 0xfe07, {.d_i32 = tidx}}, {_S(": return "), 0xfe07, {.d_i32 = ((int)(ityp))}}, {_S(";"), 0, { .d_c = 0 }}}))); Array_int idxs = __new_array_with_default(0, 0, sizeof(int), 0); for (int _t5 = 0; _t5 < sum_info.variants.len; ++_t5) { v__ast__Type v = ((v__ast__Type*)sum_info.variants.data)[_t5]; if ((Array_int_contains(idxs, v))) { continue; } v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tcase "), 0xfe07, {.d_i32 = ((int)(v))}}, {_S(": return "), 0xfe07, {.d_i32 = ((int)(v))}}, {_S(";"), 0, { .d_c = 0 }}}))); array_push((array*)&idxs, _MOV((int[]){ v })); } v__gen__c__Gen_writeln2(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tdefault: return "), 0xfe07, {.d_i32 = ((int)(ityp))}}, {_S(";"), 0, { .d_c = 0 }}})), _S("\t}")); } v__gen__c__Gen_writeln(g, _S("}")); } else if (sym->kind == v__ast__Kind__interface) { if ((sym->info)._typ != 542 /* v.ast.Interface */) { continue; } v__ast__Interface inter_info = *(v__ast__Interface*)__as_cast((sym->info)._v__ast__Interface,(sym->info)._typ, 542); if (inter_info.is_generic) { continue; } if (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } strings__Builder_writeln(&g->definitions, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("char * v_typeof_interface_"), 0xfe10, {.d_s = sym->cname}}, {_S("(int sidx);"), 0, { .d_c = 0 }}}))); if (g->pref->parallel_cc) { strings__Builder_writeln(&g->extern_out, str_intp(2, _MOV((StrIntpData[]){{_S("extern char * v_typeof_interface_"), 0xfe10, {.d_s = sym->cname}}, {_S("(int sidx);"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("char * v_typeof_interface_"), 0xfe10, {.d_s = sym->cname}}, {_S("(int sidx) {"), 0, { .d_c = 0 }}}))); for (int _t7 = 0; _t7 < inter_info.types.len; ++_t7) { v__ast__Type t = ((v__ast__Type*)inter_info.types.data)[_t7]; v__ast__TypeSymbol* sub_sym = v__ast__Table_sym(g->table, v__ast__mktyp(t)); if ((sub_sym->info)._typ == 518 /* v.ast.Struct */ && v__ast__Struct_is_unresolved_generic(((v__ast__Struct*)__as_cast((sub_sym->info)._v__ast__Struct,(sub_sym->info)._typ, 518)))) { continue; } if (g->pref->skip_unused && sub_sym->kind == v__ast__Kind__struct && !_IN_MAP(ADDR(int, sub_sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\tif (sidx == _"), 0xfe10, {.d_s = sym->cname}}, {_S("_"), 0xfe10, {.d_s = sub_sym->cname}}, {_S("_index) return \""), 0xfe10, {.d_s = v__util__strip_main_name(sub_sym->name)}}, {_S("\";"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln2(g, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn \"unknown "), 0xfe10, {.d_s = v__util__strip_main_name(sym->name)}}, {_S("\";"), 0, { .d_c = 0 }}})), _S("}")); strings__Builder_writeln(&g->definitions, str_intp(2, _MOV((StrIntpData[]){{_S("int v_typeof_interface_idx_"), 0xfe10, {.d_s = sym->cname}}, {_S("(int sidx);"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln2(g, _S(""), str_intp(2, _MOV((StrIntpData[]){{_S("int v_typeof_interface_idx_"), 0xfe10, {.d_s = sym->cname}}, {_S("(int sidx) {"), 0, { .d_c = 0 }}}))); if (g->pref->parallel_cc) { strings__Builder_writeln(&g->extern_out, str_intp(2, _MOV((StrIntpData[]){{_S("extern int v_typeof_interface_idx_"), 0xfe10, {.d_s = sym->cname}}, {_S("(int sidx);"), 0, { .d_c = 0 }}}))); } for (int _t8 = 0; _t8 < inter_info.types.len; ++_t8) { v__ast__Type t = ((v__ast__Type*)inter_info.types.data)[_t8]; v__ast__TypeSymbol* sub_sym = v__ast__Table_sym(g->table, v__ast__mktyp(t)); if ((sub_sym->info)._typ == 518 /* v.ast.Struct */ && v__ast__Struct_is_unresolved_generic(((v__ast__Struct*)__as_cast((sub_sym->info)._v__ast__Struct,(sub_sym->info)._typ, 518)))) { continue; } if (g->pref->skip_unused && sub_sym->kind == v__ast__Kind__struct && !_IN_MAP(ADDR(int, sub_sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\tif (sidx == _"), 0xfe10, {.d_s = sym->cname}}, {_S("_"), 0xfe10, {.d_s = sub_sym->cname}}, {_S("_index) return "), 0xfe07, {.d_i32 = ((int)(v__ast__Type_set_nr_muls(t, 0)))}}, {_S(";"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln2(g, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe07, {.d_i32 = ((int)(ityp))}}, {_S(";"), 0, { .d_c = 0 }}})), _S("}")); } } v__gen__c__Gen_writeln2(g, _S("// << typeof() support for sum types"), _S("")); } inline VV_LOC string v__gen__c__Gen_styp(v__gen__c__Gen* g, v__ast__Type t) { if (!v__ast__Type_has_option_or_result(t)) { return v__gen__c__Gen_base_type(g, t); } else if (v__ast__Type_has_flag(t, v__ast__TypeFlag__option)) { return v__gen__c__Gen_register_option(g, t); } else { return v__gen__c__Gen_register_result(g, t); } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC string v__gen__c__Gen_base_type(v__gen__c__Gen* g, v__ast__Type _t) { v__ast__Type t = v__gen__c__Gen_unwrap_generic(g, _t); string* _t2 = (string*)(map_get_check(ADDR(map, g->styp_cache), &(v__ast__Type[]){t})); _option_string _t1 = {0}; if (_t2) { *((string*)&_t1.data) = *((string*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { string styp = (*(string*)_t1.data); return styp; } if (g->pref->nofloat) { if (t == _const_v__ast__f32_type) { return _S("u32"); } else if (t == _const_v__ast__f64_type) { return _S("u64"); } } v__ast__ShareType share = v__ast__Type_share(t); string styp = (share == v__ast__ShareType__atomic_t ? (v__ast__Type_atomic_typename(t)) : (v__gen__c__Gen_cc_type(g, t, true))); if (v__ast__Type_has_flag(t, v__ast__TypeFlag__shared_f)) { styp = v__gen__c__Gen_find_or_register_shared(g, t, styp); } int nr_muls = v__ast__Type_nr_muls(t); if (nr_muls > 0) { styp = string__plus(styp, strings__repeat('*', nr_muls)); } map_set(&g->styp_cache, &(v__ast__Type[]){t}, &(string[]) { styp }); return styp; } VV_LOC string v__gen__c__Gen_generic_fn_name(v__gen__c__Gen* g, Array_v__ast__Type types, string before) { if (types.len == 0) { return before; } string name = string__plus(before, _S("_T")); for (int _t2 = 0; _t2 < types.len; ++_t2) { v__ast__Type typ = ((v__ast__Type*)types.data)[_t2]; name = string__plus(name, string__plus(string__plus(_S("_"), strings__repeat_string(_S("__ptr__"), v__ast__Type_nr_muls(typ))), v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(typ, 0)))); } return name; } VV_LOC string v__gen__c__Gen_expr_string(v__gen__c__Gen* g, v__ast__Expr expr) { int pos = g->out.len; v__gen__c__Gen_expr(g, expr); return string_trim_space(strings__Builder_cut_to(&g->out, pos)); } VV_LOC string v__gen__c__Gen_expr_string_opt(v__gen__c__Gen* g, v__ast__Type typ, v__ast__Expr expr) { string expr_str = v__gen__c__Gen_expr_string(g, expr); if ((expr)._typ == 371 /* v.ast.None */) { return str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, typ)}}, {_S("){.state=2, .err="), 0xfe10, {.d_s = expr_str}}, {_S(", .data={E_STRUCT}}"), 0, { .d_c = 0 }}})); } return expr_str; } VV_LOC string v__gen__c__Gen_expr_string_with_cast(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type typ, v__ast__Type exp) { int pos = g->out.len; v__gen__c__Gen_expr_with_cast(g, expr, typ, exp); return string_trim_space(strings__Builder_cut_to(&g->out, pos)); } VV_LOC string v__gen__c__Gen_expr_string_surround(v__gen__c__Gen* g, string prepend, v__ast__Expr expr, string append) { bool v__gen__c__Gen_expr_string_surround_defer_0 = false; int pos = g->out.len; array_push((array*)&g->stmt_path_pos, _MOV((int[]){ pos })); v__gen__c__Gen_expr_string_surround_defer_0 = true; v__gen__c__Gen_write(g, prepend); v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, append); string _t2 = strings__Builder_cut_to(&g->out, pos); // Defer begin if (v__gen__c__Gen_expr_string_surround_defer_0) { array_delete_last(&g->stmt_path_pos); } // Defer end return _t2; } VV_LOC multi_return_string_string v__gen__c__Gen_option_type_name(v__gen__c__Gen* g, v__ast__Type t) { string base = v__gen__c__Gen_base_type(g, t); string styp = _S(""); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, t); if ((sym->info)._typ == 553 /* v.ast.FnType */) { base = str_intp(2, _MOV((StrIntpData[]){{_S("anon_fn_"), 0xfe10, {.d_s = v__ast__Table_fn_type_signature(g->table, (voidptr)&(*sym->info._v__ast__FnType).func)}}, {_SLIT0, 0, { .d_c = 0 }}})); } if (sym->language == v__ast__Language__c && sym->kind == v__ast__Kind__struct) { styp = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("_"), 0xfe10, {.d_s = string_replace(base, _S(" "), _S("_"))}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { styp = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("_"), 0xfe10, {.d_s = base}}, {_SLIT0, 0, { .d_c = 0 }}})); } if (v__ast__Type_has_flag(t, v__ast__TypeFlag__generic) || v__ast__Type_is_ptr(t)) { styp = string_replace(styp, _S("*"), _S("_ptr")); } return (multi_return_string_string){.arg0=styp, .arg1=base}; } VV_LOC multi_return_string_string v__gen__c__Gen_result_type_name(v__gen__c__Gen* g, v__ast__Type t) { string base = v__gen__c__Gen_base_type(g, t); if (v__ast__Type_has_flag(t, v__ast__TypeFlag__option)) { v__gen__c__Gen_register_option(g, t); base = string__plus(_S("_option_"), base); } string styp = _S(""); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, t); if ((sym->info)._typ == 553 /* v.ast.FnType */) { base = str_intp(2, _MOV((StrIntpData[]){{_S("anon_fn_"), 0xfe10, {.d_s = v__ast__Table_fn_type_signature(g->table, (voidptr)&(*sym->info._v__ast__FnType).func)}}, {_SLIT0, 0, { .d_c = 0 }}})); } if (sym->language == v__ast__Language__c && sym->kind == v__ast__Kind__struct) { styp = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = string_replace(base, _S(" "), _S("_"))}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { styp = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = base}}, {_SLIT0, 0, { .d_c = 0 }}})); } if (v__ast__Type_has_flag(t, v__ast__TypeFlag__generic) || v__ast__Type_is_ptr(t)) { styp = string_replace(styp, _S("*"), _S("_ptr")); } return (multi_return_string_string){.arg0=styp, .arg1=base}; } VV_LOC string v__gen__c__Gen_option_type_text(v__gen__c__Gen* g, string styp, string base) { string size = (_SLIT_EQ(base.str, base.len, "void") ? (_S("u8")) : _SLIT_EQ(base.str, base.len, "int") ? (_const_v__ast__int_type_name) : string_starts_with(base, _S("anon_fn")) ? (_S("void*")) : string_starts_with(base, _S("_option_")) ? (string_replace(base, _S("*"), _S(""))) : ((string_starts_with(base, _S("struct ")) && !string_ends_with(base, _S("*")) ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = base}}, {_S("*"), 0, { .d_c = 0 }}}))) : (base)))); string ret = str_intp(4, _MOV((StrIntpData[]){{_S("struct "), 0xfe10, {.d_s = styp}}, {_S(" {\n\011byte state;\n\011IError err;\n\011byte data[sizeof("), 0xfe10, {.d_s = size}}, {_S(") > 1 ? sizeof("), 0xfe10, {.d_s = size}}, {_S(") : 1];\n}"), 0, { .d_c = 0 }}})); return ret; } VV_LOC string v__gen__c__Gen_result_type_text(v__gen__c__Gen* g, string styp, string base) { string size = (_SLIT_EQ(base.str, base.len, "void") ? (_S("u8")) : _SLIT_EQ(base.str, base.len, "int") ? (_const_v__ast__int_type_name) : string_starts_with(base, _S("anon_fn")) ? (_S("void*")) : string_starts_with(base, _S("_option_")) ? (string_replace(base, _S("*"), _S(""))) : ((string_starts_with(base, _S("struct ")) && !string_ends_with(base, _S("*")) ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = base}}, {_S("*"), 0, { .d_c = 0 }}}))) : (base)))); string ret = str_intp(4, _MOV((StrIntpData[]){{_S("struct "), 0xfe10, {.d_s = styp}}, {_S(" {\n\011bool is_error;\n\011IError err;\n\011byte data[sizeof("), 0xfe10, {.d_s = size}}, {_S(") > 1 ? sizeof("), 0xfe10, {.d_s = size}}, {_S(") : 1];\n}"), 0, { .d_c = 0 }}})); return ret; } VV_LOC string v__gen__c__Gen_register_option(v__gen__c__Gen* g, v__ast__Type t) { multi_return_string_string mr_55276 = v__gen__c__Gen_option_type_name(g, t); string styp = mr_55276.arg0; string base = mr_55276.arg1; map_set(&g->options, &(string[]){base}, &(string[]) { styp }); return (!v__ast__Type_has_flag(t, v__ast__TypeFlag__option_mut_param_t) ? (styp) : (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S("*"), 0, { .d_c = 0 }}})))); } VV_LOC string v__gen__c__Gen_register_result(v__gen__c__Gen* g, v__ast__Type t) { multi_return_string_string mr_55465 = v__gen__c__Gen_result_type_name(g, t); string styp = mr_55465.arg0; string base = mr_55465.arg1; map_set(&g->results, &(string[]){base}, &(string[]) { styp }); return styp; } VV_LOC void v__gen__c__Gen_write_options(v__gen__c__Gen* g) { Array_string done = __new_array_with_default(0, 0, sizeof(string), 0); sync__RwMutex_rlock(&g->done_options->mtx); /*lock*/ { done = array_clone_to_depth(&g->done_options->val, 0); } sync__RwMutex_runlock(&g->done_options->mtx);; Map_string_string _t1 = g->options; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string base = *(string*)DenseArray_key(&_t1.key_values, _t2); base = string_clone(base); string styp = (*(string*)DenseArray_value(&_t1.key_values, _t2)); if ((Array_string_contains(done, base))) { continue; } array_push((array*)&done, _MOV((string[]){ string_clone(base) })); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = styp}}, {_S(";"), 0, { .d_c = 0 }}}))); if ((Array_string_contains(g->options_forward, base))) { strings__Builder_write_string(&g->out_options_forward, string__plus(v__gen__c__Gen_option_type_text(g, styp, base), _S(";\n\n"))); } else { strings__Builder_write_string(&g->out_options, string__plus(v__gen__c__Gen_option_type_text(g, styp, base), _S(";\n\n"))); } } } VV_LOC void v__gen__c__Gen_write_results(v__gen__c__Gen* g) { Array_string done = __new_array_with_default(0, 0, sizeof(string), 0); sync__RwMutex_rlock(&g->done_results->mtx); /*lock*/ { done = array_clone_to_depth(&g->done_results->val, 0); } sync__RwMutex_runlock(&g->done_results->mtx);; Map_string_string _t1 = g->results; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string base = *(string*)DenseArray_key(&_t1.key_values, _t2); base = string_clone(base); string styp = (*(string*)DenseArray_value(&_t1.key_values, _t2)); if ((Array_string_contains(done, base))) { continue; } array_push((array*)&done, _MOV((string[]){ string_clone(base) })); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = styp}}, {_S(";"), 0, { .d_c = 0 }}}))); if ((Array_string_contains(g->results_forward, base))) { strings__Builder_write_string(&g->out_results_forward, string__plus(v__gen__c__Gen_result_type_text(g, styp, base), _S(";\n\n"))); } else { strings__Builder_write_string(&g->out_results, string__plus(v__gen__c__Gen_result_type_text(g, styp, base), _S(";\n\n"))); } } Map_string_int _t6 = g->table->anon_struct_names; int _t8 = _t6.key_values.len; for (int _t7 = 0; _t7 < _t8; ++_t7 ) { int _t9 = _t6.key_values.len - _t8; _t8 = _t6.key_values.len; if (_t9 < 0) { _t7 = -1; continue; } if (!DenseArray_has_index(&_t6.key_values, _t7)) {continue;} string k = *(string*)DenseArray_key(&_t6.key_values, _t7); k = string_clone(k); string ck = v__gen__c__c_name(k); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = ck}}, {_S(" "), 0xfe10, {.d_s = ck}}, {_S(";"), 0, { .d_c = 0 }}}))); } Map_string_int _t10 = g->table->anon_union_names; int _t12 = _t10.key_values.len; for (int _t11 = 0; _t11 < _t12; ++_t11 ) { int _t13 = _t10.key_values.len - _t12; _t12 = _t10.key_values.len; if (_t13 < 0) { _t11 = -1; continue; } if (!DenseArray_has_index(&_t10.key_values, _t11)) {continue;} string k = *(string*)DenseArray_key(&_t10.key_values, _t11); k = string_clone(k); string ck = v__gen__c__c_name(k); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef union "), 0xfe10, {.d_s = ck}}, {_S(" "), 0xfe10, {.d_s = ck}}, {_S(";"), 0, { .d_c = 0 }}}))); } } VV_LOC string v__gen__c__Gen_find_or_register_shared(v__gen__c__Gen* g, v__ast__Type t, string base) { map_set(&g->shareds, &(int[]){v__ast__Type_idx(t)}, &(string[]) { base }); return str_intp(2, _MOV((StrIntpData[]){{_S("__shared__"), 0xfe10, {.d_s = base}}, {_SLIT0, 0, { .d_c = 0 }}})); } VV_LOC void v__gen__c__Gen_write_shareds(v__gen__c__Gen* g) { Array_int done_types = __new_array_with_default(0, 0, sizeof(int), 0); Map_int_string _t1 = g->shareds; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} int typ = *(int*)DenseArray_key(&_t1.key_values, _t2); string base = (*(string*)DenseArray_value(&_t1.key_values, _t2)); if ((Array_int_contains(done_types, typ))) { continue; } array_push((array*)&done_types, _MOV((int[]){ typ })); string sh_typ = str_intp(2, _MOV((StrIntpData[]){{_S("__shared__"), 0xfe10, {.d_s = base}}, {_SLIT0, 0, { .d_c = 0 }}})); string mtx_typ = _S("sync__RwMutex"); strings__Builder_writeln(&g->shared_types, str_intp(2, _MOV((StrIntpData[]){{_S("struct "), 0xfe10, {.d_s = sh_typ}}, {_S(" {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->shared_types, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = mtx_typ}}, {_S(" mtx;"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->shared_types, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = base}}, {_S(" val;"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->shared_types, _S("};")); strings__Builder_writeln(&g->shared_functions, str_intp(2, _MOV((StrIntpData[]){{_S("static inline voidptr __dup"), 0xfe10, {.d_s = sh_typ}}, {_S("(voidptr src, int sz) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->shared_functions, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = sh_typ}}, {_S("* dest = memdup(src, sz);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->shared_functions, _S("\tsync__RwMutex_init(&dest->mtx);")); strings__Builder_writeln(&g->shared_functions, _S("\treturn dest;")); strings__Builder_writeln(&g->shared_functions, _S("}")); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = sh_typ}}, {_S(" "), 0xfe10, {.d_s = sh_typ}}, {_S(";"), 0, { .d_c = 0 }}}))); } } VV_LOC void v__gen__c__Gen_register_thread_void_wait_call(v__gen__c__Gen* g) { sync__RwMutex_lock(&g->waiter_fns->mtx); /*lock*/ { if ((Array_string_contains(g->waiter_fns->val, _S("__v_thread_wait")))) { sync__RwMutex_unlock(&g->waiter_fns->mtx);return; } array_push((array*)&g->waiter_fns->val, _MOV((string[]){ _S("__v_thread_wait") })); strings__Builder_writeln(&g->waiter_fn_definitions, _S("void __v_thread_wait(__v_thread thread);")); } sync__RwMutex_unlock(&g->waiter_fns->mtx);; strings__Builder_writeln(&g->gowrappers, _S("void __v_thread_wait(__v_thread thread) {")); if (g->pref->os == v__pref__OS__windows) { strings__Builder_writeln(&g->gowrappers, _S("\tu32 stat = WaitForSingleObject(thread, INFINITE);")); } else { strings__Builder_writeln(&g->gowrappers, _S("\tint stat = pthread_join(thread, (void **)NULL);")); } strings__Builder_writeln(&g->gowrappers, _S("\tif (stat != 0) { _v_panic(_S(\"unable to join thread\")); }")); if (g->pref->os == v__pref__OS__windows) { strings__Builder_writeln(&g->gowrappers, _S("\tCloseHandle(thread);")); } strings__Builder_writeln(&g->gowrappers, _S("}")); } VV_LOC string v__gen__c__Gen_register_thread_array_wait_call(v__gen__c__Gen* g, string eltyp) { bool is_void = _SLIT_EQ(eltyp.str, eltyp.len, "void"); string thread_typ = (is_void ? (_S("__v_thread")) : (str_intp(2, _MOV((StrIntpData[]){{_S("__v_thread_"), 0xfe10, {.d_s = eltyp}}, {_SLIT0, 0, { .d_c = 0 }}})))); string ret_typ = (is_void ? (_S("void")) : (str_intp(2, _MOV((StrIntpData[]){{_S("Array_"), 0xfe10, {.d_s = eltyp}}, {_SLIT0, 0, { .d_c = 0 }}})))); string thread_arr_typ = str_intp(2, _MOV((StrIntpData[]){{_S("Array_"), 0xfe10, {.d_s = thread_typ}}, {_SLIT0, 0, { .d_c = 0 }}})); string fn_name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = thread_arr_typ}}, {_S("_wait"), 0, { .d_c = 0 }}})); bool should_register = false; sync__RwMutex_lock(&g->waiter_fns->mtx); /*lock*/ { if (!(Array_string_contains(g->waiter_fns->val, fn_name))) { array_push((array*)&g->waiter_fns->val, _MOV((string[]){ string_clone(fn_name) })); should_register = true; } } sync__RwMutex_unlock(&g->waiter_fns->mtx);; if (should_register) { if (is_void) { v__gen__c__Gen_register_thread_void_wait_call(g); strings__Builder_writeln(&g->waiter_fn_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("void "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = thread_arr_typ}}, {_S(" a);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->gowrappers, str_intp(5, _MOV((StrIntpData[]){{_S("\nvoid "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = thread_arr_typ}}, {_S(" a) {\n\011for (int i = 0; i < a.len; ++i) {\n\011\011"), 0xfe10, {.d_s = thread_typ}}, {_S(" t = (("), 0xfe10, {.d_s = thread_typ}}, {_S("*)a.data)[i];\n\011\011if (t == 0) continue;\n\011\011__v_thread_wait(t);\n\011}\n}"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->waiter_fn_definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = thread_arr_typ}}, {_S(" a);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->gowrappers, str_intp(8, _MOV((StrIntpData[]){{_S("\n"), 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = thread_arr_typ}}, {_S(" a) {\n\011"), 0xfe10, {.d_s = ret_typ}}, {_S(" res = __new_array_with_default(a.len, a.len, sizeof("), 0xfe10, {.d_s = eltyp}}, {_S("), 0);\n\011for (int i = 0; i < a.len; ++i) {\n\011\011"), 0xfe10, {.d_s = thread_typ}}, {_S(" t = (("), 0xfe10, {.d_s = thread_typ}}, {_S("*)a.data)[i];"), 0, { .d_c = 0 }}}))); if (g->pref->os == v__pref__OS__windows) { strings__Builder_writeln(&g->gowrappers, _S("\t\tif (t.handle == 0) continue;")); } else { strings__Builder_writeln(&g->gowrappers, _S("\t\tif (t == 0) continue;")); } strings__Builder_writeln(&g->gowrappers, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t(("), 0xfe10, {.d_s = eltyp}}, {_S("*)res.data)[i] = __v_thread_"), 0xfe10, {.d_s = eltyp}}, {_S("_wait(t);\n\011}\n\011return res;\n}"), 0, { .d_c = 0 }}}))); } } return fn_name; } VV_LOC string v__gen__c__Gen_register_thread_fixed_array_wait_call(v__gen__c__Gen* g, v__ast__CallExpr node, string eltyp) { bool is_void = _SLIT_EQ(eltyp.str, eltyp.len, "void"); string thread_typ = (is_void ? (_S("__v_thread")) : (str_intp(2, _MOV((StrIntpData[]){{_S("__v_thread_"), 0xfe10, {.d_s = eltyp}}, {_SLIT0, 0, { .d_c = 0 }}})))); string ret_typ = (is_void ? (_S("void")) : (str_intp(2, _MOV((StrIntpData[]){{_S("Array_"), 0xfe10, {.d_s = eltyp}}, {_SLIT0, 0, { .d_c = 0 }}})))); v__ast__TypeSymbol* rec_sym = v__ast__Table_sym(g->table, node.receiver_type); int len = (*(v__ast__ArrayFixed*)__as_cast((rec_sym->info)._v__ast__ArrayFixed,(rec_sym->info)._typ, 549)).size; string thread_arr_typ = rec_sym->cname; string fn_name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = thread_arr_typ}}, {_S("_wait"), 0, { .d_c = 0 }}})); bool should_register = false; sync__RwMutex_lock(&g->waiter_fns->mtx); /*lock*/ { if (!(Array_string_contains(g->waiter_fns->val, fn_name))) { array_push((array*)&g->waiter_fns->val, _MOV((string[]){ string_clone(fn_name) })); should_register = true; } } sync__RwMutex_unlock(&g->waiter_fns->mtx);; if (should_register) { if (is_void) { v__gen__c__Gen_register_thread_void_wait_call(g); strings__Builder_writeln(&g->waiter_fn_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("void "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = thread_arr_typ}}, {_S(" a);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->gowrappers, str_intp(6, _MOV((StrIntpData[]){{_S("\nvoid "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = thread_arr_typ}}, {_S(" a) {\n\011for (int i = 0; i < "), 0xfe07, {.d_i32 = len}}, {_S("; ++i) {\n\011\011"), 0xfe10, {.d_s = thread_typ}}, {_S(" t = (("), 0xfe10, {.d_s = thread_typ}}, {_S("*)a)[i];\n\011\011if (t == 0) continue;\n\011\011__v_thread_wait(t);\n\011}\n}"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->waiter_fn_definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = thread_arr_typ}}, {_S(" a);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->gowrappers, str_intp(11, _MOV((StrIntpData[]){{_S("\n"), 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = thread_arr_typ}}, {_S(" a) {\n\011"), 0xfe10, {.d_s = ret_typ}}, {_S(" res = __new_array_with_default("), 0xfe07, {.d_i32 = len}}, {_S(", "), 0xfe07, {.d_i32 = len}}, {_S(", sizeof("), 0xfe10, {.d_s = eltyp}}, {_S("), 0);\n\011for (int i = 0; i < "), 0xfe07, {.d_i32 = len}}, {_S("; ++i) {\n\011\011"), 0xfe10, {.d_s = thread_typ}}, {_S(" t = (("), 0xfe10, {.d_s = thread_typ}}, {_S("*)a)[i];"), 0, { .d_c = 0 }}}))); if (g->pref->os == v__pref__OS__windows) { strings__Builder_writeln(&g->gowrappers, _S("\t\tif (t.handle == 0) continue;")); } else { strings__Builder_writeln(&g->gowrappers, _S("\t\tif (t == 0) continue;")); } strings__Builder_writeln(&g->gowrappers, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t(("), 0xfe10, {.d_s = eltyp}}, {_S("*)res.data)[i] = __v_thread_"), 0xfe10, {.d_s = eltyp}}, {_S("_wait(t);\n\011}\n\011return res;\n}"), 0, { .d_c = 0 }}}))); } } return fn_name; } VV_LOC void v__gen__c__Gen_register_chan_pop_option_call(v__gen__c__Gen* g, string opt_el_type, string styp) { map_set(&g->chan_pop_options, &(string[]){opt_el_type}, &(string[]) { styp }); } VV_LOC void v__gen__c__Gen_write_chan_pop_option_fns(v__gen__c__Gen* g) { Array_string done = __new_array_with_default(0, 0, sizeof(string), 0); Map_string_string _t1 = g->chan_pop_options; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string opt_el_type = *(string*)DenseArray_key(&_t1.key_values, _t2); opt_el_type = string_clone(opt_el_type); string styp = (*(string*)DenseArray_value(&_t1.key_values, _t2)); if ((Array_string_contains(done, opt_el_type))) { continue; } if (g->pref->skip_unused) { _option_v__ast__TypeSymbol_ptr _t5; if (_t5 = v__ast__Table_find_sym(g->table, opt_el_type), _t5.state == 0) { v__ast__TypeSymbol* sym = *(v__ast__TypeSymbol**)_t5.data; if (!_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } } } array_push((array*)&done, _MOV((string[]){ string_clone(opt_el_type) })); strings__Builder_writeln(&g->channel_definitions, str_intp(6, _MOV((StrIntpData[]){{_S("\nstatic inline "), 0xfe10, {.d_s = opt_el_type}}, {_S(" __Option_"), 0xfe10, {.d_s = styp}}, {_S("_popval("), 0xfe10, {.d_s = styp}}, {_S(" ch) {\n\011"), 0xfe10, {.d_s = opt_el_type}}, {_S(" _tmp = {0};\n\011if (sync__Channel_try_pop_priv(ch, _tmp.data, false)) {\n\011\011return ("), 0xfe10, {.d_s = opt_el_type}}, {_S("){ .state = 2, .err = _v_error(_S(\"channel closed\")), .data = {E_STRUCT} };\n\011}\n\011return _tmp;\n}"), 0, { .d_c = 0 }}}))); } } VV_LOC void v__gen__c__Gen_register_chan_push_option_fn(v__gen__c__Gen* g, string el_type, string styp) { map_set(&g->chan_push_options, &(string[]){styp}, &(string[]) { el_type }); } VV_LOC void v__gen__c__Gen_write_chan_push_option_fns(v__gen__c__Gen* g) { Array_string done = __new_array_with_default(0, 0, sizeof(string), 0); Map_string_string _t1 = g->chan_push_options; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string styp = *(string*)DenseArray_key(&_t1.key_values, _t2); styp = string_clone(styp); string el_type = (*(string*)DenseArray_value(&_t1.key_values, _t2)); if ((Array_string_contains(done, styp))) { continue; } if (g->pref->skip_unused) { _option_v__ast__TypeSymbol_ptr _t5; if (_t5 = v__ast__Table_find_sym(g->table, el_type), _t5.state == 0) { v__ast__TypeSymbol* sym = *(v__ast__TypeSymbol**)_t5.data; if (!_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } } } array_push((array*)&done, _MOV((string[]){ string_clone(styp) })); v__gen__c__Gen_register_option(g, v__ast__Type_set_flag(_const_v__ast__void_type, v__ast__TypeFlag__option)); strings__Builder_writeln(&g->channel_definitions, str_intp(7, _MOV((StrIntpData[]){{_S("\nstatic inline "), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("_void __Option_"), 0xfe10, {.d_s = styp}}, {_S("_pushval("), 0xfe10, {.d_s = styp}}, {_S(" ch, "), 0xfe10, {.d_s = el_type}}, {_S(" e) {\n\011if (sync__Channel_try_push_priv(ch, &e, false)) {\n\011\011return ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("_void){ .state = 2, .err = _v_error(_S(\"channel closed\")), .data = {E_STRUCT} };\n\011}\n\011return ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("_void){0};\n}"), 0, { .d_c = 0 }}}))); } } VV_LOC string v__gen__c__Gen_cc_type(v__gen__c__Gen* g, v__ast__Type typ, bool is_prefix_struct) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, typ)); string styp = v__ast__TypeSymbol_scoped_cname(sym); if (sym->info._typ == 518 /* v.ast.Struct */) { if ((*sym->info._v__ast__Struct).is_generic && sym->generic_types.len == 0) { string sgtyps = _S("_T"); for (int _t1 = 0; _t1 < (*sym->info._v__ast__Struct).generic_types.len; ++_t1) { v__ast__Type gt = ((v__ast__Type*)(*sym->info._v__ast__Struct).generic_types.data)[_t1]; v__ast__TypeSymbol* gts = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, gt)); sgtyps = string__plus(sgtyps, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = gts->cname}}, {_SLIT0, 0, { .d_c = 0 }}}))); } styp = string__plus(styp, sgtyps); } } else if (sym->info._typ == 542 /* v.ast.Interface */) { if ((*sym->info._v__ast__Interface).is_generic && sym->generic_types.len == 0) { string sgtyps = _S("_T"); for (int _t2 = 0; _t2 < (*sym->info._v__ast__Interface).generic_types.len; ++_t2) { v__ast__Type gt = ((v__ast__Type*)(*sym->info._v__ast__Interface).generic_types.data)[_t2]; v__ast__TypeSymbol* gts = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, gt)); sgtyps = string__plus(sgtyps, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = gts->cname}}, {_SLIT0, 0, { .d_c = 0 }}}))); } styp = string__plus(styp, sgtyps); } } else if (sym->info._typ == 544 /* v.ast.SumType */) { if ((*sym->info._v__ast__SumType).is_generic && sym->generic_types.len == 0) { string sgtyps = _S("_T"); for (int _t3 = 0; _t3 < (*sym->info._v__ast__SumType).generic_types.len; ++_t3) { v__ast__Type gt = ((v__ast__Type*)(*sym->info._v__ast__SumType).generic_types.data)[_t3]; v__ast__TypeSymbol* gts = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, gt)); sgtyps = string__plus(sgtyps, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = gts->cname}}, {_SLIT0, 0, { .d_c = 0 }}}))); } styp = string__plus(styp, sgtyps); } } else { } if (is_prefix_struct && sym->language == v__ast__Language__c) { styp = string_substr(styp, 3, 2147483647); if (sym->kind == v__ast__Kind__struct) { v__ast__Struct info = *(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518); if (!info.is_typedef) { styp = str_intp(2, _MOV((StrIntpData[]){{_S("struct "), 0xfe10, {.d_s = styp}}, {_SLIT0, 0, { .d_c = 0 }}})); } } } return styp; } inline VV_LOC string v__gen__c__Gen_type_sidx(v__gen__c__Gen* g, v__ast__Type t) { if (g->pref->build_mode == v__pref__BuildMode__build_module) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, t); return str_intp(2, _MOV((StrIntpData[]){{_S("_v_type_idx_"), 0xfe10, {.d_s = sym->cname}}, {_S("()"), 0, { .d_c = 0 }}})); } return int_str(((int)(t))); } void v__gen__c__Gen_write_typedef_types(v__gen__c__Gen* g) { Array_v__ast__TypeSymbol_ptr _t1 = {0}; Array_v__ast__TypeSymbol_ptr _t1_orig = g->table->type_symbols; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__TypeSymbol*)); for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__TypeSymbol* it = ((v__ast__TypeSymbol**) _t1_orig.data)[_t2]; if (!it->is_builtin && (it->kind == v__ast__Kind__array || it->kind == v__ast__Kind__array_fixed || it->kind == v__ast__Kind__chan || it->kind == v__ast__Kind__map)) { array_push((array*)&_t1, &it); } } Array_v__ast__TypeSymbol_ptr type_symbols =_t1; for (int _t3 = 0; _t3 < type_symbols.len; ++_t3) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)type_symbols.data)[_t3]; if (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } if (sym->kind == (v__ast__Kind__array)) { v__ast__Array info = *(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513); v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, info.elem_type); if (elem_sym->kind != v__ast__Kind__placeholder && !v__ast__Type_has_flag(info.elem_type, v__ast__TypeFlag__generic)) { strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("typedef array "), 0xfe10, {.d_s = sym->cname}}, {_S(";"), 0, { .d_c = 0 }}}))); } } else if (sym->kind == (v__ast__Kind__array_fixed)) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549); v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, info.elem_type); if (v__ast__TypeSymbol_is_builtin(elem_sym)) { string styp = sym->cname; int len = info.size; if (len > 0) { string fixed = v__gen__c__Gen_styp(g, info.elem_type); if ((elem_sym->info)._typ == 553 /* v.ast.FnType */) { int pos = g->out.len; v__gen__c__Gen_write_fn_ptr_decl(g, &(*elem_sym->info._v__ast__FnType), _S("")); fixed = strings__Builder_cut_to(&g->out, pos); string def_str = str_intp(2, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = fixed}}, {_S(";"), 0, { .d_c = 0 }}})); def_str = string_replace_once(def_str, _S("(*)"), str_intp(3, _MOV((StrIntpData[]){{_S("(*"), 0xfe10, {.d_s = styp}}, {_S("["), 0xfe07, {.d_i32 = len}}, {_S("])"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, def_str); } else if (!info.is_fn_ret) { string base = v__gen__c__Gen_styp(g, v__ast__Type_clear_option_and_result(info.elem_type)); if (v__ast__Type_has_flag(info.elem_type, v__ast__TypeFlag__option) && !(Array_string_contains(g->options_forward, base))) { sync__RwMutex_lock(&g->done_options->mtx); /*lock*/ { if (!(Array_string_contains(g->done_options->val, base))) { strings__Builder_writeln(&g->type_definitions, str_intp(4, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = fixed}}, {_S(" "), 0xfe10, {.d_s = styp}}, {_S(" ["), 0xfe07, {.d_i32 = len}}, {_S("];"), 0, { .d_c = 0 }}}))); array_push((array*)&g->options_forward, _MOV((string[]){ string_clone(base) })); array_push((array*)&g->done_options->val, _MOV((string[]){ string_clone(styp) })); } } sync__RwMutex_unlock(&g->done_options->mtx);; } else { strings__Builder_writeln(&g->type_definitions, str_intp(4, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = fixed}}, {_S(" "), 0xfe10, {.d_s = styp}}, {_S(" ["), 0xfe07, {.d_i32 = len}}, {_S("];"), 0, { .d_c = 0 }}}))); if (v__ast__Type_has_flag(info.elem_type, v__ast__TypeFlag__result) && !(Array_string_contains(g->results_forward, base))) { array_push((array*)&g->results_forward, _MOV((string[]){ string_clone(base) })); } } } } } } else if (sym->kind == (v__ast__Kind__chan)) { if (!fast_string_eq(sym->name, _S("chan"))) { v__ast__Chan chan_inf = v__ast__TypeSymbol_chan_info(sym); v__ast__Type chan_elem_type = chan_inf.elem_type; v__ast__TypeSymbol* esym = v__ast__Table_sym(g->table, chan_elem_type); strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("typedef chan "), 0xfe10, {.d_s = sym->cname}}, {_S(";"), 0, { .d_c = 0 }}}))); bool is_fixed_arr = esym->kind == v__ast__Kind__array_fixed; if (!v__ast__Type_has_flag(chan_elem_type, v__ast__TypeFlag__generic)) { string el_stype = string__plus((is_fixed_arr ? (_S("_v_")) : (_S(""))), v__gen__c__Gen_styp(g, chan_elem_type)); string val_arg_pop = (is_fixed_arr ? (_S("&val.ret_arr")) : (_S("&val"))); string val_arg_push = (is_fixed_arr ? (_S("val")) : (_S("&val"))); string push_arg = string__plus(el_stype, (is_fixed_arr ? (_S("*")) : (_S("")))); strings__Builder_writeln(&g->channel_definitions, str_intp(6, _MOV((StrIntpData[]){{_S("\nstatic inline "), 0xfe10, {.d_s = el_stype}}, {_S(" __"), 0xfe10, {.d_s = sym->cname}}, {_S("_popval("), 0xfe10, {.d_s = sym->cname}}, {_S(" ch) {\n\011"), 0xfe10, {.d_s = el_stype}}, {_S(" val;\n\011sync__Channel_try_pop_priv(ch, "), 0xfe10, {.d_s = val_arg_pop}}, {_S(", false);\n\011return val;\n}"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->channel_definitions, str_intp(5, _MOV((StrIntpData[]){{_S("\nstatic inline void __"), 0xfe10, {.d_s = sym->cname}}, {_S("_pushval("), 0xfe10, {.d_s = sym->cname}}, {_S(" ch, "), 0xfe10, {.d_s = push_arg}}, {_S(" val) {\n\011sync__Channel_try_push_priv(ch, "), 0xfe10, {.d_s = val_arg_push}}, {_S(", false);\n}"), 0, { .d_c = 0 }}}))); } } } else if (sym->kind == (v__ast__Kind__map)) { strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("typedef map "), 0xfe10, {.d_s = sym->cname}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { continue; } } for (int _t7 = 0; _t7 < g->table->type_symbols.len; ++_t7) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)g->table->type_symbols.data)[_t7]; if (sym->kind == v__ast__Kind__alias && !sym->is_builtin && !(fast_string_eq(sym->name, _S("byte")) || fast_string_eq(sym->name, _S("i32")))) { if (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } v__gen__c__Gen_write_alias_typesymbol_declaration(g, *sym); } } v__gen__c__Gen_write_sorted_fn_typesymbol_declaration(g); Array_v__ast__TypeSymbol_ptr _t8 = {0}; Array_v__ast__TypeSymbol_ptr _t8_orig = g->table->type_symbols; int _t8_len = _t8_orig.len; _t8 = __new_array(0, _t8_len, sizeof(v__ast__TypeSymbol*)); for (int _t9 = 0; _t9 < _t8_len; ++_t9) { v__ast__TypeSymbol* it = ((v__ast__TypeSymbol**) _t8_orig.data)[_t9]; if ((it->info)._typ == 542 /* v.ast.Interface */ && !it->is_builtin) { array_push((array*)&_t8, &it); } } Array_v__ast__TypeSymbol_ptr interfaces =_t8; Array_v__ast__TypeSymbol_ptr interface_non_generic_syms = __new_array_with_default(0, interfaces.len, sizeof(v__ast__TypeSymbol*), 0); for (int _t10 = 0; _t10 < interfaces.len; ++_t10) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)interfaces.data)[_t10]; v__gen__c__Gen_write_interface_typedef(g, *sym); if ((sym->info)._typ == 542 /* v.ast.Interface */ && !(*(v__ast__Interface*)__as_cast((sym->info)._v__ast__Interface,(sym->info)._typ, 542)).is_generic) { array_push((array*)&interface_non_generic_syms, _MOV((v__ast__TypeSymbol*[]){ sym })); } } for (int _t12 = 0; _t12 < interface_non_generic_syms.len; ++_t12) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)interface_non_generic_syms.data)[_t12]; if (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } v__gen__c__Gen_write_interface_typesymbol_declaration(g, *sym); } } void v__gen__c__Gen_write_alias_typesymbol_declaration(v__gen__c__Gen* g, v__ast__TypeSymbol sym) { int levels = 0; v__ast__TypeSymbol* parent = (*(v__ast__TypeSymbol**)array_get(g->table->type_symbols, sym.parent_idx)); bool is_c_parent = parent->name.len > 2 && string_at(parent->name, 0) == 'C' && string_at(parent->name, 1) == '.'; bool is_fixed_array_of_non_builtin = false; string parent_styp = parent->cname; if (is_c_parent) { if ((sym.info)._typ == 539 /* v.ast.Alias */) { parent_styp = v__gen__c__Gen_styp(g, (*sym.info._v__ast__Alias).parent_type); } } else { if ((sym.info)._typ == 539 /* v.ast.Alias */) { parent_styp = v__gen__c__Gen_styp(g, (*sym.info._v__ast__Alias).parent_type); v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(g->table, (*sym.info._v__ast__Alias).parent_type); if ((parent_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, (*parent_sym->info._v__ast__ArrayFixed).elem_type); if (!v__ast__TypeSymbol_is_builtin(elem_sym)) { is_fixed_array_of_non_builtin = true; } v__ast__ArrayFixed parent_elem_info = (*parent_sym->info._v__ast__ArrayFixed); string parent_elem_styp = v__gen__c__Gen_styp(g, (*sym.info._v__ast__Alias).parent_type); strings__Builder out = strings__new_builder(50); for (;;) { if ((elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { string old = strings__Builder_str(&out); array_clear(&out); strings__Builder_writeln(&out, str_intp(4, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = elem_sym->cname}}, {_S(" "), 0xfe10, {.d_s = parent_elem_styp}}, {_S(" ["), 0xfe07, {.d_i32 = parent_elem_info.size}}, {_S("];"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&out, old); parent_elem_styp = elem_sym->cname; parent_elem_info = (*elem_sym->info._v__ast__ArrayFixed); elem_sym = v__ast__Table_sym(g->table, (*elem_sym->info._v__ast__ArrayFixed).elem_type); levels++; } else { break; } } if (out.len != 0) { strings__Builder_writeln(&g->type_definitions, strings__Builder_str(&out)); } } } } if (_SLIT_EQ(parent_styp.str, parent_styp.len, "byte") && fast_string_eq(sym.cname, _S("u8"))) { return; } if (string_starts_with(sym.name, _S("C."))) { strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("#define "), 0xfe10, {.d_s = sym.cname}}, {_S(" "), 0xfe10, {.d_s = string_substr_ni(sym.cname, 3, 2147483647)}}, {_SLIT0, 0, { .d_c = 0 }}}))); return; } if (is_fixed_array_of_non_builtin && levels == 0) { strings__Builder_writeln(&g->alias_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = parent_styp}}, {_S(" "), 0xfe10, {.d_s = sym.cname}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = parent_styp}}, {_S(" "), 0xfe10, {.d_s = sym.cname}}, {_S(";"), 0, { .d_c = 0 }}}))); } } void v__gen__c__Gen_write_interface_typedef(v__gen__c__Gen* g, v__ast__TypeSymbol sym) { string struct_name = v__gen__c__c_name(sym.cname); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = struct_name}}, {_S(" "), 0xfe10, {.d_s = struct_name}}, {_S(";"), 0, { .d_c = 0 }}}))); } void v__gen__c__Gen_write_interface_typesymbol_declaration(v__gen__c__Gen* g, v__ast__TypeSymbol sym) { v__ast__Interface info = *(v__ast__Interface*)__as_cast((sym.info)._v__ast__Interface,(sym.info)._typ, 542); string struct_name = v__gen__c__c_name(sym.cname); strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("struct "), 0xfe10, {.d_s = struct_name}}, {_S(" {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, _S("\tunion {")); strings__Builder_writeln(&g->type_definitions, _S("\t\tvoid* _object;")); for (int _t1 = 0; _t1 < info.types.len; ++_t1) { v__ast__Type variant = ((v__ast__Type*)info.types.data)[_t1]; v__ast__Type mk_typ = v__ast__mktyp(variant); if (mk_typ != variant && (Array_v__ast__Type_contains(info.types, mk_typ))) { continue; } v__ast__TypeSymbol* vsym = v__ast__Table_sym(g->table, mk_typ); if (g->pref->skip_unused && !_IN_MAP(ADDR(int, vsym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } string vcname = vsym->cname; strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = vcname}}, {_S("* _"), 0xfe10, {.d_s = vcname}}, {_S(";"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->type_definitions, _S("\t};")); strings__Builder_writeln(&g->type_definitions, _S("\tint _typ;")); for (int _t2 = 0; _t2 < info.fields.len; ++_t2) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[_t2]; string styp = v__gen__c__Gen_styp(g, field.typ); string cname = v__gen__c__c_name(field.name); strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S("* "), 0xfe10, {.d_s = cname}}, {_S(";"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->type_definitions, _S("};")); } void v__gen__c__Gen_write_fn_typesymbol_declaration(v__gen__c__Gen* g, v__ast__TypeSymbol sym) { v__ast__FnType info = *(v__ast__FnType*)__as_cast((sym.info)._v__ast__FnType,(sym.info)._typ, 553); v__ast__Fn func = info.func; bool is_fn_sig = (func.name).len == 0; bool not_anon = !info.is_anon; bool has_generic_arg = false; if (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym.idx), ADDR(map, g->table->used_features->used_syms))) { return; } for (int _t1 = 0; _t1 < func.params.len; ++_t1) { v__ast__Param param = ((v__ast__Param*)func.params.data)[_t1]; if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { has_generic_arg = true; break; } } if (!info.has_decl && (not_anon || is_fn_sig) && !v__ast__Type_has_flag(func.return_type, v__ast__TypeFlag__generic) && !has_generic_arg) { string fn_name = sym.cname; string call_conv = _S(""); string msvc_call_conv = _S(""); for (int _t2 = 0; _t2 < func.attrs.len; ++_t2) { v__ast__Attr attr = ((v__ast__Attr*)func.attrs.data)[_t2]; if (_SLIT_EQ(attr.name.str, attr.name.len, "callconv")) { if (g->is_cc_msvc) { msvc_call_conv = str_intp(2, _MOV((StrIntpData[]){{_S("__"), 0xfe10, {.d_s = attr.arg}}, {_S(" "), 0, { .d_c = 0 }}})); } else { call_conv = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = attr.arg}}, {_SLIT0, 0, { .d_c = 0 }}})); } } else { } } string call_conv_attribute_suffix = ((call_conv).len != 0 ? (str_intp(2, _MOV((StrIntpData[]){{_S("__attribute__(("), 0xfe10, {.d_s = call_conv}}, {_S("))"), 0, { .d_c = 0 }}}))) : (_S(""))); string ret_typ = string__plus((!v__ast__Type_has_flag(func.return_type, v__ast__TypeFlag__option) && v__ast__Table_sym(g->table, func.return_type)->kind == v__ast__Kind__array_fixed ? (_S("_v_")) : (_S(""))), v__gen__c__Gen_styp(g, func.return_type)); { strings__Builder_write_string(&g->type_definitions, _S("typedef ")); strings__Builder_write_string(&g->type_definitions, ret_typ); strings__Builder_write_string(&g->type_definitions, _S(" (")); strings__Builder_write_string(&g->type_definitions, msvc_call_conv); strings__Builder_write_string(&g->type_definitions, _S("*")); strings__Builder_write_string(&g->type_definitions, fn_name); strings__Builder_write_string(&g->type_definitions, _S(")(")); } for (int i = 0; i < func.params.len; ++i) { v__ast__Param param = ((v__ast__Param*)func.params.data)[i]; strings__Builder_write_string(&g->type_definitions, v__gen__c__Gen_styp(g, param.typ)); if (i < (int)(func.params.len - 1)) { strings__Builder_write_string(&g->type_definitions, _S(",")); } } strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S(")"), 0xfe10, {.d_s = call_conv_attribute_suffix}}, {_S(";"), 0, { .d_c = 0 }}}))); } } void v__gen__c__Gen_write_array_fixed_return_types(v__gen__c__Gen* g) { Array_v__ast__TypeSymbol_ptr _t1 = {0}; Array_v__ast__TypeSymbol_ptr _t1_orig = g->table->type_symbols; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__TypeSymbol*)); for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__TypeSymbol* it = ((v__ast__TypeSymbol**) _t1_orig.data)[_t2]; if ((it->info)._typ == 549 /* v.ast.ArrayFixed */ && (*(v__ast__ArrayFixed*)__as_cast((it->info)._v__ast__ArrayFixed,(it->info)._typ, 549)).is_fn_ret && !v__ast__Type_has_flag((*(v__ast__ArrayFixed*)__as_cast((it->info)._v__ast__ArrayFixed,(it->info)._typ, 549)).elem_type, v__ast__TypeFlag__generic)) { array_push((array*)&_t1, &it); } } Array_v__ast__TypeSymbol_ptr fixed_arr_rets =_t1; if (fixed_arr_rets.len == 0) { return; } strings__Builder_writeln(&g->typedefs, _S("\n// BEGIN_array_fixed_return_typedefs")); strings__Builder_writeln(&g->type_definitions, _S("\n// BEGIN_array_fixed_return_structs")); for (int _t3 = 0; _t3 < fixed_arr_rets.len; ++_t3) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)fixed_arr_rets.data)[_t3]; v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549); if (info.size <= 0) { continue; } string fixed_elem_name = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(info.elem_type, 0)); if (v__ast__Type_is_ptr(info.elem_type)) { fixed_elem_name = string__plus(fixed_elem_name, string_repeat(_S("*"), v__ast__Type_nr_muls(info.elem_type))); } strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = sym->cname}}, {_S(" "), 0xfe10, {.d_s = sym->cname}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("struct "), 0xfe10, {.d_s = sym->cname}}, {_S(" {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = fixed_elem_name}}, {_S(" ret_arr["), 0xfe07, {.d_i32 = info.size}}, {_S("];"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, _S("};")); } strings__Builder_writeln(&g->typedefs, _S("// END_array_fixed_return_typedefs\n")); strings__Builder_writeln(&g->type_definitions, _S("// END_array_fixed_return_structs\n")); } void v__gen__c__Gen_write_multi_return_types(v__gen__c__Gen* g) { int start_pos = g->type_definitions.len; strings__Builder_writeln(&g->typedefs, _S("\n// BEGIN_multi_return_typedefs")); strings__Builder_writeln(&g->type_definitions, _S("\n// BEGIN_multi_return_structs")); Array_v__ast__TypeSymbol_ptr _t1 = {0}; Array_v__ast__TypeSymbol_ptr _t1_orig = g->table->type_symbols; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__TypeSymbol*)); for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__TypeSymbol* it = ((v__ast__TypeSymbol**) _t1_orig.data)[_t2]; if (it->kind == v__ast__Kind__multi_return && !string_contains(it->cname, _S("["))) { array_push((array*)&_t1, &it); } } Array_v__ast__TypeSymbol_ptr multi_rets =_t1; for (int _t3 = 0; _t3 < multi_rets.len; ++_t3) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)multi_rets.data)[_t3]; v__ast__MultiReturn info = v__ast__TypeSymbol_mr_info(sym); bool _t4 = false; Array_v__ast__Type _t4_orig = info.types; int _t4_len = _t4_orig.len; for (int _t5 = 0; _t5 < _t4_len; ++_t5) { v__ast__Type it = ((v__ast__Type*) _t4_orig.data)[_t5]; if (v__ast__Type_has_flag(it, v__ast__TypeFlag__generic)) { _t4 = true; break; } } if (_t4) { continue; } if (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = sym->cname}}, {_S(" "), 0xfe10, {.d_s = sym->cname}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("struct "), 0xfe10, {.d_s = sym->cname}}, {_S(" {"), 0, { .d_c = 0 }}}))); for (int i = 0; i < info.types.len; ++i) { v__ast__Type mr_typ = ((v__ast__Type*)info.types.data)[i]; string type_name = v__gen__c__Gen_styp(g, mr_typ); if (v__ast__Type_has_flag(mr_typ, v__ast__TypeFlag__option)) { multi_return_string_string mr_74044 = v__gen__c__Gen_option_type_name(g, mr_typ); string styp = mr_74044.arg0; string base = mr_74044.arg1; sync__RwMutex_lock(&g->done_options->mtx); /*lock*/ { if (!(Array_string_contains(g->done_options->val, base))) { array_push((array*)&g->done_options->val, _MOV((string[]){ string_clone(base) })); string last_text = string_clone(strings__Builder_after(&g->type_definitions, start_pos)); strings__Builder_go_back_to(&g->type_definitions, start_pos); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = styp}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_option_type_text(g, styp, base)}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_write_string(&g->type_definitions, last_text); } } sync__RwMutex_unlock(&g->done_options->mtx);; } if (v__ast__Type_has_flag(mr_typ, v__ast__TypeFlag__result)) { multi_return_string_string mr_74640 = v__gen__c__Gen_result_type_name(g, mr_typ); string styp = mr_74640.arg0; string base = mr_74640.arg1; sync__RwMutex_lock(&g->done_results->mtx); /*lock*/ { if (!(Array_string_contains(g->done_results->val, base))) { array_push((array*)&g->done_results->val, _MOV((string[]){ string_clone(base) })); string last_text = string_clone(strings__Builder_after(&g->type_definitions, start_pos)); strings__Builder_go_back_to(&g->type_definitions, start_pos); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = styp}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_result_type_text(g, styp, base)}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_write_string(&g->type_definitions, last_text); } } sync__RwMutex_unlock(&g->done_results->mtx);; } strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = type_name}}, {_S(" arg"), 0xfe07, {.d_i32 = i}}, {_S(";"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->type_definitions, _S("};\n")); } strings__Builder_writeln(&g->typedefs, _S("// END_multi_return_typedefs\n")); strings__Builder_writeln(&g->type_definitions, _S("// END_multi_return_structs\n")); } inline VV_LOC string v__gen__c__prefix_with_counter(string prefix, int counter) { strings__Builder sb = strings__new_builder((int)(prefix.len + 5)); strings__Builder_write_string(&sb, prefix); strings__Builder_write_decimal(&sb, counter); return strings__Builder_str(&sb); } string v__gen__c__Gen_new_tmp_var(v__gen__c__Gen* g) { g->tmp_count++; return v__gen__c__prefix_with_counter(_S("_t"), g->tmp_count); } int v__gen__c__Gen_reset_tmp_count(v__gen__c__Gen* g) { int old = g->tmp_count; g->tmp_count = 0; return old; } VV_LOC void v__gen__c__Gen_decrement_inside_ternary(v__gen__c__Gen* g) { string key = int_str(g->inside_ternary); Array_string _t1 = (*(Array_string*)map_get(ADDR(map, g->ternary_level_names), &(string[]){key}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })); for (int _t2 = 0; _t2 < _t1.len; ++_t2) { string name = ((string*)_t1.data)[_t2]; map_delete(&g->ternary_names, &(string[]){name}); } map_delete(&g->ternary_level_names, &(string[]){key}); g->inside_ternary--; } VV_LOC void v__gen__c__Gen_stmts(v__gen__c__Gen* g, Array_v__ast__Stmt stmts) { v__gen__c__Gen_stmts_with_tmp_var(g, stmts, _S("")); } VV_LOC bool v__gen__c__is_noreturn_callexpr(v__ast__Expr expr) { if ((expr)._typ == 344 /* v.ast.CallExpr */) { return (*expr._v__ast__CallExpr).is_noreturn; } return false; } VV_LOC bool v__gen__c__Gen_stmts_with_tmp_var(v__gen__c__Gen* g, Array_v__ast__Stmt stmts, string tmp_var) { g->indent++; if (g->inside_ternary > 0) { v__gen__c__Gen_write(g, _S("(")); } bool last_stmt_was_return = false; for (int i = 0; i < stmts.len; ++i) { v__ast__Stmt stmt = ((v__ast__Stmt*)stmts.data)[i]; if (i == (int)(stmts.len - 1)) { if ((stmt)._typ == 412 /* v.ast.Return */) { last_stmt_was_return = true; } } if (i == (int)(stmts.len - 1) && (tmp_var).len != 0) { if (g->inside_if_option || g->inside_match_option) { v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); g->skip_stmt_pos = true; if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { if ((*stmt._v__ast__ExprStmt).typ == 30 || ((*stmt._v__ast__ExprStmt).expr)._typ == 371 /* v.ast.None */) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_var}}, {_S(".state = 2;"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(".err = ")); } v__gen__c__Gen_expr(g, (*stmt._v__ast__ExprStmt).expr); v__gen__c__Gen_writeln(g, _S(";")); } else { string styp = v__gen__c__Gen_base_type(g, (*stmt._v__ast__ExprStmt).typ); #if defined(__TINYC__) && defined(TARGET_IS_32BIT) && defined(_WIN32) { if ((*stmt._v__ast__ExprStmt).typ == _const_v__ast__int_literal_type) { styp = _S("int"); } else if ((*stmt._v__ast__ExprStmt).typ == _const_v__ast__float_literal_type) { styp = _S("f64"); } } #endif if (v__ast__Type_has_flag((*stmt._v__ast__ExprStmt).typ, v__ast__TypeFlag__option) || (g->inside_if_option && ((*stmt._v__ast__ExprStmt).expr)._typ == 359 /* v.ast.IfExpr */)) { v__gen__c__Gen_writeln(g, _S("")); { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, (*stmt._v__ast__ExprStmt).expr); v__gen__c__Gen_writeln(g, _S(";")); } else { bool inside_assign_context = g->inside_struct_init || g->inside_assign || (!g->inside_return && g->inside_match_option); v__ast__Type ret_expr_typ = (inside_assign_context ? ((*stmt._v__ast__ExprStmt).typ) : (g->fn_decl->return_type)); v__ast__Type ret_typ = (inside_assign_context ? ((*stmt._v__ast__ExprStmt).typ) : (v__ast__Type_clear_flag(g->fn_decl->return_type, v__ast__TypeFlag__option))); styp = v__gen__c__Gen_base_type(g, ret_typ); if (((*stmt._v__ast__ExprStmt).expr)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast(((*stmt._v__ast__ExprStmt).expr)._v__ast__CallExpr,((*stmt._v__ast__ExprStmt).expr)._typ, 344)).is_noreturn) { v__gen__c__Gen_writeln(g, _S(";")); } else if (!v__ast__Type_has_option_or_result(ret_expr_typ) && !v__ast__Type_has_option_or_result((*stmt._v__ast__ExprStmt).typ) && g->last_if_option_type != 0 && !v__ast__Type_has_option_or_result(g->last_if_option_type)) { { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr_with_cast(g, (*stmt._v__ast__ExprStmt).expr, (*stmt._v__ast__ExprStmt).typ, ret_typ); v__gen__c__Gen_writeln(g, _S(";")); } else { { v__gen__c__Gen_write(g, _S("_option_ok(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) { ")); } v__gen__c__Gen_expr_with_cast(g, (*stmt._v__ast__ExprStmt).expr, (*stmt._v__ast__ExprStmt).typ, ret_typ); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)(&"), 0xfe10, {.d_s = tmp_var}}, {_S("), sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } } } } else if ((stmt)._typ == 412 /* v.ast.Return */) { v__gen__c__Gen_stmt(g, stmt); } } else if (g->inside_if_result || g->inside_match_result) { v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); g->skip_stmt_pos = true; if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { if ((*stmt._v__ast__ExprStmt).typ == 30) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_var}}, {_S(".is_error = true;"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(".err = ")); } v__gen__c__Gen_expr(g, (*stmt._v__ast__ExprStmt).expr); v__gen__c__Gen_writeln(g, _S(";")); } else { string styp = v__gen__c__Gen_base_type(g, (*stmt._v__ast__ExprStmt).typ); #if defined(__TINYC__) && defined(TARGET_IS_32BIT) && defined(_WIN32) { if ((*stmt._v__ast__ExprStmt).typ == _const_v__ast__int_literal_type) { styp = _S("int"); } else if ((*stmt._v__ast__ExprStmt).typ == _const_v__ast__float_literal_type) { styp = _S("f64"); } } #endif if (v__ast__Type_has_flag((*stmt._v__ast__ExprStmt).typ, v__ast__TypeFlag__result)) { v__gen__c__Gen_writeln(g, _S("")); { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, (*stmt._v__ast__ExprStmt).expr); v__gen__c__Gen_writeln(g, _S(";")); } else { v__ast__Type ret_typ = v__ast__Type_clear_flag(g->fn_decl->return_type, v__ast__TypeFlag__result); styp = v__gen__c__Gen_base_type(g, ret_typ); if (((*stmt._v__ast__ExprStmt).expr)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast(((*stmt._v__ast__ExprStmt).expr)._v__ast__CallExpr,((*stmt._v__ast__ExprStmt).expr)._typ, 344)).is_noreturn) { v__gen__c__Gen_expr(g, (*stmt._v__ast__ExprStmt).expr); v__gen__c__Gen_writeln(g, _S(";")); } else { { v__gen__c__Gen_write(g, _S("_result_ok(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) { ")); } v__gen__c__Gen_expr_with_cast(g, (*stmt._v__ast__ExprStmt).expr, (*stmt._v__ast__ExprStmt).typ, ret_typ); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("*)(&"), 0xfe10, {.d_s = tmp_var}}, {_S("), sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } } } } else if ((stmt)._typ == 412 /* v.ast.Return */) { v__gen__c__Gen_stmt(g, stmt); } } else { bool is_array_fixed_init = false; v__ast__Type ret_type = _const_v__ast__void_type; v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); g->skip_stmt_pos = true; bool is_noreturn = false; if ((stmt)._typ == 412 /* v.ast.Return */ || (stmt)._typ == 394 /* v.ast.BranchStmt */) { is_noreturn = true; } else if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { is_noreturn = v__gen__c__is_noreturn_callexpr((*stmt._v__ast__ExprStmt).expr); if (((*stmt._v__ast__ExprStmt).expr)._typ == 338 /* v.ast.ArrayInit */ && (*(v__ast__ArrayInit*)__as_cast(((*stmt._v__ast__ExprStmt).expr)._v__ast__ArrayInit,((*stmt._v__ast__ExprStmt).expr)._typ, 338)).is_fixed) { is_array_fixed_init = true; ret_type = (*(*stmt._v__ast__ExprStmt).expr._v__ast__ArrayInit).typ; } } if (!is_noreturn) { if (is_array_fixed_init) { { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(", (")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, ret_type)); v__gen__c__Gen_write(g, _S(")")); } } else { { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } } } v__gen__c__Gen_stmt(g, stmt); if (is_array_fixed_init) { string lines = string_trim_right(v__gen__c__Gen_go_before_last_stmt(g), _S("; \n")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = lines}}, {_S(", sizeof("), 0xfe10, {.d_s = tmp_var}}, {_S("));"), 0, { .d_c = 0 }}}))); } if (!string_contains(strings__Builder_last_n(&g->out, 2), _S(";"))) { v__gen__c__Gen_writeln(g, _S(";")); } } } else { if (i > 0 && (stmt)._typ == 412 /* v.ast.Return */) { v__ast__Stmt last_stmt = (*(v__ast__Stmt*)array_get(stmts, (int)(i - 1))); if ((last_stmt)._typ == 401 /* v.ast.ExprStmt */ && ((*(v__ast__ExprStmt*)__as_cast((last_stmt)._v__ast__ExprStmt,(last_stmt)._typ, 401)).expr)._typ == 344 /* v.ast.CallExpr */ && !string_contains(strings__Builder_last_n(&g->out, 2), _S(";"))) { v__gen__c__Gen_writeln(g, _S(";")); } } v__gen__c__Gen_stmt(g, stmt); if ((stmt)._typ == 401 /* v.ast.ExprStmt */ && (g->inside_if_option || g->inside_if_result || g->inside_match_option || g->inside_match_result || (((*(v__ast__ExprStmt*)__as_cast((stmt)._v__ast__ExprStmt,(stmt)._typ, 401)).expr)._typ == 361 /* v.ast.IndexExpr */ && (*(v__ast__IndexExpr*)__as_cast(((*(v__ast__ExprStmt*)__as_cast((stmt)._v__ast__ExprStmt,(stmt)._typ, 401)).expr)._v__ast__IndexExpr,((*(v__ast__ExprStmt*)__as_cast((stmt)._v__ast__ExprStmt,(stmt)._typ, 401)).expr)._typ, 361)).or_expr.kind != v__ast__OrKind__absent))) { v__gen__c__Gen_writeln(g, _S(";")); } } g->skip_stmt_pos = false; if (g->inside_ternary > 0 && i < (int)(stmts.len - 1)) { v__gen__c__Gen_write(g, _S(",")); } } g->indent--; if (g->inside_ternary > 0) { v__gen__c__Gen_write2(g, _S(""), _S(")")); } if (g->is_autofree && !g->inside_vweb_tmpl && stmts.len > 0) { v__ast__Stmt stmt = (*(v__ast__Stmt*)array_get(stmts, 0)); if ((stmt)._typ != 237 /* v.ast.FnDecl */ && g->inside_ternary == 0) { v__token__Pos stmt_pos = (*(stmt.pos)); if (stmt_pos.pos == 0) { if ((stmt)._typ == 411 /* v.ast.Module */) { return last_stmt_was_return; } if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { stmt_pos = v__ast__Expr_pos((*stmt._v__ast__ExprStmt).expr); } if (stmt_pos.pos == 0) { #if defined(CUSTOM_DEFINE_trace_autofree) { println(str_intp(2, _MOV((StrIntpData[]){{_S("autofree: first stmt pos = 0. "), 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_sumtype_v__ast__Stmt( (stmt)._typ ))}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif return last_stmt_was_return; } } v__gen__c__Gen_autofree_scope_vars(g, (int)(stmt_pos.pos - 1), stmt_pos.line_nr, false); } } return last_stmt_was_return; } VV_LOC void v__gen__c__Gen_expr_with_tmp_var(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_typ, v__ast__Type ret_typ, string tmp_var) { if (!v__ast__Type_has_option_or_result(ret_typ)) { _v_panic(_S("cgen: parameter `ret_typ` of function `expr_with_tmp_var()` must be an Option or Result")); VUNREACHABLE(); } string stmt_str = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); string styp = v__gen__c__Gen_base_type(g, ret_typ); g->empty_line = true; v__ast__TypeSymbol* final_expr_sym = v__ast__Table_final_sym(g->table, expr_typ); if (final_expr_sym->kind == v__ast__Kind__none) { { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, ret_typ)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_gen_option_error(g, ret_typ, expr); v__gen__c__Gen_writeln(g, _S(";")); } else if ((expr)._typ == 358 /* v.ast.Ident */ && expr_typ == _const_v__ast__error_type) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, ret_typ)}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(" = {.state=2, .err="), 0xfe10, {.d_s = (*expr._v__ast__Ident).name}}, {_S("};"), 0, { .d_c = 0 }}}))); } else { bool simple_assign = false; bool expr_typ_is_option = v__ast__Type_has_flag(expr_typ, v__ast__TypeFlag__option); bool ret_typ_is_option = v__ast__Type_has_flag(ret_typ, v__ast__TypeFlag__option); if (v__ast__Type_has_flag(ret_typ, v__ast__TypeFlag__generic)) { if ((expr)._typ == 379 /* v.ast.SelectorExpr */ && g->cur_concrete_types.len == 0) { if (((*expr._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */) { if (((*(*expr._v__ast__SelectorExpr).expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { if (((*(*(*expr._v__ast__SelectorExpr).expr._v__ast__Ident).obj._v__ast__Var).expr)._typ == 385 /* v.ast.StructInit */) { v__ast__TypeInfo struct_info = v__ast__Table_sym(g->table, (*(*(*expr._v__ast__SelectorExpr).expr._v__ast__Ident).obj._v__ast__Var).typ)->info; if ((struct_info)._typ == 518 /* v.ast.Struct */) { _PUSH_MANY(&g->cur_concrete_types, ((*struct_info._v__ast__Struct).concrete_types), _t1, Array_v__ast__Type); } } } } } v__ast__Type unwrapped_ret_typ = v__gen__c__Gen_unwrap_generic(g, ret_typ); styp = v__gen__c__Gen_base_type(g, unwrapped_ret_typ); string ret_styp = string_replace(v__gen__c__Gen_styp(g, unwrapped_ret_typ), _S("*"), _S("_ptr")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_styp}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { if (v__ast__Type_has_flag(ret_typ, v__ast__TypeFlag__option_mut_param_t)) { string ret_styp = string_replace(v__gen__c__Gen_styp(g, ret_typ), _S("*"), _S("")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_styp}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, ret_typ)}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); } } bool expr_is_fixed_array_var = false; bool fn_option_clone = false; if (ret_typ_is_option) { if (expr_typ_is_option && ((expr)._typ == 385 /* v.ast.StructInit */ || (expr)._typ == 338 /* v.ast.ArrayInit */ || (expr)._typ == 368 /* v.ast.MapInit */)) { simple_assign = (expr)._typ == 385 /* v.ast.StructInit */; if (simple_assign) { { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } } else { { v__gen__c__Gen_write(g, _S("_option_none(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) { ")); } } } else { simple_assign = (((expr)._typ == 379 /* v.ast.SelectorExpr */ || ((expr)._typ == 358 /* v.ast.Ident */ && !v__ast__Ident_is_auto_heap(((v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358))))) && v__ast__Type_is_ptr(ret_typ) && v__ast__Type_is_ptr(expr_typ) && expr_typ_is_option) || (expr_typ == ret_typ && !(v__ast__Type_has_option_or_result(expr_typ) && (v__ast__Type_is_ptr(expr_typ) || (expr)._typ == 365 /* v.ast.LambdaExpr */))); if (simple_assign) { { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } } else if (expr_typ_is_option && (expr)._typ == 376 /* v.ast.PrefixExpr */ && ((*(v__ast__PrefixExpr*)__as_cast((expr)._v__ast__PrefixExpr,(expr)._typ, 376)).right)._typ == 385 /* v.ast.StructInit */ && (*(v__ast__StructInit*)__as_cast(((*(v__ast__PrefixExpr*)__as_cast((expr)._v__ast__PrefixExpr,(expr)._typ, 376)).right)._v__ast__StructInit,((*(v__ast__PrefixExpr*)__as_cast((expr)._v__ast__PrefixExpr,(expr)._typ, 376)).right)._typ, 385)).init_fields.len == 0) { { v__gen__c__Gen_write(g, _S("_option_none(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) { ")); } } else if (((expr)._typ == 358 /* v.ast.Ident */ || (expr)._typ == 379 /* v.ast.SelectorExpr */) && final_expr_sym->kind == v__ast__Kind__array_fixed) { expr_is_fixed_array_var = true; v__gen__c__Gen_write(g, _S("_option_ok(&")); } else { { v__gen__c__Gen_write(g, _S("_option_ok(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) { ")); } if ((final_expr_sym->info)._typ == 553 /* v.ast.FnType */) { v__ast__TypeSymbol* final_ret_sym = v__ast__Table_final_sym(g->table, ret_typ); if ((final_ret_sym->info)._typ == 553 /* v.ast.FnType */) { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write_fn_ptr_decl(g, &(*final_ret_sym->info._v__ast__FnType), _S("")); v__gen__c__Gen_write(g, _S(")")); fn_option_clone = (expr)._typ == 379 /* v.ast.SelectorExpr */ && v__ast__Type_has_flag(expr_typ, v__ast__TypeFlag__option); } } } if (!v__ast__Expr_is_literal(expr) && expr_typ != _const_v__ast__nil_type && v__ast__Type_nr_muls(ret_typ) > v__ast__Type_nr_muls(expr_typ) && !v__ast__Type_has_flag(ret_typ, v__ast__TypeFlag__option_mut_param_t)) { v__gen__c__Gen_write(g, string_repeat(_S("&"), (int)(v__ast__Type_nr_muls(ret_typ) - v__ast__Type_nr_muls(expr_typ)))); } else if (v__ast__Type_has_flag(ret_typ, v__ast__TypeFlag__option_mut_param_t)) { if (v__ast__Type_is_ptr(expr_typ)) { if (v__ast__Type_nr_muls(ret_typ) < v__ast__Type_nr_muls(expr_typ)) { v__gen__c__Gen_write(g, _S("*")); } } else { if (v__ast__Type_has_flag(expr_typ, v__ast__TypeFlag__option)) { fn_option_clone = true; { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_write(g, _S("&")); } } } } else { { v__gen__c__Gen_write(g, _S("_result_ok(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) { ")); } } v__gen__c__Gen_expr_with_cast(g, expr, expr_typ, ret_typ); if (fn_option_clone) { v__gen__c__Gen_write(g, _S(".data")); } if (ret_typ_is_option) { if (simple_assign) { v__gen__c__Gen_writeln(g, _S(";")); } else if (expr_is_fixed_array_var) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(", ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)(&"), 0xfe10, {.d_s = tmp_var}}, {_S("), sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)(&"), 0xfe10, {.d_s = tmp_var}}, {_S("), sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("*)(&"), 0xfe10, {.d_s = tmp_var}}, {_S("), sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } v__gen__c__Gen_write2(g, stmt_str, _S(" ")); v__gen__c__Gen_write(g, tmp_var); } inline VV_LOC void v__gen__c__Gen_write_v_source_line_info_pos(v__gen__c__Gen* g, v__token__Pos pos) { if (g->inside_ternary == 0 && g->pref->is_vlines && g->is_vlines_enabled) { int nline = (int)(pos.line_nr + 1); string lineinfo = str_intp(3, _MOV((StrIntpData[]){{_S("\n#line "), 0xfe07, {.d_i32 = nline}}, {_S(" \""), 0xfe10, {.d_s = g->vlines_path}}, {_S("\""), 0, { .d_c = 0 }}})); #if defined(CUSTOM_DEFINE_trace_gen_source_line_info) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> lineinfo: "), 0xfe10, {.d_s = string_replace(lineinfo, _S("\n"), _S(""))}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__gen__c__Gen_writeln(g, lineinfo); } } inline VV_LOC void v__gen__c__Gen_write_v_source_line_info(v__gen__c__Gen* g, v__ast__Node node) { v__gen__c__Gen_write_v_source_line_info_pos(g, v__ast__Node_pos(node)); if (g->inside_ternary == 0 && g->pref->is_coverage && !((node)._typ == 428 /* v.ast.MatchBranch */ || (node)._typ == 427 /* v.ast.IfBranch */ || (node)._typ == 362 /* v.ast.InfixExpr */)) { v__gen__c__Gen_write_coverage_point(g, v__ast__Node_pos(node)); } } inline VV_LOC void v__gen__c__Gen_write_v_source_line_info_stmt(v__gen__c__Gen* g, v__ast__Stmt stmt) { v__gen__c__Gen_write_v_source_line_info_pos(g, (*(stmt.pos))); if (g->inside_ternary == 0 && g->pref->is_coverage && !g->inside_for_c_stmt && !((stmt)._typ == 237 /* v.ast.FnDecl */ || (stmt)._typ == 402 /* v.ast.ForCStmt */ || (stmt)._typ == 403 /* v.ast.ForInStmt */ || (stmt)._typ == 404 /* v.ast.ForStmt */)) { if ((stmt)._typ == 391 /* v.ast.AssertStmt */) { if (!(((*stmt._v__ast__AssertStmt).expr)._typ == 362 /* v.ast.InfixExpr */ || ((*stmt._v__ast__AssertStmt).expr)._typ == 369 /* v.ast.MatchExpr */)) { v__gen__c__Gen_write_coverage_point(g, (*stmt._v__ast__AssertStmt).pos); } } else { v__gen__c__Gen_write_coverage_point(g, (*(stmt.pos))); } } } VV_LOC void v__gen__c__Gen_stmt(v__gen__c__Gen* g, v__ast__Stmt node) { bool v__gen__c__Gen_stmt_defer_0 = false; bool old_inside_call; #if defined(CUSTOM_DEFINE_trace_cgen_stmt) { string ntype = string_replace(charptr_vstring_literal(v_typeof_sumtype_v__ast__Stmt( (node)._typ )), _S("v.ast."), _S("")); if (g->file == ((void*)0)) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S("cgen: | pos: "), 0x4efe10, {.d_s = v__token__Pos_line_str((*(node.pos)))}}, {_S(" | node: "), 0xfe10, {.d_s = ntype}}, {_S(" | "), 0xfe10, {.d_s = v__ast__Stmt_str(node)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else { eprintln(str_intp(5, _MOV((StrIntpData[]){{_S("cgen: "), 0x3cfe10, {.d_s = g->file->path}}, {_S(" | pos: "), 0x4efe10, {.d_s = v__token__Pos_line_str((*(node.pos)))}}, {_S(" | node: "), 0xfe10, {.d_s = ntype}}, {_S(" | "), 0xfe10, {.d_s = v__ast__Stmt_str(node)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } #endif old_inside_call = g->inside_call; g->inside_call = false; v__gen__c__Gen_stmt_defer_0 = true; if (!g->skip_stmt_pos) { v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } if (node._typ == 237 /* v.ast.FnDecl */) { v__gen__c__Gen_fn_decl(g, (*node._v__ast__FnDecl)); } else if (node._typ == 393 /* v.ast.Block */) { v__gen__c__Gen_write_v_source_line_info_stmt(g, node); if (!(*node._v__ast__Block).is_unsafe) { v__gen__c__Gen_writeln(g, _S("{")); } else { if (g->pref->is_prod) { v__gen__c__Gen_writeln(g, _S("{")); } else { v__gen__c__Gen_writeln(g, _S("{ // Unsafe block")); } } v__gen__c__Gen_stmts(g, (*node._v__ast__Block).stmts); v__gen__c__Gen_writeln(g, _S("}")); } else if (node._typ == 392 /* v.ast.AssignStmt */) { v__gen__c__Gen_write_v_source_line_info_stmt(g, node); v__gen__c__Gen_assign_stmt(g, (*node._v__ast__AssignStmt)); } else if (node._typ == 391 /* v.ast.AssertStmt */) { v__gen__c__Gen_write_v_source_line_info_stmt(g, node); v__gen__c__Gen_assert_stmt(g, (*node._v__ast__AssertStmt)); } else if (node._typ == 396 /* v.ast.ConstDecl */) { v__gen__c__Gen_write_v_source_line_info_stmt(g, node); v__gen__c__Gen_const_decl(g, (*node._v__ast__ConstDecl)); } else if (node._typ == 395 /* v.ast.ComptimeFor */) { v__gen__c__Gen_comptime_for(g, (*node._v__ast__ComptimeFor)); } else if (node._typ == 394 /* v.ast.BranchStmt */) { v__gen__c__Gen_write_v_source_line_info_stmt(g, node); v__gen__c__Gen_branch_stmt(g, (*node._v__ast__BranchStmt)); } else if (node._typ == 401 /* v.ast.ExprStmt */) { v__gen__c__Gen_write_v_source_line_info_stmt(g, node); bool old_is_void_expr_stmt = g->is_void_expr_stmt; g->is_void_expr_stmt = !(*node._v__ast__ExprStmt).is_expr; if (v__ast__Expr_is_auto_deref_var((*node._v__ast__ExprStmt).expr)) { v__gen__c__Gen_write(g, _S("*")); } if ((*node._v__ast__ExprStmt).typ != _const_v__ast__void_type && g->expected_cast_type != 0 && !(((*node._v__ast__ExprStmt).expr)._typ == 359 /* v.ast.IfExpr */ || ((*node._v__ast__ExprStmt).expr)._typ == 369 /* v.ast.MatchExpr */)) { v__gen__c__Gen_expr_with_cast(g, (*node._v__ast__ExprStmt).expr, (*node._v__ast__ExprStmt).typ, g->expected_cast_type); } else { v__gen__c__Gen_expr(g, (*node._v__ast__ExprStmt).expr); } g->is_void_expr_stmt = old_is_void_expr_stmt; if (g->inside_ternary == 0 && !g->inside_if_option && !g->inside_match_option && !g->inside_if_result && !g->inside_match_result && !(*node._v__ast__ExprStmt).is_expr && ((*node._v__ast__ExprStmt).expr)._typ != 359 /* v.ast.IfExpr */) { if (((*node._v__ast__ExprStmt).expr)._typ == 369 /* v.ast.MatchExpr */) { v__gen__c__Gen_writeln(g, _S("")); } else { v__gen__c__Gen_writeln(g, _S(";")); } } } else if (node._typ == 402 /* v.ast.ForCStmt */) { int prev_branch_parent_pos = g->branch_parent_pos; g->branch_parent_pos = (*node._v__ast__ForCStmt).pos.pos; v__ast__Stmt* save_inner_loop = g->inner_loop; g->inner_loop = HEAP(v__ast__Stmt, v__ast__ForCStmt_to_sumtype_v__ast__Stmt(&(*node._v__ast__ForCStmt))); if (((*node._v__ast__ForCStmt).label).len != 0) { { // Unsafe block map_set(&g->labeled_loops, &(string[]){(*node._v__ast__ForCStmt).label}, &(v__ast__Stmt*[]) { HEAP(v__ast__Stmt, v__ast__ForCStmt_to_sumtype_v__ast__Stmt(&(*node._v__ast__ForCStmt))) }); } } v__gen__c__Gen_write_v_source_line_info_stmt(g, node); v__gen__c__Gen_for_c_stmt(g, (*node._v__ast__ForCStmt)); g->branch_parent_pos = prev_branch_parent_pos; map_delete(&g->labeled_loops, &(string[]){(*node._v__ast__ForCStmt).label}); g->inner_loop = save_inner_loop; } else if (node._typ == 403 /* v.ast.ForInStmt */) { int prev_branch_parent_pos = g->branch_parent_pos; g->branch_parent_pos = (*node._v__ast__ForInStmt).pos.pos; v__ast__Stmt* save_inner_loop = g->inner_loop; g->inner_loop = HEAP(v__ast__Stmt, v__ast__ForInStmt_to_sumtype_v__ast__Stmt(&(*node._v__ast__ForInStmt))); if (((*node._v__ast__ForInStmt).label).len != 0) { { // Unsafe block map_set(&g->labeled_loops, &(string[]){(*node._v__ast__ForInStmt).label}, &(v__ast__Stmt*[]) { HEAP(v__ast__Stmt, v__ast__ForInStmt_to_sumtype_v__ast__Stmt(&(*node._v__ast__ForInStmt))) }); } } v__gen__c__Gen_write_v_source_line_info_stmt(g, node); v__gen__c__Gen_for_in_stmt(g, (*node._v__ast__ForInStmt)); g->branch_parent_pos = prev_branch_parent_pos; map_delete(&g->labeled_loops, &(string[]){(*node._v__ast__ForInStmt).label}); g->inner_loop = save_inner_loop; } else if (node._typ == 404 /* v.ast.ForStmt */) { int prev_branch_parent_pos = g->branch_parent_pos; g->branch_parent_pos = (*node._v__ast__ForStmt).pos.pos; v__ast__Stmt* save_inner_loop = g->inner_loop; g->inner_loop = HEAP(v__ast__Stmt, v__ast__ForStmt_to_sumtype_v__ast__Stmt(&(*node._v__ast__ForStmt))); if (((*node._v__ast__ForStmt).label).len != 0) { { // Unsafe block map_set(&g->labeled_loops, &(string[]){(*node._v__ast__ForStmt).label}, &(v__ast__Stmt*[]) { HEAP(v__ast__Stmt, v__ast__ForStmt_to_sumtype_v__ast__Stmt(&(*node._v__ast__ForStmt))) }); } } v__gen__c__Gen_write_v_source_line_info_stmt(g, node); v__gen__c__Gen_for_stmt(g, (*node._v__ast__ForStmt)); g->branch_parent_pos = prev_branch_parent_pos; map_delete(&g->labeled_loops, &(string[]){(*node._v__ast__ForStmt).label}); g->inner_loop = save_inner_loop; } else if (node._typ == 412 /* v.ast.Return */) { v__gen__c__Gen_return_stmt(g, (*node._v__ast__Return)); } else if (node._typ == 398 /* v.ast.DeferStmt */) { v__ast__DeferStmt defer_stmt = (*node._v__ast__DeferStmt); defer_stmt.ifdef = g->defer_ifdef; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_defer_flag_var(g, (voidptr)&defer_stmt)}}, {_S(" = true;"), 0, { .d_c = 0 }}}))); array_push((array*)&g->defer_stmts, _MOV((v__ast__DeferStmt[]){ defer_stmt })); } else if (node._typ == 400 /* v.ast.EnumDecl */) { v__gen__c__Gen_enum_decl(g, (*node._v__ast__EnumDecl)); } else if (node._typ == 405 /* v.ast.GlobalDecl */) { v__gen__c__Gen_global_decl(g, (*node._v__ast__GlobalDecl)); } else if (node._typ == 409 /* v.ast.Import */) { } else if (node._typ == 410 /* v.ast.InterfaceDecl */) { v__ast__TypeSymbol* ts = v__ast__Table_sym(g->table, (*node._v__ast__InterfaceDecl).typ); if (!(*(v__ast__Interface*)__as_cast((ts->info)._v__ast__Interface,(ts->info)._typ, 542)).is_generic && (!g->pref->skip_unused || _IN_MAP(ADDR(int, ts->idx), ADDR(map, g->table->used_features->used_syms)))) { for (int _t3 = 0; _t3 < (*node._v__ast__InterfaceDecl).methods.len; ++_t3) { v__ast__FnDecl method = ((v__ast__FnDecl*)(*node._v__ast__InterfaceDecl).methods.data)[_t3]; if (v__ast__Type_has_flag(method.return_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_register_option(g, method.return_type); } else if (v__ast__Type_has_flag(method.return_type, v__ast__TypeFlag__result)) { if (g->pref->skip_unused && !_IN_MAP(ADDR(int, v__ast__Table_sym(g->table, method.return_type)->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } v__gen__c__Gen_register_result(g, method.return_type); } } } } else if (node._typ == 415 /* v.ast.StructDecl */) { string name = ((*node._v__ast__StructDecl).language == v__ast__Language__c ? (v__util__no_dots((*node._v__ast__StructDecl).name)) : (fast_string_eq((*node._v__ast__StructDecl).name, _S("array")) || fast_string_eq((*node._v__ast__StructDecl).name, _S("string"))) ? ((*node._v__ast__StructDecl).name) : ((*node._v__ast__StructDecl).scoped_name).len != 0 ? (v__gen__c__c_name((*node._v__ast__StructDecl).scoped_name)) : (v__gen__c__c_name((*node._v__ast__StructDecl).name))); if ((*node._v__ast__StructDecl).language == v__ast__Language__c) { // Defer begin if (v__gen__c__Gen_stmt_defer_0) { g->inside_call = old_inside_call; } // Defer end return; } if (g->pref->skip_unused && !_IN_MAP(ADDR(int, (*node._v__ast__StructDecl).idx), ADDR(map, g->table->used_features->used_syms))) { // Defer begin if (v__gen__c__Gen_stmt_defer_0) { g->inside_call = old_inside_call; } // Defer end return; } if ((*node._v__ast__StructDecl).is_union) { strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef union "), 0xfe10, {.d_s = name}}, {_S(" "), 0xfe10, {.d_s = name}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = name}}, {_S(" "), 0xfe10, {.d_s = name}}, {_S(";"), 0, { .d_c = 0 }}}))); } } else if (node._typ == 406 /* v.ast.GotoLabel */) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name((*node._v__ast__GotoLabel).name)}}, {_S(": {}"), 0, { .d_c = 0 }}}))); } else if (node._typ == 407 /* v.ast.GotoStmt */) { v__gen__c__Gen_write_v_source_line_info_stmt(g, node); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("goto "), 0xfe10, {.d_s = v__gen__c__c_name((*node._v__ast__GotoStmt).name)}}, {_S(";"), 0, { .d_c = 0 }}}))); } else if (node._typ == 390 /* v.ast.AsmStmt */) { if (g->is_cc_msvc) { v__gen__c__Gen_error(g, _S("msvc does not support inline assembly"), (*node._v__ast__AsmStmt).pos); VUNREACHABLE(); } v__gen__c__Gen_write_v_source_line_info_stmt(g, node); v__gen__c__Gen_asm_stmt(g, (*node._v__ast__AsmStmt)); } else if (node._typ == 408 /* v.ast.HashStmt */) { v__gen__c__Gen_hash_stmt(g, (*node._v__ast__HashStmt)); } else if (node._typ == 334 /* v.ast.TypeDecl */) { if (!g->pref->skip_unused) { v__gen__c__Gen_writeln(g, _S("// TypeDecl")); } } else if (node._typ == 413 /* v.ast.SemicolonStmt */) { v__gen__c__Gen_writeln(g, _S(";")); } else if (node._typ == 414 /* v.ast.SqlStmt */) { v__gen__c__Gen_sql_stmt(g, (*node._v__ast__SqlStmt)); } else if (node._typ == 411 /* v.ast.Module */) { g->is_builtin_mod = v__util__module_is_builtin((*node._v__ast__Module).name); g->cur_mod = (*node._v__ast__Module); } else if (node._typ == 399 /* v.ast.EmptyStmt */) { } else if (node._typ == 397 /* v.ast.DebuggerStmt */) { v__gen__c__Gen_debugger_stmt(g, (*node._v__ast__DebuggerStmt)); } else if (node._typ == 335 /* v.ast.NodeError */) { } if (!g->skip_stmt_pos) { array_delete_last(&g->stmt_path_pos); } // Defer begin if (v__gen__c__Gen_stmt_defer_0) { g->inside_call = old_inside_call; } // Defer end } VV_LOC void v__gen__c__Gen_write_defer_stmts(v__gen__c__Gen* g) { for (int i = (int)(g->defer_stmts.len - 1); i >= 0; i--) { v__ast__DeferStmt defer_stmt = (*(v__ast__DeferStmt*)array_get(g->defer_stmts, i)); if (!g->pref->is_prod) { v__gen__c__Gen_writeln(g, _S("// Defer begin")); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = v__gen__c__Gen_defer_flag_var(g, (voidptr)&defer_stmt)}}, {_S(") {"), 0, { .d_c = 0 }}}))); if (defer_stmt.ifdef.len > 0) { v__gen__c__Gen_writeln(g, defer_stmt.ifdef); v__gen__c__Gen_stmts(g, defer_stmt.stmts); v__gen__c__Gen_writeln2(g, _S(""), _S("#endif")); } else { v__gen__c__Gen_stmts(g, defer_stmt.stmts); } v__gen__c__Gen_writeln(g, _S("}")); if (!g->pref->is_prod) { v__gen__c__Gen_writeln(g, _S("// Defer end")); } } } VV_LOC string v__gen__c__Gen_get_sumtype_casting_fn(v__gen__c__Gen* g, v__ast__Type got_, v__ast__Type exp_) { v__ast__Type got = v__ast__Type_idx_type(got_); v__ast__Type exp = v__ast__Type_idx_type(exp_); int i = (((((int)(got)) | ((int)((((u32)(exp)) << 18U)))) | ((int)(((u32[]){(v__ast__Type_has_flag(exp_, v__ast__TypeFlag__option))?1:0}[0] << 17U)))) | ((int)(((u32[]){(v__ast__Type_has_flag(got_, v__ast__TypeFlag__option))?1:0}[0] << 16U)))); v__ast__TypeSymbol* exp_sym = v__ast__Table_sym(g->table, exp); v__ast__TypeSymbol* got_sym = v__ast__Table_sym(g->table, got); string cname = (exp == 8 ? (_const_v__ast__int_type_name) : (v__gen__c__Gen_get_sumtype_variant_name(g, exp_, *exp_sym))); string sumtype_variant_name = v__gen__c__Gen_get_sumtype_variant_name(g, got_, *got_sym); string fn_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sumtype_variant_name}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = cname}}, {_SLIT0, 0, { .d_c = 0 }}})); if (g->pref->experimental && string_contains(fn_name, _S("v__ast__Struct_to_sumtype_v__ast__TypeInfo"))) { print_backtrace(); eprintln(_S("======\n\n")); } if (got == exp || (*(bool*)map_get(ADDR(map, g->sumtype_definitions), &(int[]){i}, &(bool[]){ 0 }))) { return fn_name; } for (;;) { if (!(got_sym->parent_idx != 0 && !(Array_v__ast__Type_contains((*(v__ast__SumType*)__as_cast((exp_sym->info)._v__ast__SumType,(exp_sym->info)._typ, 544)).variants, got_sym->idx)))) break; got_sym = v__ast__Table_sym(g->table, v__ast__idx_to_type(got_sym->parent_idx)); } map_set(&g->sumtype_definitions, &(int[]){i}, &(bool[]) { true }); v__ast__Type _t3; /* if prepend */ if (v__ast__Type_has_flag(got_, v__ast__TypeFlag__option)) { v__ast__Type new_got = v__ast__Type_set_flag(v__ast__idx_to_type(got_sym->idx), v__ast__TypeFlag__option); _t3 = new_got; } else { _t3 = got_sym->idx; } v__ast__Type _t4; /* if prepend */ if (v__ast__Type_has_flag(exp_, v__ast__TypeFlag__option)) { v__ast__Type new_exp = v__ast__Type_set_flag(exp, v__ast__TypeFlag__option); _t4 = new_exp; } else { _t4 = exp; } array_push((array*)&g->sumtype_casting_fns, _MOV((v__gen__c__SumtypeCastingFn[]){ ((v__gen__c__SumtypeCastingFn){.fn_name = fn_name,.got = _t3,.exp = _t4,}) })); return fn_name; } VV_LOC void v__gen__c__Gen_write_sumtype_casting_fn(v__gen__c__Gen* g, v__gen__c__SumtypeCastingFn fun) { v__ast__Type got = fun.got; v__ast__Type exp = fun.exp; v__ast__TypeSymbol* got_sym = v__ast__Table_sym(g->table, got); v__ast__TypeSymbol* exp_sym = v__ast__Table_sym(g->table, exp); string got_cname = v__gen__c__Gen_get_sumtype_variant_type_name(g, got, *got_sym); string exp_cname = exp_sym->cname; string type_idx = v__gen__c__Gen_type_sidx(g, got); strings__Builder sb = strings__new_builder(128); string variant_name = v__gen__c__Gen_get_sumtype_variant_name(g, got, *got_sym); if ((got_sym->info)._typ == 553 /* v.ast.FnType */) { string got_name = str_intp(2, _MOV((StrIntpData[]){{_S("fn "), 0xfe10, {.d_s = v__ast__Table_fn_type_source_signature(g->table, (voidptr)&(*got_sym->info._v__ast__FnType).func)}}, {_SLIT0, 0, { .d_c = 0 }}})); got_cname = str_intp(2, _MOV((StrIntpData[]){{_S("anon_fn_"), 0xfe10, {.d_s = v__ast__Table_fn_type_signature(g->table, (voidptr)&(*got_sym->info._v__ast__FnType).func)}}, {_SLIT0, 0, { .d_c = 0 }}})); type_idx = int_str((*(int*)map_get(ADDR(map, g->table->type_idxs), &(string[]){got_name}, &(int[]){ 0 }))); v__ast__SumType exp_info = *(v__ast__SumType*)__as_cast((exp_sym->info)._v__ast__SumType,(exp_sym->info)._typ, 544); for (int _t1 = 0; _t1 < exp_info.variants.len; ++_t1) { v__ast__Type variant = ((v__ast__Type*)exp_info.variants.data)[_t1]; v__ast__TypeSymbol* variant_sym = v__ast__Table_sym(g->table, variant); if ((variant_sym->info)._typ == 553 /* v.ast.FnType */) { if (string__eq(v__ast__Table_fn_type_source_signature(g->table, (voidptr)&(*variant_sym->info._v__ast__FnType).func), v__ast__Table_fn_type_source_signature(g->table, (voidptr)&(*got_sym->info._v__ast__FnType).func))) { variant_name = v__gen__c__Gen_get_sumtype_variant_name(g, variant, *variant_sym); got_cname = v__gen__c__Gen_get_sumtype_variant_type_name(g, variant, *variant_sym); type_idx = int_str(((int)(variant))); break; } } } strings__Builder_writeln(&sb, str_intp(4, _MOV((StrIntpData[]){{_S("static inline "), 0xfe10, {.d_s = exp_cname}}, {_S(" "), 0xfe10, {.d_s = fun.fn_name}}, {_S("("), 0xfe10, {.d_s = got_cname}}, {_S(" x) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&sb, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = got_cname}}, {_S(" ptr = x;"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = exp_cname}}, {_S(" "), 0xfe10, {.d_s = fun.fn_name}}, {_S("("), 0xfe10, {.d_s = got_cname}}, {_S("* x);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&sb, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = exp_cname}}, {_S(" "), 0xfe10, {.d_s = fun.fn_name}}, {_S("("), 0xfe10, {.d_s = got_cname}}, {_S("* x) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&sb, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = got_cname}}, {_S("* ptr = memdup(x, sizeof("), 0xfe10, {.d_s = got_cname}}, {_S("));"), 0, { .d_c = 0 }}}))); } Array_Array_v__ast__Type _t2 = v__ast__Table_get_embeds(g->table, got_sym, ((v__ast__GetEmbedsOptions){.preceding = __new_array(0, 0, sizeof(v__ast__Type)),})); for (int _t3 = 0; _t3 < _t2.len; ++_t3) { Array_v__ast__Type embed_hierarchy = ((Array_v__ast__Type*)_t2.data)[_t3]; string embed_cname = _S(""); string embed_name = _S(""); string accessor = _S("&x->"); for (int j = 0; j < embed_hierarchy.len; ++j) { v__ast__Type embed = ((v__ast__Type*)embed_hierarchy.data)[j]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(g->table, embed); embed_cname = embed_sym->cname; embed_name = v__ast__TypeSymbol_embed_name(embed_sym); if (j > 0) { accessor = string__plus(accessor, _S(".")); } accessor = string__plus(accessor, embed_name); } strings__Builder_writeln(&sb, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = embed_cname}}, {_S("* "), 0xfe10, {.d_s = embed_name}}, {_S("_ptr = memdup("), 0xfe10, {.d_s = accessor}}, {_S(", sizeof("), 0xfe10, {.d_s = embed_cname}}, {_S("));"), 0, { .d_c = 0 }}}))); } { strings__Builder_write_string(&sb, _S("\treturn (")); strings__Builder_write_string(&sb, exp_cname); strings__Builder_write_string(&sb, _S("){ ._")); strings__Builder_write_string(&sb, variant_name); strings__Builder_write_string(&sb, _S(" = ptr, ._typ = ")); strings__Builder_write_string(&sb, type_idx); } for (int _t4 = 0; _t4 < (*(v__ast__SumType*)__as_cast((exp_sym->info)._v__ast__SumType,(exp_sym->info)._typ, 544)).fields.len; ++_t4) { v__ast__StructField field = ((v__ast__StructField*)(*(v__ast__SumType*)__as_cast((exp_sym->info)._v__ast__SumType,(exp_sym->info)._typ, 544)).fields.data)[_t4]; string ptr = _S("ptr"); string type_cname = got_cname; _result_multi_return_v__ast__StructField_Array_v__ast__Type _t5 = v__ast__Table_find_field_from_embeds(g->table, got_sym, field.name); if (_t5.is_error) { IError err = _t5.err; *(multi_return_v__ast__StructField_Array_v__ast__Type*) _t5.data = (multi_return_v__ast__StructField_Array_v__ast__Type){.arg0=((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } multi_return_v__ast__StructField_Array_v__ast__Type mr_98975 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t5.data); Array_v__ast__Type embed_types = mr_98975.arg1; if (embed_types.len > 0) { v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_last(embed_types))); ptr = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__TypeSymbol_embed_name(embed_sym)}}, {_S("_ptr"), 0, { .d_c = 0 }}})); type_cname = embed_sym->cname; } string field_styp = v__gen__c__Gen_styp(g, field.typ); if (got_sym->kind == v__ast__Kind__sum_type || got_sym->kind == v__ast__Kind__interface) { { strings__Builder_write_string(&sb, _S(", .")); strings__Builder_write_string(&sb, v__gen__c__c_name(field.name)); strings__Builder_write_string(&sb, _S(" = ptr->")); strings__Builder_write_string(&sb, field.name); } } else { { strings__Builder_write_string(&sb, _S(", .")); strings__Builder_write_string(&sb, v__gen__c__c_name(field.name)); strings__Builder_write_string(&sb, _S(" = (")); strings__Builder_write_string(&sb, field_styp); strings__Builder_write_string(&sb, _S("*)((char*)")); strings__Builder_write_string(&sb, ptr); strings__Builder_write_string(&sb, _S(" + __offsetof_ptr(")); strings__Builder_write_string(&sb, ptr); strings__Builder_write_string(&sb, _S(", ")); strings__Builder_write_string(&sb, type_cname); strings__Builder_write_string(&sb, _S(", ")); strings__Builder_write_string(&sb, v__gen__c__c_name(field.name)); strings__Builder_write_string(&sb, _S("))")); } } } strings__Builder_writeln(&sb, _S("};\n}")); array_push((array*)&g->auto_fn_definitions, _MOV((string[]){ strings__Builder_str(&sb) })); } VV_LOC void v__gen__c__Gen_call_cfn_for_casting_expr(v__gen__c__Gen* g, string fname, v__ast__Expr expr, v__ast__Type exp, v__ast__Type got, string exp_styp, bool got_is_ptr, bool got_is_fn, string got_styp) { bool v__gen__c__Gen_call_cfn_for_casting_expr_defer_0 = false; bool old_inside_smartcast; int rparen_n = 1; int mutable_idx = 0; bool is_not_ptr_and_fn = !got_is_ptr && !got_is_fn; bool is_sumtype_cast = !got_is_fn && string_contains(fname, _S("_to_sumtype_")); bool is_comptime_variant = is_not_ptr_and_fn && (expr)._typ == 358 /* v.ast.Ident */ && v__type_resolver__ResolverInfo_is_comptime_variant_var(g->comptime, *(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)); if (v__ast__Type_is_ptr(exp)) { if (false && is_sumtype_cast && g->expected_arg_mut && (expr)._typ == 358 /* v.ast.Ident */) { { v__gen__c__Gen_write(g, _S("&(")); v__gen__c__Gen_write(g, string_trim_right(exp_styp, _S("*"))); v__gen__c__Gen_write(g, _S("){._")); v__gen__c__Gen_write(g, string_trim_right(got_styp, _S("*"))); v__gen__c__Gen_write(g, _S("=")); } rparen_n = 0; mutable_idx = v__ast__Type_idx(got); } else if (((expr)._typ == 388 /* v.ast.UnsafeExpr */ && ((*(v__ast__UnsafeExpr*)__as_cast((expr)._v__ast__UnsafeExpr,(expr)._typ, 388)).expr)._typ == 370 /* v.ast.Nil */) || got == _const_v__ast__nil_type) { v__gen__c__Gen_write(g, _S("(void*)0")); return; } else { { v__gen__c__Gen_write(g, _S("HEAP(")); v__gen__c__Gen_write(g, exp_styp); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, fname); v__gen__c__Gen_write(g, _S("(")); } rparen_n++; } } else { { v__gen__c__Gen_write(g, fname); v__gen__c__Gen_write(g, _S("(")); } } if (is_not_ptr_and_fn) { bool is_cast_fixed_array_init = (expr)._typ == 345 /* v.ast.CastExpr */ && (((*(v__ast__CastExpr*)__as_cast((expr)._v__ast__CastExpr,(expr)._typ, 345)).expr)._typ == 338 /* v.ast.ArrayInit */ && (*(v__ast__ArrayInit*)__as_cast(((*(v__ast__CastExpr*)__as_cast((expr)._v__ast__CastExpr,(expr)._typ, 345)).expr)._v__ast__ArrayInit,((*(v__ast__CastExpr*)__as_cast((expr)._v__ast__CastExpr,(expr)._typ, 345)).expr)._typ, 338)).is_fixed); if (!is_cast_fixed_array_init && (is_comptime_variant || !v__ast__Expr_is_lvalue(expr) || ((expr)._typ == 358 /* v.ast.Ident */ && (v__ast__ScopeObject_is_simple_define_const((*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).obj) || (((*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).obj)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast(((*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).obj)._v__ast__Var,((*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).obj)._typ, 422)).is_index_var))))) { if (v__ast__Expr_is_as_cast(expr)) { if (!got_is_ptr && (expr)._typ == 379 /* v.ast.SelectorExpr */) { v__gen__c__Gen_write(g, _S("&")); } old_inside_smartcast = g->inside_smartcast; g->inside_smartcast = true; v__gen__c__Gen_call_cfn_for_casting_expr_defer_0 = true; } else { string promotion_macro_name = (is_sumtype_cast ? (_S("ADDR")) : (_S("HEAP"))); { v__gen__c__Gen_write(g, promotion_macro_name); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, got_styp); v__gen__c__Gen_write(g, _S(", (")); } rparen_n += 2; } } else { v__gen__c__Gen_write(g, _S("&")); } } if (_SLIT_EQ(got_styp.str, got_styp.len, "none") && !v__ast__Type_has_flag(g->cur_fn->return_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_write(g, _S("(none){E_STRUCT}")); } else if (is_comptime_variant) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->comptime->comptime_for_variant_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), _const_v__ast__void_type); v__gen__c__Gen_write(g, v__gen__c__Gen_type_default(g, ctyp)); } else { bool old_left_is_opt = g->left_is_opt; g->left_is_opt = !v__ast__Type_has_flag(exp, v__ast__TypeFlag__option); v__gen__c__Gen_expr(g, expr); g->left_is_opt = old_left_is_opt; } if (mutable_idx != 0) { { v__gen__c__Gen_write(g, _S(", ._typ=")); v__gen__c__Gen_write_decimal(g, mutable_idx); v__gen__c__Gen_write(g, _S("}")); } } v__gen__c__Gen_write(g, string_repeat(_S(")"), rparen_n)); // Defer begin if (v__gen__c__Gen_call_cfn_for_casting_expr_defer_0) { g->inside_smartcast = old_inside_smartcast; } // Defer end } VV_LOC string v__gen__c__Gen_expr_with_var(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expected_type, bool do_cast) { string stmt_str = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; string tmp_var = v__gen__c__Gen_new_tmp_var(g); string styp = v__gen__c__Gen_styp(g, expected_type); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("memcpy(&")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(", ")); } if (do_cast) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write(g, stmt_str); return tmp_var; } VV_LOC string v__gen__c__Gen_expr_with_fixed_array(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type got_type_raw, v__ast__Type expected_type) { string stmt_str = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; string tmp_var = v__gen__c__Gen_new_tmp_var(g); string styp = v__gen__c__Gen_styp(g, expected_type); if ((expr)._typ == 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); v__ast__Type val_typ = v__ast__Table_value_type(g->table, got_type_raw); string val_styp = v__gen__c__Gen_styp(g, val_typ); v__ast__TypeSymbol* val_sym = v__ast__Table_final_sym(g->table, val_typ); string prefix = (!(val_sym->kind == v__ast__Kind__array || val_sym->kind == v__ast__Kind__array_fixed) ? (_S("&")) : (_S(""))); for (int i = 0; i < (*expr._v__ast__ArrayInit).exprs.len; ++i) { v__ast__Expr item_expr = ((v__ast__Expr*)(*expr._v__ast__ArrayInit).exprs.data)[i]; { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, prefix); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_write_decimal(g, i); v__gen__c__Gen_write(g, _S("], ")); } bool needs_addr = ((item_expr)._typ == 344 /* v.ast.CallExpr */ && !v__ast__Type_is_ptr((*(v__ast__CallExpr*)__as_cast((item_expr)._v__ast__CallExpr,(item_expr)._typ, 344)).return_type) && !(v__ast__Table_final_sym(g->table, (*(v__ast__CallExpr*)__as_cast((item_expr)._v__ast__CallExpr,(item_expr)._typ, 344)).return_type)->kind == v__ast__Kind__array || v__ast__Table_final_sym(g->table, (*(v__ast__CallExpr*)__as_cast((item_expr)._v__ast__CallExpr,(item_expr)._typ, 344)).return_type)->kind == v__ast__Kind__array_fixed)) || ((item_expr)._typ == 362 /* v.ast.InfixExpr */ && !v__ast__Type_is_ptr((*(v__ast__InfixExpr*)__as_cast((item_expr)._v__ast__InfixExpr,(item_expr)._typ, 362)).promoted_type)) || (item_expr)._typ == 385 /* v.ast.StructInit */; if (needs_addr) { { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, val_styp); v__gen__c__Gen_write(g, _S(", ")); } } v__gen__c__Gen_expr(g, item_expr); if (needs_addr) { v__gen__c__Gen_write(g, _S(")")); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = val_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } } else if ((expr)._typ == 344 /* v.ast.CallExpr */) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("memcpy(&")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(".data, ")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, expected_type)}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_expr(g, expr); } v__gen__c__Gen_write(g, stmt_str); return tmp_var; } VV_LOC void v__gen__c__Gen_expr_with_cast(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type got_type_raw, v__ast__Type expected_type) { v__ast__Type got_type = v__ast__mktyp(got_type_raw); v__ast__TypeSymbol* exp_sym = v__ast__Table_sym(g->table, expected_type); v__ast__TypeSymbol* got_sym = v__ast__Table_sym(g->table, got_type); bool expected_is_ptr = v__ast__Type_is_ptr(expected_type); bool got_is_ptr = v__ast__Type_is_ptr(got_type); if (got_type == 30 && expected_type == 21) { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(".msg))")); return; } if (got_sym->kind == v__ast__Kind__none && exp_sym->idx == 30) { v__gen__c__Gen_expr(g, expr); return; } if ((got_sym->info)._typ != 542 /* v.ast.Interface */ && (exp_sym->info)._typ == 542 /* v.ast.Interface */ && v__ast__Type_idx(got_type) != v__ast__Type_idx(expected_type) && !v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__result)) { if ((expr)._typ == 385 /* v.ast.StructInit */ && !v__ast__Type_is_ptr(got_type)) { g->inside_cast_in_heap++; string got_styp = v__gen__c__Gen_cc_type(g, v__ast__Type_ref(got_type), true); string exp_styp = exp_sym->cname; string fname = str_intp(3, _MOV((StrIntpData[]){{_S("I_"), 0xfe10, {.d_s = got_styp}}, {_S("_to_Interface_"), 0xfe10, {.d_s = exp_styp}}, {_SLIT0, 0, { .d_c = 0 }}})); if ((*exp_sym->info._v__ast__Interface).is_generic) { fname = v__gen__c__Gen_generic_fn_name(g, (*exp_sym->info._v__ast__Interface).concrete_types, fname); } v__gen__c__Gen_call_cfn_for_casting_expr(g, fname, expr, expected_type, got_type, exp_styp, true, false, got_styp); g->inside_cast_in_heap--; } else { string got_styp = v__gen__c__Gen_cc_type(g, got_type, true); bool got_is_shared = v__ast__Type_has_flag(got_type, v__ast__TypeFlag__shared_f); string exp_styp = (got_is_shared ? (str_intp(2, _MOV((StrIntpData[]){{_S("__shared__"), 0xfe10, {.d_s = exp_sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (exp_sym->cname)); string fname = (got_is_shared ? (str_intp(3, _MOV((StrIntpData[]){{_S("I___shared__"), 0xfe10, {.d_s = got_styp}}, {_S("_to_shared_Interface_"), 0xfe10, {.d_s = exp_styp}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (str_intp(3, _MOV((StrIntpData[]){{_S("I_"), 0xfe10, {.d_s = got_styp}}, {_S("_to_Interface_"), 0xfe10, {.d_s = exp_styp}}, {_SLIT0, 0, { .d_c = 0 }}})))); sync__RwMutex_lock(&g->referenced_fns->mtx); /*lock*/ { map_set(&g->referenced_fns->val, &(string[]){fname}, &(bool[]) { true }); } sync__RwMutex_unlock(&g->referenced_fns->mtx);; if ((*exp_sym->info._v__ast__Interface).is_generic) { fname = v__gen__c__Gen_generic_fn_name(g, (*exp_sym->info._v__ast__Interface).concrete_types, fname); } if (g->pref->experimental) { bool is_nil_cast = (expr)._typ == 388 /* v.ast.UnsafeExpr */ && ((*(v__ast__UnsafeExpr*)__as_cast((expr)._v__ast__UnsafeExpr,(expr)._typ, 388)).expr)._typ == 370 /* v.ast.Nil */; if (is_nil_cast) { v__gen__c__Gen_write(g, _S("((void*)0)")); return; } } v__gen__c__Gen_call_cfn_for_casting_expr(g, fname, expr, expected_type, got_type, exp_styp, got_is_ptr, false, got_styp); } return; } string exp_styp = v__gen__c__Gen_styp(g, expected_type); string got_styp = v__gen__c__Gen_styp(g, got_type); bool got_is_fn = false; if ((got_sym->info)._typ == 553 /* v.ast.FnType */) { if ((*got_sym->info._v__ast__FnType).is_anon) { got_styp = str_intp(2, _MOV((StrIntpData[]){{_S("anon_fn_"), 0xfe10, {.d_s = v__ast__Table_fn_type_signature(g->table, (voidptr)&(*got_sym->info._v__ast__FnType).func)}}, {_SLIT0, 0, { .d_c = 0 }}})); } got_is_fn = true; } if (expected_type != _const_v__ast__void_type) { v__ast__Type unwrapped_expected_type = v__gen__c__Gen_unwrap_generic(g, expected_type); v__ast__TypeSymbol* unwrapped_exp_sym = v__ast__Table_sym(g->table, unwrapped_expected_type); v__ast__Type unwrapped_got_type = v__gen__c__Gen_unwrap_generic(g, got_type); v__ast__TypeSymbol* unwrapped_got_sym = v__ast__Table_sym(g->table, unwrapped_got_type); v__ast__Type expected_deref_type = (expected_is_ptr ? (v__ast__Type_deref(unwrapped_expected_type)) : (unwrapped_expected_type)); v__ast__Type got_deref_type = (got_is_ptr ? (v__ast__Type_deref(unwrapped_got_type)) : (unwrapped_got_type)); if (v__ast__Table_sumtype_has_variant(g->table, expected_deref_type, got_deref_type, false)) { bool is_already_sum_type = false; v__ast__Scope* scope = v__ast__Scope_innermost(g->file->scope, v__ast__Expr_pos(expr).pos); if ((expr)._typ == 358 /* v.ast.Ident */) { _option_v__ast__Var_ptr _t1; if (_t1 = v__ast__Scope_find_var(scope, (*expr._v__ast__Ident).name), _t1.state == 0) { v__ast__Var* v = *(v__ast__Var**)_t1.data; if (v->smartcasts.len > 0 && unwrapped_expected_type == v->orig_type) { is_already_sum_type = true; } } } else if ((expr)._typ == 379 /* v.ast.SelectorExpr */) { v__ast__ScopeStructField* v = v__ast__Scope_find_struct_field(scope, v__ast__Expr_str(&(*expr._v__ast__SelectorExpr).expr), (*expr._v__ast__SelectorExpr).expr_type, (*expr._v__ast__SelectorExpr).field_name); if (v != ((void*)0)) { if (v->smartcasts.len > 0 && unwrapped_expected_type == v->orig_type) { is_already_sum_type = true; } } } if (is_already_sum_type && !g->inside_return) { g->prevent_sum_type_unwrapping_once = true; v__gen__c__Gen_expr(g, expr); } else { if ((unwrapped_got_sym->info)._typ == 537 /* v.ast.Aggregate */) { unwrapped_got_type = (*(v__ast__Type*)array_get((*unwrapped_got_sym->info._v__ast__Aggregate).types, g->aggregate_type_idx)); unwrapped_got_sym = v__ast__Table_sym(g->table, unwrapped_got_type); } string fname = v__gen__c__Gen_get_sumtype_casting_fn(g, unwrapped_got_type, unwrapped_expected_type); if ((expr)._typ == 338 /* v.ast.ArrayInit */ && got_sym->kind == v__ast__Kind__array_fixed) { string stmt_str = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; string tmp_var = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, got_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write2(g, stmt_str, _S(" ")); { v__gen__c__Gen_write(g, fname); v__gen__c__Gen_write(g, _S("(&")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(")")); } return; } else { v__gen__c__Gen_call_cfn_for_casting_expr(g, fname, expr, expected_type, got_type, unwrapped_exp_sym->cname, got_is_ptr, got_is_fn, got_styp); } } return; } } bool neither_void = !(_const_v__ast__voidptr_type == got_type || _const_v__ast__voidptr_type == expected_type) && !(_const_v__ast__nil_type == got_type || _const_v__ast__nil_type == expected_type); if (v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__shared_f) && !v__ast__Type_has_flag(got_type_raw, v__ast__TypeFlag__shared_f) && !v__ast__Type_has_option_or_result(expected_type)) { string shared_styp = string_substr(exp_styp, 0, (int)(exp_styp.len - 1)); if (v__ast__Type_is_ptr(got_type_raw)) { v__gen__c__Gen_error(g, _S("cannot convert reference to `shared`"), v__ast__Expr_pos(expr)); VUNREACHABLE(); } if (exp_sym->kind == v__ast__Kind__array) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = shared_styp}}, {_S("*)__dup_shared_array(&("), 0xfe10, {.d_s = shared_styp}}, {_S("){.mtx = {0}, .val ="), 0, { .d_c = 0 }}}))); } else if (exp_sym->kind == v__ast__Kind__map) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = shared_styp}}, {_S("*)__dup_shared_map(&("), 0xfe10, {.d_s = shared_styp}}, {_S("){.mtx = {0}, .val ="), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = shared_styp}}, {_S("*)__dup"), 0xfe10, {.d_s = shared_styp}}, {_S("(&("), 0xfe10, {.d_s = shared_styp}}, {_S("){.mtx = {0}, .val ="), 0, { .d_c = 0 }}}))); } bool old_is_shared = g->is_shared; g->is_shared = false; v__gen__c__Gen_expr(g, expr); g->is_shared = old_is_shared; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("}, sizeof("), 0xfe10, {.d_s = shared_styp}}, {_S("))"), 0, { .d_c = 0 }}}))); return; } else if (v__ast__Type_has_flag(got_type_raw, v__ast__TypeFlag__shared_f) && !v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__shared_f)) { if (expected_is_ptr) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, expr); if ((expr)._typ != 361 /* v.ast.IndexExpr */) { v__gen__c__Gen_write(g, _S("->val")); } return; } if (got_is_ptr && !expected_is_ptr && neither_void && exp_sym->kind != v__ast__Kind__placeholder && (expr)._typ != 362 /* v.ast.InfixExpr */) { v__ast__Type got_deref_type = v__ast__Type_deref(got_type); v__ast__TypeSymbol* deref_sym = v__ast__Table_sym(g->table, got_deref_type); bool deref_will_match = (expected_type == got_type || expected_type == got_deref_type || expected_type == (u32)deref_sym->parent_idx); bool got_is_opt_or_res = v__ast__Type_has_option_or_result(got_type); if (deref_will_match || got_is_opt_or_res || v__ast__Expr_is_auto_deref_var(expr)) { v__gen__c__Gen_write(g, _S("*")); } } if ((expr)._typ == 363 /* v.ast.IntegerLiteral */) { if ((expected_type == _const_v__ast__u64_type || expected_type == _const_v__ast__u32_type || expected_type == _const_v__ast__u16_type) && string_at((*expr._v__ast__IntegerLiteral).val, 0) != '-') { v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S("U")); return; } } if ((exp_sym->kind == v__ast__Kind__function && !v__ast__Type_has_option_or_result(expected_type)) || (g->inside_struct_init && expected_type == _const_v__ast__voidptr_type && expected_type != got_type_raw && (expr)._typ != 385 /* v.ast.StructInit */)) { v__gen__c__Gen_write(g, _S("(voidptr)")); } v__gen__c__Gen_expr(g, expr); } VV_LOC void v__gen__c__write_octal_escape(strings__Builder* b, u8 c) { array_push((array*)b, _MOV((u8[]){ 92 })); array_push((array*)b, _MOV((u8[]){ (u8)(48 + ((c >> 6))) })); array_push((array*)b, _MOV((u8[]){ (u8)(48 + (((c >> 3)) & 7)) })); array_push((array*)b, _MOV((u8[]){ (u8)(48 + (c & 7)) })); } VV_LOC string v__gen__c__cescape_nonascii(string original) { strings__Builder b = strings__new_builder(original.len); for (int _t1 = 0; _t1 < original.len; ++_t1) { u8 c = original.str[_t1]; if (c < 32 || c > 126) { v__gen__c__write_octal_escape((voidptr)&b, c); continue; } array_push((array*)&b, _MOV((u8[]){ c })); } string res = strings__Builder_str(&b); return res; } VV_LOC string v__gen__c__cestring(string s) { return string_replace(string_replace(s, _S("\\"), _S("\\\\")), _S("\""), _S("'")); } VV_LOC string v__gen__c__ctoslit(string s) { return string__plus(string__plus(_S("_S(\""), v__gen__c__cescape_nonascii(v__gen__c__cestring(s))), _S("\")")); } VV_LOC void v__gen__c__Gen_gen_attrs(v__gen__c__Gen* g, Array_v__ast__Attr attrs) { if (g->pref->skip_unused) { return; } if (g->inside_c_extern) { return; } for (int _t1 = 0; _t1 < attrs.len; ++_t1) { v__ast__Attr attr = ((v__ast__Attr*)attrs.data)[_t1]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("// Attr: ["), 0xfe10, {.d_s = attr.name}}, {_S("]"), 0, { .d_c = 0 }}}))); } } VV_LOC void v__gen__c__Gen_asm_stmt(v__gen__c__Gen* g, v__ast__AsmStmt stmt) { v__gen__c__Gen_write(g, _S("__asm__")); if (stmt.is_volatile) { v__gen__c__Gen_write(g, _S(" volatile")); } if (stmt.is_goto) { v__gen__c__Gen_write(g, _S(" goto")); } v__gen__c__Gen_writeln(g, _S(" (")); g->indent++; for (int _t1 = 0; _t1 < stmt.templates.len; ++_t1) { v__ast__AsmTemplate template_tmp = ((v__ast__AsmTemplate*)stmt.templates.data)[_t1]; v__ast__AsmTemplate __v_template = template_tmp; v__gen__c__Gen_write(g, _S("\"")); if (__v_template.is_directive) { v__gen__c__Gen_write(g, _S(".")); } v__gen__c__Gen_write(g, __v_template.name); if (__v_template.is_label) { v__gen__c__Gen_write(g, _S(":")); } else { v__gen__c__Gen_write(g, _S(" ")); } if (__v_template.args.len != 0 && !__v_template.is_directive && stmt.arch != v__pref__Arch__arm64 && stmt.arch != v__pref__Arch__s390x && stmt.arch != v__pref__Arch__ppc64le && stmt.arch != v__pref__Arch__loongarch64) { array_prepend(&__v_template.args, &(v__ast__AsmArg[]){(*(v__ast__AsmArg*)array_last(__v_template.args))}); array_delete(&__v_template.args, (int)(__v_template.args.len - 1)); } for (int i = 0; i < __v_template.args.len; ++i) { v__ast__AsmArg arg = ((v__ast__AsmArg*)__v_template.args.data)[i]; if (stmt.arch == v__pref__Arch__amd64 && (fast_string_eq(__v_template.name, _S("call")) || string_at(__v_template.name, 0) == 'j') && (arg)._typ == 419 /* v.ast.AsmRegister */) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_asm_arg(g, arg, stmt); if ((int)(i + 1) < __v_template.args.len) { v__gen__c__Gen_write(g, _S(", ")); } } if (!__v_template.is_label) { v__gen__c__Gen_write(g, _S(";")); } v__gen__c__Gen_writeln(g, _S("\"")); } if (stmt.output.len != 0 || stmt.input.len != 0 || stmt.clobbered.len != 0 || stmt.is_goto) { v__gen__c__Gen_write(g, _S(": ")); } v__gen__c__Gen_gen_asm_ios(g, stmt.output); if (stmt.input.len != 0 || stmt.clobbered.len != 0 || stmt.is_goto) { v__gen__c__Gen_write(g, _S(": ")); } v__gen__c__Gen_gen_asm_ios(g, stmt.input); if (stmt.clobbered.len != 0 || stmt.is_goto) { v__gen__c__Gen_write(g, _S(": ")); } for (int i = 0; i < stmt.clobbered.len; ++i) { v__ast__AsmClobbered clob = ((v__ast__AsmClobbered*)stmt.clobbered.data)[i]; v__gen__c__Gen_write2(g, _S("\""), clob.reg.name); v__gen__c__Gen_write(g, _S("\"")); if ((int)(i + 1) < stmt.clobbered.len) { v__gen__c__Gen_writeln(g, _S(",")); } else { v__gen__c__Gen_writeln(g, _S("")); } } if (stmt.is_goto) { v__gen__c__Gen_write(g, _S(": ")); } for (int i = 0; i < stmt.global_labels.len; ++i) { string label = ((string*)stmt.global_labels.data)[i]; v__gen__c__Gen_write(g, label); if ((int)(i + 1) < stmt.clobbered.len) { v__gen__c__Gen_writeln(g, _S(",")); } else { v__gen__c__Gen_writeln(g, _S("")); } } g->indent--; v__gen__c__Gen_writeln(g, _S(");")); } VV_LOC void v__gen__c__Gen_asm_arg(v__gen__c__Gen* g, v__ast__AsmArg arg, v__ast__AsmStmt stmt) { if (arg._typ == 497 /* v.ast.AsmAlias */) { string name = (*arg._v__ast__AsmAlias).name; bool _t2 = ((Array_string_contains(stmt.local_labels, name)) || (Array_string_contains(stmt.global_labels, name)) || (Array_string_contains(g->file->global_labels, name)) || stmt.is_basic); Array_string _t4 = {0}; if (!_t2) { Array_v__ast__AsmIO _t4_orig = stmt.input; int _t4_len = _t4_orig.len; _t4 = __new_array(0, _t4_len, sizeof(string)); for (int _t6 = 0; _t6 < _t4_len; ++_t6) { v__ast__AsmIO it = ((v__ast__AsmIO*) _t4_orig.data)[_t6]; string _t5 = it.alias; array_push((array*)&_t4, &_t5); } } bool _t3 = ((!_t2) && !(Array_string_contains(_t4, name))); Array_string _t7 = {0}; if (_t3) { Array_v__ast__AsmIO _t7_orig = stmt.output; int _t7_len = _t7_orig.len; _t7 = __new_array(0, _t7_len, sizeof(string)); for (int _t9 = 0; _t9 < _t7_len; ++_t9) { v__ast__AsmIO it = ((v__ast__AsmIO*) _t7_orig.data)[_t9]; string _t8 = it.alias; array_push((array*)&_t7, &_t8); } } bool _t1 = _t2 || ( _t3 && !(Array_string_contains(_t7, name))); if (_t1) { string asm_formatted_name = ((Array_string_contains(stmt.global_labels, name)) ? (str_intp(2, _MOV((StrIntpData[]){{_S("%l["), 0xfe10, {.d_s = name}}, {_S("]"), 0, { .d_c = 0 }}}))) : (name)); v__gen__c__Gen_write(g, asm_formatted_name); } else { { v__gen__c__Gen_write(g, _S("%[")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S("]")); } } } else if (arg._typ == 347 /* v.ast.CharLiteral */) { { v__gen__c__Gen_write(g, _S("'")); v__gen__c__Gen_write(g, (*arg._v__ast__CharLiteral).val); v__gen__c__Gen_write(g, _S("'")); } } else if (arg._typ == 363 /* v.ast.IntegerLiteral */) { if (stmt.arch == v__pref__Arch__arm64) { { v__gen__c__Gen_write(g, _S("#")); v__gen__c__Gen_write(g, (*arg._v__ast__IntegerLiteral).val); } } else if (stmt.arch == v__pref__Arch__s390x || stmt.arch == v__pref__Arch__ppc64le || stmt.arch == v__pref__Arch__loongarch64) { { v__gen__c__Gen_write(g, (*arg._v__ast__IntegerLiteral).val); } } else { { v__gen__c__Gen_write(g, _S("$")); v__gen__c__Gen_write(g, (*arg._v__ast__IntegerLiteral).val); } } } else if (arg._typ == 356 /* v.ast.FloatLiteral */) { if (g->pref->nofloat) { { v__gen__c__Gen_write(g, _S("$")); v__gen__c__Gen_write_decimal(g, string_int((*arg._v__ast__FloatLiteral).val)); } } else { { v__gen__c__Gen_write(g, _S("$")); v__gen__c__Gen_write(g, (*arg._v__ast__FloatLiteral).val); } } } else if (arg._typ == 342 /* v.ast.BoolLiteral */) { { v__gen__c__Gen_write(g, _S("$")); v__gen__c__Gen_write(g, bool_str((*arg._v__ast__BoolLiteral).val)); } } else if (arg._typ == 419 /* v.ast.AsmRegister */) { if (stmt.arch == v__pref__Arch__loongarch64) { { v__gen__c__Gen_write(g, _S("$")); v__gen__c__Gen_write(g, (*arg._v__ast__AsmRegister).name); } } else { if (!stmt.is_basic) { v__gen__c__Gen_write(g, _S("%")); } { v__gen__c__Gen_write(g, _S("%")); v__gen__c__Gen_write(g, (*arg._v__ast__AsmRegister).name); } } } else if (arg._typ == 496 /* v.ast.AsmAddressing */) { if (((*arg._v__ast__AsmAddressing).segment).len != 0) { { v__gen__c__Gen_write(g, _S("%%")); v__gen__c__Gen_write(g, (*arg._v__ast__AsmAddressing).segment); v__gen__c__Gen_write(g, _S(":")); } } v__ast__AsmArg base = (*arg._v__ast__AsmAddressing).base; v__ast__AsmArg index = (*arg._v__ast__AsmAddressing).index; v__ast__AsmArg displacement = (*arg._v__ast__AsmAddressing).displacement; int scale = (*arg._v__ast__AsmAddressing).scale; switch ((*arg._v__ast__AsmAddressing).mode) { case v__ast__AddressingMode__base: { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_asm_arg(g, base, stmt); v__gen__c__Gen_write(g, _S(")")); break; } case v__ast__AddressingMode__displacement: { v__gen__c__Gen_asm_arg(g, displacement, stmt); break; } case v__ast__AddressingMode__base_plus_displacement: { v__gen__c__Gen_asm_arg(g, displacement, stmt); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_asm_arg(g, base, stmt); v__gen__c__Gen_write(g, _S(")")); break; } case v__ast__AddressingMode__index_times_scale_plus_displacement: { if ((displacement)._typ == 498 /* v.ast.AsmDisp */) { v__gen__c__Gen_asm_arg(g, displacement, stmt); v__gen__c__Gen_write(g, _S("(, ")); } else if ((displacement)._typ == 419 /* v.ast.AsmRegister */) { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_asm_arg(g, displacement, stmt); v__gen__c__Gen_write(g, _S(",")); } else { _v_panic(str_intp(2, _MOV((StrIntpData[]){{_S("unexpected "), 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_sumtype_v__ast__AsmArg( (displacement)._typ ))}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } v__gen__c__Gen_asm_arg(g, index, stmt); { v__gen__c__Gen_write(g, _S(",")); v__gen__c__Gen_write_decimal(g, scale); v__gen__c__Gen_write(g, _S(")")); } break; } case v__ast__AddressingMode__base_plus_index_plus_displacement: { v__gen__c__Gen_asm_arg(g, displacement, stmt); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_asm_arg(g, base, stmt); v__gen__c__Gen_write(g, _S(",")); v__gen__c__Gen_asm_arg(g, index, stmt); v__gen__c__Gen_write(g, _S(",1)")); break; } case v__ast__AddressingMode__base_plus_index_times_scale_plus_displacement: { v__gen__c__Gen_asm_arg(g, displacement, stmt); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_asm_arg(g, base, stmt); v__gen__c__Gen_write(g, _S(",")); v__gen__c__Gen_asm_arg(g, index, stmt); { v__gen__c__Gen_write(g, _S(",")); v__gen__c__Gen_write_decimal(g, scale); v__gen__c__Gen_write(g, _S(")")); } break; } case v__ast__AddressingMode__rip_plus_displacement: { v__gen__c__Gen_asm_arg(g, displacement, stmt); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_asm_arg(g, base, stmt); v__gen__c__Gen_write(g, _S(")")); break; } case v__ast__AddressingMode__invalid: { v__gen__c__Gen_error(g, _S("invalid addressing mode"), (*arg._v__ast__AsmAddressing).pos); VUNREACHABLE(); break; } } } else if (arg._typ == 498 /* v.ast.AsmDisp */) { v__gen__c__Gen_write(g, (*arg._v__ast__AsmDisp).val); } else if (arg._typ == 21 /* string */) { v__gen__c__Gen_write(g, (*arg._string)); } } VV_LOC void v__gen__c__Gen_gen_asm_ios(v__gen__c__Gen* g, Array_v__ast__AsmIO ios) { for (int i = 0; i < ios.len; ++i) { v__ast__AsmIO io = ((v__ast__AsmIO*)ios.data)[i]; if ((io.alias).len != 0) { { v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_write(g, io.alias); v__gen__c__Gen_write(g, _S("] ")); } } { v__gen__c__Gen_write(g, _S("\"")); v__gen__c__Gen_write(g, io.constraint); v__gen__c__Gen_write(g, _S("\" (")); } v__gen__c__Gen_expr(g, io.expr); v__gen__c__Gen_write(g, _S(")")); if ((int)(i + 1) < ios.len) { v__gen__c__Gen_writeln(g, _S(",")); } else { v__gen__c__Gen_writeln(g, _S("")); } } } VV_LOC string v__gen__c__cnewlines(string s) { return string_replace(s, _S("\n"), _S("\\n")); } VV_LOC void v__gen__c__Gen_write_fn_ptr_decl(v__gen__c__Gen* g, v__ast__FnType* func, string ptr_name) { string ret_styp = v__gen__c__Gen_styp(g, func->func.return_type); { v__gen__c__Gen_write(g, ret_styp); v__gen__c__Gen_write(g, _S(" (*")); v__gen__c__Gen_write(g, ptr_name); v__gen__c__Gen_write(g, _S(") (")); } int arg_len = func->func.params.len; for (int i = 0; i < func->func.params.len; ++i) { v__ast__Param arg = ((v__ast__Param*)func->func.params.data)[i]; string arg_styp = v__gen__c__Gen_styp(g, arg.typ); v__gen__c__Gen_write(g, arg_styp); { v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, arg.name); } if (i < (int)(arg_len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } } v__gen__c__Gen_write(g, _S(")")); } VV_LOC void v__gen__c__Gen_register_ternary_name(v__gen__c__Gen* g, string name) { string level_key = int_str(g->inside_ternary); if (!_IN_MAP(ADDR(string, level_key), ADDR(map, g->ternary_level_names))) { (*(Array_string*)map_get_and_set((map*)&g->ternary_level_names, &(string[]){level_key}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })) = __new_array_with_default(0, 0, sizeof(string), 0); } string new_name = v__gen__c__Gen_new_tmp_var(g); map_set(&g->ternary_names, &(string[]){name}, &(string[]) { new_name }); array_push((array*)&(*(Array_string*)map_get_and_set((map*)&g->ternary_level_names, &(string[]){level_key}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })), _MOV((string[]){ string_clone(name) })); } VV_LOC string v__gen__c__Gen_get_ternary_name(v__gen__c__Gen* g, string name) { if (g->inside_ternary == 0) { return name; } if (!_IN_MAP(ADDR(string, name), ADDR(map, g->ternary_names))) { return name; } return (*(string*)map_get(ADDR(map, g->ternary_names), &(string[]){name}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })); } VV_LOC bool v__gen__c__Gen_gen_clone_assignment(v__gen__c__Gen* g, v__ast__Type var_type, v__ast__Expr val, v__ast__Type typ, bool add_eq) { if (!((val)._typ == 358 /* v.ast.Ident */ || (val)._typ == 379 /* v.ast.SelectorExpr */)) { return false; } v__ast__TypeSymbol* right_sym = v__ast__Table_sym(g->table, typ); if (g->is_autofree) { if (add_eq) { v__gen__c__Gen_write(g, _S("=")); } if (right_sym->kind == v__ast__Kind__array) { string shared_styp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(typ, 0)); if (v__ast__Type_share(typ) == v__ast__ShareType__shared_t) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("*)__dup_shared_array(&(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("){.mtx = {0}, .val =")); } } bool is_sumtype = v__ast__Table_type_kind(g->table, var_type) == v__ast__Kind__sum_type; if (is_sumtype) { string variant_typ = string_replace(v__gen__c__Gen_styp(g, typ), _S("*"), _S("")); string fn_name = v__gen__c__Gen_get_sumtype_casting_fn(g, typ, var_type); { v__gen__c__Gen_write(g, fn_name); v__gen__c__Gen_write(g, _S("(ADDR(")); v__gen__c__Gen_write(g, variant_typ); v__gen__c__Gen_write(g, _S(", array_clone_static_to_depth(")); } if (v__ast__Type_is_ptr(typ)) { v__gen__c__Gen_write(g, _S("*")); } } else { v__gen__c__Gen_write(g, _S(" array_clone_static_to_depth(")); } v__gen__c__Gen_expr(g, val); if (v__ast__Type_share(typ) == v__ast__ShareType__shared_t) { v__gen__c__Gen_write(g, _S("->val")); } v__ast__Type elem_type = (*(v__ast__Array*)__as_cast((right_sym->info)._v__ast__Array,(right_sym->info)._typ, 513)).elem_type; int array_depth = v__gen__c__Gen_get_array_depth(g, elem_type); { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, array_depth); v__gen__c__Gen_write(g, _S(")")); } if (v__ast__Type_share(typ) == v__ast__ShareType__shared_t) { { v__gen__c__Gen_write(g, _S("}, sizeof(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("))")); } } if (is_sumtype) { v__gen__c__Gen_write(g, _S("))")); } } else if (right_sym->kind == v__ast__Kind__string) { if (v__ast__Type_has_flag(var_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_write(g, _S(" string_option_clone_static(")); } else { v__gen__c__Gen_write(g, _S(" string_clone_static(")); } v__gen__c__Gen_expr(g, val); v__gen__c__Gen_write(g, _S(")")); } } return true; } VV_LOC multi_return_string_string_string_string v__gen__c__Gen_map_fn_ptrs(v__gen__c__Gen* g, v__ast__TypeSymbol key_sym) { string hash_fn = _S(""); string key_eq_fn = _S(""); string clone_fn = _S(""); string free_fn = _S("&map_free_nop"); switch (key_sym.kind) { case v__ast__Kind__alias: { v__ast__Type alias_key_type = (*(v__ast__Alias*)__as_cast((key_sym.info)._v__ast__Alias,(key_sym.info)._typ, 539)).parent_type; return v__gen__c__Gen_map_fn_ptrs(g, *v__ast__Table_sym(g->table, alias_key_type)); } case v__ast__Kind__u8: case v__ast__Kind__i8: case v__ast__Kind__char: { hash_fn = _S("&map_hash_int_1"); key_eq_fn = _S("&map_eq_int_1"); clone_fn = _S("&map_clone_int_1"); break; } case v__ast__Kind__i16: case v__ast__Kind__u16: { hash_fn = _S("&map_hash_int_2"); key_eq_fn = _S("&map_eq_int_2"); clone_fn = _S("&map_clone_int_2"); break; } case v__ast__Kind__enum: { v__ast__Enum einfo = *(v__ast__Enum*)__as_cast(((key_sym.info))._v__ast__Enum,((key_sym.info))._typ, 548); if (g->pref->ccompiler_type == v__pref__CompilerType__tinyc && (einfo.typ == _const_v__ast__u8_type || einfo.typ == _const_v__ast__u16_type || einfo.typ == _const_v__ast__i8_type || einfo.typ == _const_v__ast__i16_type)) { return v__gen__c__Gen_map_fn_ptrs(g, *v__ast__Table_sym(g->table, _const_v__ast__int_type)); } return v__gen__c__Gen_map_fn_ptrs(g, *v__ast__Table_sym(g->table, einfo.typ)); } case v__ast__Kind__int: case v__ast__Kind__i32: case v__ast__Kind__u32: case v__ast__Kind__rune: case v__ast__Kind__f32: { hash_fn = _S("&map_hash_int_4"); key_eq_fn = _S("&map_eq_int_4"); clone_fn = _S("&map_clone_int_4"); break; } case v__ast__Kind__voidptr: { v__ast__TypeSymbol* ts = (g->pref->m64 ? (v__ast__Table_sym_by_idx(g->table, _const_v__ast__u64_type_idx)) : (v__ast__Table_sym_by_idx(g->table, _const_v__ast__u32_type_idx))); return v__gen__c__Gen_map_fn_ptrs(g, *ts); } case v__ast__Kind__u64: case v__ast__Kind__i64: case v__ast__Kind__f64: { hash_fn = _S("&map_hash_int_8"); key_eq_fn = _S("&map_eq_int_8"); clone_fn = _S("&map_clone_int_8"); break; } case v__ast__Kind__string: { hash_fn = _S("&map_hash_string"); key_eq_fn = _S("&map_eq_string"); clone_fn = _S("&map_clone_string"); free_fn = _S("&map_free_string"); break; } case v__ast__Kind__placeholder: case v__ast__Kind__void: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__isize: case v__ast__Kind__usize: case v__ast__Kind__bool: case v__ast__Kind__none: case v__ast__Kind__array: case v__ast__Kind__array_fixed: case v__ast__Kind__map: case v__ast__Kind__chan: case v__ast__Kind__any: case v__ast__Kind__struct: case v__ast__Kind__generic_inst: case v__ast__Kind__multi_return: case v__ast__Kind__sum_type: case v__ast__Kind__function: case v__ast__Kind__interface: case v__ast__Kind__float_literal: case v__ast__Kind__int_literal: case v__ast__Kind__aggregate: case v__ast__Kind__thread: default: { { v__gen__c__verror(str_intp(2, _MOV((StrIntpData[]){{_S("map key type `"), 0xfe10, {.d_s = key_sym.name}}, {_S("` not supported"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); break; } } } return (multi_return_string_string_string_string){.arg0=hash_fn, .arg1=key_eq_fn, .arg2=clone_fn, .arg3=free_fn}; } VV_LOC void v__gen__c__Gen_expr(v__gen__c__Gen* g, v__ast__Expr node_) { bool old_discard_or_result = g->discard_or_result; bool old_is_void_expr_stmt = g->is_void_expr_stmt; if (g->is_void_expr_stmt) { g->discard_or_result = true; g->is_void_expr_stmt = false; } else { g->discard_or_result = false; } v__ast__Expr node = node_; if (node._typ == 351 /* v.ast.ComptimeType */) { v__gen__c__Gen_error(g, _S("g.expr(): Unhandled ComptimeType"), (*node._v__ast__ComptimeType).pos); VUNREACHABLE(); } else if (node._typ == 354 /* v.ast.EmptyExpr */) { v__gen__c__Gen_error(g, _S("g.expr(): unhandled EmptyExpr"), ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,})); VUNREACHABLE(); } else if (node._typ == 336 /* v.ast.AnonFn */) { v__gen__c__Gen_gen_anon_fn(g, &/*mut*/(*node._v__ast__AnonFn)); } else if (node._typ == 337 /* v.ast.ArrayDecompose */) { v__gen__c__Gen_expr(g, (*node._v__ast__ArrayDecompose).expr); } else if (node._typ == 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_array_init(g, (*node._v__ast__ArrayInit), _S("")); } else if (node._typ == 339 /* v.ast.AsCast */) { v__gen__c__Gen_as_cast(g, (*node._v__ast__AsCast)); } else if (node._typ == 340 /* v.ast.Assoc */) { v__gen__c__Gen_assoc(g, (*node._v__ast__Assoc)); } else if (node._typ == 341 /* v.ast.AtExpr */) { v__gen__c__Gen_comptime_at(g, (*node._v__ast__AtExpr)); } else if (node._typ == 342 /* v.ast.BoolLiteral */) { v__gen__c__Gen_write(g, bool_str((*node._v__ast__BoolLiteral).val)); } else if (node._typ == 344 /* v.ast.CallExpr */) { v__ast__Type ret_type = ((*node._v__ast__CallExpr).or_block.kind == v__ast__OrKind__absent ? ((*node._v__ast__CallExpr).return_type) : (v__ast__Type_clear_option_and_result((*node._v__ast__CallExpr).return_type))); string shared_styp = _S(""); bool ret_typ_is_shared = v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__shared_f); if (g->is_shared && !ret_typ_is_shared && !g->inside_or_block) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(g->table, ret_type); v__ast__Type shared_typ = (v__ast__Type_is_ptr(ret_type) ? (v__ast__Type_set_flag(v__ast__Type_deref(ret_type), v__ast__TypeFlag__shared_f)) : (v__ast__Type_set_flag(ret_type, v__ast__TypeFlag__shared_f))); shared_styp = v__gen__c__Gen_styp(g, shared_typ); if (ret_sym->kind == v__ast__Kind__array) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = shared_styp}}, {_S("*)__dup_shared_array(&("), 0xfe10, {.d_s = shared_styp}}, {_S("){.mtx = {0}, .val ="), 0, { .d_c = 0 }}}))); } else if (ret_sym->kind == v__ast__Kind__map) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = shared_styp}}, {_S("*)__dup_shared_map(&("), 0xfe10, {.d_s = shared_styp}}, {_S("){.mtx = {0}, .val ="), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = shared_styp}}, {_S("*)__dup"), 0xfe10, {.d_s = shared_styp}}, {_S("(&("), 0xfe10, {.d_s = shared_styp}}, {_S("){.mtx = {0}, .val ="), 0, { .d_c = 0 }}}))); } } int _t1; /* if prepend */ if (g->stmt_path_pos.len > 0) { _t1 = (*(int*)array_last(g->stmt_path_pos)); } else { _t1 = 0; } int stmt_before_call_expr_pos = _t1; if (g->is_shared && !ret_typ_is_shared && !g->inside_or_block && v__ast__Type_is_ptr(ret_type)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(ret_type))); } v__gen__c__Gen_call_expr(g, (*node._v__ast__CallExpr)); if (g->is_autofree && !g->is_builtin_mod && !g->is_js_call && g->strs_to_free0.len == 0 && !g->inside_lambda) { v__gen__c__Gen_autofree_call_pregen(g, (*node._v__ast__CallExpr)); if (g->strs_to_free0.len > 0) { v__gen__c__Gen_insert_at(g, stmt_before_call_expr_pos, string__plus(Array_string_join(g->strs_to_free0, _S("\n")), _S("/* inserted before */"))); } g->strs_to_free0 = __new_array_with_default(0, 0, sizeof(string), 0); } if (g->is_shared && !ret_typ_is_shared && !g->inside_or_block) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("}, sizeof("), 0xfe10, {.d_s = shared_styp}}, {_S("))"), 0, { .d_c = 0 }}}))); } } else if (node._typ == 345 /* v.ast.CastExpr */) { v__gen__c__Gen_cast_expr(g, (*node._v__ast__CastExpr)); } else if (node._typ == 346 /* v.ast.ChanInit */) { string elem_typ_str = v__gen__c__Gen_styp(g, (*node._v__ast__ChanInit).elem_type); string noscan = v__gen__c__Gen_check_noscan(g, (*node._v__ast__ChanInit).elem_type); { v__gen__c__Gen_write(g, _S("sync__new_channel_st")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); } if ((*node._v__ast__ChanInit).has_cap) { v__gen__c__Gen_expr(g, (*node._v__ast__ChanInit).cap_expr); } else { v__gen__c__Gen_write(g, _S("0")); } v__gen__c__Gen_write2(g, _S(", sizeof("), elem_typ_str); v__gen__c__Gen_write2(g, _S(")>0 ? sizeof("), elem_typ_str); v__gen__c__Gen_write(g, _S(") : 1)")); } else if (node._typ == 347 /* v.ast.CharLiteral */) { v__gen__c__Gen_char_literal(g, (*node._v__ast__CharLiteral)); } else if (node._typ == 348 /* v.ast.Comment */) { } else if (node._typ == 349 /* v.ast.ComptimeCall */) { v__gen__c__Gen_comptime_call(g, &/*mut*/(*node._v__ast__ComptimeCall)); } else if (node._typ == 350 /* v.ast.ComptimeSelector */) { v__gen__c__Gen_comptime_selector(g, (*node._v__ast__ComptimeSelector)); } else if (node._typ == 352 /* v.ast.ConcatExpr */) { v__gen__c__Gen_concat_expr(g, (*node._v__ast__ConcatExpr)); } else if (node._typ == 343 /* v.ast.CTempVar */) { v__gen__c__Gen_write(g, (*node._v__ast__CTempVar).name); if ((*node._v__ast__CTempVar).is_fixed_ret) { v__gen__c__Gen_write(g, _S(".ret_arr")); } } else if (node._typ == 353 /* v.ast.DumpExpr */) { v__gen__c__Gen_dump_expr(g, (*node._v__ast__DumpExpr)); } else if (node._typ == 355 /* v.ast.EnumVal */) { v__gen__c__Gen_enum_val(g, (*node._v__ast__EnumVal)); } else if (node._typ == 356 /* v.ast.FloatLiteral */) { if (g->pref->nofloat) { v__gen__c__Gen_write(g, int_str(string_int((*node._v__ast__FloatLiteral).val))); } else { v__gen__c__Gen_write(g, (*node._v__ast__FloatLiteral).val); } } else if (node._typ == 381 /* v.ast.SpawnExpr */) { bool old_is_arraymap_set = g->is_arraymap_set; g->is_arraymap_set = false; v__gen__c__Gen_spawn_and_go_expr(g, (*node._v__ast__SpawnExpr), v__gen__c__SpawnGoMode__spawn_); g->is_arraymap_set = old_is_arraymap_set; } else if (node._typ == 357 /* v.ast.GoExpr */) { bool old_is_arraymap_set = g->is_arraymap_set; g->is_arraymap_set = false; v__gen__c__Gen_spawn_and_go_expr(g, ((v__ast__SpawnExpr){.pos = (*node._v__ast__GoExpr).pos,.call_expr = (*node._v__ast__GoExpr).call_expr,.is_expr = (*node._v__ast__GoExpr).is_expr,}), v__gen__c__SpawnGoMode__go_); g->is_arraymap_set = old_is_arraymap_set; } else if (node._typ == 358 /* v.ast.Ident */) { v__gen__c__Gen_ident(g, (*node._v__ast__Ident)); } else if (node._typ == 359 /* v.ast.IfExpr */) { if (!(*node._v__ast__IfExpr).is_comptime) { v__gen__c__Gen_if_expr(g, (*node._v__ast__IfExpr)); } else { v__gen__c__Gen_comptime_if(g, (*node._v__ast__IfExpr)); } } else if (node._typ == 360 /* v.ast.IfGuardExpr */) { v__gen__c__Gen_write(g, _S("/* guard */")); } else if (node._typ == 361 /* v.ast.IndexExpr */) { v__gen__c__Gen_index_expr(g, (*node._v__ast__IndexExpr)); } else if (node._typ == 362 /* v.ast.InfixExpr */) { if (!((*node._v__ast__InfixExpr).op == v__token__Kind__left_shift || (*node._v__ast__InfixExpr).op == v__token__Kind__plus_assign || (*node._v__ast__InfixExpr).op == v__token__Kind__minus_assign)) { v__gen__c__Gen_infix_expr(g, (*node._v__ast__InfixExpr)); } else { g->inside_map_infix = true; v__gen__c__Gen_infix_expr(g, (*node._v__ast__InfixExpr)); g->inside_map_infix = false; } } else if (node._typ == 363 /* v.ast.IntegerLiteral */) { if (string_starts_with((*node._v__ast__IntegerLiteral).val, _S("0o"))) { v__gen__c__Gen_write2(g, _S("0"), string_substr((*node._v__ast__IntegerLiteral).val, 2, 2147483647)); } else if (string_starts_with((*node._v__ast__IntegerLiteral).val, _S("-0o"))) { v__gen__c__Gen_write2(g, _S("-0"), string_substr((*node._v__ast__IntegerLiteral).val, 3, 2147483647)); } else { v__gen__c__Gen_write(g, (*node._v__ast__IntegerLiteral).val); } } else if (node._typ == 364 /* v.ast.IsRefType */) { v__ast__Type typ = v__type_resolver__TypeResolver_typeof_type(&g->type_resolver, (*node._v__ast__IsRefType).expr, v__gen__c__Gen_get_type(g, (*node._v__ast__IsRefType).typ)); v__ast__Type node_typ = v__gen__c__Gen_unwrap_generic(g, typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, node_typ); if (sym->language == v__ast__Language__v && (sym->kind == v__ast__Kind__placeholder || sym->kind == v__ast__Kind__any)) { v__gen__c__Gen_error(g, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), (*node._v__ast__IsRefType).pos); VUNREACHABLE(); } bool is_ref_type = v__gen__c__Gen_contains_ptr(g, node_typ); v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_S("/*IsRefType*/ "), 0xfe10, {.d_s = is_ref_type ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else if (node._typ == 365 /* v.ast.LambdaExpr */) { if ((*node._v__ast__LambdaExpr).call_ctx != ((void*)0)) { Array_v__ast__Type save_cur_concrete_types = g->cur_concrete_types; g->cur_concrete_types = (*node._v__ast__LambdaExpr).call_ctx->concrete_types; v__gen__c__Gen_gen_anon_fn(g, (*node._v__ast__LambdaExpr).func); g->cur_concrete_types = save_cur_concrete_types; } else { v__gen__c__Gen_gen_anon_fn(g, (*node._v__ast__LambdaExpr).func); } } else if (node._typ == 366 /* v.ast.Likely */) { if ((*node._v__ast__Likely).is_likely) { v__gen__c__Gen_write(g, _S("_likely_")); } else { v__gen__c__Gen_write(g, _S("_unlikely_")); } v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_expr(g, (*node._v__ast__Likely).expr); v__gen__c__Gen_write(g, _S(")")); } else if (node._typ == 367 /* v.ast.LockExpr */) { v__gen__c__Gen_lock_expr(g, (*node._v__ast__LockExpr)); } else if (node._typ == 368 /* v.ast.MapInit */) { v__gen__c__Gen_map_init(g, (*node._v__ast__MapInit)); } else if (node._typ == 369 /* v.ast.MatchExpr */) { v__gen__c__Gen_match_expr(g, (*node._v__ast__MatchExpr)); } else if (node._typ == 335 /* v.ast.NodeError */) { } else if (node._typ == 370 /* v.ast.Nil */) { v__gen__c__Gen_write(g, _S("((void*)0)")); } else if (node._typ == 371 /* v.ast.None */) { v__gen__c__Gen_write(g, _S("_const_none__")); } else if (node._typ == 372 /* v.ast.OffsetOf */) { string styp = v__gen__c__Gen_styp(g, (*node._v__ast__OffsetOf).struct_type); { v__gen__c__Gen_write(g, _S("/*OffsetOf*/ (u32)(__offsetof(")); v__gen__c__Gen_write(g, v__util__no_dots(styp)); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, (*node._v__ast__OffsetOf).field); v__gen__c__Gen_write(g, _S("))")); } } else if (node._typ == 373 /* v.ast.OrExpr */) { } else if (node._typ == 374 /* v.ast.ParExpr */) { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_expr(g, (*node._v__ast__ParExpr).expr); v__gen__c__Gen_write(g, _S(")")); } else if (node._typ == 375 /* v.ast.PostfixExpr */) { if (((*node._v__ast__PostfixExpr).auto_locked).len != 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("sync__RwMutex_lock(&"), 0xfe10, {.d_s = (*node._v__ast__PostfixExpr).auto_locked}}, {_S("->mtx);"), 0, { .d_c = 0 }}}))); } g->inside_map_postfix = true; if ((*node._v__ast__PostfixExpr).is_c2v_prefix) { v__gen__c__Gen_write(g, v__token__Kind_str((*node._v__ast__PostfixExpr).op)); } if (v__ast__Expr_is_auto_deref_var((*node._v__ast__PostfixExpr).expr)) { v__gen__c__Gen_write(g, _S("(*")); v__gen__c__Gen_expr(g, (*node._v__ast__PostfixExpr).expr); v__gen__c__Gen_write(g, _S(")")); } else if ((*node._v__ast__PostfixExpr).op == v__token__Kind__question) { string cur_line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); string expr_str = _S(""); bool is_unwrapped = true; string dot_or_ptr = _S("."); if (((*node._v__ast__PostfixExpr).expr)._typ == 350 /* v.ast.ComptimeSelector */ && ((*(v__ast__ComptimeSelector*)__as_cast(((*node._v__ast__PostfixExpr).expr)._v__ast__ComptimeSelector,((*node._v__ast__PostfixExpr).expr)._typ, 350)).left)._typ == 358 /* v.ast.Ident */) { expr_str = v__gen__c__Gen_gen_comptime_selector(g, (*(*node._v__ast__PostfixExpr).expr._v__ast__ComptimeSelector)); } else if (((*node._v__ast__PostfixExpr).expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*node._v__ast__PostfixExpr).expr)._v__ast__Ident,((*node._v__ast__PostfixExpr).expr)._typ, 358)).ct_expr) { expr_str = (*(*node._v__ast__PostfixExpr).expr._v__ast__Ident).name; is_unwrapped = !g->inside_assign; dot_or_ptr = (!(((*(*node._v__ast__PostfixExpr).expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast(((*(*node._v__ast__PostfixExpr).expr._v__ast__Ident).obj)._v__ast__Var,((*(*node._v__ast__PostfixExpr).expr._v__ast__Ident).obj)._typ, 422)).is_auto_deref) ? (_S(".")) : (_S("->"))); } v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = expr_str}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("state != 0) {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln2(g, _S("\tpanic_option_not_set(_S(\"none\"));"), _S("}")); v__gen__c__Gen_write(g, cur_line); if (is_unwrapped) { v__ast__Type typ = v__type_resolver__TypeResolver_typeof_type(&g->type_resolver, (*node._v__ast__PostfixExpr).expr, (*node._v__ast__PostfixExpr).typ); { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, typ)); v__gen__c__Gen_write(g, _S("*)&")); } v__gen__c__Gen_expr(g, (*node._v__ast__PostfixExpr).expr); v__gen__c__Gen_write(g, _S(".data")); } else { v__gen__c__Gen_expr(g, (*node._v__ast__PostfixExpr).expr); } } else { v__gen__c__Gen_expr(g, (*node._v__ast__PostfixExpr).expr); } g->inside_map_postfix = false; if (!(*node._v__ast__PostfixExpr).is_c2v_prefix && (*node._v__ast__PostfixExpr).op != v__token__Kind__question) { v__gen__c__Gen_write(g, v__token__Kind_str((*node._v__ast__PostfixExpr).op)); } if (((*node._v__ast__PostfixExpr).auto_locked).len != 0) { v__gen__c__Gen_writeln(g, _S(";")); { v__gen__c__Gen_write(g, _S("sync__RwMutex_unlock(&")); v__gen__c__Gen_write(g, (*node._v__ast__PostfixExpr).auto_locked); v__gen__c__Gen_write(g, _S("->mtx)")); } } } else if (node._typ == 376 /* v.ast.PrefixExpr */) { bool gen_or = (*node._v__ast__PrefixExpr).op == v__token__Kind__arrow && ((*node._v__ast__PrefixExpr).or_block.kind != v__ast__OrKind__absent || (*node._v__ast__PrefixExpr).is_option); if ((*node._v__ast__PrefixExpr).op == v__token__Kind__amp) { g->is_amp = true; } if ((*node._v__ast__PrefixExpr).op == v__token__Kind__arrow) { string styp = v__gen__c__Gen_styp(g, (*node._v__ast__PrefixExpr).right_type); v__ast__TypeSymbol* right_sym = v__ast__Table_sym(g->table, (*node._v__ast__PrefixExpr).right_type); v__ast__Chan right_inf = *(v__ast__Chan*)__as_cast((right_sym->info)._v__ast__Chan,(right_sym->info)._typ, 550); v__ast__Type elem_type = right_inf.elem_type; bool is_gen_or_and_assign_rhs = gen_or && !g->discard_or_result; string _t2; /* if prepend */ if (is_gen_or_and_assign_rhs) { string line = v__gen__c__Gen_go_before_last_stmt(g); strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); _t2 = line; } else { _t2 = _S(""); } string cur_line = _t2; string tmp_opt = (gen_or ? (v__gen__c__Gen_new_tmp_var(g)) : (_S(""))); if (gen_or) { string opt_elem_type = v__gen__c__Gen_styp(g, v__ast__Type_set_flag(elem_type, v__ast__TypeFlag__option)); v__gen__c__Gen_register_chan_pop_option_call(g, opt_elem_type, styp); { v__gen__c__Gen_write(g, opt_elem_type); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(" = __Option_")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("_popval(")); } } else { { v__gen__c__Gen_write(g, _S("__")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("_popval(")); } } v__gen__c__Gen_expr(g, (*node._v__ast__PrefixExpr).right); v__gen__c__Gen_write(g, _S(")")); if (gen_or) { if (!(*node._v__ast__PrefixExpr).is_option) { v__gen__c__Gen_or_block(g, tmp_opt, (*node._v__ast__PrefixExpr).or_block, elem_type); } if (is_gen_or_and_assign_rhs) { string elem_styp = v__gen__c__Gen_styp(g, elem_type); { v__gen__c__Gen_write(g, _S(";\n")); v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, elem_styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(".data")); } } } } else { if (g->is_option_auto_heap) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, (*node._v__ast__PrefixExpr).right_type)); v__gen__c__Gen_write(g, _S("*)")); } } bool has_slice_call = false; if (!g->is_option_auto_heap && !(g->is_amp && v__ast__Expr_is_auto_deref_var((*node._v__ast__PrefixExpr).right))) { has_slice_call = (*node._v__ast__PrefixExpr).op == v__token__Kind__amp && ((*node._v__ast__PrefixExpr).right)._typ == 361 /* v.ast.IndexExpr */ && ((*(v__ast__IndexExpr*)__as_cast(((*node._v__ast__PrefixExpr).right)._v__ast__IndexExpr,((*node._v__ast__PrefixExpr).right)._typ, 361)).index)._typ == 377 /* v.ast.RangeExpr */; if (has_slice_call) { { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, (*node._v__ast__PrefixExpr).right_type)); v__gen__c__Gen_write(g, _S(", ")); } } else { v__gen__c__Gen_write(g, v__token__Kind_str((*node._v__ast__PrefixExpr).op)); } } v__gen__c__Gen_expr(g, (*node._v__ast__PrefixExpr).right); if (has_slice_call) { v__gen__c__Gen_write(g, _S(")")); } if (g->is_option_auto_heap) { v__gen__c__Gen_write(g, _S(".data")); } } g->is_amp = false; } else if (node._typ == 377 /* v.ast.RangeExpr */) { } else if (node._typ == 378 /* v.ast.SelectExpr */) { v__gen__c__Gen_select_expr(g, (*node._v__ast__SelectExpr)); } else if (node._typ == 379 /* v.ast.SelectorExpr */) { v__gen__c__Gen_selector_expr(g, (*node._v__ast__SelectorExpr)); } else if (node._typ == 380 /* v.ast.SizeOf */) { v__gen__c__Gen_size_of(g, (*node._v__ast__SizeOf)); } else if (node._typ == 382 /* v.ast.SqlExpr */) { if ((*node._v__ast__SqlExpr).is_insert) { v__gen__c__Gen_sql_insert_expr(g, (*node._v__ast__SqlExpr)); } else { v__gen__c__Gen_sql_select_expr(g, (*node._v__ast__SqlExpr)); } } else if (node._typ == 384 /* v.ast.StringLiteral */) { v__gen__c__Gen_string_literal(g, (*node._v__ast__StringLiteral)); } else if (node._typ == 383 /* v.ast.StringInterLiteral */) { v__gen__c__Gen_string_inter_literal(g, (*node._v__ast__StringInterLiteral)); } else if (node._typ == 385 /* v.ast.StructInit */) { if ((*node._v__ast__StructInit).unresolved) { v__gen__c__Gen_expr(g, v__ast__Table_resolve_init(g->table, (*node._v__ast__StructInit), v__gen__c__Gen_unwrap_generic(g, (*node._v__ast__StructInit).typ))); } else { g->inside_struct_init = true; g->cur_struct_init_typ = (*node._v__ast__StructInit).typ; v__gen__c__Gen_struct_init(g, (*node._v__ast__StructInit)); g->cur_struct_init_typ = 0; g->inside_struct_init = false; } } else if (node._typ == 386 /* v.ast.TypeNode */) { v__ast__Type typ = v__gen__c__Gen_unwrap_generic(g, (*node._v__ast__TypeNode).typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); string sidx = v__gen__c__Gen_type_sidx(g, typ); { v__gen__c__Gen_write(g, sidx); } if (!g->pref->is_prod) { { v__gen__c__Gen_write(g, _S(" /* ")); v__gen__c__Gen_write(g, sym->name); v__gen__c__Gen_write(g, _S(" */")); } } } else if (node._typ == 387 /* v.ast.TypeOf */) { v__gen__c__Gen_typeof_expr(g, (*node._v__ast__TypeOf)); } else if (node._typ == 388 /* v.ast.UnsafeExpr */) { v__gen__c__Gen_expr(g, (*node._v__ast__UnsafeExpr).expr); } g->discard_or_result = old_discard_or_result; g->is_void_expr_stmt = old_is_void_expr_stmt; } VV_LOC void v__gen__c__Gen_char_literal(v__gen__c__Gen* g, v__ast__CharLiteral node) { if (fast_string_eq(node.val, _S("\\`"))) { v__gen__c__Gen_write(g, _S("'`'")); return; } if (!string_is_pure_ascii(node.val)) { { v__gen__c__Gen_write(g, _S("((rune)0x")); v__gen__c__Gen_write(g, int_hex(string_utf32_code(node.val))); v__gen__c__Gen_write(g, _S(" /* `")); v__gen__c__Gen_write(g, node.val); v__gen__c__Gen_write(g, _S("` */)")); } return; } if (node.val.len == 1) { u8 clit = string_at(node.val, 0); if (clit < 32 || clit == 92 || clit > 126) { v__gen__c__Gen_write(g, _S("'")); v__gen__c__write_octal_escape((voidptr)&g->out, clit); v__gen__c__Gen_write(g, _S("'")); return; } } { v__gen__c__Gen_write(g, _S("'")); v__gen__c__Gen_write(g, node.val); v__gen__c__Gen_write(g, _S("'")); } } VV_LOC void v__gen__c__Gen_type_name(v__gen__c__Gen* g, v__ast__Type raw_type) { v__ast__Type typ = v__gen__c__Gen_get_type(g, raw_type); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); string s = _S(""); if (sym->kind == v__ast__Kind__function) { if (v__ast__Type_is_ptr(typ)) { s = string__plus(_S("&"), v__gen__c__Gen_fn_decl_str(g, *(v__ast__FnType*)__as_cast((sym->info)._v__ast__FnType,(sym->info)._typ, 553))); } else { s = v__gen__c__Gen_fn_decl_str(g, *(v__ast__FnType*)__as_cast((sym->info)._v__ast__FnType,(sym->info)._typ, 553)); } } else { s = v__ast__Table_type_to_str(g->table, v__gen__c__Gen_unwrap_generic(g, typ)); } { v__gen__c__Gen_write(g, _S("_S(\"")); v__gen__c__Gen_write(g, v__util__strip_main_name(s)); v__gen__c__Gen_write(g, _S("\")")); } } VV_LOC void v__gen__c__Gen_typeof_expr(v__gen__c__Gen* g, v__ast__TypeOf node) { v__ast__Type typ = v__type_resolver__TypeResolver_typeof_type(&g->type_resolver, node.expr, v__gen__c__Gen_get_type(g, node.typ)); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); if (sym->kind == v__ast__Kind__sum_type) { { v__gen__c__Gen_write(g, _S("charptr_vstring_literal(v_typeof_sumtype_")); v__gen__c__Gen_write(g, sym->cname); v__gen__c__Gen_write(g, _S("( (")); } if (v__ast__Type_nr_muls(typ) > 0) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(typ))); } v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write(g, _S(")._typ ))")); } else if (sym->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed fixed_info = *(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549); string typ_name = v__ast__Table_get_type_name(g->table, fixed_info.elem_type); { v__gen__c__Gen_write(g, _S("_S(\"[")); v__gen__c__Gen_write_decimal(g, fixed_info.size); v__gen__c__Gen_write(g, _S("]")); v__gen__c__Gen_write(g, v__util__strip_main_name(typ_name)); v__gen__c__Gen_write(g, _S("\")")); } } else if (sym->kind == v__ast__Kind__function) { v__ast__FnType info = *(v__ast__FnType*)__as_cast((sym->info)._v__ast__FnType,(sym->info)._typ, 553); { v__gen__c__Gen_write(g, _S("_S(\"")); v__gen__c__Gen_write(g, v__gen__c__Gen_fn_decl_str(g, info)); v__gen__c__Gen_write(g, _S("\")")); } } else if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__variadic)) { v__ast__TypeSymbol* varg_elem_type_sym = v__ast__Table_sym(g->table, v__ast__Table_value_type(g->table, typ)); { v__gen__c__Gen_write(g, _S("_S(\"...")); v__gen__c__Gen_write(g, v__util__strip_main_name(varg_elem_type_sym->name)); v__gen__c__Gen_write(g, _S("\")")); } } else { v__gen__c__Gen_type_name(g, typ); } } VV_LOC void v__gen__c__Gen_selector_expr(v__gen__c__Gen* g, v__ast__SelectorExpr node) { bool prevent_sum_type_unwrapping_once = g->prevent_sum_type_unwrapping_once; g->prevent_sum_type_unwrapping_once = false; if (node.name_type > 0) { if (node.gkind_field == (v__ast__GenericKindField__name)) { v__gen__c__Gen_type_name(g, node.name_type); return; } else if (node.gkind_field == (v__ast__GenericKindField__typ)) { v__gen__c__Gen_write(g, int_str(((int)(v__gen__c__Gen_unwrap_generic(g, node.name_type))))); return; } else if (node.gkind_field == (v__ast__GenericKindField__unaliased_typ)) { v__gen__c__Gen_write(g, int_str(((int)(v__ast__Table_unaliased_type(g->table, v__gen__c__Gen_unwrap_generic(g, node.name_type)))))); return; } else if (node.gkind_field == (v__ast__GenericKindField__indirections)) { v__gen__c__Gen_write(g, int_str(((int)(v__ast__Type_nr_muls(v__gen__c__Gen_unwrap_generic(g, node.name_type)))))); return; } else if (node.gkind_field == (v__ast__GenericKindField__unknown)) { if (fast_string_eq(node.field_name, _S("name"))) { v__ast__Type name_type = node.name_type; if ((node.expr)._typ == 387 /* v.ast.TypeOf */) { name_type = v__type_resolver__TypeResolver_typeof_type(&g->type_resolver, (*node.expr._v__ast__TypeOf).expr, name_type); } v__gen__c__Gen_type_name(g, name_type); return; } else if (fast_string_eq(node.field_name, _S("idx")) || fast_string_eq(node.field_name, _S("unaliased_typ"))) { v__ast__Type name_type = node.name_type; if ((node.expr)._typ == 387 /* v.ast.TypeOf */) { name_type = v__type_resolver__TypeResolver_typeof_field_type(&g->type_resolver, v__type_resolver__TypeResolver_typeof_type(&g->type_resolver, (*node.expr._v__ast__TypeOf).expr, name_type), node.field_name); v__gen__c__Gen_write(g, int_str(((int)(name_type)))); } else { v__gen__c__Gen_write(g, int_str(((int)(v__gen__c__Gen_unwrap_generic(g, name_type))))); } return; } else if (fast_string_eq(node.field_name, _S("key_type")) || fast_string_eq(node.field_name, _S("value_type")) || fast_string_eq(node.field_name, _S("element_type"))) { v__ast__Type name_type = node.name_type; name_type = v__type_resolver__TypeResolver_typeof_field_type(&g->type_resolver, v__type_resolver__TypeResolver_typeof_type(&g->type_resolver, node.expr, name_type), node.field_name); v__gen__c__Gen_write(g, int_str(((int)(name_type)))); return; } else if (fast_string_eq(node.field_name, _S("indirections"))) { v__ast__Type name_type = node.name_type; if ((node.expr)._typ == 387 /* v.ast.TypeOf */) { name_type = v__type_resolver__TypeResolver_typeof_type(&g->type_resolver, (*node.expr._v__ast__TypeOf).expr, name_type); } v__gen__c__Gen_write(g, int_str(((int)(v__ast__Type_nr_muls(v__gen__c__Gen_unwrap_generic(g, name_type)))))); return; } v__gen__c__Gen_error(g, _S("unknown generic field"), node.pos); VUNREACHABLE(); } } if (node.expr_type == 0) { v__gen__c__Gen_checker_bug(g, _S("unexpected SelectorExpr.expr_type = 0"), node.pos); } v__ast__Type unwrapped_expr_type = v__gen__c__Gen_unwrap_generic(g, node.expr_type); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, unwrapped_expr_type); string field_name = (sym->language == v__ast__Language__v ? (v__gen__c__c_name(node.field_name)) : (node.field_name)); bool is_as_cast = (node.expr)._typ == 339 /* v.ast.AsCast */; if (is_as_cast) { v__gen__c__Gen_write(g, _S("(")); } if (node.or_block.kind != v__ast__OrKind__absent && v__ast__Table_sym(g->table, node.typ)->kind != v__ast__Kind__chan) { bool is_ptr = (sym->kind == v__ast__Kind__interface || sym->kind == v__ast__Kind__sum_type); string stmt_str = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); string styp = v__gen__c__Gen_styp(g, v__gen__c__Gen_unwrap_generic(g, node.typ)); g->empty_line = true; bool is_option_unwrap = v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__option); string tmp_var = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); } if (is_option_unwrap) { v__gen__c__Gen_write(g, _S("*")); } { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } bool needs_addr = false; bool needs_deref = is_ptr && !is_option_unwrap; if (needs_deref) { v__gen__c__Gen_write(g, _S("*(")); } else if (is_option_unwrap && !is_ptr) { needs_addr = !((node.expr)._typ == 358 /* v.ast.Ident */ || (node.expr)._typ == 376 /* v.ast.PrefixExpr */); if (!needs_addr) { v__gen__c__Gen_write(g, _S("&")); } else { { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(", ")); } } } v__gen__c__Gen_expr(g, node.expr); for (int i = 0; i < node.from_embed_types.len; ++i) { v__ast__Type embed = ((v__ast__Type*)node.from_embed_types.data)[i]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(g->table, embed); string embed_name = v__ast__TypeSymbol_embed_name(embed_sym); bool is_left_ptr = (i == 0 ? (v__ast__Type_is_ptr(node.expr_type)) : (v__ast__Type_is_ptr((*(v__ast__Type*)array_get(node.from_embed_types, (int)(i - 1)))))); if (is_left_ptr) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } v__gen__c__Gen_write(g, embed_name); } if (v__ast__Type_is_ptr(node.expr_type) && node.from_embed_types.len == 0) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } v__gen__c__Gen_write(g, field_name); if (needs_deref) { v__gen__c__Gen_write(g, _S(")")); } if (needs_addr) { v__gen__c__Gen_write(g, _S(")")); } if (is_option_unwrap) { map_set(&g->tmp_var_ptr, &(string[]){tmp_var}, &(bool[]) { true }); } v__gen__c__Gen_or_block(g, tmp_var, node.or_block, node.typ); if (is_option_unwrap) { map_delete(&g->tmp_var_ptr, &(string[]){tmp_var}); } v__gen__c__Gen_write2(g, stmt_str, _S(" ")); v__ast__Type unwrapped_typ = v__ast__Type_clear_option_and_result(node.typ); string unwrapped_styp = v__gen__c__Gen_styp(g, unwrapped_typ); { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, unwrapped_styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S("->data)")); } return; } bool is_opt_or_res = (node.expr)._typ == 358 /* v.ast.Ident */ && v__ast__Type_has_option_or_result(node.expr_type); if (is_opt_or_res) { string opt_base_typ = v__gen__c__Gen_base_type(g, node.expr_type); { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, opt_base_typ); v__gen__c__Gen_write(g, _S("*)")); } } v__ast__TypeSymbol* final_sym = v__ast__Table_final_sym(g->table, unwrapped_expr_type); if (final_sym->kind == v__ast__Kind__array_fixed) { if (!fast_string_eq(node.field_name, _S("len"))) { v__gen__c__Gen_error(g, _S("field_name should be `len`"), node.pos); VUNREACHABLE(); } v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((final_sym->info)._v__ast__ArrayFixed,(final_sym->info)._typ, 549); { v__gen__c__Gen_write_decimal(g, info.size); } return; } else if (sym->kind == v__ast__Kind__chan && (fast_string_eq(node.field_name, _S("len")) || fast_string_eq(node.field_name, _S("closed")))) { { v__gen__c__Gen_write(g, _S("sync__Channel_")); v__gen__c__Gen_write(g, node.field_name); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write(g, _S(")")); return; } else if (g->enum_data_type == node.typ) { v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write2(g, _S("."), node.field_name); return; } string sum_type_deref_field = _S(""); string sum_type_dot = _S("."); v__ast__Type field_typ = _const_v__ast__void_type; bool is_option_unwrap = false; bool is_iface_or_sumtype = (sym->kind == v__ast__Kind__interface || sym->kind == v__ast__Kind__sum_type); int deref_count = 0; _result_v__ast__StructField _t1; _option_v__ast__Fn _t2; if (_t1 = v__ast__Table_find_field_with_embeds(g->table, sym, node.field_name), !_t1.is_error) { v__ast__StructField f = *(v__ast__StructField*)_t1.data; v__ast__TypeSymbol* field_sym = v__ast__Table_sym(g->table, f.typ); field_typ = f.typ; if (is_iface_or_sumtype) { v__gen__c__Gen_write(g, _S("(*(")); deref_count++; } bool is_option = v__ast__Type_has_flag(field_typ, v__ast__TypeFlag__option); if ((field_sym->kind == v__ast__Kind__sum_type || field_sym->kind == v__ast__Kind__interface) || is_option) { if (!prevent_sum_type_unwrapping_once) { v__ast__Scope* scope = v__ast__Scope_innermost(g->file->scope, node.pos.pos); v__ast__ScopeStructField* field = v__ast__Scope_find_struct_field(scope, v__ast__Expr_str(&node.expr), node.expr_type, node.field_name); if (field != ((void*)0)) { bool nested_unwrap = is_option && field->smartcasts.len > 1; bool _t3 = (is_option && field->smartcasts.len > 0); is_option_unwrap = _t3 && v__ast__Type_clear_flag(field->typ, v__ast__TypeFlag__option) == (*(v__ast__Type*)array_last(field->smartcasts)); if (v__ast__Type_is_ptr(field->orig_type)) { sum_type_dot = _S("->"); } if (nested_unwrap && field_sym->kind == v__ast__Kind__sum_type) { v__gen__c__Gen_write(g, _S("*(")); deref_count++; } for (int i = 0; i < field->smartcasts.len; ++i) { v__ast__Type typ = ((v__ast__Type*)field->smartcasts.data)[i]; if (i == 0 && (is_option_unwrap || nested_unwrap)) { string deref = (g->inside_selector ? ((is_iface_or_sumtype || (v__ast__Type_is_ptr(field->orig_type) && g->left_is_opt && is_option_unwrap) ? (string_repeat(_S("*"), v__ast__Type_nr_muls(typ))) : (string_repeat(_S("*"), (int)(v__ast__Type_nr_muls(typ) + 1))))) : sym->kind == v__ast__Kind__interface && !v__ast__Type_is_ptr(typ) && v__ast__Type_has_flag(field->orig_type, v__ast__TypeFlag__option) ? (_S("")) : (_S("*"))); deref_count += deref.len; g->inside_selector_deref = deref_count > v__ast__Type_nr_muls(typ); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, deref); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, typ)); v__gen__c__Gen_write(g, _S("*)")); } } if (i == 0 || !nested_unwrap) { v__gen__c__Gen_write(g, _S("(")); } if (field_sym->kind == v__ast__Kind__sum_type && !is_option) { v__gen__c__Gen_write(g, _S("*")); } v__ast__TypeSymbol* cast_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, typ)); if (field_sym->kind == v__ast__Kind__interface && cast_sym->kind == v__ast__Kind__interface && !is_option_unwrap) { string ptr = string_repeat(_S("*"), v__ast__Type_nr_muls(field->typ)); string dot = (v__ast__Type_is_ptr(node.expr_type) ? (_S("->")) : (_S("."))); v__gen__c__Gen_write(g, str_intp(7, _MOV((StrIntpData[]){{_S("I_"), 0xfe10, {.d_s = field_sym->cname}}, {_S("_as_I_"), 0xfe10, {.d_s = cast_sym->cname}}, {_S("("), 0xfe10, {.d_s = ptr}}, {_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&node.expr)}}, {_SLIT0, 0xfe10, {.d_s = dot}}, {_SLIT0, 0xfe10, {.d_s = node.field_name}}, {_S("))"), 0, { .d_c = 0 }}}))); return; } else if (!is_option_unwrap) { if (i != 0) { string dot = (v__ast__Type_is_ptr(field->typ) ? (_S("->")) : (_S("."))); sum_type_deref_field = string__plus(sum_type_deref_field, str_intp(2, _MOV((StrIntpData[]){{_S(")"), 0xfe10, {.d_s = dot}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if ((cast_sym->info)._typ == 537 /* v.ast.Aggregate */) { v__ast__TypeSymbol* agg_sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get((*cast_sym->info._v__ast__Aggregate).types, g->aggregate_type_idx))); sum_type_deref_field = string__plus(sum_type_deref_field, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = agg_sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else { if (i == 0 && nested_unwrap) { sum_type_deref_field = string__plus(sum_type_deref_field, _S("data)")); } else { sum_type_deref_field = string__plus(sum_type_deref_field, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = cast_sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } } } } } } } else if (_t2 = v__ast__TypeSymbol_find_method_with_generic_parent(sym, node.field_name), _t2.state == 0) { v__ast__Fn m = *(v__ast__Fn*)_t2.data; bool has_embeds = false; if ((sym->info)._typ == 518 /* v.ast.Struct */ || (sym->info)._typ == 537 /* v.ast.Aggregate */) { if (node.from_embed_types.len > 0) { has_embeds = true; } } if (!has_embeds) { if (!node.has_hidden_receiver) { if ((node.expr)._typ == 358 /* v.ast.Ident */ && (sym->info)._typ == 542 /* v.ast.Interface */) { string left_cc_type = v__gen__c__Gen_cc_type(g, v__ast__Table_unaliased_type(g->table, node.expr_type), false); string left_type_name = v__util__no_dots(left_cc_type); { v__gen__c__Gen_write(g, v__gen__c__c_name(left_type_name)); v__gen__c__Gen_write(g, _S("_name_table[")); v__gen__c__Gen_write(g, (*node.expr._v__ast__Ident).name); v__gen__c__Gen_write(g, v__gen__c__Gen_dot_or_ptr(g, node.expr_type)); v__gen__c__Gen_write(g, _S("_typ]._method_")); v__gen__c__Gen_write(g, m.name); } } else { { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, v__ast__Type_idx_type(node.expr_type))); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, m.name); } } return; } v__ast__Param receiver = (*(v__ast__Param*)array_get(m.params, 0)); string expr_styp = v__gen__c__Gen_styp(g, v__ast__Type_idx_type(v__gen__c__Gen_unwrap_generic(g, node.expr_type))); string name = str_intp(4, _MOV((StrIntpData[]){{_S("_V_closure_"), 0xfe10, {.d_s = expr_styp}}, {_S("_"), 0xfe10, {.d_s = m.name}}, {_S("_"), 0xfe07, {.d_i32 = node.pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}})); sync__RwMutex_lock(&g->anon_fns->mtx); /*lock*/ { if (!(Array_string_contains(g->anon_fns->val, name))) { array_push((array*)&g->anon_fns->val, _MOV((string[]){ string_clone(name) })); v__gen__c__Gen_gen_closure_fn(g, expr_styp, m, name); } } sync__RwMutex_unlock(&g->anon_fns->mtx);; { v__gen__c__Gen_write(g, _S("builtin__closure__closure_create(")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S(", ")); } if (!v__ast__Type_is_ptr(receiver.typ)) { v__gen__c__Gen_write(g, _S("memdup_uncollectable(")); } bool has_addr = false; if (!v__ast__Type_is_ptr(node.expr_type)) { if ((node.expr)._typ == 361 /* v.ast.IndexExpr */) { has_addr = true; { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, node.expr_type)); v__gen__c__Gen_write(g, _S(", ")); } } else { v__gen__c__Gen_write(g, _S("&")); } } if (!v__ast__Expr_is_lvalue(node.expr)) { string current_stmt = v__gen__c__Gen_go_before_last_stmt(g); g->empty_line = true; v__ast__CTempVar var = v__gen__c__Gen_new_ctemp_var_then_gen(g, node.expr, node.expr_type); v__gen__c__Gen_write(g, string_trim_left(current_stmt, _S("\t "))); v__gen__c__Gen_expr(g, v__ast__CTempVar_to_sumtype_v__ast__Expr(&var)); } else { v__gen__c__Gen_expr(g, node.expr); } if (has_addr) { v__gen__c__Gen_write(g, _S(")")); } if (!v__ast__Type_is_ptr(receiver.typ)) { { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, expr_styp); v__gen__c__Gen_write(g, _S("))")); } } v__gen__c__Gen_write(g, _S(")")); return; } } else { IError err = _t2.err; if (is_iface_or_sumtype) { v__gen__c__Gen_write(g, _S("(*(")); } } bool field_is_opt = (node.expr)._typ == 358 /* v.ast.Ident */ && v__ast__Ident_is_auto_heap(((v__ast__Ident*)__as_cast((node.expr)._v__ast__Ident,(node.expr)._typ, 358))) && (*(v__ast__Ident*)__as_cast((node.expr)._v__ast__Ident,(node.expr)._typ, 358)).or_expr.kind != v__ast__OrKind__absent && v__ast__Type_has_flag(field_typ, v__ast__TypeFlag__option); if (field_is_opt) { { v__gen__c__Gen_write(g, _S("((")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, field_typ)); v__gen__c__Gen_write(g, _S(")")); } } bool old_inside_selector = g->inside_selector; bool old_inside_selector_deref = g->inside_selector_deref; g->inside_selector = (node.expr)._typ == 379 /* v.ast.SelectorExpr */ && ((*(v__ast__SelectorExpr*)__as_cast((node.expr)._v__ast__SelectorExpr,(node.expr)._typ, 379)).expr)._typ == 358 /* v.ast.Ident */; int n_ptr = (int)(v__ast__Type_nr_muls(node.expr_type) - 1); if (n_ptr > 0) { v__gen__c__Gen_write2(g, _S("("), string_repeat(_S("*"), n_ptr)); v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_expr(g, node.expr); } bool opt_ptr_already_deref = g->inside_selector_deref; g->inside_selector = old_inside_selector; g->inside_selector_deref = old_inside_selector_deref; if (field_is_opt) { v__gen__c__Gen_write(g, _S(")")); } if (is_opt_or_res) { v__gen__c__Gen_write(g, _S(".data)")); } if (is_as_cast) { v__gen__c__Gen_write(g, _S(")")); } bool has_embed = false; if ((sym->info)._typ == 518 /* v.ast.Struct */ || (sym->info)._typ == 537 /* v.ast.Aggregate */) { if (node.generic_from_embed_types.len > 0 && (sym->info)._typ == 518 /* v.ast.Struct */) { if ((*sym->info._v__ast__Struct).embeds.len > 0) { bool is_find = false; for (int _t5 = 0; _t5 < node.generic_from_embed_types.len; ++_t5) { Array_v__ast__Type arr_val = ((Array_v__ast__Type*)node.generic_from_embed_types.data)[_t5]; if (arr_val.len > 0) { if ((*(v__ast__Type*)array_get(arr_val, 0)) == (*(v__ast__Type*)array_get((*sym->info._v__ast__Struct).embeds, 0))) { v__gen__c__Gen_write_selector_expr_embed_name(g, node, arr_val); is_find = true; has_embed = true; break; } } } if (!is_find) { has_embed = node.from_embed_types.len > 0; v__gen__c__Gen_write_selector_expr_embed_name(g, node, node.from_embed_types); } } else { has_embed = node.from_embed_types.len > 0; v__gen__c__Gen_write_selector_expr_embed_name(g, node, node.from_embed_types); } } else if ((sym->info)._typ == 537 /* v.ast.Aggregate */) { v__ast__TypeSymbol* agg_sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get((*sym->info._v__ast__Aggregate).types, g->aggregate_type_idx))); if (!v__ast__Table_struct_has_field(g->table, agg_sym, field_name)) { has_embed = node.from_embed_types.len > 0; v__gen__c__Gen_write_selector_expr_embed_name(g, node, node.from_embed_types); } } else { has_embed = node.from_embed_types.len > 0; v__gen__c__Gen_write_selector_expr_embed_name(g, node, node.from_embed_types); } } bool alias_to_ptr = (sym->info)._typ == 539 /* v.ast.Alias */ && v__ast__Type_is_ptr((*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type); bool is_dereferenced = (node.expr)._typ == 379 /* v.ast.SelectorExpr */ && v__ast__Type_is_ptr((*(v__ast__SelectorExpr*)__as_cast((node.expr)._v__ast__SelectorExpr,(node.expr)._typ, 379)).expr_type) && !v__ast__Type_is_ptr((*(v__ast__SelectorExpr*)__as_cast((node.expr)._v__ast__SelectorExpr,(node.expr)._typ, 379)).typ) && (final_sym->kind == v__ast__Kind__interface || final_sym->kind == v__ast__Kind__sum_type); bool left_is_ptr = field_is_opt || (((!is_dereferenced && v__ast__Type_is_ptr(unwrapped_expr_type)) || sym->kind == v__ast__Kind__chan || alias_to_ptr) && node.from_embed_types.len == 0) || (v__ast__Expr_is_as_cast(node.expr) && g->inside_smartcast) || (!opt_ptr_already_deref && v__ast__Type_is_ptr(unwrapped_expr_type)); if (!has_embed && left_is_ptr) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } if (!has_embed && v__ast__Type_has_flag(node.expr_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("val.")); } if (node.expr_type == 0) { v__gen__c__verror(str_intp(5, _MOV((StrIntpData[]){{_S("cgen: SelectorExpr | expr_type: 0 | it.expr: `"), 0xfe10, {.d_s = v__ast__Expr_str(&node.expr)}}, {_S("` | field: `"), 0xfe10, {.d_s = node.field_name}}, {_S("` | file: "), 0xfe10, {.d_s = g->file->path}}, {_S(" | line: "), 0xfe07, {.d_i32 = node.pos.line_nr}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } v__gen__c__Gen_write(g, field_name); if (is_option_unwrap) { if (v__ast__Table_final_sym(g->table, node.expr_type)->kind == v__ast__Kind__sum_type || v__ast__Table_final_sym(g->table, node.expr_type)->kind == v__ast__Kind__interface) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } v__gen__c__Gen_write(g, _S("data))")); } if ((sum_type_deref_field).len != 0) { v__gen__c__Gen_write2(g, sum_type_dot, sum_type_deref_field); v__gen__c__Gen_write(g, _S(")")); } if (sym->kind == v__ast__Kind__interface || sym->kind == v__ast__Kind__sum_type) { v__gen__c__Gen_write(g, _S("))")); } } VV_LOC void v__gen__c__Gen_gen_closure_fn(v__gen__c__Gen* g, string expr_styp, v__ast__Fn m, string name) { v__ast__Param receiver = (*(v__ast__Param*)array_get(m.params, 0)); string data_styp = v__gen__c__Gen_styp(g, v__ast__Type_idx_type(receiver.typ)); strings__Builder sb = strings__new_builder(256); { strings__Builder_write_string(&sb, v__gen__c__Gen_styp(g, m.return_type)); strings__Builder_write_string(&sb, _S(" ")); strings__Builder_write_string(&sb, name); strings__Builder_write_string(&sb, _S("(")); } for (int i = 1; i < m.params.len; ++i) { v__ast__Param param = (*(v__ast__Param*)array_get(m.params, i)); if (i != 1) { strings__Builder_write_string(&sb, _S(", ")); } { strings__Builder_write_string(&sb, v__gen__c__Gen_styp(g, param.typ)); strings__Builder_write_string(&sb, _S(" a")); strings__Builder_write_decimal(&sb, i); } } strings__Builder_write_string(&sb, _S(")")); if (g->pref->parallel_cc) { strings__Builder_write_string(&g->extern_out, Array_u8_bytestr(sb)); strings__Builder_writeln(&g->extern_out, _S(";")); } strings__Builder_writeln(&sb, _S(" {")); strings__Builder_writeln(&sb, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = data_styp}}, {_S("* a0 = g_closure.closure_get_data();"), 0, { .d_c = 0 }}}))); if (m.return_type != _const_v__ast__void_type) { strings__Builder_write_string(&sb, _S("\treturn ")); } else { strings__Builder_write_string(&sb, _S("\t")); } string method_name = m.name; v__ast__TypeSymbol* rec_sym = v__ast__Table_sym(g->table, receiver.typ); if ((rec_sym->info)._typ == 518 /* v.ast.Struct */) { if ((*rec_sym->info._v__ast__Struct).concrete_types.len > 0) { method_name = v__gen__c__Gen_generic_fn_name(g, (*rec_sym->info._v__ast__Struct).concrete_types, m.name); } } bool _t2 = ((rec_sym->info)._typ == 542 /* v.ast.Interface */); bool _t1 = _t2 && Array_string_contains(v__ast__Interface_get_methods((*(v__ast__Interface*)__as_cast((rec_sym->info)._v__ast__Interface,(rec_sym->info)._typ, 542))), method_name); if (_t1) { string left_cc_type = v__gen__c__Gen_cc_type(g, v__ast__Table_unaliased_type(g->table, receiver.typ), false); string left_type_name = v__util__no_dots(left_cc_type); { strings__Builder_write_string(&sb, v__gen__c__c_name(left_type_name)); strings__Builder_write_string(&sb, _S("_name_table[a0->_typ]._method_")); strings__Builder_write_string(&sb, method_name); strings__Builder_write_string(&sb, _S("(")); } } else { { strings__Builder_write_string(&sb, expr_styp); strings__Builder_write_string(&sb, _S("_")); strings__Builder_write_string(&sb, method_name); strings__Builder_write_string(&sb, _S("(")); } if (!v__ast__Type_is_ptr(receiver.typ)) { strings__Builder_write_string(&sb, _S("*")); } } for (int i = 0; i < m.params.len; ++i) { if (i != 0) { strings__Builder_write_string(&sb, _S(", ")); } { strings__Builder_write_string(&sb, _S("a")); strings__Builder_write_decimal(&sb, i); } } strings__Builder_writeln(&sb, _S(");")); strings__Builder_writeln(&sb, _S("}")); array_push((array*)&g->anon_fn_definitions, _MOV((string[]){ strings__Builder_str(&sb) })); g->nr_closures++; } VV_LOC void v__gen__c__Gen_write_selector_expr_embed_name(v__gen__c__Gen* g, v__ast__SelectorExpr node, Array_v__ast__Type embed_types) { bool is_shared = v__ast__Type_has_flag(node.expr_type, v__ast__TypeFlag__shared_f); for (int i = 0; i < embed_types.len; ++i) { v__ast__Type embed = ((v__ast__Type*)embed_types.data)[i]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(g->table, embed); string embed_name = v__ast__TypeSymbol_embed_name(embed_sym); bool is_left_ptr = (i == 0 ? (v__ast__Type_is_ptr(node.expr_type) && !is_shared) : (v__ast__Type_is_ptr((*(v__ast__Type*)array_get(embed_types, (int)(i - 1)))))); if (i == 0 && is_shared) { v__gen__c__Gen_write(g, _S("->val")); } if (is_left_ptr) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } v__gen__c__Gen_write(g, embed_name); } } inline VV_LOC bool v__gen__c__Gen_check_var_scope(v__gen__c__Gen* g, v__ast__Var obj, int node_pos) { if (obj.pos.pos >= node_pos) { return false; } if (obj.expr._typ == 369 /* v.ast.MatchExpr */) { for (int _t2 = 0; _t2 < (*obj.expr._v__ast__MatchExpr).branches.len; ++_t2) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)(*obj.expr._v__ast__MatchExpr).branches.data)[_t2]; if (v__ast__Scope_contains(branch.scope, node_pos)) { return false; } } } else if (obj.expr._typ == 359 /* v.ast.IfExpr */) { for (int _t4 = 0; _t4 < (*obj.expr._v__ast__IfExpr).branches.len; ++_t4) { v__ast__IfBranch branch = ((v__ast__IfBranch*)(*obj.expr._v__ast__IfExpr).branches.data)[_t4]; if (v__ast__Scope_contains(branch.scope, node_pos)) { return false; } } } else { } return true; } VV_LOC void v__gen__c__Gen_debugger_stmt(v__gen__c__Gen* g, v__ast__DebuggerStmt node) { multi_return_int_string_string_string mr_148764 = v__gen__c__Gen_panic_debug_info(g, node.pos); int paline = mr_148764.arg0; string pafile = mr_148764.arg1; string pamod = mr_148764.arg2; string pafn = mr_148764.arg3; bool is_anon = g->cur_fn != ((void*)0) && g->cur_fn->is_anon; bool is_generic = g->cur_fn != ((void*)0) && g->cur_fn->generic_names.len > 0; bool is_method = g->cur_fn != ((void*)0) && g->cur_fn->is_method; string receiver_type = (g->cur_fn != ((void*)0) && g->cur_fn->is_method ? (v__ast__Table_type_to_str(g->table, g->cur_fn->receiver.typ)) : (_S(""))); Array_v__ast__ScopeObject scope_vars = v__ast__Scope_get_all_vars(v__ast__Scope_innermost(g->file->scope, node.pos.pos)); Array_string vars = __new_array_with_default(0, 0, sizeof(string), 0); strings__Builder keys = strings__new_builder(100); strings__Builder values = strings__new_builder(100); int count = 1; outer: {} for (int _t1 = 0; _t1 < scope_vars.len; ++_t1) { v__ast__ScopeObject obj = ((v__ast__ScopeObject*)scope_vars.data)[_t1]; if (!(Array_string_contains(vars, (*(obj.name))))) { if ((Array_string_contains(g->curr_var_name, (*(obj.name))))) { continue; } if ((obj)._typ == 422 /* v.ast.Var */ && v__gen__c__Gen_check_var_scope(g, *(v__ast__Var*)__as_cast((obj)._v__ast__Var,(obj)._typ, 422), node.pos.pos)) { { strings__Builder_write_string(&keys, _S("_S(\"")); strings__Builder_write_string(&keys, (*obj._v__ast__Var).name); strings__Builder_write_string(&keys, _S("\")")); } v__ast__Type _t2; /* if prepend */ if ((*obj._v__ast__Var).ct_type_var != v__ast__ComptimeVarKind__no_comptime) { _t2 = v__type_resolver__TypeResolver_get_type(&g->type_resolver, v__ast__Ident_to_sumtype_v__ast__Expr(ADDR(v__ast__Ident, (((v__ast__Ident){.language = 0,.tok_kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.comptime = 0,.scope = ((void*)0),.obj = obj,.mod = (string){.str=(byteptr)"", .is_lit=1},.name = (string){.str=(byteptr)"", .is_lit=1},.full_name = (string){.str=(byteptr)"", .is_lit=1},.cached_name = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.info = (v__ast__IdentInfo){._v__ast__IdentFn=HEAP(v__ast__IdentFn, ((v__ast__IdentFn){.typ = 0,})),._typ=476},.is_mut = 0,.or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.concrete_types = __new_array(0, 0, sizeof(v__ast__Type)),.ct_expr = 0,}))))); } else if ((*obj._v__ast__Var).smartcasts.len > 0) { _t2 = (*(v__ast__Type*)array_last((*obj._v__ast__Var).smartcasts)); } else { _t2 = (*obj._v__ast__Var).typ; } v__ast__Type var_typ = _t2; { strings__Builder_write_string(&values, _S("{.typ=_S(\"")); strings__Builder_write_string(&values, v__ast__Table_type_to_str(g->table, v__gen__c__Gen_unwrap_generic(g, var_typ))); strings__Builder_write_string(&values, _S("\"),.value=")); } v__ast__TypeSymbol* obj_sym = v__ast__Table_sym(g->table, (*obj._v__ast__Var).typ); v__ast__TypeSymbol* cast_sym = v__ast__Table_sym(g->table, var_typ); strings__Builder param_var = strings__new_builder(50); bool is_option = v__ast__Type_has_flag((*obj._v__ast__Var).orig_type, v__ast__TypeFlag__option); bool var_typ_is_option = v__ast__Type_has_flag(var_typ, v__ast__TypeFlag__option); if ((*obj._v__ast__Var).smartcasts.len > 0) { bool is_option_unwrap = is_option && !v__ast__Type_has_flag((*obj._v__ast__Var).typ, v__ast__TypeFlag__option) && v__ast__Type_has_flag((*obj._v__ast__Var).orig_type, v__ast__TypeFlag__option); bool opt_cast = false; string func = ((cast_sym->info)._typ == 537 /* v.ast.Aggregate */ ? (_S("")) : (v__gen__c__Gen_get_str_fn(g, var_typ))); if ((*obj._v__ast__Var).smartcasts.len > 1 && obj_sym->kind == v__ast__Kind__sum_type) { strings__Builder_write_string(¶m_var, _S("*(")); } strings__Builder_write_string(¶m_var, _S("(")); if (obj_sym->kind == v__ast__Kind__sum_type && !(*obj._v__ast__Var).is_auto_heap) { if (is_option) { if (!is_option_unwrap) { strings__Builder_write_string(¶m_var, _S("*(")); } string styp = v__gen__c__Gen_base_type(g, (*obj._v__ast__Var).typ); { strings__Builder_write_string(¶m_var, _S("*(")); strings__Builder_write_string(¶m_var, styp); strings__Builder_write_string(¶m_var, _S("*)")); } opt_cast = true; } else { strings__Builder_write_string(¶m_var, _S("*")); } } else if (v__ast__Table_is_interface_var(g->table, obj) || (*obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__smartcast) { strings__Builder_write_string(¶m_var, _S("*")); } else if (is_option) { opt_cast = true; { strings__Builder_write_string(¶m_var, _S("*(")); strings__Builder_write_string(¶m_var, v__gen__c__Gen_base_type(g, (*obj._v__ast__Var).typ)); strings__Builder_write_string(¶m_var, _S("*)")); } } string dot = (v__ast__Type_is_ptr((*obj._v__ast__Var).orig_type) || (*obj._v__ast__Var).is_auto_heap ? (_S("->")) : (_S("."))); if ((*obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__smartcast) { v__ast__TypeSymbol* cur_variant_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->comptime->comptime_for_variant_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), _const_v__ast__void_type))); { strings__Builder_write_string(¶m_var, (*obj._v__ast__Var).name); strings__Builder_write_string(¶m_var, dot); strings__Builder_write_string(¶m_var, _S("_")); strings__Builder_write_string(¶m_var, cur_variant_sym->cname); } } else if ((cast_sym->info)._typ == 537 /* v.ast.Aggregate */) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get((*cast_sym->info._v__ast__Aggregate).types, g->aggregate_type_idx))); func = v__gen__c__Gen_get_str_fn(g, (*(v__ast__Type*)array_get((*cast_sym->info._v__ast__Aggregate).types, g->aggregate_type_idx))); { strings__Builder_write_string(¶m_var, (*obj._v__ast__Var).name); strings__Builder_write_string(¶m_var, dot); strings__Builder_write_string(¶m_var, _S("_")); strings__Builder_write_string(¶m_var, sym->cname); } } else if (obj_sym->kind == v__ast__Kind__interface && cast_sym->kind == v__ast__Kind__interface) { string ptr = string_repeat(_S("*"), v__ast__Type_nr_muls((*obj._v__ast__Var).typ)); { strings__Builder_write_string(¶m_var, _S("I_")); strings__Builder_write_string(¶m_var, obj_sym->cname); strings__Builder_write_string(¶m_var, _S("_as_I_")); strings__Builder_write_string(¶m_var, cast_sym->cname); strings__Builder_write_string(¶m_var, _S("(")); strings__Builder_write_string(¶m_var, ptr); strings__Builder_write_string(¶m_var, (*obj._v__ast__Var).name); strings__Builder_write_string(¶m_var, _S(")")); } } else if (obj_sym->kind == v__ast__Kind__sum_type || obj_sym->kind == v__ast__Kind__interface) { { strings__Builder_write_string(¶m_var, (*obj._v__ast__Var).name); } if (opt_cast) { strings__Builder_write_string(¶m_var, _S(".data)")); } { strings__Builder_write_string(¶m_var, dot); strings__Builder_write_string(¶m_var, _S("_")); strings__Builder_write_string(¶m_var, cast_sym->cname); } } else if (is_option && !var_typ_is_option) { { strings__Builder_write_string(¶m_var, (*obj._v__ast__Var).name); strings__Builder_write_string(¶m_var, _S(".data")); } } else { { strings__Builder_write_string(¶m_var, (*obj._v__ast__Var).name); } } strings__Builder_write_string(¶m_var, _S(")")); { strings__Builder_write_string(&values, func); strings__Builder_write_string(&values, _S("(")); strings__Builder_write_string(&values, strings__Builder_str(¶m_var)); strings__Builder_write_string(&values, _S(")}")); } } else { string func = v__gen__c__Gen_get_str_fn(g, var_typ); if (is_option && !var_typ_is_option) { string base_typ = v__gen__c__Gen_base_type(g, (*obj._v__ast__Var).typ); { strings__Builder_write_string(&values, func); strings__Builder_write_string(&values, _S("(*(")); strings__Builder_write_string(&values, base_typ); strings__Builder_write_string(&values, _S("*)")); strings__Builder_write_string(&values, (*obj._v__ast__Var).name); strings__Builder_write_string(&values, _S(".data)}")); } } else { multi_return_bool_bool_int mr_152640 = v__ast__TypeSymbol_str_method_info(cast_sym); bool str_method_expects_ptr = mr_152640.arg1; string deref = (var_typ_is_option ? (_S("")) : str_method_expects_ptr && !v__ast__Type_is_ptr((*obj._v__ast__Var).typ) ? (_S("&")) : !str_method_expects_ptr && v__ast__Type_is_ptr((*obj._v__ast__Var).typ) ? (string_repeat(_S("*"), v__ast__Type_nr_muls((*obj._v__ast__Var).typ))) : !str_method_expects_ptr && v__ast__TypeSymbol_is_heap(obj_sym) ? (_S("*")) : (*obj._v__ast__Var).is_auto_heap && v__ast__Type_is_ptr(var_typ) && str_method_expects_ptr ? (_S("*")) : !(*obj._v__ast__Var).is_auto_heap && v__ast__Type_is_ptr(var_typ) && str_method_expects_ptr ? (_S("")) : (*obj._v__ast__Var).is_auto_heap && v__ast__Type_is_ptr(var_typ) ? (_S("*")) : v__ast__Type_is_ptr((*obj._v__ast__Var).typ) && !(*obj._v__ast__Var).is_auto_deref ? (_S("&")) : v__ast__Type_is_ptr((*obj._v__ast__Var).typ) && (*obj._v__ast__Var).is_auto_deref ? (_S("*")) : (_S(""))); { strings__Builder_write_string(&values, func); strings__Builder_write_string(&values, _S("(")); strings__Builder_write_string(&values, deref); strings__Builder_write_string(&values, (*obj._v__ast__Var).name); strings__Builder_write_string(&values, _S(")}")); } } } array_push((array*)&vars, _MOV((string[]){ string_clone((*obj._v__ast__Var).name) })); if (count != scope_vars.len) { strings__Builder_write_string(&keys, _S(",")); strings__Builder_write_string(&values, _S(",")); } } } count += 1; outer__continue: {} } outer__break: {} v__gen__c__Gen_writeln(g, _S("{")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tMap_string_string _scope = new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, "), 0xfe07, {.d_i32 = vars.len}}, {_S(", sizeof(string), sizeof(v__debug__DebugContextVar),"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t_MOV((string["), 0xfe07, {.d_i32 = vars.len}}, {_S("]){"), 0, { .d_c = 0 }}})), strings__Builder_str(&keys)); v__gen__c__Gen_writeln(g, _S("}),")); v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t_MOV((v__debug__DebugContextVar["), 0xfe07, {.d_i32 = vars.len}}, {_S("]){"), 0, { .d_c = 0 }}})), strings__Builder_str(&values)); v__gen__c__Gen_writeln(g, _S("}));")); v__gen__c__Gen_writeln(g, str_intp(9, _MOV((StrIntpData[]){{_S("\tv__debug__Debugger_interact(&g_debugger, (v__debug__DebugContextInfo){.is_anon="), 0xfe10, {.d_s = is_anon ? _S("true") : _S("false")}}, {_S(",.is_generic="), 0xfe10, {.d_s = is_generic ? _S("true") : _S("false")}}, {_S(",.is_method="), 0xfe10, {.d_s = is_method ? _S("true") : _S("false")}}, {_S(",.receiver_typ_name=_S(\""), 0xfe10, {.d_s = receiver_type}}, {_S("\"),.line="), 0xfe07, {.d_i32 = paline}}, {_S(",.file=_S(\""), 0xfe10, {.d_s = pafile}}, {_S("\"),.mod=_S(\""), 0xfe10, {.d_s = pamod}}, {_S("\"),.fn_name=_S(\""), 0xfe10, {.d_s = pafn}}, {_S("\"),.scope=_scope});"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write(g, _S("}")); } VV_LOC void v__gen__c__Gen_enum_decl(v__gen__c__Gen* g, v__ast__EnumDecl node) { string enum_name = v__util__no_dots(node.name); bool is_flag = node.is_flag; if (g->is_cc_msvc) { string last_value = _S("0"); string enum_typ_name = v__ast__Table_get_type_name(g->table, node.typ); if (g->pref->skip_unused && !_IN_MAP(ADDR(int, v__ast__Type_idx(node.typ)), ADDR(map, g->table->used_features->used_syms))) { return; } strings__Builder_writeln(&g->enum_typedefs, _S("")); strings__Builder_writeln(&g->enum_typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = enum_typ_name}}, {_S(" "), 0xfe10, {.d_s = enum_name}}, {_S(";"), 0, { .d_c = 0 }}}))); for (int i = 0; i < node.fields.len; ++i) { v__ast__EnumField field = ((v__ast__EnumField*)node.fields.data)[i]; strings__Builder_write_string2(&g->enum_typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("\t#define "), 0xfe10, {.d_s = enum_name}}, {_S("__"), 0xfe10, {.d_s = field.name}}, {_S(" "), 0, { .d_c = 0 }}})), _S("(")); if (is_flag) { strings__Builder_write_string2(&g->enum_typedefs, u64_str(((((u64)(1U)) << i))), _S("ULL")); } else if (field.has_expr) { string expr_str = v__gen__c__Gen_expr_string(g, field.expr); strings__Builder_write_string(&g->enum_typedefs, expr_str); last_value = expr_str; } else { if (i != 0) { last_value = string__plus(last_value, _S("+1")); } strings__Builder_write_string(&g->enum_typedefs, last_value); } strings__Builder_writeln(&g->enum_typedefs, _S(")")); } return; } if (g->pref->skip_unused && !_IN_MAP(ADDR(int, v__ast__Type_idx(node.typ)), ADDR(map, g->table->used_features->used_syms))) { return; } strings__Builder_writeln(&g->enum_typedefs, _S("")); if (node.typ != _const_v__ast__int_type) { strings__Builder_writeln(&g->enum_typedefs, _S("#pragma pack(push, 1)")); } strings__Builder_writeln(&g->enum_typedefs, _S("typedef enum {")); string cur_enum_expr = _S(""); int cur_enum_offset = 0; for (int i = 0; i < node.fields.len; ++i) { v__ast__EnumField field = ((v__ast__EnumField*)node.fields.data)[i]; { strings__Builder_write_string(&g->enum_typedefs, _S("\t")); strings__Builder_write_string(&g->enum_typedefs, enum_name); strings__Builder_write_string(&g->enum_typedefs, _S("__")); strings__Builder_write_string(&g->enum_typedefs, field.name); } if (field.has_expr) { strings__Builder_write_string(&g->enum_typedefs, _S(" = ")); string expr_str = v__gen__c__Gen_expr_string(g, field.expr); if ((field.expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((field.expr)._v__ast__Ident,(field.expr)._typ, 358)).kind == v__ast__IdentKind__constant) { v__gen__c__GlobalConstDef const_def = (*(v__gen__c__GlobalConstDef*)map_get(ADDR(map, g->global_const_defs), &(string[]){v__util__no_dots((*field.expr._v__ast__Ident).name)}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })); if (string_starts_with(const_def.def, _S("#define"))) { strings__Builder_write_string(&g->enum_typedefs, string_all_after_last(const_def.def, _S(" "))); } else if (string_contains(const_def.def, _S("const "))) { strings__Builder_write_string(&g->enum_typedefs, string_all_before_last(string_all_after_last(const_def.def, _S("=")), _S(";"))); } else { strings__Builder_write_string(&g->enum_typedefs, expr_str); } } else { strings__Builder_write_string(&g->enum_typedefs, expr_str); } cur_enum_expr = expr_str; cur_enum_offset = 0; } else if (is_flag) { strings__Builder_write_string(&g->enum_typedefs, _S(" = ")); cur_enum_expr = str_intp(2, _MOV((StrIntpData[]){{_S("u64(1) << "), 0xfe07, {.d_i32 = i}}, {_SLIT0, 0, { .d_c = 0 }}})); strings__Builder_write_string2(&g->enum_typedefs, u64_str(((((u64)(1U)) << i))), _S("U")); cur_enum_offset = 0; } string cur_value = (cur_enum_offset > 0 ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = cur_enum_expr}}, {_S("+"), 0xfe07, {.d_i32 = cur_enum_offset}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (cur_enum_expr)); if (g->pref->is_prod) { strings__Builder_writeln(&g->enum_typedefs, _S(",")); } else { strings__Builder_writeln(&g->enum_typedefs, str_intp(2, _MOV((StrIntpData[]){{_S(", // "), 0xfe10, {.d_s = cur_value}}, {_SLIT0, 0, { .d_c = 0 }}}))); } cur_enum_offset++; } string packed_attribute = (!g->is_cc_msvc && node.typ != _const_v__ast__int_type ? (_S("__attribute__((packed))")) : (_S(""))); strings__Builder_writeln(&g->enum_typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("} "), 0xfe10, {.d_s = packed_attribute}}, {_S(" "), 0xfe10, {.d_s = enum_name}}, {_S(";"), 0, { .d_c = 0 }}}))); if (node.typ != _const_v__ast__int_type) { strings__Builder_writeln(&g->enum_typedefs, _S("#pragma pack(pop)\n")); } } VV_LOC void v__gen__c__Gen_enum_expr(v__gen__c__Gen* g, v__ast__Expr node) { if (node._typ == 355 /* v.ast.EnumVal */) { v__gen__c__Gen_write(g, (*node._v__ast__EnumVal).val); } else { v__gen__c__Gen_expr(g, node); } } VV_LOC void v__gen__c__Gen_lock_expr(v__gen__c__Gen* g, v__ast__LockExpr node) { bool v__gen__c__Gen_lock_expr_defer_0 = false; bool v__gen__c__Gen_lock_expr_defer_1 = false; g->cur_lock = node; v__gen__c__Gen_lock_expr_defer_0 = true; string tmp_result = (node.is_expr ? (v__gen__c__Gen_new_tmp_var(g)) : (_S(""))); string cur_line = _S(""); if (node.is_expr) { string styp = v__gen__c__Gen_styp(g, node.typ); cur_line = v__gen__c__Gen_go_before_last_stmt(g); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = tmp_result}}, {_S(";"), 0, { .d_c = 0 }}}))); } string mtxs = _S(""); if (node.lockeds.len == 0) { } else if (node.lockeds.len == 1) { string lock_prefix = ((*(bool*)array_get(node.is_rlock, 0)) ? (_S("r")) : (_S(""))); { v__gen__c__Gen_write(g, _S("sync__RwMutex_")); v__gen__c__Gen_write(g, lock_prefix); v__gen__c__Gen_write(g, _S("lock(&")); } v__gen__c__Gen_expr(g, (*(v__ast__Expr*)array_get(node.lockeds, 0))); v__gen__c__Gen_writeln(g, _S("->mtx);")); } else { mtxs = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln2(g, str_intp(3, _MOV((StrIntpData[]){{_S("uintptr_t _arr_"), 0xfe10, {.d_s = mtxs}}, {_S("["), 0xfe07, {.d_i32 = node.lockeds.len}}, {_S("];"), 0, { .d_c = 0 }}})), str_intp(3, _MOV((StrIntpData[]){{_S("bool _isrlck_"), 0xfe10, {.d_s = mtxs}}, {_S("["), 0xfe07, {.d_i32 = node.lockeds.len}}, {_S("];"), 0, { .d_c = 0 }}}))); int j = 0; for (int i = 0; i < node.is_rlock.len; ++i) { bool is_rlock = ((bool*)node.is_rlock.data)[i]; if (!is_rlock) { { v__gen__c__Gen_write(g, _S("_arr_")); v__gen__c__Gen_write(g, mtxs); v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_write_decimal(g, j); v__gen__c__Gen_write(g, _S("] = (uintptr_t)&")); } v__gen__c__Gen_expr(g, (*(v__ast__Expr*)array_get(node.lockeds, i))); v__gen__c__Gen_writeln2(g, _S("->mtx;"), str_intp(3, _MOV((StrIntpData[]){{_S("_isrlck_"), 0xfe10, {.d_s = mtxs}}, {_S("["), 0xfe07, {.d_i32 = j}}, {_S("] = false;"), 0, { .d_c = 0 }}}))); j++; } } for (int i = 0; i < node.is_rlock.len; ++i) { bool is_rlock = ((bool*)node.is_rlock.data)[i]; if (is_rlock) { { v__gen__c__Gen_write(g, _S("_arr_")); v__gen__c__Gen_write(g, mtxs); v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_write_decimal(g, j); v__gen__c__Gen_write(g, _S("] = (uintptr_t)&")); } v__gen__c__Gen_expr(g, (*(v__ast__Expr*)array_get(node.lockeds, i))); v__gen__c__Gen_writeln2(g, _S("->mtx;"), str_intp(3, _MOV((StrIntpData[]){{_S("_isrlck_"), 0xfe10, {.d_s = mtxs}}, {_S("["), 0xfe07, {.d_i32 = j}}, {_S("] = true;"), 0, { .d_c = 0 }}}))); j++; } } if (node.lockeds.len == 2) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("if (_arr_"), 0xfe10, {.d_s = mtxs}}, {_S("[0] > _arr_"), 0xfe10, {.d_s = mtxs}}, {_S("[1]) {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\tuintptr_t _ptr_"), 0xfe10, {.d_s = mtxs}}, {_S(" = _arr_"), 0xfe10, {.d_s = mtxs}}, {_S("[0];"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t_arr_"), 0xfe10, {.d_s = mtxs}}, {_S("[0] = _arr_"), 0xfe10, {.d_s = mtxs}}, {_S("[1];"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t_arr_"), 0xfe10, {.d_s = mtxs}}, {_S("[1] = _ptr_"), 0xfe10, {.d_s = mtxs}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\tbool _bool_"), 0xfe10, {.d_s = mtxs}}, {_S(" = _isrlck_"), 0xfe10, {.d_s = mtxs}}, {_S("[0];"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t_isrlck_"), 0xfe10, {.d_s = mtxs}}, {_S("[0] = _isrlck_"), 0xfe10, {.d_s = mtxs}}, {_S("[1];"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t_isrlck_"), 0xfe10, {.d_s = mtxs}}, {_S("[1] = _bool_"), 0xfe10, {.d_s = mtxs}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("}")); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("__sort_ptr(_arr_"), 0xfe10, {.d_s = mtxs}}, {_S(", _isrlck_"), 0xfe10, {.d_s = mtxs}}, {_S(", "), 0xfe07, {.d_i32 = node.lockeds.len}}, {_S(");"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln2(g, str_intp(5, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = mtxs}}, {_S("=0; "), 0xfe10, {.d_s = mtxs}}, {_S("<"), 0xfe07, {.d_i32 = node.lockeds.len}}, {_S("; "), 0xfe10, {.d_s = mtxs}}, {_S("++) {"), 0, { .d_c = 0 }}})), str_intp(6, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = mtxs}}, {_S(" && _arr_"), 0xfe10, {.d_s = mtxs}}, {_S("["), 0xfe10, {.d_s = mtxs}}, {_S("] == _arr_"), 0xfe10, {.d_s = mtxs}}, {_S("["), 0xfe10, {.d_s = mtxs}}, {_S("-1]) continue;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln2(g, str_intp(3, _MOV((StrIntpData[]){{_S("\tif (_isrlck_"), 0xfe10, {.d_s = mtxs}}, {_S("["), 0xfe10, {.d_s = mtxs}}, {_S("])"), 0, { .d_c = 0 }}})), str_intp(3, _MOV((StrIntpData[]){{_S("\t\tsync__RwMutex_rlock((sync__RwMutex*)_arr_"), 0xfe10, {.d_s = mtxs}}, {_S("["), 0xfe10, {.d_s = mtxs}}, {_S("]);"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln2(g, _S("\telse"), str_intp(3, _MOV((StrIntpData[]){{_S("\t\tsync__RwMutex_lock((sync__RwMutex*)_arr_"), 0xfe10, {.d_s = mtxs}}, {_S("["), 0xfe10, {.d_s = mtxs}}, {_S("]);"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("}")); } g->mtxs = mtxs; v__gen__c__Gen_lock_expr_defer_1 = true; v__gen__c__Gen_writeln(g, _S("/*lock*/ {")); v__gen__c__Gen_stmts_with_tmp_var(g, node.stmts, tmp_result); if (node.is_expr) { v__gen__c__Gen_writeln(g, _S(";")); } v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_unlock_locks(g); if (node.is_expr) { v__gen__c__Gen_writeln(g, _S("")); v__gen__c__Gen_write2(g, cur_line, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_result}}, {_SLIT0, 0, { .d_c = 0 }}}))); } // Defer begin if (v__gen__c__Gen_lock_expr_defer_1) { g->mtxs = _S(""); } // Defer end // Defer begin if (v__gen__c__Gen_lock_expr_defer_0) { g->cur_lock = ((v__ast__LockExpr){.is_rlock = __new_array(0, 0, sizeof(bool)),.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.lockeds = __new_array(0, 0, sizeof(v__ast__Expr)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_expr = 0,.typ = 0,.scope = ((void*)0),}); } // Defer end } VV_LOC void v__gen__c__Gen_unlock_locks(v__gen__c__Gen* g) { if (g->cur_lock.lockeds.len == 0) { } else if (g->cur_lock.lockeds.len == 1) { string lock_prefix = ((*(bool*)array_get(g->cur_lock.is_rlock, 0)) ? (_S("r")) : (_S(""))); { v__gen__c__Gen_write(g, _S("sync__RwMutex_")); v__gen__c__Gen_write(g, lock_prefix); v__gen__c__Gen_write(g, _S("unlock(&")); } v__gen__c__Gen_expr(g, (*(v__ast__Expr*)array_get(g->cur_lock.lockeds, 0))); v__gen__c__Gen_write(g, _S("->mtx);")); } else { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = g->mtxs}}, {_S("="), 0xfe07, {.d_i32 = (int)(g->cur_lock.lockeds.len - 1)}}, {_S("; "), 0xfe10, {.d_s = g->mtxs}}, {_S(">=0; "), 0xfe10, {.d_s = g->mtxs}}, {_S("--) {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = g->mtxs}}, {_S(" && _arr_"), 0xfe10, {.d_s = g->mtxs}}, {_S("["), 0xfe10, {.d_s = g->mtxs}}, {_S("] == _arr_"), 0xfe10, {.d_s = g->mtxs}}, {_S("["), 0xfe10, {.d_s = g->mtxs}}, {_S("-1]) continue;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\tif (_isrlck_"), 0xfe10, {.d_s = g->mtxs}}, {_S("["), 0xfe10, {.d_s = g->mtxs}}, {_S("])"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tsync__RwMutex_runlock((sync__RwMutex*)_arr_"), 0xfe10, {.d_s = g->mtxs}}, {_S("["), 0xfe10, {.d_s = g->mtxs}}, {_S("]);"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\telse")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tsync__RwMutex_unlock((sync__RwMutex*)_arr_"), 0xfe10, {.d_s = g->mtxs}}, {_S("["), 0xfe10, {.d_s = g->mtxs}}, {_S("]);"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write(g, _S("}")); } } VV_LOC void v__gen__c__Gen_map_init(v__gen__c__Gen* g, v__ast__MapInit node) { v__ast__Type unwrap_key_typ = v__gen__c__Gen_unwrap_generic(g, node.key_type); v__ast__Type unwrap_val_typ = v__ast__Type_clear_flag(v__gen__c__Gen_unwrap_generic(g, node.value_type), v__ast__TypeFlag__result); string key_typ_str = v__gen__c__Gen_styp(g, unwrap_key_typ); string value_typ_str = v__gen__c__Gen_styp(g, unwrap_val_typ); v__ast__TypeSymbol* value_sym = v__ast__Table_sym(g->table, unwrap_val_typ); v__ast__TypeSymbol* key_sym = v__ast__Table_final_sym(g->table, unwrap_key_typ); multi_return_string_string_string_string mr_160763 = v__gen__c__Gen_map_fn_ptrs(g, *key_sym); string hash_fn = mr_160763.arg0; string key_eq_fn = mr_160763.arg1; string clone_fn = mr_160763.arg2; string free_fn = mr_160763.arg3; int size = node.vals.len; string shared_styp = _S(""); string styp = _S(""); bool is_amp = g->is_amp; g->is_amp = false; if (is_amp) { v__gen__c__Gen_go_back(g, 1); } if (g->is_shared) { v__ast__Type shared_typ = v__ast__Type_set_flag(node.typ, v__ast__TypeFlag__shared_f); shared_styp = v__gen__c__Gen_styp(g, shared_typ); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = shared_styp}}, {_S("*)__dup_shared_map(&("), 0xfe10, {.d_s = shared_styp}}, {_S("){.mtx = {0}, .val ="), 0, { .d_c = 0 }}}))); } else if (is_amp) { styp = v__gen__c__Gen_styp(g, node.typ); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)memdup(ADDR(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(", ")); } } string noscan_key = v__gen__c__Gen_check_noscan(g, node.key_type); string noscan_value = v__gen__c__Gen_check_noscan(g, node.value_type); string noscan = (noscan_key.len != 0 || noscan_value.len != 0 ? (_S("_noscan")) : (_S(""))); if (noscan.len != 0) { if (noscan_key.len != 0) { noscan = string__plus(noscan, _S("_key")); } if (noscan_value.len != 0) { noscan = string__plus(noscan, _S("_value")); } } if (size > 0) { string effective_typ_str = (value_sym->kind == v__ast__Kind__function ? (_S("voidptr")) : (value_typ_str)); if (node.has_update_expr) { v__gen__c__Gen_writeln(g, _S("new_map_update_init(")); v__gen__c__Gen_write(g, _S("\t&(")); v__gen__c__Gen_expr(g, node.update_expr); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("), "), 0xfe07, {.d_i32 = size}}, {_S(", sizeof("), 0xfe10, {.d_s = key_typ_str}}, {_S("), sizeof("), 0xfe10, {.d_s = effective_typ_str}}, {_S("),"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(9, _MOV((StrIntpData[]){{_S("new_map_init"), 0xfe10, {.d_s = noscan}}, {_S("("), 0xfe10, {.d_s = hash_fn}}, {_S(", "), 0xfe10, {.d_s = key_eq_fn}}, {_S(", "), 0xfe10, {.d_s = clone_fn}}, {_S(", "), 0xfe10, {.d_s = free_fn}}, {_S(", "), 0xfe07, {.d_i32 = size}}, {_S(", sizeof("), 0xfe10, {.d_s = key_typ_str}}, {_S("), sizeof("), 0xfe10, {.d_s = effective_typ_str}}, {_S("),"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t_MOV(("), 0xfe10, {.d_s = key_typ_str}}, {_S("["), 0xfe07, {.d_i32 = size}}, {_S("]){"), 0, { .d_c = 0 }}}))); for (int _t1 = 0; _t1 < node.keys.len; ++_t1) { v__ast__Expr expr = ((v__ast__Expr*)node.keys.data)[_t1]; v__gen__c__Gen_write(g, _S("\t\t")); v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_writeln(g, _S(",")); } v__gen__c__Gen_writeln2(g, _S("\t}),"), str_intp(3, _MOV((StrIntpData[]){{_S("\t_MOV(("), 0xfe10, {.d_s = effective_typ_str}}, {_S("["), 0xfe07, {.d_i32 = size}}, {_S("]){"), 0, { .d_c = 0 }}}))); for (int i = 0; i < node.vals.len; ++i) { v__ast__Expr expr = ((v__ast__Expr*)node.vals.data)[i]; v__gen__c__Gen_write(g, _S("\t\t")); if (v__ast__Expr_is_auto_deref_var(expr)) { v__gen__c__Gen_write(g, _S("*")); } if (value_sym->kind == v__ast__Kind__sum_type) { v__gen__c__Gen_expr_with_cast(g, expr, (*(v__ast__Type*)array_get(node.val_types, i)), unwrap_val_typ); } else if (v__ast__Type_has_flag((*(v__ast__Type*)array_get(node.val_types, i)), v__ast__TypeFlag__option) || (*(v__ast__Type*)array_get(node.val_types, i)) == _const_v__ast__none_type) { v__gen__c__Gen_expr_with_opt(g, expr, (*(v__ast__Type*)array_get(node.val_types, i)), unwrap_val_typ); } else { v__gen__c__Gen_expr(g, expr); } v__gen__c__Gen_writeln(g, _S(", ")); } v__gen__c__Gen_writeln2(g, _S("\t})"), _S(")")); } else if (node.has_update_expr) { v__gen__c__Gen_write(g, _S("map_clone(&(")); v__gen__c__Gen_expr(g, node.update_expr); v__gen__c__Gen_writeln(g, _S("))")); } else { v__gen__c__Gen_writeln(g, str_intp(8, _MOV((StrIntpData[]){{_S("new_map"), 0xfe10, {.d_s = noscan}}, {_S("(sizeof("), 0xfe10, {.d_s = key_typ_str}}, {_S("), sizeof("), 0xfe10, {.d_s = value_typ_str}}, {_S("), "), 0xfe10, {.d_s = hash_fn}}, {_S(", "), 0xfe10, {.d_s = key_eq_fn}}, {_S(", "), 0xfe10, {.d_s = clone_fn}}, {_S(", "), 0xfe10, {.d_s = free_fn}}, {_S(")"), 0, { .d_c = 0 }}}))); } if (g->is_shared) { { v__gen__c__Gen_write(g, _S("}, sizeof(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("))")); } } else if (is_amp) { { v__gen__c__Gen_write(g, _S("), sizeof(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("))")); } } } VV_LOC void v__gen__c__Gen_select_expr(v__gen__c__Gen* g, v__ast__SelectExpr node) { bool is_expr = node.is_expr || g->inside_ternary > 0; string _t1; /* if prepend */ if (is_expr) { g->empty_line = true; _t1 = v__gen__c__Gen_go_before_last_stmt(g); } else { _t1 = _S(""); } string cur_line = _t1; int n_channels = (node.has_exception ? ((int)(node.branches.len - 1)) : (node.branches.len)); Array_v__ast__Expr channels = __new_array_with_default(0, n_channels, sizeof(v__ast__Expr), 0); Array_v__ast__Expr objs = __new_array_with_default(0, n_channels, sizeof(v__ast__Expr), 0); Array_string tmp_objs = __new_array_with_default(0, n_channels, sizeof(string), 0); Array_string elem_types = __new_array_with_default(0, n_channels, sizeof(string), 0); Array_bool is_push = __new_array_with_default(0, n_channels, sizeof(bool), 0); bool has_else = false; bool has_timeout = false; v__ast__Expr timeout_expr = _const_v__ast__empty_expr; int exception_branch = -1; for (int j = 0; j < node.branches.len; ++j) { v__ast__SelectBranch branch = ((v__ast__SelectBranch*)node.branches.data)[j]; if (branch.is_else) { has_else = true; exception_branch = j; } else if (branch.is_timeout) { has_timeout = true; exception_branch = j; timeout_expr = (*(v__ast__ExprStmt*)__as_cast((branch.stmt)._v__ast__ExprStmt,(branch.stmt)._typ, 401)).expr; } else { if (branch.stmt._typ == 401 /* v.ast.ExprStmt */) { v__ast__InfixExpr expr = *(v__ast__InfixExpr*)__as_cast(((*branch.stmt._v__ast__ExprStmt).expr)._v__ast__InfixExpr,((*branch.stmt._v__ast__ExprStmt).expr)._typ, 362); array_push((array*)&channels, _MOV((v__ast__Expr[]){ expr.left })); if ((expr.right)._typ == 358 /* v.ast.Ident */ || (expr.right)._typ == 361 /* v.ast.IndexExpr */ || (expr.right)._typ == 379 /* v.ast.SelectorExpr */ || (expr.right)._typ == 385 /* v.ast.StructInit */) { array_push((array*)&objs, _MOV((v__ast__Expr[]){ expr.right })); array_push((array*)&tmp_objs, _MOV((string[]){ _S("") })); array_push((array*)&elem_types, _MOV((string[]){ _S("") })); } else { array_push((array*)&objs, _MOV((v__ast__Expr[]){ _const_v__ast__empty_expr })); string tmp_obj = v__gen__c__Gen_new_tmp_var(g); array_push((array*)&tmp_objs, _MOV((string[]){ string_clone(tmp_obj) })); string el_stype = v__gen__c__Gen_styp(g, v__ast__mktyp(expr.right_type)); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = el_stype}}, {_S(" "), 0xfe10, {.d_s = tmp_obj}}, {_S(";"), 0, { .d_c = 0 }}}))); } array_push((array*)&is_push, _MOV((bool[]){ true })); } else if (branch.stmt._typ == 392 /* v.ast.AssignStmt */) { v__ast__PrefixExpr rec_expr = *(v__ast__PrefixExpr*)__as_cast(((*(v__ast__Expr*)array_get((*branch.stmt._v__ast__AssignStmt).right, 0)))._v__ast__PrefixExpr,((*(v__ast__Expr*)array_get((*branch.stmt._v__ast__AssignStmt).right, 0)))._typ, 376); array_push((array*)&channels, _MOV((v__ast__Expr[]){ rec_expr.right })); array_push((array*)&is_push, _MOV((bool[]){ false })); if ((*branch.stmt._v__ast__AssignStmt).op == v__token__Kind__decl_assign || (*(v__ast__Type*)array_get((*branch.stmt._v__ast__AssignStmt).right_types, 0)) != (*(v__ast__Type*)array_get((*branch.stmt._v__ast__AssignStmt).left_types, 0))) { string tmp_obj = v__gen__c__Gen_new_tmp_var(g); array_push((array*)&tmp_objs, _MOV((string[]){ string_clone(tmp_obj) })); string el_stype = v__gen__c__Gen_styp(g, (*(v__ast__Type*)array_get((*branch.stmt._v__ast__AssignStmt).right_types, 0))); array_push((array*)&elem_types, _MOV((string[]){ string_clone(((*branch.stmt._v__ast__AssignStmt).op == v__token__Kind__decl_assign ? (string__plus(el_stype, _S(" "))) : (_S("")))) })); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = el_stype}}, {_S(" "), 0xfe10, {.d_s = tmp_obj}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { array_push((array*)&tmp_objs, _MOV((string[]){ _S("") })); array_push((array*)&elem_types, _MOV((string[]){ _S("") })); } array_push((array*)&objs, _MOV((v__ast__Expr[]){ (*(v__ast__Expr*)array_get((*branch.stmt._v__ast__AssignStmt).left, 0)) })); } else { } } } string chan_array = v__gen__c__Gen_new_tmp_var(g); if (n_channels == 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("Array_sync__Channel_ptr "), 0xfe10, {.d_s = chan_array}}, {_S(" = __new_array_with_default(0, 0, sizeof(sync__Channel*), 0);"), 0, { .d_c = 0 }}}))); } else { { v__gen__c__Gen_write(g, _S("Array_sync__Channel_ptr ")); v__gen__c__Gen_write(g, chan_array); v__gen__c__Gen_write(g, _S(" = new_array_from_c_array(")); v__gen__c__Gen_write_decimal(g, n_channels); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, n_channels); v__gen__c__Gen_write(g, _S(", sizeof(sync__Channel*), _MOV((sync__Channel*[")); v__gen__c__Gen_write_decimal(g, n_channels); v__gen__c__Gen_write(g, _S("]){")); } for (int i = 0; i < n_channels; ++i) { if (i > 0) { v__gen__c__Gen_write(g, _S(", ")); } v__gen__c__Gen_write(g, _S("(sync__Channel*)(")); v__gen__c__Gen_expr(g, (*(v__ast__Expr*)array_get(channels, i))); v__gen__c__Gen_write(g, _S(")")); } v__gen__c__Gen_writeln(g, _S("}));\n")); } string directions_array = v__gen__c__Gen_new_tmp_var(g); if (n_channels == 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("Array_sync__Direction "), 0xfe10, {.d_s = directions_array}}, {_S(" = __new_array_with_default(0, 0, sizeof(sync__Direction), 0);"), 0, { .d_c = 0 }}}))); } else { { v__gen__c__Gen_write(g, _S("Array_sync__Direction ")); v__gen__c__Gen_write(g, directions_array); v__gen__c__Gen_write(g, _S(" = new_array_from_c_array(")); v__gen__c__Gen_write_decimal(g, n_channels); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, n_channels); v__gen__c__Gen_write(g, _S(", sizeof(sync__Direction), _MOV((sync__Direction[")); v__gen__c__Gen_write_decimal(g, n_channels); v__gen__c__Gen_write(g, _S("]){")); } for (int i = 0; i < n_channels; ++i) { if (i > 0) { v__gen__c__Gen_write(g, _S(", ")); } if ((*(bool*)array_get(is_push, i))) { v__gen__c__Gen_write(g, _S("sync__Direction__push")); } else { v__gen__c__Gen_write(g, _S("sync__Direction__pop")); } } v__gen__c__Gen_writeln(g, _S("}));\n")); } string objs_array = v__gen__c__Gen_new_tmp_var(g); if (n_channels == 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("Array_voidptr "), 0xfe10, {.d_s = objs_array}}, {_S(" = __new_array_with_default(0, 0, sizeof(voidptr), 0);"), 0, { .d_c = 0 }}}))); } else { { v__gen__c__Gen_write(g, _S("Array_voidptr ")); v__gen__c__Gen_write(g, objs_array); v__gen__c__Gen_write(g, _S(" = new_array_from_c_array(")); v__gen__c__Gen_write_decimal(g, n_channels); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, n_channels); v__gen__c__Gen_write(g, _S(", sizeof(voidptr), _MOV((voidptr[")); v__gen__c__Gen_write_decimal(g, n_channels); v__gen__c__Gen_write(g, _S("]){")); } for (int i = 0; i < n_channels; ++i) { if (i > 0) { v__gen__c__Gen_write(g, _S(", &")); } else { v__gen__c__Gen_write(g, _S("&")); } if (((*(string*)array_get(tmp_objs, i))).len == 0) { v__gen__c__Gen_expr(g, (*(v__ast__Expr*)array_get(objs, i))); } else { v__gen__c__Gen_write(g, (*(string*)array_get(tmp_objs, i))); } } v__gen__c__Gen_writeln(g, _S("}));\n")); } string select_result = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, _S("int ")); v__gen__c__Gen_write(g, select_result); v__gen__c__Gen_write(g, _S(" = sync__channel_select(&")); v__gen__c__Gen_write(g, chan_array); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, directions_array); v__gen__c__Gen_write(g, _S(", &")); v__gen__c__Gen_write(g, objs_array); v__gen__c__Gen_write(g, _S(", ")); } if (has_timeout) { v__gen__c__Gen_expr(g, timeout_expr); } else if (has_else) { v__gen__c__Gen_write(g, _S("0")); } else { v__gen__c__Gen_write(g, _S("_const_time__infinite")); } v__gen__c__Gen_writeln(g, _S(");")); v__gen__c__Gen_writeln2(g, str_intp(2, _MOV((StrIntpData[]){{_S("array_free(&"), 0xfe10, {.d_s = objs_array}}, {_S(");"), 0, { .d_c = 0 }}})), str_intp(2, _MOV((StrIntpData[]){{_S("array_free(&"), 0xfe10, {.d_s = directions_array}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("array_free(&"), 0xfe10, {.d_s = chan_array}}, {_S(");"), 0, { .d_c = 0 }}}))); int i = 0; for (int j = 0; j < node.branches.len; ++j) { if (j > 0) { v__gen__c__Gen_write(g, _S("} else ")); } { v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_write(g, select_result); v__gen__c__Gen_write(g, _S(" == ")); } if (j == exception_branch) { v__gen__c__Gen_writeln(g, _S("-1) {")); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = i}}, {_S(") {"), 0, { .d_c = 0 }}}))); if (!(*(bool*)array_get(is_push, i)) && ((*(string*)array_get(tmp_objs, i))).len != 0) { { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, (*(string*)array_get(elem_types, i))); } v__gen__c__Gen_expr(g, (*(v__ast__Expr*)array_get(objs, i))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(" = "), 0xfe10, {.d_s = (*(string*)array_get(tmp_objs, i))}}, {_S(";"), 0, { .d_c = 0 }}}))); } i++; } v__gen__c__Gen_stmts(g, (*(v__ast__SelectBranch*)array_get(node.branches, j)).stmts); } v__gen__c__Gen_writeln(g, _S("}")); if (is_expr) { g->empty_line = false; v__gen__c__Gen_write2(g, cur_line, str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = select_result}}, {_S(" != -2)"), 0, { .d_c = 0 }}}))); } } VV_LOC string v__gen__c__Gen_get_const_name(v__gen__c__Gen* g, v__ast__Ident node) { if (g->pref->translated && !g->is_builtin_mod && !v__util__module_is_builtin(string_all_before_last(node.name, _S(".")))) { string x = v__util__no_dots(node.name); if (string_starts_with(x, _S("main__"))) { x = string_substr(x, 6, 2147483647); } return x; } else { return string__plus(_S("_const_"), v__gen__c__Gen_get_ternary_name(g, v__gen__c__c_name(node.name))); } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC void v__gen__c__Gen_ident(v__gen__c__Gen* g, v__ast__Ident node) { bool v__gen__c__Gen_ident_defer_0 = false; bool prevent_sum_type_unwrapping_once = g->prevent_sum_type_unwrapping_once; g->prevent_sum_type_unwrapping_once = false; if (fast_string_eq(node.name, _S("lld"))) { return; } if (string_starts_with(node.name, _S("C."))) { v__gen__c__Gen_write(g, v__util__no_dots(string_substr(node.name, 2, 2147483647))); return; } string name = (node.kind == v__ast__IdentKind__function ? (v__gen__c__c_fn_name(node.name)) : (v__gen__c__c_name(node.name))); if (node.kind == v__ast__IdentKind__constant) { if (g->pref->translated && !g->is_builtin_mod && !v__util__module_is_builtin(string_all_before_last(node.name, _S(".")))) { string x = v__util__no_dots(node.name); if (string_starts_with(x, _S("main__"))) { x = string_substr(x, 6, 2147483647); } v__gen__c__Gen_write(g, x); return; } else { if (g->inside_opt_or_res && node.or_expr.kind != v__ast__OrKind__absent && v__ast__Type_has_flag((*(node.obj.typ)), v__ast__TypeFlag__option)) { string styp = v__gen__c__Gen_base_type(g, (*(node.obj.typ))); { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)")); } v__gen__c__Gen_ident_defer_0 = true; } v__gen__c__Gen_write(g, _S("_const_")); } } bool is_auto_heap = v__ast__Ident_is_auto_heap(&node); bool is_option = false; if ((node.info)._typ == 477 /* v.ast.IdentVar */) { if ((node.obj)._typ == 422 /* v.ast.Var */) { if (!g->is_assign_lhs && !((*node.obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__smartcast || (*node.obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__generic_param || (*node.obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__no_comptime || (*node.obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__aggregate)) { v__ast__Type comptime_type = v__type_resolver__TypeResolver_get_type(&g->type_resolver, v__ast__Ident_to_sumtype_v__ast__Expr(&node)); if (v__ast__Type_has_flag(comptime_type, v__ast__TypeFlag__option)) { if ((g->inside_opt_or_res || g->left_is_opt) && node.or_expr.kind == v__ast__OrKind__absent) { if (!g->is_assign_lhs && is_auto_heap) { { v__gen__c__Gen_write(g, _S("(*")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S(")")); } } else { v__gen__c__Gen_write(g, name); } } else { string styp = v__gen__c__Gen_base_type(g, comptime_type); if (is_auto_heap) { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S("->data)")); } } else { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S(".data)")); } } } } else { if (is_auto_heap) { v__gen__c__Gen_write2(g, _S("*"), name); } else { v__gen__c__Gen_write(g, name); } } if (node.or_expr.kind != v__ast__OrKind__absent && !(g->inside_opt_or_res && g->inside_assign && !g->is_assign_lhs)) { string stmt_str = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; string var_name = (!g->is_assign_lhs && is_auto_heap ? (str_intp(2, _MOV((StrIntpData[]){{_S("(*"), 0xfe10, {.d_s = name}}, {_S(")"), 0, { .d_c = 0 }}}))) : (name)); v__gen__c__Gen_or_block(g, var_name, node.or_expr, comptime_type); v__gen__c__Gen_writeln(g, stmt_str); } // Defer begin if (v__gen__c__Gen_ident_defer_0) { v__gen__c__Gen_write(g, _S(".data)")); } // Defer end return; } } if ((*node.info._v__ast__IdentVar).is_option && !(g->is_assign_lhs && g->right_is_opt)) { bool has_smartcast = (node.obj)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast((node.obj)._v__ast__Var,(node.obj)._typ, 422)).smartcasts.len > 0 && !((*(v__ast__Var*)__as_cast((node.obj)._v__ast__Var,(node.obj)._typ, 422)).ct_type_var == v__ast__ComptimeVarKind__no_comptime && (*(v__ast__Var*)__as_cast((node.obj)._v__ast__Var,(node.obj)._typ, 422)).is_unwrapped); if (has_smartcast) { v__gen__c__Gen_write(g, _S("*(")); } if ((g->inside_opt_or_res || g->left_is_opt) && node.or_expr.kind == v__ast__OrKind__absent) { if (!g->is_assign_lhs && is_auto_heap) { { v__gen__c__Gen_write(g, _S("(*")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S(")")); } } else { if ((node.obj)._typ == 422 /* v.ast.Var */) { if ((g->is_assign_lhs || g->inside_struct_init) && (*node.obj._v__ast__Var).is_auto_deref) { v__gen__c__Gen_write(g, _S("*")); } if ((*node.obj._v__ast__Var).is_inherited) { v__gen__c__Gen_write(g, _S("_V_closure_ctx->")); } } v__gen__c__Gen_write(g, name); } } else { v__gen__c__Gen_unwrap_option_type(g, (*node.info._v__ast__IdentVar).typ, name, is_auto_heap); } if (node.or_expr.kind != v__ast__OrKind__absent && !(g->inside_opt_or_res && g->inside_assign && !g->is_assign_lhs)) { string stmt_str = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; string var_name = (!g->is_assign_lhs && is_auto_heap ? (str_intp(2, _MOV((StrIntpData[]){{_S("(*"), 0xfe10, {.d_s = name}}, {_S(")"), 0, { .d_c = 0 }}}))) : (name)); v__gen__c__Gen_or_block(g, var_name, node.or_expr, (*node.info._v__ast__IdentVar).typ); v__gen__c__Gen_write(g, stmt_str); } if ((node.obj)._typ == 422 /* v.ast.Var */) { if (has_smartcast) { v__ast__TypeSymbol* obj_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, (*node.obj._v__ast__Var).typ)); if ((*node.obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__smartcast) { v__ast__Type ctyp = v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, v__ast__Ident_to_sumtype_v__ast__Expr(&node))); v__ast__TypeSymbol* cur_variant_sym = v__ast__Table_sym(g->table, ctyp); string variant_name = v__gen__c__Gen_get_sumtype_variant_name(g, ctyp, *cur_variant_sym); { v__gen__c__Gen_write(g, _S("._")); v__gen__c__Gen_write(g, variant_name); } if ((*node.obj._v__ast__Var).is_unwrapped) { v__gen__c__Gen_write(g, _S(".data")); } } else if (obj_sym->kind == v__ast__Kind__sum_type) { v__ast__Type variant_typ = v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Type*)array_last((*node.obj._v__ast__Var).smartcasts))); v__ast__TypeSymbol* cast_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Type*)array_last((*node.obj._v__ast__Var).smartcasts)))); string variant_name = v__gen__c__Gen_get_sumtype_variant_name(g, variant_typ, *cast_sym); { v__gen__c__Gen_write(g, _S("._")); v__gen__c__Gen_write(g, variant_name); } } v__gen__c__Gen_write(g, _S(")")); } } // Defer begin if (v__gen__c__Gen_ident_defer_0) { v__gen__c__Gen_write(g, _S(".data)")); } // Defer end return; } if (!g->is_assign_lhs && (*node.info._v__ast__IdentVar).share == v__ast__ShareType__shared_t) { { v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S(".val")); } // Defer begin if (v__gen__c__Gen_ident_defer_0) { v__gen__c__Gen_write(g, _S(".data)")); } // Defer end return; } is_option = (*node.info._v__ast__IdentVar).is_option || ((node.obj)._typ == 422 /* v.ast.Var */ && v__ast__Type_has_flag((*(v__ast__Var*)__as_cast((node.obj)._v__ast__Var,(node.obj)._typ, 422)).typ, v__ast__TypeFlag__option)); if ((node.obj)._typ == 422 /* v.ast.Var */) { is_auto_heap = (*node.obj._v__ast__Var).is_auto_heap && (!g->is_assign_lhs || g->assign_op != v__token__Kind__decl_assign); if (is_auto_heap) { v__gen__c__Gen_write(g, _S("(*(")); } is_option = is_option || v__ast__Type_has_flag((*node.obj._v__ast__Var).orig_type, v__ast__TypeFlag__option); if ((*node.obj._v__ast__Var).smartcasts.len > 0) { v__ast__TypeSymbol* obj_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, (*node.obj._v__ast__Var).typ)); if (!prevent_sum_type_unwrapping_once) { bool nested_unwrap = (*node.obj._v__ast__Var).smartcasts.len > 1; bool unwrap_sumtype = is_option && nested_unwrap && obj_sym->kind == v__ast__Kind__sum_type; if (unwrap_sumtype) { v__gen__c__Gen_write(g, _S("(*(")); } for (int i = 0; i < (*node.obj._v__ast__Var).smartcasts.len; ++i) { v__ast__Type typ = ((v__ast__Type*)(*node.obj._v__ast__Var).smartcasts.data)[i]; bool is_option_unwrap = i == 0 && is_option && typ == v__ast__Type_clear_flag((*node.obj._v__ast__Var).orig_type, v__ast__TypeFlag__option); v__gen__c__Gen_write(g, _S("(")); if (i == 0 && (*node.obj._v__ast__Var).is_unwrapped && (*node.obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__smartcast) { v__ast__Type ctyp = v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, v__ast__Ident_to_sumtype_v__ast__Expr(&node))); { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, ctyp)); v__gen__c__Gen_write(g, _S("*)(")); } } if (obj_sym->kind == v__ast__Kind__sum_type && !is_auto_heap) { if (is_option) { if (i == 0) { if (!is_option_unwrap) { v__gen__c__Gen_write(g, _S("*(")); } string styp = v__gen__c__Gen_base_type(g, (*node.obj._v__ast__Var).typ); { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)")); } } } else if (!g->arg_no_auto_deref) { v__gen__c__Gen_write(g, _S("*")); } } else if ((g->inside_interface_deref && v__ast__Table_is_interface_var(g->table, node.obj)) || (*node.obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__smartcast || (obj_sym->kind == v__ast__Kind__interface && v__ast__Table_type_kind(g->table, (*node.obj._v__ast__Var).typ) == v__ast__Kind__any)) { v__gen__c__Gen_write(g, _S("*")); } else if (is_option) { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, (*node.obj._v__ast__Var).typ)); v__gen__c__Gen_write(g, _S("*)")); } } } for (int i = 0; i < (*node.obj._v__ast__Var).smartcasts.len; ++i) { v__ast__Type typ = ((v__ast__Type*)(*node.obj._v__ast__Var).smartcasts.data)[i]; bool is_option_unwrap = is_option && typ == v__ast__Type_clear_flag((*node.obj._v__ast__Var).typ, v__ast__TypeFlag__option); v__ast__TypeSymbol* cast_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, typ)); if (obj_sym->kind == v__ast__Kind__interface && cast_sym->kind == v__ast__Kind__interface) { if (!string__eq(cast_sym->cname, obj_sym->cname)) { string ptr = string_repeat(_S("*"), v__ast__Type_nr_muls((*node.obj._v__ast__Var).typ)); { v__gen__c__Gen_write(g, _S("I_")); v__gen__c__Gen_write(g, obj_sym->cname); v__gen__c__Gen_write(g, _S("_as_I_")); v__gen__c__Gen_write(g, cast_sym->cname); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, ptr); v__gen__c__Gen_write(g, node.name); v__gen__c__Gen_write(g, _S(")")); } } else { string ptr = (is_option ? (_S("")) : (string_repeat(_S("*"), v__ast__Type_nr_muls((*node.obj._v__ast__Var).typ)))); { v__gen__c__Gen_write(g, ptr); v__gen__c__Gen_write(g, node.name); } } } else { bool is_ptr = false; if (i == 0) { if ((*node.obj._v__ast__Var).is_inherited) { v__gen__c__Gen_write(g, _S("_V_closure_ctx->")); } if (v__ast__Type_nr_muls((*node.obj._v__ast__Var).typ) > 1) { v__gen__c__Gen_write2(g, _S("("), string_repeat(_S("*"), (int)(v__ast__Type_nr_muls((*node.obj._v__ast__Var).typ) - 1))); v__gen__c__Gen_write2(g, name, _S(")")); } else { v__gen__c__Gen_write(g, name); } if (v__ast__Type_is_ptr((*node.obj._v__ast__Var).orig_type)) { is_ptr = true; } } string dot = (is_ptr || is_auto_heap ? (_S("->")) : (_S("."))); if ((cast_sym->info)._typ == 537 /* v.ast.Aggregate */) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get((*cast_sym->info._v__ast__Aggregate).types, g->aggregate_type_idx))); { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, sym->cname); } } else { if (is_option && !(*node.obj._v__ast__Var).is_unwrapped) { if (i == 0) { v__gen__c__Gen_write(g, _S(".data")); } if (!is_option_unwrap) { v__gen__c__Gen_write(g, _S(")")); } } if ((*node.obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__smartcast) { v__ast__Type ctyp = v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, v__ast__Ident_to_sumtype_v__ast__Expr(&node))); v__ast__TypeSymbol* cur_variant_sym = v__ast__Table_sym(g->table, ctyp); if ((*node.obj._v__ast__Var).is_unwrapped) { ctyp = v__ast__Type_set_flag(ctyp, v__ast__TypeFlag__option); { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, v__gen__c__Gen_get_sumtype_variant_name(g, ctyp, *cur_variant_sym)); } v__gen__c__Gen_write(g, _S(").data")); } else { { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, v__gen__c__Gen_get_sumtype_variant_name(g, ctyp, *cur_variant_sym)); } } } else if (!is_option_unwrap && (obj_sym->kind == v__ast__Kind__sum_type || obj_sym->kind == v__ast__Kind__interface)) { { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, cast_sym->cname); } } if (i != 0 && unwrap_sumtype) { v__gen__c__Gen_write(g, _S(")")); } } } if (i == 0 && (*node.obj._v__ast__Var).ct_type_var != v__ast__ComptimeVarKind__smartcast && (*node.obj._v__ast__Var).is_unwrapped) { string dot = ((!(*node.obj._v__ast__Var).ct_type_unwrapped && !v__ast__Type_is_ptr((*node.obj._v__ast__Var).orig_type) && v__ast__TypeSymbol_is_heap(obj_sym)) || v__ast__Type_has_flag((*node.obj._v__ast__Var).orig_type, v__ast__TypeFlag__option_mut_param_t) ? (_S("->")) : (_S("."))); { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("data")); } } v__gen__c__Gen_write(g, _S(")")); } if (is_auto_heap) { v__gen__c__Gen_write(g, _S("))")); } // Defer begin if (v__gen__c__Gen_ident_defer_0) { v__gen__c__Gen_write(g, _S(".data)")); } // Defer end return; } } if ((*node.obj._v__ast__Var).is_inherited) { v__gen__c__Gen_write(g, _S("_V_closure_ctx->")); } } } else if ((node.info)._typ == 476 /* v.ast.IdentFn */) { _option_v__ast__Fn _t1; if (_t1 = v__ast__Table_find_fn(g->table, node.name), _t1.state == 0) { v__ast__Fn func = *(v__ast__Fn*)_t1.data; if (g->pref->translated || g->file->is_translated || func.is_file_translated) { _option_v__ast__Attr _t2; if (_t2 = Array_v__ast__Attr_find_first(func.attrs, _S("c")), _t2.state == 0) { v__ast__Attr cattr = *(v__ast__Attr*)_t2.data; name = cattr.arg; } } else if (node.concrete_types.len > 0) { name = v__gen__c__Gen_generic_fn_name(g, node.concrete_types, name); } } } v__gen__c__Gen_write(g, v__gen__c__Gen_get_ternary_name(g, name)); if (is_auto_heap) { v__gen__c__Gen_write(g, _S("))")); if (is_option && node.or_expr.kind != v__ast__OrKind__absent) { v__gen__c__Gen_write(g, _S(".data")); } } if (node.or_expr.kind != v__ast__OrKind__absent && !(g->inside_opt_or_res && g->inside_assign && !g->is_assign_lhs)) { string stmt_str = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; string var_opt = (is_auto_heap ? (str_intp(2, _MOV((StrIntpData[]){{_S("(*"), 0xfe10, {.d_s = name}}, {_S(")"), 0, { .d_c = 0 }}}))) : (name)); v__gen__c__Gen_or_block(g, var_opt, node.or_expr, (*(node.obj.typ))); v__gen__c__Gen_write(g, stmt_str); } // Defer begin if (v__gen__c__Gen_ident_defer_0) { v__gen__c__Gen_write(g, _S(".data)")); } // Defer end } VV_LOC void v__gen__c__Gen_cast_expr(v__gen__c__Gen* g, v__ast__CastExpr node) { bool v__gen__c__Gen_cast_expr_defer_0 = false; bool tmp_inside_cast; tmp_inside_cast = g->inside_cast; g->inside_cast = true; v__gen__c__Gen_cast_expr_defer_0 = true; v__ast__Type node_typ = v__gen__c__Gen_unwrap_generic(g, node.typ); v__ast__Type expr_type = node.expr_type; v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, node_typ); if (v__type_resolver__ResolverInfo_is_comptime(g->comptime, node.expr)) { expr_type = v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, node.expr)); } bool node_typ_is_option = v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__option); if (sym->kind == v__ast__Kind__sum_type || sym->kind == v__ast__Kind__interface) { if (node_typ_is_option && (node.expr)._typ == 371 /* v.ast.None */) { v__gen__c__Gen_gen_option_error(g, node.typ, node.expr); } else if ((node.expr)._typ == 358 /* v.ast.Ident */ && v__type_resolver__ResolverInfo_is_comptime_variant_var(g->comptime, *(v__ast__Ident*)__as_cast((node.expr)._v__ast__Ident,(node.expr)._typ, 358))) { v__gen__c__Gen_expr_with_cast(g, node.expr, v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->comptime->comptime_for_variant_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), _const_v__ast__void_type), node_typ); } else if (node_typ_is_option) { v__gen__c__Gen_expr_with_opt(g, node.expr, expr_type, node.typ); } else { v__gen__c__Gen_expr_with_cast(g, node.expr, expr_type, node_typ); } } else if (!node_typ_is_option && !v__ast__Type_is_ptr(node.typ) && (sym->info)._typ == 518 /* v.ast.Struct */ && !(*(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518)).is_typedef) { string styp = v__gen__c__Gen_styp(g, node.typ); { v__gen__c__Gen_write(g, _S("*((")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" *)(&")); } v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write(g, _S("))")); } else if (sym->kind == v__ast__Kind__alias && v__ast__Table_final_sym(g->table, node.typ)->kind == v__ast__Kind__array_fixed) { if (node_typ_is_option) { v__gen__c__Gen_expr_with_opt(g, node.expr, expr_type, node.typ); } else { if ((node.expr)._typ == 338 /* v.ast.ArrayInit */ && g->assign_op != v__token__Kind__decl_assign && !g->inside_const) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, (*node.expr._v__ast__ArrayInit).typ)); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_expr(g, node.expr); } } else if (expr_type == _const_v__ast__bool_type && v__ast__Type_is_int(node.typ)) { string styp = v__gen__c__Gen_styp(g, node_typ); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]){(")); } v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write(g, _S(")?1:0}[0]")); } else { string styp = v__gen__c__Gen_styp(g, node.typ); if ((g->pref->translated || g->file->is_translated) && sym->kind == v__ast__Kind__function) { } string cast_label = _S(""); if (sym->kind != v__ast__Kind__alias || ((sym->info)._typ == 539 /* v.ast.Alias */ && !v__ast__Type_has_flag((*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type, v__ast__TypeFlag__option) && !((*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type == expr_type || (*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type == _const_v__ast__string_type))) { if (sym->kind == v__ast__Kind__string && !v__ast__Type_is_ptr(node.typ)) { cast_label = _S("*(string*)&"); } else if (!(g->is_cc_msvc && string__eq(v__gen__c__Gen_styp(g, node.typ), v__gen__c__Gen_styp(g, expr_type)))) { cast_label = str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = styp}}, {_S(")"), 0, { .d_c = 0 }}})); } } if (node_typ_is_option && (node.expr)._typ == 371 /* v.ast.None */) { v__gen__c__Gen_gen_option_error(g, node.typ, node.expr); } else if (node_typ_is_option) { if ((sym->info)._typ == 539 /* v.ast.Alias */) { if (v__ast__Type_has_flag((*sym->info._v__ast__Alias).parent_type, v__ast__TypeFlag__option)) { string cur_stmt = v__gen__c__Gen_go_before_last_stmt(g); g->empty_line = true; v__ast__Type parent_type = (*sym->info._v__ast__Alias).parent_type; string tmp_var = v__gen__c__Gen_new_tmp_var(g); string tmp_var2 = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln2(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(";"), 0, { .d_c = 0 }}})), str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, parent_type)}}, {_S(" "), 0xfe10, {.d_s = tmp_var2}}, {_S(";"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("_option_ok(&(")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, parent_type)); v__gen__c__Gen_write(g, _S("[]) { ")); } v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)(&"), 0xfe10, {.d_s = tmp_var2}}, {_S("), sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, parent_type)}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("_option_ok(&("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, parent_type)}}, {_S("[]) { "), 0xfe10, {.d_s = tmp_var2}}, {_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = tmp_var}}, {_S(", sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, parent_type)}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write2(g, cur_stmt, tmp_var); } else if (v__ast__Type_has_flag(node.expr_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_opt_with_alias(g, node.expr, expr_type, node.typ); } else { v__gen__c__Gen_expr_with_opt(g, node.expr, expr_type, node.typ); } } else { v__gen__c__Gen_expr_with_opt(g, node.expr, expr_type, node.typ); } } else if ((sym->info)._typ == 539 /* v.ast.Alias */ && v__ast__Type_has_flag((*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_opt(g, node.expr, expr_type, (*sym->info._v__ast__Alias).parent_type); } else { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, cast_label); v__gen__c__Gen_write(g, _S("(")); } if ((node.expr)._typ == 358 /* v.ast.Ident */) { if (!v__ast__Type_is_ptr(node.typ) && v__ast__Type_is_ptr(node.expr_type) && ((*node.expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast(((*node.expr._v__ast__Ident).obj)._v__ast__Var,((*node.expr._v__ast__Ident).obj)._typ, 422)).smartcasts.len > 0) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(node.expr_type))); } } if (sym->kind == v__ast__Kind__alias && v__ast__Table_final_sym(g->table, node.typ)->kind == v__ast__Kind__string) { int ptr_cnt = (int)(v__ast__Type_nr_muls(node.typ) - v__ast__Type_nr_muls(expr_type)); if (ptr_cnt > 0) { v__gen__c__Gen_write(g, string_repeat(_S("&"), ptr_cnt)); } } v__gen__c__Gen_expr(g, node.expr); if ((node.expr)._typ == 363 /* v.ast.IntegerLiteral */) { if (node_typ == _const_v__ast__u64_type || node_typ == _const_v__ast__u32_type || node_typ == _const_v__ast__u16_type) { if (!string_starts_with((*node.expr._v__ast__IntegerLiteral).val, _S("-"))) { v__gen__c__Gen_write(g, _S("U")); } } } v__gen__c__Gen_write(g, _S("))")); } } // Defer begin if (v__gen__c__Gen_cast_expr_defer_0) { g->inside_cast = tmp_inside_cast; } // Defer end } VV_LOC void v__gen__c__Gen_concat_expr(v__gen__c__Gen* g, v__ast__ConcatExpr node) { v__ast__Type typ = v__ast__Type_clear_option_and_result(node.return_type); if (g->inside_return) { typ = v__ast__Type_clear_option_and_result(g->fn_decl->return_type); } else if (g->inside_or_block) { typ = v__ast__Type_clear_option_and_result(g->or_expr_return_type); } string styp = v__gen__c__Gen_styp(g, typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, node.return_type); bool is_multi = sym->kind == v__ast__Kind__multi_return; if (!is_multi) { v__gen__c__Gen_expr(g, (*(v__ast__Expr*)array_get(node.vals, 0))); } else { Array_v__ast__Type types = (({ v__ast__TypeInfo _t1 = v__ast__Table_sym(g->table, typ)->info; *(v__ast__MultiReturn*)__as_cast(_t1._v__ast__MultiReturn,_t1._typ, 552); })).types; { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("){")); } for (int i = 0; i < node.vals.len; ++i) { v__ast__Expr expr = ((v__ast__Expr*)node.vals.data)[i]; { v__gen__c__Gen_write(g, _S(".arg")); v__gen__c__Gen_write_decimal(g, i); v__gen__c__Gen_write(g, _S("=")); } v__ast__Type expr_typ = v__gen__c__Gen_get_expr_type(g, expr); if (expr_typ != _const_v__ast__void_type && v__ast__Type_has_flag((*(v__ast__Type*)array_get(types, i)), v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_opt(g, expr, expr_typ, (*(v__ast__Type*)array_get(types, i))); } else { bool old_left_is_opt = g->left_is_opt; g->left_is_opt = true; v__gen__c__Gen_expr(g, expr); g->left_is_opt = old_left_is_opt; } if (i < (int)(node.vals.len - 1)) { v__gen__c__Gen_write(g, _S(",")); } } v__gen__c__Gen_write(g, _S("}")); } } inline VV_LOC bool v__gen__c__Gen_expr_is_multi_return_call(v__gen__c__Gen* g, v__ast__Expr expr) { if ((expr)._typ == 344 /* v.ast.CallExpr */) { return v__ast__Table_sym(g->table, (*expr._v__ast__CallExpr).return_type)->kind == v__ast__Kind__multi_return; } return false; } VV_LOC void v__gen__c__Gen_gen_result_error(v__gen__c__Gen* g, v__ast__Type target_type, v__ast__Expr expr) { string styp = v__gen__c__Gen_styp(g, v__gen__c__Gen_unwrap_generic(g, target_type)); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("){ .is_error=true, .err=")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(", .data={E_STRUCT} }")); } VV_LOC void v__gen__c__Gen_gen_option_error(v__gen__c__Gen* g, v__ast__Type target_type, v__ast__Expr expr) { string styp = v__gen__c__Gen_styp(g, v__gen__c__Gen_unwrap_generic(g, target_type)); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("){ .state=2, .err=")); } if (v__ast__Type_has_flag(target_type, v__ast__TypeFlag__option) && (expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).or_expr.kind == v__ast__OrKind__propagate_option) { v__gen__c__Gen_expr(g, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}))))); } else { v__gen__c__Gen_expr(g, expr); } v__gen__c__Gen_write(g, _S(", .data={E_STRUCT} }")); } VV_LOC string v__gen__c__Gen_hash_stmt_guarded_include(v__gen__c__Gen* g, v__ast__HashStmt node) { string missing_message = str_intp(3, _MOV((StrIntpData[]){{_S("Header file "), 0xfe10, {.d_s = node.main}}, {_S(", needed for module `"), 0xfe10, {.d_s = node.mod}}, {_S("` was not found."), 0, { .d_c = 0 }}})); if ((node.msg).len != 0) { missing_message = string__plus(missing_message, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = node.msg}}, {_S("."), 0, { .d_c = 0 }}}))); } else { missing_message = string__plus(missing_message, _S(" Please install the corresponding development headers.")); } string guarded_include = v__gen__c__get_guarded_include_text(node.main, missing_message); if (fast_string_eq(node.main, _S(""))) { guarded_include = str_intp(2, _MOV((StrIntpData[]){{_S("#include "), 0xfe10, {.d_s = node.main}}, {_SLIT0, 0, { .d_c = 0 }}})); } return guarded_include; } VV_LOC void v__gen__c__Gen_hash_stmt(v__gen__c__Gen* g, v__ast__HashStmt node) { int line_nr = (int)(node.pos.line_nr + 1); string ct_condition = _S(""); if (node.ct_conds.len > 0) { int ct_condition_start = g->out.len; for (int idx = 0; idx < node.ct_conds.len; ++idx) { v__ast__Expr ct_expr = ((v__ast__Expr*)node.ct_conds.data)[idx]; v__gen__c__Gen_comptime_if_cond(g, ct_expr, false); if (idx < (int)(node.ct_conds.len - 1)) { v__gen__c__Gen_write(g, _S(" && ")); } } ct_condition = string_trim_space(strings__Builder_cut_to(&g->out, ct_condition_start)); } if (fast_string_eq(node.kind, _S("include"))) { string guarded_include = v__gen__c__Gen_hash_stmt_guarded_include(g, node); if (string_contains(node.main, _S(".m"))) { strings__Builder_writeln(&g->definitions, _S("")); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->definitions, str_intp(2, _MOV((StrIntpData[]){{_S("#if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_S("// added by module `"), 0xfe10, {.d_s = node.mod}}, {_S("`, file: "), 0xfe10, {.d_s = os__file_name(node.source_file)}}, {_S(":"), 0xfe07, {.d_i32 = line_nr}}, {_S(":"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, guarded_include); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->definitions, str_intp(2, _MOV((StrIntpData[]){{_S("#endif // $if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } else { strings__Builder_writeln(&g->includes, _S("")); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->includes, str_intp(2, _MOV((StrIntpData[]){{_S("#if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->includes, str_intp(4, _MOV((StrIntpData[]){{_S("// added by module `"), 0xfe10, {.d_s = node.mod}}, {_S("`, file: "), 0xfe10, {.d_s = os__file_name(node.source_file)}}, {_S(":"), 0xfe07, {.d_i32 = line_nr}}, {_S(":"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->includes, guarded_include); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->includes, str_intp(2, _MOV((StrIntpData[]){{_S("#endif // $if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } } else if (fast_string_eq(node.kind, _S("preinclude"))) { string guarded_include = v__gen__c__Gen_hash_stmt_guarded_include(g, node); if (string_contains(node.main, _S(".m"))) { strings__Builder_writeln(&g->definitions, _S("")); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->definitions, str_intp(2, _MOV((StrIntpData[]){{_S("#if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->definitions, str_intp(4, _MOV((StrIntpData[]){{_S("// added by module `"), 0xfe10, {.d_s = node.mod}}, {_S("`, file: "), 0xfe10, {.d_s = os__file_name(node.source_file)}}, {_S(":"), 0xfe07, {.d_i32 = line_nr}}, {_S(":"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->definitions, guarded_include); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->definitions, str_intp(2, _MOV((StrIntpData[]){{_S("#endif // $if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } else { strings__Builder_writeln(&g->preincludes, _S("")); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->preincludes, str_intp(2, _MOV((StrIntpData[]){{_S("#if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->preincludes, str_intp(4, _MOV((StrIntpData[]){{_S("// added by module `"), 0xfe10, {.d_s = node.mod}}, {_S("`, file: "), 0xfe10, {.d_s = os__file_name(node.source_file)}}, {_S(":"), 0xfe07, {.d_i32 = line_nr}}, {_S(":"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->preincludes, guarded_include); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->preincludes, str_intp(2, _MOV((StrIntpData[]){{_S("#endif // $if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } } else if (fast_string_eq(node.kind, _S("postinclude"))) { string guarded_include = v__gen__c__Gen_hash_stmt_guarded_include(g, node); strings__Builder_writeln(&g->postincludes, _S("")); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->postincludes, str_intp(2, _MOV((StrIntpData[]){{_S("#if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->postincludes, str_intp(4, _MOV((StrIntpData[]){{_S("// added by module `"), 0xfe10, {.d_s = node.mod}}, {_S("`, file: "), 0xfe10, {.d_s = os__file_name(node.source_file)}}, {_S(":"), 0xfe07, {.d_i32 = line_nr}}, {_S(":"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->postincludes, guarded_include); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->postincludes, str_intp(2, _MOV((StrIntpData[]){{_S("#endif // $if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } else if (fast_string_eq(node.kind, _S("insert"))) { if ((ct_condition).len != 0) { strings__Builder_writeln(&g->includes, str_intp(2, _MOV((StrIntpData[]){{_S("#if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->includes, str_intp(4, _MOV((StrIntpData[]){{_S("// inserted by module `"), 0xfe10, {.d_s = node.mod}}, {_S("`, file: "), 0xfe10, {.d_s = os__file_name(node.source_file)}}, {_S(":"), 0xfe07, {.d_i32 = line_nr}}, {_S(":"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->includes, node.val); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->includes, str_intp(2, _MOV((StrIntpData[]){{_S("#endif // $if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } else if (fast_string_eq(node.kind, _S("define"))) { if ((ct_condition).len != 0) { strings__Builder_writeln(&g->includes, str_intp(2, _MOV((StrIntpData[]){{_S("#if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->includes, str_intp(2, _MOV((StrIntpData[]){{_S("// defined by module `"), 0xfe10, {.d_s = node.mod}}, {_S("`"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->includes, str_intp(2, _MOV((StrIntpData[]){{_S("#define "), 0xfe10, {.d_s = node.main}}, {_SLIT0, 0, { .d_c = 0 }}}))); if ((ct_condition).len != 0) { strings__Builder_writeln(&g->includes, str_intp(2, _MOV((StrIntpData[]){{_S("#endif // $if "), 0xfe10, {.d_s = ct_condition}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } } VV_LOC void v__gen__c__Gen_branch_stmt(v__gen__c__Gen* g, v__ast__BranchStmt node) { if ((node.label).len != 0) { v__ast__Stmt** _t2 = (v__ast__Stmt**)(map_get_check(ADDR(map, g->labeled_loops), &(string[]){node.label})); _option_v__ast__Stmt_ptr _t1 = {0}; if (_t2) { *((v__ast__Stmt**)&_t1.data) = *((v__ast__Stmt**)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } ; if (_t1.state != 0) { IError err = _t1.err; _v_panic(str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.label}}, {_S(" doesn\'t exist "), 0xfe10, {.d_s = g->file->path}}, {_S(", "), 0xfe10, {.d_s = v__token__Pos_str(node.pos)}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } v__ast__Stmt* x = (*(v__ast__Stmt**)_t1.data); if (x->_typ == 402 /* v.ast.ForCStmt */) { if (v__ast__Scope_contains((*x->_v__ast__ForCStmt).scope, g->cur_lock.pos.pos)) { v__gen__c__Gen_unlock_locks(g); } } else if (x->_typ == 403 /* v.ast.ForInStmt */) { if (v__ast__Scope_contains((*x->_v__ast__ForInStmt).scope, g->cur_lock.pos.pos)) { v__gen__c__Gen_unlock_locks(g); } } else if (x->_typ == 404 /* v.ast.ForStmt */) { if (v__ast__Scope_contains((*x->_v__ast__ForStmt).scope, g->cur_lock.pos.pos)) { v__gen__c__Gen_unlock_locks(g); } } else { } if (node.kind == v__token__Kind__key_break) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("goto "), 0xfe10, {.d_s = node.label}}, {_S("__break;"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("goto "), 0xfe10, {.d_s = node.label}}, {_S("__continue;"), 0, { .d_c = 0 }}}))); } } else { v__ast__Stmt* inner_loop = g->inner_loop; if (inner_loop->_typ == 402 /* v.ast.ForCStmt */) { if (v__ast__Scope_contains((*inner_loop->_v__ast__ForCStmt).scope, g->cur_lock.pos.pos)) { v__gen__c__Gen_unlock_locks(g); } } else if (inner_loop->_typ == 403 /* v.ast.ForInStmt */) { if (v__ast__Scope_contains((*inner_loop->_v__ast__ForInStmt).scope, g->cur_lock.pos.pos)) { v__gen__c__Gen_unlock_locks(g); } } else if (inner_loop->_typ == 404 /* v.ast.ForStmt */) { if (v__ast__Scope_contains((*inner_loop->_v__ast__ForStmt).scope, g->cur_lock.pos.pos)) { v__gen__c__Gen_unlock_locks(g); } } else { } if (g->is_autofree && !g->is_builtin_mod) { ; v__gen__c__Gen_autofree_scope_vars_stop(g, (int)(node.pos.pos - 1), node.pos.line_nr, true, g->branch_parent_pos); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__token__Kind_str(node.kind)}}, {_S(";"), 0, { .d_c = 0 }}}))); } } VV_LOC void v__gen__c__Gen_return_stmt(v__gen__c__Gen* g, v__ast__Return node) { bool v__gen__c__Gen_return_stmt_defer_0 = false; bool old_inside_return; v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); v__gen__c__Gen_write_v_source_line_info_stmt(g, v__ast__Return_to_sumtype_v__ast__Stmt(&node)); old_inside_return = g->inside_return; g->inside_return = true; v__gen__c__Gen_return_stmt_defer_0 = true; int exprs_len = node.exprs.len; v__ast__Expr expr0 = (exprs_len > 0 ? ((*(v__ast__Expr*)array_get(node.exprs, 0))) : (_const_v__ast__empty_expr)); v__ast__Type type0 = (exprs_len > 0 ? (v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Type*)array_get(node.types, 0)))) : (_const_v__ast__void_type)); if (exprs_len > 0) { if ((expr0)._typ == 349 /* v.ast.ComptimeCall */ && (*(v__ast__ComptimeCall*)__as_cast((expr0)._v__ast__ComptimeCall,(expr0)._typ, 349)).is_vweb) { g->inside_return_tmpl = true; v__gen__c__Gen_expr(g, expr0); g->inside_return_tmpl = false; v__gen__c__Gen_writeln(g, _S(";")); // Defer begin if (v__gen__c__Gen_return_stmt_defer_0) { g->inside_return = old_inside_return; } // Defer end return; } } v__ast__Type ret_type = v__gen__c__Gen_unwrap_generic(g, g->fn_decl->return_type); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, ret_type); v__ast__Type fn_ret_type = ret_type; if (sym->kind == v__ast__Kind__alias) { v__ast__Type unaliased_type = v__ast__Table_unaliased_type(g->table, fn_ret_type); if (v__ast__Type_has_option_or_result(unaliased_type)) { fn_ret_type = v__gen__c__Gen_unwrap_generic(g, unaliased_type); } } bool fn_return_is_multi = sym->kind == v__ast__Kind__multi_return; bool fn_return_is_option = v__ast__Type_has_flag(fn_ret_type, v__ast__TypeFlag__option); bool fn_return_is_result = v__ast__Type_has_flag(fn_ret_type, v__ast__TypeFlag__result); bool fn_return_is_fixed_array = v__ast__TypeSymbol_is_array_fixed(sym); bool fn_return_is_fixed_array_non_result = fn_return_is_fixed_array && !v__ast__Type_has_option_or_result(fn_ret_type); bool has_semicolon = false; if (exprs_len == 0) { v__gen__c__Gen_write_defer_stmts_when_needed(g); if (fn_return_is_option || fn_return_is_result) { string styp = v__gen__c__Gen_styp(g, fn_ret_type); if (g->is_autofree) { ; v__gen__c__Gen_autofree_scope_vars(g, node.pos.pos, node.pos.line_nr, false); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("return ("), 0xfe10, {.d_s = styp}}, {_S("){0};"), 0, { .d_c = 0 }}}))); } else { if (g->is_autofree) { ; v__gen__c__Gen_autofree_scope_vars(g, (int)(node.pos.pos - 1), node.pos.line_nr, true); } v__gen__c__Gen_writeln(g, _S("return;")); } // Defer begin if (v__gen__c__Gen_return_stmt_defer_0) { g->inside_return = old_inside_return; } // Defer end return; } string tmpvar = v__gen__c__Gen_new_tmp_var(g); g->defer_return_tmp_var = tmpvar; string ret_typ = v__gen__c__Gen_ret_styp(g, fn_ret_type); if (exprs_len == 1 && (fn_return_is_option || fn_return_is_result) && (expr0)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast((expr0)._v__ast__CallExpr,(expr0)._typ, 344)).return_type == ret_type && (*(v__ast__CallExpr*)__as_cast((expr0)._v__ast__CallExpr,(expr0)._typ, 344)).or_block.kind == v__ast__OrKind__absent) { if (g->defer_stmts.len > 0) { { v__gen__c__Gen_write(g, ret_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, expr0); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write_defer_stmts_when_needed(g); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("return "), 0xfe10, {.d_s = tmpvar}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_write_defer_stmts_when_needed(g); v__gen__c__Gen_write(g, _S("return ")); v__gen__c__Gen_expr(g, expr0); v__gen__c__Gen_writeln(g, _S(";")); } // Defer begin if (v__gen__c__Gen_return_stmt_defer_0) { g->inside_return = old_inside_return; } // Defer end return; } bool _t1 = (g->defer_stmts.len > 0 || g->defer_profile_code.len > 0 || g->cur_lock.lockeds.len > 0 || (fn_return_is_multi && exprs_len >= 1 && fn_return_is_option) || fn_return_is_fixed_array_non_result); bool _t2 = ((!_t1) && fn_return_is_multi); bool _t3 = false; if (_t2) { Array_v__ast__Type _t3_orig = node.types; int _t3_len = _t3_orig.len; for (int _t4 = 0; _t4 < _t3_len; ++_t4) { v__ast__Type it = ((v__ast__Type*) _t3_orig.data)[_t4]; if (v__ast__Table_final_sym(g->table, it)->kind == v__ast__Kind__array_fixed) { _t3 = true; break; } } } bool use_tmp_var = _t1 || ( _t2 &&_t3); if (fn_return_is_option) { bool option_none = (expr0)._typ == 371 /* v.ast.None */; string ftyp = v__gen__c__Gen_styp(g, type0); bool is_regular_option = _SLIT_EQ(ftyp.str, ftyp.len, "_option"); if (option_none || is_regular_option || type0 == 30) { if (g->fn_decl != ((void*)0) && g->fn_decl->is_test) { string test_error_var = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, ret_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, test_error_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_gen_option_error(g, fn_ret_type, expr0); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write_defer_stmts_when_needed(g); v__gen__c__Gen_gen_failing_return_error_for_test_fn(g, node, test_error_var); // Defer begin if (v__gen__c__Gen_return_stmt_defer_0) { g->inside_return = old_inside_return; } // Defer end return; } if (use_tmp_var) { { v__gen__c__Gen_write(g, ret_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(" = ")); } } else { v__gen__c__Gen_write(g, _S("return ")); } v__gen__c__Gen_gen_option_error(g, fn_ret_type, expr0); v__gen__c__Gen_writeln(g, _S(";")); if (use_tmp_var) { if (fn_return_is_multi && exprs_len >= 1) { v__ast__MultiReturn mr_info = *(v__ast__MultiReturn*)__as_cast((sym->info)._v__ast__MultiReturn,(sym->info)._typ, 552); for (int i = 0; i < mr_info.types.len; ++i) { if (v__ast__Type_has_flag((*(v__ast__Type*)array_get(mr_info.types, i)), v__ast__TypeFlag__option)) { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, fn_ret_type)); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(".data).arg")); v__gen__c__Gen_write_decimal(g, i); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_gen_option_error(g, (*(v__ast__Type*)array_get(mr_info.types, i)), v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}))))); v__gen__c__Gen_writeln(g, _S(";")); } } } v__gen__c__Gen_write_defer_stmts_when_needed(g); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("return "), 0xfe10, {.d_s = tmpvar}}, {_S(";"), 0, { .d_c = 0 }}}))); } // Defer begin if (v__gen__c__Gen_return_stmt_defer_0) { g->inside_return = old_inside_return; } // Defer end return; } } if (fn_return_is_result) { string ftyp = v__gen__c__Gen_styp(g, type0); bool is_regular_result = string__eq(ftyp, _const_v__gen__c__result_name); if (is_regular_result || type0 == 30) { if (g->fn_decl != ((void*)0) && g->fn_decl->is_test) { string test_error_var = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, ret_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, test_error_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_gen_result_error(g, fn_ret_type, expr0); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write_defer_stmts_when_needed(g); v__gen__c__Gen_gen_failing_return_error_for_test_fn(g, node, test_error_var); // Defer begin if (v__gen__c__Gen_return_stmt_defer_0) { g->inside_return = old_inside_return; } // Defer end return; } if (use_tmp_var) { { v__gen__c__Gen_write(g, ret_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(" = ")); } } else { v__gen__c__Gen_write(g, _S("return ")); } v__gen__c__Gen_gen_result_error(g, fn_ret_type, expr0); v__gen__c__Gen_writeln(g, _S(";")); if (use_tmp_var) { v__gen__c__Gen_write_defer_stmts_when_needed(g); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("return "), 0xfe10, {.d_s = tmpvar}}, {_S(";"), 0, { .d_c = 0 }}}))); } // Defer begin if (v__gen__c__Gen_return_stmt_defer_0) { g->inside_return = old_inside_return; } // Defer end return; } } if (fn_return_is_multi && exprs_len > 0 && !v__gen__c__Gen_expr_is_multi_return_call(g, expr0)) { if (exprs_len == 1 && ((expr0)._typ == 359 /* v.ast.IfExpr */ || (expr0)._typ == 369 /* v.ast.MatchExpr */)) { { v__gen__c__Gen_write(g, ret_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, expr0); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write_defer_stmts_when_needed(g); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("return "), 0xfe10, {.d_s = tmpvar}}, {_S(";"), 0, { .d_c = 0 }}}))); // Defer begin if (v__gen__c__Gen_return_stmt_defer_0) { g->inside_return = old_inside_return; } // Defer end return; } v__ast__MultiReturn mr_info = *(v__ast__MultiReturn*)__as_cast((sym->info)._v__ast__MultiReturn,(sym->info)._typ, 552); string styp = _S(""); if (fn_return_is_option) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = tmpvar}}, {_S(";"), 0, { .d_c = 0 }}}))); styp = v__gen__c__Gen_base_type(g, ret_type); { v__gen__c__Gen_write(g, _S("_option_ok(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) { ")); } } else if (fn_return_is_result) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = tmpvar}}, {_S(";"), 0, { .d_c = 0 }}}))); styp = v__gen__c__Gen_base_type(g, ret_type); { v__gen__c__Gen_write(g, _S("_result_ok(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) { ")); } } else { if (use_tmp_var) { { v__gen__c__Gen_write(g, ret_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(" = ")); } } else { v__gen__c__Gen_write(g, _S("return ")); } styp = v__gen__c__Gen_styp(g, ret_type); } string multi_unpack = _S(""); string final_assignments = _S(""); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("){")); } int arg_idx = 0; for (int i = 0; i < node.exprs.len; ++i) { v__ast__Expr expr = ((v__ast__Expr*)node.exprs.data)[i]; if (v__gen__c__Gen_expr_is_multi_return_call(g, expr)) { v__ast__CallExpr call_expr = *(v__ast__CallExpr*)__as_cast((expr)._v__ast__CallExpr,(expr)._typ, 344); v__ast__TypeSymbol* expr_sym = v__ast__Table_sym(g->table, call_expr.return_type); string tmp = v__gen__c__Gen_new_tmp_var(g); if (!v__ast__Type_has_option_or_result(call_expr.return_type)) { string line = v__gen__c__Gen_go_before_last_stmt(g); string expr_styp = v__gen__c__Gen_styp(g, call_expr.return_type); { v__gen__c__Gen_write(g, expr_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S("=")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_writeln(g, _S(";")); multi_unpack = string__plus(multi_unpack, v__gen__c__Gen_go_before_last_stmt(g)); v__gen__c__Gen_write(g, line); } else { string line = v__gen__c__Gen_go_before_last_stmt(g); g->tmp_count--; v__gen__c__Gen_expr(g, expr); multi_unpack = string__plus(multi_unpack, v__gen__c__Gen_go_before_last_stmt(g)); v__gen__c__Gen_write(g, line); string expr_styp = v__gen__c__Gen_base_type(g, call_expr.return_type); tmp = str_intp(3, _MOV((StrIntpData[]){{_S("(*("), 0xfe10, {.d_s = expr_styp}}, {_S("*)"), 0xfe10, {.d_s = tmp}}, {_S(".data)"), 0, { .d_c = 0 }}})); } Array_v__ast__Type expr_types = v__ast__TypeSymbol_mr_info(expr_sym).types; for (int j = 0; j < expr_types.len; ++j) { { v__gen__c__Gen_write(g, _S(".arg")); v__gen__c__Gen_write_decimal(g, arg_idx); v__gen__c__Gen_write(g, _S("=")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S(".arg")); v__gen__c__Gen_write_decimal(g, j); } if (j < expr_types.len || i < (int)(exprs_len - 1)) { v__gen__c__Gen_write(g, _S(",")); } arg_idx++; } continue; } { v__gen__c__Gen_write(g, _S(".arg")); v__gen__c__Gen_write_decimal(g, arg_idx); v__gen__c__Gen_write(g, _S("=")); } if ((expr)._typ != 338 /* v.ast.ArrayInit */ && v__ast__Table_final_sym(g->table, (*(v__ast__Type*)array_get(node.types, i)))->kind == v__ast__Kind__array_fixed) { string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); string expr_styp = v__gen__c__Gen_styp(g, (*(v__ast__Type*)array_get(node.types, i))); { v__gen__c__Gen_write(g, _S("memcpy(&")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(".arg")); v__gen__c__Gen_write_decimal(g, arg_idx); v__gen__c__Gen_write(g, _S(", ")); } if ((expr)._typ == 385 /* v.ast.StructInit */) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, expr_styp); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = expr_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); final_assignments = string__plus(final_assignments, string__plus(v__gen__c__Gen_go_before_last_stmt(g), _S("\t"))); v__gen__c__Gen_write2(g, line, _S("{0}")); } else { if (v__ast__Expr_is_auto_deref_var(expr)) { v__gen__c__Gen_write(g, _S("*")); } if (v__ast__Type_has_flag((*(v__ast__Type*)array_get(mr_info.types, i)), v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_opt(g, expr, (*(v__ast__Type*)array_get(node.types, i)), (*(v__ast__Type*)array_get(mr_info.types, i))); } else if (v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get(mr_info.types, i)))->kind == v__ast__Kind__sum_type || v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get(mr_info.types, i)))->kind == v__ast__Kind__interface) { v__gen__c__Gen_expr_with_cast(g, expr, (*(v__ast__Type*)array_get(node.types, i)), (*(v__ast__Type*)array_get(mr_info.types, i))); } else { v__gen__c__Gen_expr(g, expr); } } if (i < (int)(exprs_len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } arg_idx++; } v__gen__c__Gen_write(g, _S("}")); if (fn_return_is_option) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)(&"), 0xfe10, {.d_s = tmpvar}}, {_S("), sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write_defer_stmts_when_needed(g); { v__gen__c__Gen_write(g, _S("return ")); v__gen__c__Gen_write(g, tmpvar); } } else if (fn_return_is_result) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("*)(&"), 0xfe10, {.d_s = tmpvar}}, {_S("), sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write_defer_stmts_when_needed(g); { v__gen__c__Gen_write(g, _S("return ")); v__gen__c__Gen_write(g, tmpvar); } } if ((multi_unpack).len != 0) { v__gen__c__Gen_insert_before_stmt(g, multi_unpack); } if ((final_assignments).len != 0) { v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write(g, final_assignments); } if (use_tmp_var && !fn_return_is_option && !fn_return_is_result) { if (!has_semicolon) { v__gen__c__Gen_writeln(g, _S(";")); } v__gen__c__Gen_write_defer_stmts_when_needed(g); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("return "), 0xfe10, {.d_s = tmpvar}}, {_S(";"), 0, { .d_c = 0 }}}))); has_semicolon = true; } } else if (exprs_len >= 1) { if (node.types.len == 0) { v__gen__c__Gen_checker_bug(g, str_intp(2, _MOV((StrIntpData[]){{_S("node.exprs.len == "), 0xfe07, {.d_i32 = node.exprs.len}}, {_S(" && node.types.len == 0"), 0, { .d_c = 0 }}})), node.pos); } v__ast__TypeSymbol* return_sym = v__ast__Table_final_sym(g->table, type0); bool expr_type_is_opt = ((expr0._typ == 344 /* v.ast.CallExpr */)? (v__ast__Type_has_flag((*expr0._v__ast__CallExpr).return_type, v__ast__TypeFlag__option) && (*expr0._v__ast__CallExpr).or_block.kind == v__ast__OrKind__absent) : (v__ast__Type_has_flag(type0, v__ast__TypeFlag__option))); if (fn_return_is_option && !expr_type_is_opt && !string__eq(return_sym->name, _const_v__gen__c__option_name)) { if (fn_return_is_fixed_array && (((expr0)._typ == 385 /* v.ast.StructInit */ || (expr0)._typ == 344 /* v.ast.CallExpr */ || (expr0)._typ == 345 /* v.ast.CastExpr */) || ((expr0)._typ == 338 /* v.ast.ArrayInit */ && (*(v__ast__ArrayInit*)__as_cast((expr0)._v__ast__ArrayInit,(expr0)._typ, 338)).has_callexpr)) && v__ast__Table_final_sym(g->table, type0)->kind == v__ast__Kind__array_fixed) { string styp = v__gen__c__Gen_styp(g, v__ast__Type_clear_option_and_result(fn_ret_type)); if ((expr0)._typ == 344 /* v.ast.CallExpr */) { string tmp_var = v__gen__c__Gen_expr_with_fixed_array(g, expr0, type0, fn_ret_type); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = tmpvar}}, {_S(" = "), 0xfe10, {.d_s = tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = tmpvar}}, {_S(" = ("), 0xfe10, {.d_s = ret_typ}}, {_S("){ .state=0, .err=_const_none__, .data={E_STRUCT} };"), 0, { .d_c = 0 }}}))); if ((expr0)._typ == 385 /* v.ast.StructInit */) { { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(".data, ")); } string tmp_var = v__gen__c__Gen_expr_with_opt(g, expr0, type0, fn_ret_type); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".data, sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); if ((tmp_var).len != 0) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmpvar}}, {_S(".state = "), 0xfe10, {.d_s = tmp_var}}, {_S(".state;"), 0, { .d_c = 0 }}}))); } } else { { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(".data, ")); } v__gen__c__Gen_expr(g, expr0); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } } } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = tmpvar}}, {_S(";"), 0, { .d_c = 0 }}}))); string styp = v__gen__c__Gen_base_type(g, fn_ret_type); { v__gen__c__Gen_write(g, _S("_option_ok(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) { ")); } if (!v__ast__Type_is_ptr(fn_ret_type) && v__ast__Type_is_ptr(type0)) { if (!((expr0)._typ == 358 /* v.ast.Ident */ && !g->is_amp)) { v__gen__c__Gen_write(g, _S("*")); } } if (return_sym->kind == v__ast__Kind__array_fixed && (expr0)._typ != 338 /* v.ast.ArrayInit */) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((return_sym->info)._v__ast__ArrayFixed,(return_sym->info)._typ, 549); v__gen__c__Gen_fixed_array_var_init(g, v__gen__c__Gen_expr_string(g, expr0), v__ast__Expr_is_auto_deref_var(expr0), info.elem_type, info.size); } else { v__gen__c__Gen_expr_with_cast(g, expr0, type0, v__ast__Type_clear_option_and_result(fn_ret_type)); } v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)(&"), 0xfe10, {.d_s = tmpvar}}, {_S("), sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_write_defer_stmts_when_needed(g); v__gen__c__Gen_autofree_scope_vars(g, (int)(node.pos.pos - 1), node.pos.line_nr, true); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("return "), 0xfe10, {.d_s = tmpvar}}, {_S(";"), 0, { .d_c = 0 }}}))); // Defer begin if (v__gen__c__Gen_return_stmt_defer_0) { g->inside_return = old_inside_return; } // Defer end return; } bool expr_type_is_result = ((expr0._typ == 344 /* v.ast.CallExpr */)? (v__ast__Type_has_flag((*expr0._v__ast__CallExpr).return_type, v__ast__TypeFlag__result) && (*expr0._v__ast__CallExpr).or_block.kind == v__ast__OrKind__absent) : (v__ast__Type_has_flag(type0, v__ast__TypeFlag__result))); if (fn_return_is_result && !expr_type_is_result && !string__eq(return_sym->name, _const_v__gen__c__result_name)) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = tmpvar}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); if (fn_return_is_fixed_array && (expr0)._typ != 338 /* v.ast.ArrayInit */ && v__ast__Table_final_sym(g->table, type0)->kind == v__ast__Kind__array_fixed) { string styp = v__gen__c__Gen_styp(g, v__ast__Type_clear_option_and_result(fn_ret_type)); { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(".data, ")); } if ((expr0)._typ == 344 /* v.ast.CallExpr */ || (expr0)._typ == 385 /* v.ast.StructInit */) { v__gen__c__Gen_expr_with_opt(g, expr0, type0, fn_ret_type); v__gen__c__Gen_write(g, _S(".data")); } else { v__gen__c__Gen_expr(g, expr0); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { string styp = v__gen__c__Gen_base_type(g, fn_ret_type); { v__gen__c__Gen_write(g, _S("_result_ok(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("[]) { ")); } if (!v__ast__Type_is_ptr(fn_ret_type) && v__ast__Type_is_ptr(type0)) { if (!(((expr0)._typ == 358 /* v.ast.Ident */ && !g->is_amp) || sym->kind == v__ast__Kind__interface)) { v__gen__c__Gen_write(g, _S("*")); } } if (v__ast__Type_has_flag(fn_ret_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_opt(g, expr0, type0, v__ast__Type_clear_flag(fn_ret_type, v__ast__TypeFlag__result)); } else if (return_sym->kind == v__ast__Kind__array_fixed && (expr0)._typ != 338 /* v.ast.ArrayInit */) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((return_sym->info)._v__ast__ArrayFixed,(return_sym->info)._typ, 549); v__gen__c__Gen_fixed_array_var_init(g, v__gen__c__Gen_expr_string(g, expr0), v__ast__Expr_is_auto_deref_var(expr0), info.elem_type, info.size); } else { v__gen__c__Gen_expr_with_cast(g, expr0, type0, v__ast__Type_clear_flag(fn_ret_type, v__ast__TypeFlag__result)); } v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("*)(&"), 0xfe10, {.d_s = tmpvar}}, {_S("), sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_write_defer_stmts_when_needed(g); v__gen__c__Gen_autofree_scope_vars(g, (int)(node.pos.pos - 1), node.pos.line_nr, true); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("return "), 0xfe10, {.d_s = tmpvar}}, {_S(";"), 0, { .d_c = 0 }}}))); // Defer begin if (v__gen__c__Gen_return_stmt_defer_0) { g->inside_return = old_inside_return; } // Defer end return; } if (g->is_autofree) { if ((expr0)._typ == 358 /* v.ast.Ident */) { g->returned_var_name = (*expr0._v__ast__Ident).name; } if (!use_tmp_var && !g->is_builtin_mod) { use_tmp_var = (expr0)._typ == 344 /* v.ast.CallExpr */; } } if (use_tmp_var || !g->is_builtin_mod) { if (use_tmp_var) { use_tmp_var = true; { v__gen__c__Gen_write(g, ret_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(" = ")); } } else { if (!g->is_builtin_mod) { v__gen__c__Gen_autofree_scope_vars(g, (int)(node.pos.pos - 1), node.pos.line_nr, true); } v__gen__c__Gen_write(g, _S("return ")); } } else { v__gen__c__Gen_autofree_scope_vars(g, (int)(node.pos.pos - 1), node.pos.line_nr, true); v__gen__c__Gen_write(g, _S("return ")); } if (v__ast__Expr_is_auto_deref_var(expr0) && !fn_return_is_fixed_array) { if (v__ast__Type_is_ptr(ret_type)) { string var_str = v__gen__c__Gen_expr_string(g, expr0); v__gen__c__Gen_write(g, string_trim(var_str, _S("&"))); } else if (v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_opt(g, expr0, type0, ret_type); } else if (v__ast__Table_sym(g->table, ret_type)->kind == v__ast__Kind__sum_type || v__ast__Table_sym(g->table, ret_type)->kind == v__ast__Kind__interface) { v__gen__c__Gen_expr_with_cast(g, expr0, type0, ret_type); } else { v__gen__c__Gen_write(g, _S("*")); v__gen__c__Gen_expr(g, expr0); } } else { if (v__ast__Type_has_flag(ret_type, v__ast__TypeFlag__option)) { bool expr0_is_alias_fn_ret = (expr0)._typ == 344 /* v.ast.CallExpr */ && v__ast__Type_has_flag(type0, v__ast__TypeFlag__option) && (Array_v__ast__Kind_contains(new_array_from_c_array(2, 2, sizeof(v__ast__Kind), _MOV((v__ast__Kind[2]){v__ast__Kind__placeholder, v__ast__Kind__alias})), v__ast__Table_type_kind(g->table, type0))); if (expr0_is_alias_fn_ret) { v__gen__c__Gen_expr_opt_with_cast(g, expr0, type0, ret_type); } else { v__gen__c__Gen_expr_with_opt(g, expr0, type0, ret_type); } } else { if (fn_return_is_fixed_array && !v__ast__Type_has_option_or_result(type0)) { if (((*(v__ast__Expr*)array_get(node.exprs, 0)))._typ == 358 /* v.ast.Ident */) { v__gen__c__Gen_writeln(g, _S("{0};")); v__ast__Type typ = (v__ast__Expr_is_auto_deref_var((*(v__ast__Expr*)array_get(node.exprs, 0))) ? (v__ast__Type_deref(type0)) : (type0)); v__ast__TypeSymbol* typ_sym = v__ast__Table_final_sym(g->table, typ); if (typ_sym->kind == v__ast__Kind__array_fixed && (*(v__ast__ArrayFixed*)__as_cast((typ_sym->info)._v__ast__ArrayFixed,(typ_sym->info)._typ, 549)).is_fn_ret) { { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(".ret_arr, ")); v__gen__c__Gen_write(g, v__gen__c__Gen_expr_string(g, expr0)); v__gen__c__Gen_write(g, _S(".ret_arr, sizeof(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, typ)); v__gen__c__Gen_write(g, _S("))")); } } else { { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(".ret_arr, ")); v__gen__c__Gen_write(g, v__gen__c__Gen_expr_string(g, expr0)); v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, typ)); v__gen__c__Gen_write(g, _S("))")); } } } else if ((expr0)._typ == 338 /* v.ast.ArrayInit */ || (expr0)._typ == 385 /* v.ast.StructInit */) { if ((expr0)._typ == 338 /* v.ast.ArrayInit */ && (*(v__ast__ArrayInit*)__as_cast((expr0)._v__ast__ArrayInit,(expr0)._typ, 338)).is_fixed && (*(v__ast__ArrayInit*)__as_cast((expr0)._v__ast__ArrayInit,(expr0)._typ, 338)).has_init) { if (v__ast__Expr_is_literal(((*expr0._v__ast__ArrayInit)).init_expr)) { v__gen__c__Gen_write(g, _S("{.ret_arr=")); v__gen__c__Gen_expr_with_cast(g, expr0, type0, ret_type); v__gen__c__Gen_writeln(g, _S("};")); } else { v__gen__c__Gen_writeln(g, _S("{0};")); { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(".ret_arr, ")); } v__gen__c__Gen_expr_with_cast(g, expr0, type0, ret_type); { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, type0)); v__gen__c__Gen_write(g, _S("))")); } } } else { v__gen__c__Gen_writeln(g, _S("{0};")); string tmpvar2 = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, type0)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmpvar2); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr_with_cast(g, expr0, type0, ret_type); v__gen__c__Gen_writeln(g, _S(";")); { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(".ret_arr, ")); v__gen__c__Gen_write(g, tmpvar2); v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, type0)); v__gen__c__Gen_write(g, _S("))")); } } } else { v__gen__c__Gen_writeln(g, _S("{0};")); { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, tmpvar); v__gen__c__Gen_write(g, _S(".ret_arr, ")); } v__gen__c__Gen_expr_with_cast(g, expr0, type0, ret_type); { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, type0)); v__gen__c__Gen_write(g, _S("))")); } } } else { v__gen__c__Gen_expr_with_cast(g, expr0, type0, ret_type); } } } if (use_tmp_var) { v__gen__c__Gen_writeln(g, _S(";")); has_semicolon = true; v__gen__c__Gen_write_defer_stmts_when_needed(g); if (!g->is_builtin_mod) { v__gen__c__Gen_autofree_scope_vars(g, (int)(node.pos.pos - 1), node.pos.line_nr, true); } { v__gen__c__Gen_write(g, _S("return ")); v__gen__c__Gen_write(g, tmpvar); } has_semicolon = false; } } else { println(_S("this should never happen")); v__gen__c__Gen_write(g, _S("/*F*/return")); } if (!has_semicolon) { v__gen__c__Gen_writeln(g, _S(";")); } // Defer begin if (v__gen__c__Gen_return_stmt_defer_0) { g->inside_return = old_inside_return; } // Defer end } VV_LOC bool v__gen__c__Gen_check_expr_is_const(v__gen__c__Gen* g, v__ast__Expr expr) { if (expr._typ == 384 /* v.ast.StringLiteral */) { return true; } else if (expr._typ == 363 /* v.ast.IntegerLiteral */) { return true; } else if (expr._typ == 342 /* v.ast.BoolLiteral */) { return true; } else if (expr._typ == 356 /* v.ast.FloatLiteral */) { return true; } else if (expr._typ == 347 /* v.ast.CharLiteral */) { return true; } else if (expr._typ == 338 /* v.ast.ArrayInit */) { bool _t7 = true; Array_v__ast__Expr _t7_orig = (*expr._v__ast__ArrayInit).exprs; int _t7_len = _t7_orig.len; for (int _t8 = 0; _t8 < _t7_len; ++_t8) { v__ast__Expr it = ((v__ast__Expr*) _t7_orig.data)[_t8]; if (!(v__gen__c__Gen_check_expr_is_const(g, it))) { _t7 = false; break; } } return _t7; } else if (expr._typ == 374 /* v.ast.ParExpr */) { return v__gen__c__Gen_check_expr_is_const(g, (*expr._v__ast__ParExpr).expr); } else if (expr._typ == 362 /* v.ast.InfixExpr */) { return v__gen__c__Gen_check_expr_is_const(g, (*expr._v__ast__InfixExpr).left) && v__gen__c__Gen_check_expr_is_const(g, (*expr._v__ast__InfixExpr).right); } else if (expr._typ == 358 /* v.ast.Ident */) { return (*expr._v__ast__Ident).kind == v__ast__IdentKind__function || v__ast__Table_final_sym(g->table, (*((*expr._v__ast__Ident).obj.typ)))->kind != v__ast__Kind__array_fixed; } else if (expr._typ == 385 /* v.ast.StructInit */) { return true; } else if (expr._typ == 355 /* v.ast.EnumVal */) { return true; } else if (expr._typ == 345 /* v.ast.CastExpr */) { return v__gen__c__Gen_check_expr_is_const(g, (*expr._v__ast__CastExpr).expr); } else if (expr._typ == 376 /* v.ast.PrefixExpr */) { return ((*expr._v__ast__PrefixExpr).right)._typ == 358 /* v.ast.Ident */ || v__gen__c__Gen_check_expr_is_const(g, (*expr._v__ast__PrefixExpr).right); } else if (expr._typ == 388 /* v.ast.UnsafeExpr */) { return v__gen__c__Gen_check_expr_is_const(g, (*expr._v__ast__UnsafeExpr).expr); } else { return false; } return 0; } VV_LOC void v__gen__c__Gen_assoc(v__gen__c__Gen* g, v__ast__Assoc node) { v__gen__c__Gen_writeln(g, _S("// assoc")); if (node.typ == 0) { return; } string styp = v__gen__c__Gen_styp(g, node.typ); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = styp}}, {_S("){"), 0, { .d_c = 0 }}}))); Map_string_int inited_fields = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int i = 0; i < node.fields.len; ++i) { string field = ((string*)node.fields.data)[i]; map_set(&inited_fields, &(string[]){field}, &(int[]) { i }); } v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, node.typ); v__ast__Struct info = *(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518); for (int _t1 = 0; _t1 < info.fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[_t1]; string field_name = v__gen__c__c_name(field.name); if (_IN_MAP(ADDR(string, field.name), ADDR(map, inited_fields))) { { v__gen__c__Gen_write(g, _S("\t.")); v__gen__c__Gen_write(g, field_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, (*(v__ast__Expr*)array_get(node.exprs, (*(int*)map_get(ADDR(map, inited_fields), &(string[]){field.name}, &(int[]){ 0 }))))); v__gen__c__Gen_writeln(g, _S(", ")); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\t."), 0xfe10, {.d_s = field_name}}, {_S(" = "), 0xfe10, {.d_s = node.var_name}}, {_S("."), 0xfe10, {.d_s = field_name}}, {_S(","), 0, { .d_c = 0 }}}))); } } v__gen__c__Gen_write(g, _S("}")); if (g->is_amp) { { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("))")); } } } VNORETURN VV_LOC void v__gen__c__verror(string s) { v__util__verror(_S("cgen error"), s); VUNREACHABLE(); while(1); } VNORETURN VV_LOC void v__gen__c__Gen_error(v__gen__c__Gen* g, string s, v__token__Pos pos) { v__util__show_compiler_message(_S("cgen error:"), ((v__errors__CompilerMessage){.message = s,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = g->file->path,.pos = pos,.reporter = 0,})); _v_exit(1); VUNREACHABLE(); while(1); } VV_LOC void v__gen__c__Gen_checker_bug(v__gen__c__Gen* g, string s, v__token__Pos pos) { v__gen__c__Gen_error(g, str_intp(2, _MOV((StrIntpData[]){{_S("checker bug; "), 0xfe10, {.d_s = s}}, {_SLIT0, 0, { .d_c = 0 }}})), pos); VUNREACHABLE(); } VV_LOC void v__gen__c__Gen_write_debug_calls_typeof_functions(v__gen__c__Gen* g) { if (!g->pref->is_debug) { return; } v__gen__c__Gen_writeln2(g, _S("\t// we call these functions in debug mode so that the C compiler"), _S("\t// does not optimize them and we can access them in the debugger.")); for (int _t1 = 0; _t1 < g->table->type_symbols.len; ++_t1) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)g->table->type_symbols.data)[_t1]; if (sym->kind == v__ast__Kind__sum_type) { v__ast__SumType sum_info = *(v__ast__SumType*)__as_cast((sym->info)._v__ast__SumType,(sym->info)._typ, 544); if (sum_info.is_generic) { continue; } if (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tv_typeof_sumtype_"), 0xfe10, {.d_s = sym->cname}}, {_S("(0);"), 0, { .d_c = 0 }}}))); } if (sym->kind == v__ast__Kind__interface) { if ((sym->info)._typ != 542 /* v.ast.Interface */) { continue; } v__ast__Interface inter_info = *(v__ast__Interface*)__as_cast((sym->info)._v__ast__Interface,(sym->info)._typ, 542); if (inter_info.is_generic || (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms)))) { continue; } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tv_typeof_interface_"), 0xfe10, {.d_s = sym->cname}}, {_S("(0);"), 0, { .d_c = 0 }}}))); } } } VV_LOC void v__gen__c__Gen_write_init_function(v__gen__c__Gen* g) { bool v__gen__c__Gen_write_init_function_defer_0 = false; if (g->pref->no_builtin || (g->pref->translated && g->pref->is_o)) { return; } v__util__timing_start(_S("Gen.write_init_function")); v__gen__c__Gen_write_init_function_defer_0 = true; if (g->pref->is_liveshared && g->pref->os != v__pref__OS__windows) { // Defer begin if (v__gen__c__Gen_write_init_function_defer_0) { v__util__timing_measure(_S("Gen.write_init_function")); } // Defer end return; } int fn_vinit_start_pos = g->out.len; v__gen__c__Gen_writeln(g, _S("void _vinit(int ___argc, voidptr ___argv) {")); v__gen__c__Gen_write_debug_calls_typeof_functions(g); if (g->pref->trace_calls && v__pref__Preferences_should_trace_fn_name(g->pref, _S("_vinit"))) { v__gen__c__Gen_writeln(g, _S("\tv__trace_calls__on_call(_S(\"_vinit\"));")); } if (g->use_segfault_handler && !g->pref->is_shared) { v__ast__Fn* _t2 = (v__ast__Fn*)(map_get_check(ADDR(map, g->table->fns), &(string[]){_S("v_segmentation_fault_handler")})); _option_v__ast__Fn _t1 = {0}; if (_t2) { *((v__ast__Fn*)&_t1.data) = *((v__ast__Fn*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { v__ast__Fn _dummy_1 = (*(v__ast__Fn*)_t1.data); v__gen__c__Gen_writeln(g, _S("#if __STDC_HOSTED__ == 1\n\tsignal(11, v_segmentation_fault_handler);\n#endif")); } } if (g->pref->is_bare) { v__ast__Fn* _t4 = (v__ast__Fn*)(map_get_check(ADDR(map, g->table->fns), &(string[]){_S("init_global_allocator")})); _option_v__ast__Fn _t3 = {0}; if (_t4) { *((v__ast__Fn*)&_t3.data) = *((v__ast__Fn*)_t4); } else { _t3.state = 2; _t3.err = _v_error(_S("map key does not exist")); } if (_t3.state == 0) { v__ast__Fn _dummy_3 = (*(v__ast__Fn*)_t3.data); v__gen__c__Gen_writeln(g, _S("init_global_allocator();")); } } if (g->pref->prealloc) { v__ast__Fn* _t6 = (v__ast__Fn*)(map_get_check(ADDR(map, g->table->fns), &(string[]){_S("prealloc_vinit")})); _option_v__ast__Fn _t5 = {0}; if (_t6) { *((v__ast__Fn*)&_t5.data) = *((v__ast__Fn*)_t6); } else { _t5.state = 2; _t5.err = _v_error(_S("map key does not exist")); } if (_t5.state == 0) { v__ast__Fn _dummy_5 = (*(v__ast__Fn*)_t5.data); v__gen__c__Gen_writeln(g, _S("prealloc_vinit();")); } } if (g->as_cast_type_names.len > 0) { v__gen__c__Gen_write(g, _S("\tas_cast_type_indexes = ")); v__gen__c__Gen_writeln(g, v__gen__c__Gen_as_cast_name_table(g)); } if (!g->pref->is_shared && (!g->pref->skip_unused || (*(bool*)map_get(ADDR(map, g->table->used_features->used_fns), &(string[]){_S("builtin_init")}, &(bool[]){ 0 })))) { v__gen__c__Gen_writeln(g, _S("\tbuiltin_init();")); } if (g->has_reflection) { v__gen__c__GlobalConstDef* _t8 = (v__gen__c__GlobalConstDef*)(map_get_check(ADDR(map, g->global_const_defs), &(string[]){_S("g_reflection")})); _option_v__gen__c__GlobalConstDef _t7 = {0}; if (_t8) { *((v__gen__c__GlobalConstDef*)&_t7.data) = *((v__gen__c__GlobalConstDef*)_t8); } else { _t7.state = 2; _t7.err = _v_error(_S("map key does not exist")); } if (_t7.state == 0) { v__gen__c__GlobalConstDef var = (*(v__gen__c__GlobalConstDef*)_t7.data); v__gen__c__Gen_writeln(g, var.init); v__gen__c__Gen_gen_reflection_data(g); } } Array_string cleaning_up_array = __new_array_with_default(0, g->table->modules.len, sizeof(string), 0); for (int _t9 = 0; _t9 < g->table->modules.len; ++_t9) { string mod_name = ((string*)g->table->modules.data)[_t9]; if (g->has_reflection && _SLIT_EQ(mod_name.str, mod_name.len, "v.reflection")) { continue; } bool const_section_header_shown = false; for (int _t10 = 0; _t10 < g->sorted_global_const_names.len; ++_t10) { string var_name = ((string*)g->sorted_global_const_names.data)[_t10]; v__gen__c__GlobalConstDef* _t12 = (v__gen__c__GlobalConstDef*)(map_get_check(ADDR(map, g->global_const_defs), &(string[]){var_name})); _option_v__gen__c__GlobalConstDef _t11 = {0}; if (_t12) { *((v__gen__c__GlobalConstDef*)&_t11.data) = *((v__gen__c__GlobalConstDef*)_t12); } else { _t11.state = 2; _t11.err = _v_error(_S("map key does not exist")); } if (_t11.state == 0) { v__gen__c__GlobalConstDef var = (*(v__gen__c__GlobalConstDef*)_t11.data); if (string__eq(var.mod, mod_name) && var.init.len > 0) { if (!const_section_header_shown) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t// Initializations of consts for module "), 0xfe10, {.d_s = mod_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); const_section_header_shown = true; } v__gen__c__Gen_writeln(g, var.init); } } } string init_fn_name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mod_name}}, {_S(".init"), 0, { .d_c = 0 }}})); _option_v__ast__Fn _t13; if (_t13 = v__ast__Table_find_fn(g->table, init_fn_name), _t13.state == 0) { v__ast__Fn initfn = *(v__ast__Fn*)_t13.data; if (initfn.return_type == _const_v__ast__void_type && initfn.params.len == 0) { bool should_be_skipped = false; if (initfn.source_fn != ((void*)0)) { v__ast__FnDecl* fndecl = ((v__ast__FnDecl*)(initfn.source_fn)); if (fndecl->should_be_skipped) { should_be_skipped = fndecl->should_be_skipped; } } if (should_be_skipped) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t// Skipping fn init() for module "), 0xfe10, {.d_s = mod_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t// Calling fn init() for module "), 0xfe10, {.d_s = mod_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); string mod_c_name = v__util__no_dots(mod_name); string init_fn_c_name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mod_c_name}}, {_S("__init"), 0, { .d_c = 0 }}})); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = init_fn_c_name}}, {_S("();"), 0, { .d_c = 0 }}}))); } } } string cleanup_fn_name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mod_name}}, {_S(".cleanup"), 0, { .d_c = 0 }}})); _option_v__ast__Fn _t14; if (_t14 = v__ast__Table_find_fn(g->table, cleanup_fn_name), _t14.state == 0) { v__ast__Fn cleanupfn = *(v__ast__Fn*)_t14.data; if (cleanupfn.return_type == _const_v__ast__void_type && cleanupfn.params.len == 0) { string mod_c_name = v__util__no_dots(mod_name); string cleanup_fn_c_name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = mod_c_name}}, {_S("__cleanup"), 0, { .d_c = 0 }}})); array_push((array*)&cleaning_up_array, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = cleanup_fn_c_name}}, {_S("();"), 0, { .d_c = 0 }}})) })); array_push((array*)&cleaning_up_array, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("\t// Cleaning up for module "), 0xfe10, {.d_s = mod_name}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } } if (g->nr_closures > 0) { v__gen__c__Gen_writeln(g, _S("\tbuiltin__closure__closure_init();")); } v__gen__c__Gen_writeln(g, _S("}")); if (g->pref->printfn_list.len > 0 && (Array_string_contains(g->pref->printfn_list, _S("_vinit")))) { println(strings__Builder_after(&g->out, fn_vinit_start_pos)); } int fn_vcleanup_start_pos = g->out.len; v__gen__c__Gen_writeln(g, _S("void _vcleanup(void) {")); if (g->pref->trace_calls && v__pref__Preferences_should_trace_fn_name(g->pref, _S("_vcleanup"))) { v__gen__c__Gen_writeln(g, _S("\tv__trace_calls__on_call(_S(\"_vcleanup\"));")); } if (g->is_autofree) { Array_string reversed_table_modules = array_reverse(g->table->modules); for (int _t17 = 0; _t17 < reversed_table_modules.len; ++_t17) { string mod_name = ((string*)reversed_table_modules.data)[_t17]; v__gen__c__Gen_writeln2(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t// Cleanups for module "), 0xfe10, {.d_s = mod_name}}, {_S(" :"), 0, { .d_c = 0 }}})), strings__Builder_str(&(*(strings__Builder*)map_get(ADDR(map, g->cleanups), &(string[]){mod_name}, &(strings__Builder[]){ __new_array(0, 0, sizeof(u8)) })))); } if (g->as_cast_type_names.len > 0) { v__gen__c__Gen_writeln(g, _S("\tarray_free(&as_cast_type_indexes);")); } } Array_string _t18 = array_reverse(cleaning_up_array); for (int _t19 = 0; _t19 < _t18.len; ++_t19) { string x = ((string*)_t18.data)[_t19]; v__gen__c__Gen_writeln(g, x); } if (g->pref->use_coroutines) { v__gen__c__Gen_writeln(g, _S("\tdelete_photon_work_pool();")); } if (g->pref->is_coverage) { v__gen__c__Gen_write_coverage_stats(g); v__gen__c__Gen_writeln(g, _S("\tvprint_coverage_stats();")); } v__gen__c__Gen_writeln(g, _S("}")); if (g->pref->printfn_list.len > 0 && (Array_string_contains(g->pref->printfn_list, _S("_vcleanup")))) { println(strings__Builder_after(&g->out, fn_vcleanup_start_pos)); } if (g->pref->is_shared) { if (g->pref->os != v__pref__OS__windows) { v__gen__c__Gen_writeln(g, _S("__attribute__ ((constructor))")); } array_push((array*)&g->export_funcs, _MOV((string[]){ _S("_vinit_caller") })); v__gen__c__Gen_writeln(g, _S("void _vinit_caller() {")); v__gen__c__Gen_writeln(g, _S("\tstatic bool once = false; if (once) {return;} once = true;")); if (g->nr_closures > 0) { v__gen__c__Gen_writeln(g, _S("\tbuiltin__closure__closure_init(); // vinit_caller()")); } v__gen__c__Gen_writeln(g, _S("\t_vinit(0,0);")); v__gen__c__Gen_writeln(g, _S("}")); if (g->pref->os != v__pref__OS__windows) { v__gen__c__Gen_writeln(g, _S("__attribute__ ((destructor))")); } array_push((array*)&g->export_funcs, _MOV((string[]){ _S("_vcleanup_caller") })); v__gen__c__Gen_writeln(g, _S("void _vcleanup_caller() {")); v__gen__c__Gen_writeln(g, _S("\tstatic bool once = false; if (once) {return;} once = true;")); v__gen__c__Gen_writeln(g, _S("\t_vcleanup();")); v__gen__c__Gen_writeln(g, _S("}")); } // Defer begin if (v__gen__c__Gen_write_init_function_defer_0) { v__util__timing_measure(_S("Gen.write_init_function")); } // Defer end } VV_LOC void v__gen__c__Gen_write_builtin_types(v__gen__c__Gen* g) { if (g->pref->no_builtin) { return; } Array_v__ast__TypeSymbol_ptr builtin_types = __new_array_with_default(0, 0, sizeof(v__ast__TypeSymbol*), 0); for (int _t1 = 0; _t1 < _const_v__ast__builtins.len; ++_t1) { string builtin_name = ((string*)_const_v__ast__builtins.data)[_t1]; v__ast__TypeSymbol* sym = v__ast__Table_sym_by_idx(g->table, (*(int*)map_get(ADDR(map, g->table->type_idxs), &(string[]){builtin_name}, &(int[]){ 0 }))); if (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } if ((sym->info)._typ == 542 /* v.ast.Interface */) { v__gen__c__Gen_write_interface_typedef(g, *sym); if (!(*sym->info._v__ast__Interface).is_generic) { v__gen__c__Gen_write_interface_typesymbol_declaration(g, *sym); } } else { array_push((array*)&builtin_types, _MOV((v__ast__TypeSymbol*[]){ sym })); } } v__gen__c__Gen_write_types(g, builtin_types); } VV_LOC void v__gen__c__Gen_write_sorted_types(v__gen__c__Gen* g) { bool v__gen__c__Gen_write_sorted_types_defer_0 = false; strings__Builder_writeln(&g->type_definitions, _S("// #start sorted_symbols")); v__gen__c__Gen_write_sorted_types_defer_0 = true; { // Unsafe block Array_v__ast__TypeSymbol_ptr symbols = __new_array_with_default(0, g->table->type_symbols.len, sizeof(v__ast__TypeSymbol*), 0); Array_v__ast__TypeSymbol_ptr _t1 = {0}; Array_v__ast__TypeSymbol_ptr _t1_orig = g->table->type_symbols; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__TypeSymbol*)); for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__TypeSymbol* it = ((v__ast__TypeSymbol**) _t1_orig.data)[_t2]; if (!it->is_builtin) { array_push((array*)&_t1, &it); } } Array_v__ast__TypeSymbol_ptr non_builtin_syms =_t1; for (int _t3 = 0; _t3 < non_builtin_syms.len; ++_t3) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)non_builtin_syms.data)[_t3]; array_push((array*)&symbols, _MOV((v__ast__TypeSymbol*[]){ sym })); } Array_v__ast__TypeSymbol_ptr sorted_symbols = v__gen__c__Gen_sort_structs(g, symbols); v__gen__c__Gen_write_types(g, sorted_symbols); } // Defer begin if (v__gen__c__Gen_write_sorted_types_defer_0) { strings__Builder_writeln(&g->type_definitions, _S("// #end sorted_symbols")); } // Defer end } VV_LOC void v__gen__c__Gen_write_types(v__gen__c__Gen* g, Array_v__ast__TypeSymbol_ptr symbols) { Map_string_bool struct_names = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int _t1 = 0; _t1 < symbols.len; ++_t1) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)symbols.data)[_t1]; if (string_starts_with(sym->name, _S("C."))) { continue; } if (sym->kind == v__ast__Kind__none && (!g->pref->skip_unused || g->table->used_features->used_none > 0)) { strings__Builder_writeln(&g->type_definitions, _S("struct none {")); strings__Builder_writeln(&g->type_definitions, _S("\tEMPTY_STRUCT_DECLARATION;")); strings__Builder_writeln(&g->type_definitions, _S("};")); strings__Builder_writeln(&g->typedefs, _S("typedef struct none none;")); } string name = v__ast__TypeSymbol_scoped_cname(sym); if (g->pref->skip_unused && g->table->used_features->used_maps == 0) { if (_SLIT_EQ(name.str, name.len, "map") || _SLIT_EQ(name.str, name.len, "mapnode") || _SLIT_EQ(name.str, name.len, "SortedMap") || _SLIT_EQ(name.str, name.len, "MapMode") || _SLIT_EQ(name.str, name.len, "DenseArray")) { continue; } } if (sym->info._typ == 518 /* v.ast.Struct */) { if (!(*(bool*)map_get(ADDR(map, struct_names), &(string[]){name}, &(bool[]){ 0 })) && (!g->pref->skip_unused || _IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms)))) { Array_v__ast__StructField _t2 = {0}; Array_v__ast__StructField _t2_orig = (*sym->info._v__ast__Struct).fields; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(v__ast__StructField)); for (int _t3 = 0; _t3 < _t2_len; ++_t3) { v__ast__StructField it = ((v__ast__StructField*) _t2_orig.data)[_t3]; if (v__ast__Table_final_sym(g->table, it.typ)->kind == v__ast__Kind__array_fixed) { array_push((array*)&_t2, &it); } } Array_v__ast__StructField opt_fields =_t2; for (int _t4 = 0; _t4 < opt_fields.len; ++_t4) { v__ast__StructField opt_field = ((v__ast__StructField*)opt_fields.data)[_t4]; v__ast__TypeSymbol* field_sym = v__ast__Table_final_sym(g->table, opt_field.typ); v__ast__ArrayFixed arr = *(v__ast__ArrayFixed*)__as_cast((field_sym->info)._v__ast__ArrayFixed,(field_sym->info)._typ, 549); if (!v__ast__Type_has_flag(arr.elem_type, v__ast__TypeFlag__option)) { continue; } string styp = field_sym->cname; string fixed_elem_name = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(arr.elem_type, 0)); if (v__ast__Type_is_ptr(arr.elem_type)) { fixed_elem_name = string__plus(fixed_elem_name, string_repeat(_S("*"), v__ast__Type_nr_muls(arr.elem_type))); } int len = arr.size; sync__RwMutex_lock(&g->done_options->mtx); /*lock*/ { if (!(Array_string_contains(g->done_options->val, styp))) { strings__Builder_writeln(&g->type_definitions, str_intp(4, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = fixed_elem_name}}, {_S(" "), 0xfe10, {.d_s = styp}}, {_S(" ["), 0xfe07, {.d_i32 = len}}, {_S("];"), 0, { .d_c = 0 }}}))); array_push((array*)&g->done_options->val, _MOV((string[]){ string_clone(styp) })); } } sync__RwMutex_unlock(&g->done_options->mtx);; } v__gen__c__Gen_struct_decl(g, (*sym->info._v__ast__Struct), name, false, false); map_set(&struct_names, &(string[]){name}, &(bool[]) { true }); } } else if (sym->info._typ == 551 /* v.ast.Thread */) { if (!g->pref->is_bare && !g->pref->no_builtin && (!g->pref->skip_unused || _IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms)))) { if (g->pref->os == v__pref__OS__windows) { if (_SLIT_EQ(name.str, name.len, "__v_thread")) { strings__Builder_writeln(&g->thread_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("typedef HANDLE "), 0xfe10, {.d_s = name}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->thread_definitions, _S("typedef struct {")); strings__Builder_writeln(&g->thread_definitions, _S("\tvoid* ret_ptr;")); strings__Builder_writeln(&g->thread_definitions, _S("\tHANDLE handle;")); strings__Builder_writeln(&g->thread_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("} "), 0xfe10, {.d_s = name}}, {_S(";"), 0, { .d_c = 0 }}}))); } } else { strings__Builder_writeln(&g->thread_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("typedef pthread_t "), 0xfe10, {.d_s = name}}, {_S(";"), 0, { .d_c = 0 }}}))); } } } else if (sym->info._typ == 544 /* v.ast.SumType */) { if ((*sym->info._v__ast__SumType).is_generic || (*(bool*)map_get(ADDR(map, struct_names), &(string[]){name}, &(bool[]){ 0 })) || (g->pref->skip_unused && !_IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms)))) { continue; } map_set(&struct_names, &(string[]){name}, &(bool[]) { true }); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = name}}, {_S(" "), 0xfe10, {.d_s = name}}, {_S(";"), 0, { .d_c = 0 }}}))); Array_int idxs = __new_array_with_default(0, 0, sizeof(int), 0); if (!g->pref->is_prod) { strings__Builder_writeln(&g->type_definitions, _S("")); strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("// Union sum type "), 0xfe10, {.d_s = name}}, {_S(" = "), 0, { .d_c = 0 }}}))); for (int _t6 = 0; _t6 < (*sym->info._v__ast__SumType).variants.len; ++_t6) { v__ast__Type variant = ((v__ast__Type*)(*sym->info._v__ast__SumType).variants.data)[_t6]; if ((Array_int_contains(idxs, variant))) { continue; } strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("// | "), 0x8fe26, {.d_u32 = variant}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, v__ast__Type_idx_type(variant))}}, {_SLIT0, 0, { .d_c = 0 }}}))); array_push((array*)&idxs, _MOV((int[]){ variant })); } array_clear(&idxs); } strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("struct "), 0xfe10, {.d_s = name}}, {_S(" {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, _S("\tunion {")); for (int _t8 = 0; _t8 < (*sym->info._v__ast__SumType).variants.len; ++_t8) { v__ast__Type variant = ((v__ast__Type*)(*sym->info._v__ast__SumType).variants.data)[_t8]; if ((Array_int_contains(idxs, variant))) { continue; } array_push((array*)&idxs, _MOV((int[]){ variant })); v__ast__TypeSymbol* variant_sym = v__ast__Table_sym(g->table, variant); v__ast__Type var = (v__ast__Type_has_flag(variant, v__ast__TypeFlag__option) ? (variant) : (v__ast__Type_ref(variant))); string variant_name = v__gen__c__Gen_get_sumtype_variant_name(g, variant, *variant_sym); if ((variant_sym->info)._typ == 553 /* v.ast.FnType */) { if ((*variant_sym->info._v__ast__FnType).is_anon) { var = variant; } } string var_type = (v__ast__Type_has_flag(variant, v__ast__TypeFlag__option) ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, var)}}, {_S("*"), 0, { .d_c = 0 }}}))) : (v__gen__c__Gen_styp(g, var))); strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = var_type}}, {_S(" _"), 0xfe10, {.d_s = variant_name}}, {_S(";"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->type_definitions, _S("\t};")); strings__Builder_writeln(&g->type_definitions, _S("\tint _typ;")); if ((*sym->info._v__ast__SumType).fields.len > 0) { v__gen__c__Gen_writeln(g, _S("\t// pointers to common sumtype fields")); for (int _t10 = 0; _t10 < (*sym->info._v__ast__SumType).fields.len; ++_t10) { v__ast__StructField field = ((v__ast__StructField*)(*sym->info._v__ast__SumType).fields.data)[_t10]; strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, field.typ)}}, {_S("* "), 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(";"), 0, { .d_c = 0 }}}))); } } strings__Builder_writeln(&g->type_definitions, _S("};")); } else if (sym->info._typ == 549 /* v.ast.ArrayFixed */) { v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, (*sym->info._v__ast__ArrayFixed).elem_type); if (!v__ast__TypeSymbol_is_builtin(elem_sym) && !v__ast__Type_has_flag((*sym->info._v__ast__ArrayFixed).elem_type, v__ast__TypeFlag__generic) && (!g->pref->skip_unused || (!(*sym->info._v__ast__ArrayFixed).is_fn_ret && _IN_MAP(ADDR(int, sym->idx), ADDR(map, g->table->used_features->used_syms))))) { string styp = sym->cname; string fixed_elem_name = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls((*sym->info._v__ast__ArrayFixed).elem_type, 0)); if (v__ast__Type_is_ptr((*sym->info._v__ast__ArrayFixed).elem_type)) { fixed_elem_name = string__plus(fixed_elem_name, string_repeat(_S("*"), v__ast__Type_nr_muls((*sym->info._v__ast__ArrayFixed).elem_type))); } int len = (*sym->info._v__ast__ArrayFixed).size; if (len > 0) { if ((elem_sym->info)._typ == 553 /* v.ast.FnType */) { int pos = g->out.len; v__gen__c__Gen_write_fn_ptr_decl(g, &(*elem_sym->info._v__ast__FnType), _S("")); fixed_elem_name = strings__Builder_cut_to(&g->out, pos); string def_str = str_intp(2, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = fixed_elem_name}}, {_S(";"), 0, { .d_c = 0 }}})); def_str = string_replace_once(def_str, _S("(*)"), str_intp(3, _MOV((StrIntpData[]){{_S("(*"), 0xfe10, {.d_s = styp}}, {_S("["), 0xfe07, {.d_i32 = len}}, {_S("])"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, def_str); } else if ((elem_sym->info)._typ != 549 /* v.ast.ArrayFixed */ || (*(v__ast__ArrayFixed*)__as_cast((elem_sym->info)._v__ast__ArrayFixed,(elem_sym->info)._typ, 549)).size > 0) { if (v__ast__Type_has_flag((*sym->info._v__ast__ArrayFixed).elem_type, v__ast__TypeFlag__option) && (elem_sym->info)._typ == 518 /* v.ast.Struct */) { multi_return_string_string mr_221118 = v__gen__c__Gen_option_type_name(g, (*sym->info._v__ast__ArrayFixed).elem_type); string styp_elem = mr_221118.arg0; string base = mr_221118.arg1; sync__RwMutex_lock(&g->done_options->mtx); /*lock*/ { if (!(Array_string_contains(g->done_options->val, base))) { array_push((array*)&g->done_options->val, _MOV((string[]){ string_clone(base) })); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = styp_elem}}, {_S(" "), 0xfe10, {.d_s = styp_elem}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_option_type_text(g, styp_elem, base)}}, {_S(";"), 0, { .d_c = 0 }}}))); } } sync__RwMutex_unlock(&g->done_options->mtx);; strings__Builder_writeln(&g->type_definitions, str_intp(4, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = fixed_elem_name}}, {_S(" "), 0xfe10, {.d_s = styp}}, {_S(" ["), 0xfe07, {.d_i32 = len}}, {_S("];"), 0, { .d_c = 0 }}}))); } else if (!((elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && (*(v__ast__ArrayFixed*)__as_cast((elem_sym->info)._v__ast__ArrayFixed,(elem_sym->info)._typ, 549)).is_fn_ret)) { strings__Builder_writeln(&g->type_definitions, str_intp(4, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = fixed_elem_name}}, {_S(" "), 0xfe10, {.d_s = styp}}, {_S(" ["), 0xfe07, {.d_i32 = len}}, {_S("];"), 0, { .d_c = 0 }}}))); } } } } } else { } } } VV_LOC void v__gen__c__Gen_write_sorted_fn_typesymbol_declaration(v__gen__c__Gen* g) { bool v__gen__c__Gen_write_sorted_fn_typesymbol_declaration_defer_0 = false; v__util__timing_start(_S("Gen.write_sorted_fn_typesymbol_declaration")); v__gen__c__Gen_write_sorted_fn_typesymbol_declaration_defer_0 = true; Array_v__ast__TypeSymbol_ptr syms = __new_array_with_default(0, 0, sizeof(v__ast__TypeSymbol*), 0); for (int _t1 = 0; _t1 < g->table->type_symbols.len; ++_t1) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)g->table->type_symbols.data)[_t1]; if (sym->kind == v__ast__Kind__function && !sym->is_builtin) { array_push((array*)&syms, _MOV((v__ast__TypeSymbol*[]){ sym })); } } Array_v__ast__TypeSymbol_ptr pending = __new_array_with_default(0, 0, sizeof(v__ast__TypeSymbol*), 0); for (;;) { next: {} for (int _t3 = 0; _t3 < syms.len; ++_t3) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)syms.data)[_t3]; v__ast__FnType info = *(v__ast__FnType*)__as_cast((sym->info)._v__ast__FnType,(sym->info)._typ, 553); v__ast__Fn func = info.func; v__ast__TypeSymbol* return_sym = v__ast__Table_sym(g->table, func.return_type); if ((Array_v__ast__TypeSymbol_ptr_contains(syms, return_sym))) { array_push((array*)&pending, _MOV((v__ast__TypeSymbol*[]){ sym })); continue; } for (int _t5 = 0; _t5 < func.params.len; ++_t5) { v__ast__Param param = ((v__ast__Param*)func.params.data)[_t5]; v__ast__TypeSymbol* param_sym = v__ast__Table_sym(g->table, param.typ); if ((Array_v__ast__TypeSymbol_ptr_contains(syms, param_sym))) { array_push((array*)&pending, _MOV((v__ast__TypeSymbol*[]){ sym })); goto next__continue; } } v__gen__c__Gen_write_fn_typesymbol_declaration(g, *sym); next__continue: {} } next__break: {} if (pending.len == 0) { break; } if (syms.len == pending.len) { Array_string deps = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t7 = 0; _t7 < pending.len; ++_t7) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)pending.data)[_t7]; array_push((array*)&deps, _MOV((string[]){ string_clone(sym->name) })); } v__gen__c__verror(string__plus(_S("cgen.write_sorted_fn_typesymbol_declaration(): the following functions form a dependency cycle:\n"), Array_string_join(deps, _S(",")))); VUNREACHABLE(); } { // Unsafe block Array_v__ast__TypeSymbol_ptr _var_223233 = array_clone(&syms); Array_v__ast__TypeSymbol_ptr _var_223239 = array_clone(&pending); syms = _var_223239; pending = array_slice(syms, 0, 0); } } // Defer begin if (v__gen__c__Gen_write_sorted_fn_typesymbol_declaration_defer_0) { v__util__timing_measure(_S("Gen.write_sorted_fn_typesymbol_declaration")); } // Defer end } VV_LOC Array_v__ast__TypeSymbol_ptr v__gen__c__Gen_sort_structs(v__gen__c__Gen* g, Array_v__ast__TypeSymbol_ptr typesa) { bool v__gen__c__Gen_sort_structs_defer_0 = false; v__util__timing_start(_S("Gen.sort_structs")); v__gen__c__Gen_sort_structs_defer_0 = true; v__depgraph__DepGraph* dep_graph = v__depgraph__new_dep_graph(); Array_string type_names = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < typesa.len; ++_t1) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)typesa.data)[_t1]; array_push((array*)&type_names, _MOV((string[]){ v__ast__TypeSymbol_scoped_name(sym) })); } for (int _t3 = 0; _t3 < typesa.len; ++_t3) { v__ast__TypeSymbol* sym = ((v__ast__TypeSymbol**)typesa.data)[_t3]; if (sym->kind == v__ast__Kind__interface) { v__depgraph__DepGraph_add(dep_graph, sym->name, __new_array_with_default(0, 0, sizeof(string), 0)); continue; } Array_string field_deps = __new_array_with_default(0, 0, sizeof(string), 0); if (sym->info._typ == 549 /* v.ast.ArrayFixed */) { bool skip = false; v__ast__TypeSymbol* elem_sym = v__ast__Table_final_sym(g->table, (*sym->info._v__ast__ArrayFixed).elem_type); if ((elem_sym->info)._typ == 518 /* v.ast.Struct */ && v__ast__Type_is_ptr((*sym->info._v__ast__ArrayFixed).elem_type)) { for (int _t4 = 0; _t4 < (*elem_sym->info._v__ast__Struct).fields.len; ++_t4) { v__ast__StructField field = ((v__ast__StructField*)(*elem_sym->info._v__ast__Struct).fields.data)[_t4]; if (sym->idx == v__ast__Type_idx(field.typ)) { skip = true; break; } } } if (!skip) { string dep = v__ast__Table_final_sym(g->table, (*sym->info._v__ast__ArrayFixed).elem_type)->name; if ((Array_string_contains(type_names, dep))) { array_push((array*)&field_deps, _MOV((string[]){ string_clone(dep) })); } } } else if (sym->info._typ == 518 /* v.ast.Struct */) { for (int _t6 = 0; _t6 < (*sym->info._v__ast__Struct).embeds.len; ++_t6) { v__ast__Type embed = ((v__ast__Type*)(*sym->info._v__ast__Struct).embeds.data)[_t6]; string dep = v__ast__Table_sym(g->table, embed)->name; if (!(Array_string_contains(type_names, dep)) || (Array_string_contains(field_deps, dep))) { continue; } array_push((array*)&field_deps, _MOV((string[]){ string_clone(dep) })); } for (int _t8 = 0; _t8 < (*sym->info._v__ast__Struct).fields.len; ++_t8) { v__ast__StructField field = ((v__ast__StructField*)(*sym->info._v__ast__Struct).fields.data)[_t8]; if (v__ast__Type_is_ptr(field.typ)) { continue; } v__ast__TypeSymbol* fsym = v__ast__Table_sym(g->table, field.typ); string dep = fsym->name; if (!(Array_string_contains(type_names, dep)) || (Array_string_contains(field_deps, dep))) { continue; } array_push((array*)&field_deps, _MOV((string[]){ string_clone(dep) })); if ((fsym->info)._typ == 539 /* v.ast.Alias */) { string xdep = v__ast__Table_sym(g->table, (*fsym->info._v__ast__Alias).parent_type)->name; if (!(Array_string_contains(type_names, xdep)) || (Array_string_contains(field_deps, xdep))) { continue; } array_push((array*)&field_deps, _MOV((string[]){ string_clone(xdep) })); } } } else if (sym->info._typ == 544 /* v.ast.SumType */) { for (int _t11 = 0; _t11 < (*sym->info._v__ast__SumType).variants.len; ++_t11) { v__ast__Type variant = ((v__ast__Type*)(*sym->info._v__ast__SumType).variants.data)[_t11]; v__ast__TypeSymbol* vsym = v__ast__Table_sym(g->table, variant); if ((vsym->info)._typ != 518 /* v.ast.Struct */) { continue; } Array_v__ast__StructField fields = v__ast__Table_struct_fields(g->table, vsym); for (int _t12 = 0; _t12 < fields.len; ++_t12) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t12]; if (v__ast__Type_is_ptr(field.typ)) { continue; } v__ast__TypeSymbol* fsym = v__ast__Table_sym(g->table, field.typ); if ((fsym->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* xsym = v__ast__Table_sym(g->table, (*fsym->info._v__ast__Alias).parent_type); if ((xsym->info)._typ != 549 /* v.ast.ArrayFixed */) { continue; } string xdep = xsym->name; if (!(Array_string_contains(type_names, xdep)) || (Array_string_contains(field_deps, xdep))) { continue; } array_push((array*)&field_deps, _MOV((string[]){ string_clone(xdep) })); continue; } if ((fsym->info)._typ != 549 /* v.ast.ArrayFixed */) { continue; } string dep = fsym->name; if (!(Array_string_contains(type_names, dep)) || (Array_string_contains(field_deps, dep))) { continue; } array_push((array*)&field_deps, _MOV((string[]){ string_clone(dep) })); } } } else { } v__depgraph__DepGraph_add(dep_graph, v__ast__TypeSymbol_scoped_name(sym), field_deps); } v__depgraph__DepGraph* dep_graph_sorted = v__depgraph__DepGraph_resolve(dep_graph); if (!dep_graph_sorted->acyclic) { v__gen__c__verror(string__plus(string__plus(string__plus(_S("cgen.sort_structs(): the following structs form a dependency cycle:\n"), v__depgraph__DepGraph_display_cycles(dep_graph_sorted)), _S("\nyou can solve this by making one or both of the dependent struct fields references, eg: field &MyStruct")), _S("\nif you feel this is an error, please create a new issue here: https://github.com/vlang/v/issues and tag @joe-conigliaro"))); VUNREACHABLE(); } { // Unsafe block Array_v__ast__TypeSymbol_ptr sorted_symbols = __new_array_with_default(0, dep_graph_sorted->nodes.len, sizeof(v__ast__TypeSymbol*), 0); for (int _t15 = 0; _t15 < dep_graph_sorted->nodes.len; ++_t15) { v__depgraph__DepGraphNode node = ((v__depgraph__DepGraphNode*)dep_graph_sorted->nodes.data)[_t15]; array_push((array*)&sorted_symbols, _MOV((v__ast__TypeSymbol*[]){ v__ast__Table_sym_by_idx(g->table, (*(int*)map_get((map*)&g->table->type_idxs, &(string[]){node.name}, &(int[]){ 0 }))) })); } Array_v__ast__TypeSymbol_ptr _t17 = sorted_symbols; // Defer begin if (v__gen__c__Gen_sort_structs_defer_0) { v__util__timing_measure(_S("Gen.sort_structs")); } // Defer end return _t17; } return __new_array(0, 0, sizeof(v__ast__TypeSymbol*)); } VV_LOC void v__gen__c__Gen_gen_or_block_stmts(v__gen__c__Gen* g, string cvar_name, string cast_typ, Array_v__ast__Stmt stmts, v__ast__Type return_type, bool is_option) { g->indent++; for (int i = 0; i < stmts.len; ++i) { v__ast__Stmt stmt = ((v__ast__Stmt*)stmts.data)[i]; if (i == (int)(stmts.len - 1)) { v__ast__ExprStmt expr_stmt = *(v__ast__ExprStmt*)__as_cast((stmt)._v__ast__ExprStmt,(stmt)._typ, 401); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); if (g->inside_return && (v__ast__Type_idx(expr_stmt.typ) == 30 || (expr_stmt.typ == _const_v__ast__none_type || expr_stmt.typ == _const_v__ast__error_type))) { if (g->cur_fn != ((void*)0)) { if (v__ast__Type_has_flag(g->cur_fn->return_type, v__ast__TypeFlag__result)) { v__gen__c__Gen_write(g, _S("return ")); v__gen__c__Gen_gen_result_error(g, g->cur_fn->return_type, expr_stmt.expr); v__gen__c__Gen_writeln(g, _S(";")); } else if (v__ast__Type_has_flag(g->cur_fn->return_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_write(g, _S("return ")); v__gen__c__Gen_gen_option_error(g, g->cur_fn->return_type, expr_stmt.expr); v__gen__c__Gen_writeln(g, _S(";")); } } } else { if (expr_stmt.typ == 20) { { v__gen__c__Gen_write(g, cvar_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_gen_option_error(g, return_type, expr_stmt.expr); v__gen__c__Gen_writeln(g, _S(";")); } else if (return_type == _const_v__ast__rvoid_type) { bool old_inside_opt_data = g->inside_opt_data; g->inside_opt_data = true; v__gen__c__Gen_expr(g, expr_stmt.expr); g->inside_opt_data = old_inside_opt_data; v__gen__c__Gen_writeln(g, _S(";")); array_delete_last(&g->stmt_path_pos); } else { bool is_array_fixed = false; bool return_wrapped = false; bool return_is_option = is_option && v__ast__Type_has_option_or_result(return_type); string tmp_op = (_IN_MAP(ADDR(string, cvar_name), ADDR(map, g->tmp_var_ptr)) ? (_S("->")) : (_S("."))); if (is_option) { is_array_fixed = v__ast__Table_final_sym(g->table, return_type)->kind == v__ast__Kind__array_fixed; if (!is_array_fixed) { if (g->inside_return && !g->inside_struct_init && (expr_stmt.expr)._typ == 344 /* v.ast.CallExpr */ && v__ast__Type_has_option_or_result((*(v__ast__CallExpr*)__as_cast((expr_stmt.expr)._v__ast__CallExpr,(expr_stmt.expr)._typ, 344)).return_type) && v__ast__Type_has_option_or_result(g->cur_fn->return_type) && return_is_option && (*(v__ast__CallExpr*)__as_cast((expr_stmt.expr)._v__ast__CallExpr,(expr_stmt.expr)._typ, 344)).or_block.kind == v__ast__OrKind__absent) { { v__gen__c__Gen_write(g, cvar_name); v__gen__c__Gen_write(g, _S(" = ")); } return_wrapped = true; } else if ((expr_stmt.expr)._typ == 344 /* v.ast.CallExpr */) { if ((*expr_stmt.expr._v__ast__CallExpr).is_return_used) { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, cast_typ); v__gen__c__Gen_write(g, _S("*) ")); v__gen__c__Gen_write(g, cvar_name); v__gen__c__Gen_write(g, tmp_op); v__gen__c__Gen_write(g, _S("data = ")); } } } else if (g->inside_opt_or_res && return_is_option && g->inside_assign) { { v__gen__c__Gen_write(g, _S("_option_ok(&(")); v__gen__c__Gen_write(g, cast_typ); v__gen__c__Gen_write(g, _S("[]) { ")); } v__gen__c__Gen_expr_with_cast(g, expr_stmt.expr, expr_stmt.typ, v__ast__Type_clear_option_and_result(return_type)); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = cvar_name}}, {_S(", sizeof("), 0xfe10, {.d_s = cast_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); g->indent--; return; } else { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, cast_typ); v__gen__c__Gen_write(g, _S("*) ")); v__gen__c__Gen_write(g, cvar_name); v__gen__c__Gen_write(g, tmp_op); v__gen__c__Gen_write(g, _S("data = ")); } } } } else { { v__gen__c__Gen_write(g, cvar_name); v__gen__c__Gen_write(g, _S(" = ")); } } if (is_array_fixed) { { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, cvar_name); v__gen__c__Gen_write(g, tmp_op); v__gen__c__Gen_write(g, _S("data, (")); v__gen__c__Gen_write(g, cast_typ); v__gen__c__Gen_write(g, _S(")")); } } if (is_option && g->inside_return && (expr_stmt.expr)._typ == 344 /* v.ast.CallExpr */ && return_is_option) { v__gen__c__Gen_expr_with_cast(g, expr_stmt.expr, expr_stmt.typ, return_type); } else { bool old_inside_opt_data = g->inside_opt_data; g->inside_opt_data = true; v__gen__c__Gen_expr_with_cast(g, expr_stmt.expr, expr_stmt.typ, v__ast__Type_clear_option_and_result(return_type)); g->inside_opt_data = old_inside_opt_data; } if (is_array_fixed) { { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, cast_typ); v__gen__c__Gen_write(g, _S("))")); } } v__gen__c__Gen_writeln(g, _S(";")); array_delete_last(&g->stmt_path_pos); if (return_wrapped) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("return "), 0xfe10, {.d_s = cvar_name}}, {_S(";"), 0, { .d_c = 0 }}}))); } } } } else { v__gen__c__Gen_stmt(g, stmt); } } g->indent--; } VV_LOC void v__gen__c__Gen_or_block(v__gen__c__Gen* g, string var_name, v__ast__OrExpr or_block, v__ast__Type return_type) { bool v__gen__c__Gen_or_block_defer_0 = false; string cvar_name = v__gen__c__c_name(var_name); string tmp_op = (_IN_MAP(ADDR(string, var_name), ADDR(map, g->tmp_var_ptr)) || v__ast__Type_has_flag(return_type, v__ast__TypeFlag__option_mut_param_t) ? (_S("->")) : (_S("."))); if (or_block.kind == v__ast__OrKind__block && or_block.stmts.len == 0) { { v__gen__c__Gen_write(g, _S(";\n")); v__gen__c__Gen_write(g, v__util__tabs(g->indent)); v__gen__c__Gen_write(g, _S("(void)")); v__gen__c__Gen_write(g, cvar_name); v__gen__c__Gen_write(g, _S(";")); } return; } string mr_styp = v__gen__c__Gen_base_type(g, return_type); bool is_none_ok = return_type == _const_v__ast__ovoid_type; v__gen__c__Gen_writeln(g, _S(";")); if (is_none_ok) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = tmp_op}}, {_S("state != 0) {"), 0, { .d_c = 0 }}}))); } else { if (return_type != 0 && v__ast__Table_sym(g->table, return_type)->kind == v__ast__Kind__function) { mr_styp = _S("voidptr"); } if (v__ast__Type_has_flag(return_type, v__ast__TypeFlag__result)) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = tmp_op}}, {_S("is_error) {"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = tmp_op}}, {_S("state != 0) {"), 0, { .d_c = 0 }}}))); } } if (or_block.kind == v__ast__OrKind__block) { g->or_expr_return_type = v__ast__Type_clear_option_and_result(return_type); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\tIError err = "), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = tmp_op}}, {_S("err;"), 0, { .d_c = 0 }}}))); g->inside_or_block = true; v__gen__c__Gen_or_block_defer_0 = true; Array_v__ast__Stmt stmts = or_block.stmts; bool _t2 = (stmts.len > 0); bool _t1 = _t2 && ((*(v__ast__Stmt*)array_last(stmts)))._typ == 401 /* v.ast.ExprStmt */ && (({ v__ast__Stmt _t3 = (*(v__ast__Stmt*)array_last(stmts)); *(v__ast__ExprStmt*)__as_cast(_t3._v__ast__ExprStmt,_t3._typ, 401); })).typ != _const_v__ast__void_type; if (_t1) { v__gen__c__Gen_gen_or_block_stmts(g, cvar_name, mr_styp, stmts, return_type, true); } else { v__gen__c__Gen_stmts(g, stmts); bool _t4 = (stmts.len > 0); if ( _t4 && ((*(v__ast__Stmt*)array_last(stmts)))._typ == 401 /* v.ast.ExprStmt */) { v__gen__c__Gen_writeln(g, _S(";")); } } g->or_expr_return_type = _const_v__ast__void_type; } else if (or_block.kind == v__ast__OrKind__propagate_result || (or_block.kind == v__ast__OrKind__propagate_option && v__ast__Type_has_flag(return_type, v__ast__TypeFlag__result))) { if (fast_string_eq(g->file->mod.name, _S("main")) && (g->fn_decl == ((void*)0) || g->fn_decl->is_main)) { string err_msg = str_intp(5, _MOV((StrIntpData[]){{_S("IError_name_table["), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = tmp_op}}, {_S("err._typ]._method_msg("), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = tmp_op}}, {_S("err._object)"), 0, { .d_c = 0 }}})); if (g->pref->is_debug) { multi_return_int_string_string_string mr_232678 = v__gen__c__Gen_panic_debug_info(g, or_block.pos); int paline = mr_232678.arg0; string pafile = mr_232678.arg1; string pamod = mr_232678.arg2; string pafn = mr_232678.arg3; v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("panic_debug("), 0xfe07, {.d_i32 = paline}}, {_S(", tos3(\""), 0xfe10, {.d_s = pafile}}, {_S("\"), tos3(\""), 0xfe10, {.d_s = pamod}}, {_S("\"), tos3(\""), 0xfe10, {.d_s = pafn}}, {_S("\"), "), 0xfe10, {.d_s = err_msg}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tpanic_result_not_set("), 0xfe10, {.d_s = err_msg}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else if (g->fn_decl != ((void*)0) && g->fn_decl->is_test) { v__gen__c__Gen_gen_failing_error_propagation_for_test_fn(g, or_block, cvar_name); } else { v__gen__c__Gen_write_defer_stmts(g); if (g->fn_decl == ((void*)0) || g->fn_decl->return_type == _const_v__ast__void_type) { v__gen__c__Gen_writeln(g, _S("\treturn;")); } else { string styp = v__gen__c__Gen_styp(g, g->fn_decl->return_type); string err_obj = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = err_obj}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); if (v__ast__Type_has_flag(g->fn_decl->return_type, v__ast__TypeFlag__result)) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = err_obj}}, {_S(".is_error = true;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = err_obj}}, {_S(".err = "), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = tmp_op}}, {_S("err;"), 0, { .d_c = 0 }}}))); } else if (v__ast__Type_has_flag(g->fn_decl->return_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = err_obj}}, {_S(".state = 2;"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = err_obj}}, {_S(";"), 0, { .d_c = 0 }}}))); } } } else if (or_block.kind == v__ast__OrKind__propagate_option) { if (fast_string_eq(g->file->mod.name, _S("main")) && (g->fn_decl == ((void*)0) || g->fn_decl->is_main)) { string err_msg = str_intp(5, _MOV((StrIntpData[]){{_S("IError_name_table["), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = tmp_op}}, {_S("err._typ]._method_msg("), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = tmp_op}}, {_S("err._object)"), 0, { .d_c = 0 }}})); if (g->pref->is_debug) { multi_return_int_string_string_string mr_234231 = v__gen__c__Gen_panic_debug_info(g, or_block.pos); int paline = mr_234231.arg0; string pafile = mr_234231.arg1; string pamod = mr_234231.arg2; string pafn = mr_234231.arg3; v__gen__c__Gen_writeln(g, str_intp(7, _MOV((StrIntpData[]){{_S("panic_debug("), 0xfe07, {.d_i32 = paline}}, {_S(", tos3(\""), 0xfe10, {.d_s = pafile}}, {_S("\"), tos3(\""), 0xfe10, {.d_s = pamod}}, {_S("\"), tos3(\""), 0xfe10, {.d_s = pafn}}, {_S("\"), "), 0xfe10, {.d_s = err_msg}}, {_S(".len == 0 ? _S(\"option not set ()\") : "), 0xfe10, {.d_s = err_msg}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tpanic_option_not_set( "), 0xfe10, {.d_s = err_msg}}, {_S(" );"), 0, { .d_c = 0 }}}))); } } else if (g->fn_decl != ((void*)0) && g->fn_decl->is_test) { v__gen__c__Gen_gen_failing_error_propagation_for_test_fn(g, or_block, cvar_name); } else { v__gen__c__Gen_write_defer_stmts(g); if (g->fn_decl == ((void*)0) || g->fn_decl->return_type == _const_v__ast__void_type) { v__gen__c__Gen_writeln(g, _S("\treturn;")); } else if (v__ast__Type_clear_option_and_result(g->fn_decl->return_type) == v__ast__Type_clear_option_and_result(return_type)) { string styp = string_replace(v__gen__c__Gen_styp(g, g->fn_decl->return_type), _S("*"), _S("_ptr")); string err_obj = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln2(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = err_obj}}, {_S(";"), 0, { .d_c = 0 }}})), str_intp(3, _MOV((StrIntpData[]){{_S("\tmemcpy(&"), 0xfe10, {.d_s = err_obj}}, {_S(", &"), 0xfe10, {.d_s = cvar_name}}, {_S(", sizeof(_option));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = err_obj}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_write(g, _S("\treturn ")); v__gen__c__Gen_gen_option_error(g, g->fn_decl->return_type, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}))))); v__gen__c__Gen_writeln(g, _S(";")); } } } v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); // Defer begin if (v__gen__c__Gen_or_block_defer_0) { g->inside_or_block = false; } // Defer end } inline VV_LOC string v__gen__c__c_name(string name_) { string name = v__util__no_dots(name_); if (v__token__KeywordsMatcherTrie_matches(&_const_v__gen__c__c_reserved_chk, name)) { return str_intp(2, _MOV((StrIntpData[]){{_S("__v_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); } return name; } inline VV_LOC string v__gen__c__c_fn_name(string name_) { string name = v__util__no_dots(name_); if (v__token__KeywordsMatcherTrie_matches(&_const_v__gen__c__c_reserved_chk, name)) { return str_intp(2, _MOV((StrIntpData[]){{_S("_v_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); } return name; } VV_LOC string v__gen__c__Gen_type_default_sumtype(v__gen__c__Gen* g, v__ast__Type typ_, v__ast__TypeSymbol sym) { if (v__ast__Type_has_flag(typ_, v__ast__TypeFlag__option)) { return str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, typ_)}}, {_S("){.state=2, .err=_const_none__, .data={E_STRUCT}}"), 0, { .d_c = 0 }}})); } v__ast__Type first_typ = v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Type*)array_get((*(v__ast__SumType*)__as_cast((sym.info)._v__ast__SumType,(sym.info)._typ, 544)).variants, 0))); v__ast__TypeSymbol* first_sym = v__ast__Table_sym(g->table, first_typ); string first_styp = v__gen__c__Gen_styp(g, first_typ); string first_field = v__gen__c__Gen_get_sumtype_variant_name(g, first_typ, *first_sym); string default_str = (v__ast__Type_has_flag(first_typ, v__ast__TypeFlag__option) ? (str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = first_styp}}, {_S("){.state=2, .err=_const_none__, .data={E_STRUCT}}"), 0, { .d_c = 0 }}}))) : (first_sym->info)._typ == 518 /* v.ast.Struct */ && v__ast__Struct_is_empty_struct(((v__ast__Struct*)__as_cast((first_sym->info)._v__ast__Struct,(first_sym->info)._typ, 518))) ? (_S("{E_STRUCT}")) : (v__gen__c__Gen_type_default_no_sumtype(g, first_typ))); if (string_at(default_str, 0) == '{') { return str_intp(7, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, typ_)}}, {_S("){._"), 0xfe10, {.d_s = first_field}}, {_S("=HEAP("), 0xfe10, {.d_s = first_styp}}, {_S(", (("), 0xfe10, {.d_s = first_styp}}, {_S(")"), 0xfe10, {.d_s = default_str}}, {_S(")),._typ="), 0xfe07, {.d_i32 = ((int)(first_typ))}}, {_S("}"), 0, { .d_c = 0 }}})); } else { return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, typ_)}}, {_S("){._"), 0xfe10, {.d_s = first_field}}, {_S("=HEAP("), 0xfe10, {.d_s = first_styp}}, {_S(", ("), 0xfe10, {.d_s = default_str}}, {_S(")),._typ="), 0xfe07, {.d_i32 = ((int)(first_typ))}}, {_S("}"), 0, { .d_c = 0 }}})); } return (string){.str=(byteptr)"", .is_lit=1}; } inline VV_LOC string v__gen__c__Gen_type_default_no_sumtype(v__gen__c__Gen* g, v__ast__Type typ_) { return v__gen__c__Gen_type_default_impl(g, typ_, false); } inline VV_LOC string v__gen__c__Gen_type_default(v__gen__c__Gen* g, v__ast__Type typ_) { return v__gen__c__Gen_type_default_impl(g, typ_, true); } VV_LOC string v__gen__c__Gen_type_default_impl(v__gen__c__Gen* g, v__ast__Type typ_, bool decode_sumtype) { bool v__gen__c__Gen_type_default_impl_defer_0 = false; g->type_default_impl_level++; v__gen__c__Gen_type_default_impl_defer_0 = true; if (g->type_default_impl_level > 37) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S(">>> Gen.type_default_impl g.type_default_impl_level: "), 0xfe07, {.d_i32 = g->type_default_impl_level}}, {_S(" | typ_: "), 0xfe10, {.d_s = v__ast__Type_str(typ_)}}, {_S(" | decode_sumtype: "), 0xfe10, {.d_s = decode_sumtype ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (g->type_default_impl_level > 40) { v__gen__c__verror(str_intp(2, _MOV((StrIntpData[]){{_S("reached maximum levels of nesting for "), 0xfe10, {.d_s = _S("/home/runner/work/v/v/vlib/v/gen/c/cgen.v:7327, &c.Gen{}.type_default_impl")}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } v__ast__Type typ = v__gen__c__Gen_unwrap_generic(g, typ_); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { string _t1 = str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, typ)}}, {_S("){.state=2, .err=_const_none__, .data={E_STRUCT}}"), 0, { .d_c = 0 }}})); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t1; } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__result)) { string _t2 = _S("{0}"); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t2; } if (v__ast__Type_is_ptr(typ) && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f)) { string _t3 = _S("0"); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t3; } if (v__ast__Type_idx(typ) < 21) { string _t4 = _S("0"); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t4; } v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); switch (sym->kind) { case v__ast__Kind__string: { string _t5 = _S("(string){.str=(byteptr)\"\", .is_lit=1}"); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t5; } case v__ast__Kind__array_fixed: { if (v__ast__TypeSymbol_is_empty_struct_array(sym)) { string _t6 = _S("{E_STRUCT}"); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t6; } string _t7 = _S("{0}"); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t7; } case v__ast__Kind__sum_type: { string _t8 = (decode_sumtype ? (v__gen__c__Gen_type_default_sumtype(g, typ, *sym)) : (_S("{0}"))); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t8; } case v__ast__Kind__interface: case v__ast__Kind__multi_return: case v__ast__Kind__thread: { string _t9 = _S("{0}"); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t9; } case v__ast__Kind__alias: { string _t10 = v__gen__c__Gen_type_default(g, (*(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539)).parent_type); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t10; } case v__ast__Kind__chan: { v__ast__Type elem_type = v__ast__TypeSymbol_chan_info(sym).elem_type; string elemtypstr = v__gen__c__Gen_styp(g, elem_type); string noscan = v__gen__c__Gen_check_noscan(g, elem_type); string _t11 = str_intp(3, _MOV((StrIntpData[]){{_S("sync__new_channel_st"), 0xfe10, {.d_s = noscan}}, {_S("(0, sizeof("), 0xfe10, {.d_s = elemtypstr}}, {_S("))"), 0, { .d_c = 0 }}})); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t11; } case v__ast__Kind__array: { v__ast__Type elem_typ = v__ast__TypeSymbol_array_info(sym).elem_type; string elem_sym = v__gen__c__Gen_styp(g, elem_typ); string elem_type_str = v__util__no_dots(elem_sym); if (string_starts_with(elem_type_str, _S("C__"))) { elem_type_str = string_substr(elem_type_str, 3, 2147483647); } string noscan = v__gen__c__Gen_check_noscan(g, elem_typ); string init_str = str_intp(3, _MOV((StrIntpData[]){{_S("__new_array"), 0xfe10, {.d_s = noscan}}, {_S("(0, 0, sizeof("), 0xfe10, {.d_s = elem_type_str}}, {_S("))"), 0, { .d_c = 0 }}})); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f)) { string atyp = str_intp(2, _MOV((StrIntpData[]){{_S("__shared__"), 0xfe10, {.d_s = sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}})); string _t12 = str_intp(5, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = atyp}}, {_S("*)__dup_shared_array(&("), 0xfe10, {.d_s = atyp}}, {_S("){.mtx = {0}, .val ="), 0xfe10, {.d_s = init_str}}, {_S("}, sizeof("), 0xfe10, {.d_s = atyp}}, {_S("))"), 0, { .d_c = 0 }}})); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t12; } else { string _t13 = init_str; // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t13; } break; } case v__ast__Kind__map: { v__ast__Map info = v__ast__TypeSymbol_map_info(sym); v__ast__TypeSymbol* key_typ = v__ast__Table_sym(g->table, info.key_type); multi_return_string_string_string_string mr_239144 = v__gen__c__Gen_map_fn_ptrs(g, *key_typ); string hash_fn = mr_239144.arg0; string key_eq_fn = mr_239144.arg1; string clone_fn = mr_239144.arg2; string free_fn = mr_239144.arg3; string noscan_key = v__gen__c__Gen_check_noscan(g, info.key_type); string noscan_value = v__gen__c__Gen_check_noscan(g, info.value_type); string noscan = (noscan_key.len != 0 || noscan_value.len != 0 ? (_S("_noscan")) : (_S(""))); if (noscan.len != 0) { if (noscan_key.len != 0) { noscan = string__plus(noscan, _S("_key")); } if (noscan_value.len != 0) { noscan = string__plus(noscan, _S("_value")); } } string init_str = str_intp(8, _MOV((StrIntpData[]){{_S("new_map"), 0xfe10, {.d_s = noscan}}, {_S("(sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, info.key_type)}}, {_S("), sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, info.value_type)}}, {_S("), "), 0xfe10, {.d_s = hash_fn}}, {_S(", "), 0xfe10, {.d_s = key_eq_fn}}, {_S(", "), 0xfe10, {.d_s = clone_fn}}, {_S(", "), 0xfe10, {.d_s = free_fn}}, {_S(")"), 0, { .d_c = 0 }}})); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f)) { string mtyp = str_intp(3, _MOV((StrIntpData[]){{_S("__shared__Map_"), 0xfe10, {.d_s = key_typ->cname}}, {_S("_"), 0xfe10, {.d_s = string_replace(v__gen__c__Gen_styp(g, info.value_type), _S("*"), _S("_ptr"))}}, {_SLIT0, 0, { .d_c = 0 }}})); string _t14 = str_intp(5, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = mtyp}}, {_S("*)__dup_shared_map(&("), 0xfe10, {.d_s = mtyp}}, {_S("){.mtx = {0}, .val ="), 0xfe10, {.d_s = init_str}}, {_S("}, sizeof("), 0xfe10, {.d_s = mtyp}}, {_S("))"), 0, { .d_c = 0 }}})); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t14; } else { string _t15 = init_str; // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t15; } break; } case v__ast__Kind__struct: { bool has_none_zero = false; v__ast__Struct info = *(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518); string init_str = (info.is_anon && !g->inside_global_decl ? (str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, typ)}}, {_S("){"), 0, { .d_c = 0 }}}))) : (_S("{"))); #if defined(_WIN32) { if (!v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f) && g->inside_global_decl) { init_str = str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, typ)}}, {_S("){"), 0, { .d_c = 0 }}})); } } #endif if (sym->language == v__ast__Language__c || sym->language == v__ast__Language__v) { for (int _t17 = 0; _t17 < info.fields.len; ++_t17) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[_t17]; v__ast__TypeSymbol* field_sym = v__ast__Table_sym(g->table, field.typ); bool is_option = v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option); if (is_option || field.has_default_expr || (field_sym->kind == v__ast__Kind__enum || field_sym->kind == v__ast__Kind__array_fixed || field_sym->kind == v__ast__Kind__array || field_sym->kind == v__ast__Kind__map || field_sym->kind == v__ast__Kind__string || field_sym->kind == v__ast__Kind__bool || field_sym->kind == v__ast__Kind__alias || field_sym->kind == v__ast__Kind__i8 || field_sym->kind == v__ast__Kind__i16 || field_sym->kind == v__ast__Kind__int || field_sym->kind == v__ast__Kind__i64 || field_sym->kind == v__ast__Kind__u8 || field_sym->kind == v__ast__Kind__u16 || field_sym->kind == v__ast__Kind__u32 || field_sym->kind == v__ast__Kind__u64 || field_sym->kind == v__ast__Kind__f32 || field_sym->kind == v__ast__Kind__f64 || field_sym->kind == v__ast__Kind__char || field_sym->kind == v__ast__Kind__voidptr || field_sym->kind == v__ast__Kind__byteptr || field_sym->kind == v__ast__Kind__charptr || field_sym->kind == v__ast__Kind__struct || field_sym->kind == v__ast__Kind__chan || field_sym->kind == v__ast__Kind__sum_type)) { if (sym->language == v__ast__Language__c && !field.has_default_expr && !is_option) { continue; } string field_name = v__gen__c__c_name(field.name); if (field.has_default_expr) { string expr_str = _S(""); if (field_sym->kind == v__ast__Kind__sum_type || field_sym->kind == v__ast__Kind__interface) { expr_str = v__gen__c__Gen_expr_string_with_cast(g, field.default_expr, field.default_expr_typ, field.typ); } else if (v__ast__TypeSymbol_is_array_fixed(field_sym) && g->inside_global_decl) { v__ast__ArrayFixed array_info = v__ast__TypeSymbol_array_fixed_info(field_sym); if (field.default_expr._typ == 344 /* v.ast.CallExpr */) { string ret_typ = v__gen__c__Gen_styp(g, (*field.default_expr._v__ast__CallExpr).return_type); string tmp_var = v__gen__c__Gen_new_tmp_var(g); strings__Builder_writeln(&g->type_default_vars, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_default_vars, str_intp(4, _MOV((StrIntpData[]){{_S("memcpy("), 0xfe10, {.d_s = tmp_var}}, {_S(", "), 0xfe10, {.d_s = v__gen__c__Gen_expr_string(g, field.default_expr)}}, {_S(", sizeof("), 0xfe10, {.d_s = ret_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); expr_str = string__plus(expr_str, _S("{")); for (int i = 0; i < array_info.size; ++i) { expr_str = string__plus(expr_str, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_var}}, {_S("["), 0xfe07, {.d_i32 = i}}, {_S("]"), 0, { .d_c = 0 }}}))); if (i != (int)(array_info.size - 1)) { expr_str = string__plus(expr_str, _S(", ")); } } expr_str = string__plus(expr_str, _S("}")); } else if (field.default_expr._typ == 338 /* v.ast.ArrayInit */) { string ret_typ = v__gen__c__Gen_styp(g, (*field.default_expr._v__ast__ArrayInit).typ); string tmp_var = v__gen__c__Gen_new_tmp_var(g); strings__Builder_writeln(&g->type_default_vars, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_typ}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__Gen_expr_string(g, field.default_expr)}}, {_S(";"), 0, { .d_c = 0 }}}))); expr_str = string__plus(expr_str, _S("{")); for (int i = 0; i < array_info.size; ++i) { expr_str = string__plus(expr_str, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_var}}, {_S("["), 0xfe07, {.d_i32 = i}}, {_S("]"), 0, { .d_c = 0 }}}))); if (i != (int)(array_info.size - 1)) { expr_str = string__plus(expr_str, _S(", ")); } } expr_str = string__plus(expr_str, _S("}")); } else { expr_str = v__gen__c__Gen_expr_string(g, field.default_expr); } } else { string default_str = v__gen__c__Gen_expr_string_opt(g, field.typ, field.default_expr); if (string_count(default_str, _S(";\n")) > 1) { strings__Builder_writeln(&g->type_default_vars, string_all_before_last(default_str, _S("\n"))); expr_str = string_all_after_last(default_str, _S("\n")); } else { expr_str = default_str; } } init_str = string__plus(init_str, str_intp(3, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = field_name}}, {_S(" = "), 0xfe10, {.d_s = expr_str}}, {_S(","), 0, { .d_c = 0 }}}))); } else { string zero_str = (field_sym->language == v__ast__Language__v && (field_sym->info)._typ == 518 /* v.ast.Struct */ && v__ast__Struct_is_empty_struct(((v__ast__Struct*)__as_cast((field_sym->info)._v__ast__Struct,(field_sym->info)._typ, 518))) ? (_S("{E_STRUCT}")) : field_sym->kind == v__ast__Kind__sum_type ? ((decode_sumtype ? (v__gen__c__Gen_type_default_sumtype(g, field.typ, *field_sym)) : (_S("{0}")))) : (v__gen__c__Gen_type_default(g, field.typ))); init_str = string__plus(init_str, str_intp(3, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = field_name}}, {_S(" = "), 0xfe10, {.d_s = zero_str}}, {_S(","), 0, { .d_c = 0 }}}))); } has_none_zero = true; } } } bool typ_is_shared_f = v__ast__Type_has_flag(typ, v__ast__TypeFlag__shared_f); if (has_none_zero) { init_str = string__plus(init_str, _S("}")); if (!typ_is_shared_f) { string type_name = (info.is_anon || g->inside_global_decl ? (_S("")) : (str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, typ)}}, {_S(")"), 0, { .d_c = 0 }}})))); init_str = string__plus(type_name, init_str); } } else { init_str = string__plus(init_str, _S("0}")); } if (typ_is_shared_f) { string styp = str_intp(2, _MOV((StrIntpData[]){{_S("__shared__"), 0xfe10, {.d_s = v__ast__Table_sym(g->table, typ)->cname}}, {_SLIT0, 0, { .d_c = 0 }}})); string _t18 = str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = styp}}, {_S("*)__dup"), 0xfe10, {.d_s = styp}}, {_S("(&("), 0xfe10, {.d_s = styp}}, {_S("){.mtx = {0}, .val = "), 0xfe10, {.d_s = init_str}}, {_S("}, sizeof("), 0xfe10, {.d_s = styp}}, {_S("))"), 0, { .d_c = 0 }}})); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t18; } else { string _t19 = init_str; // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t19; } break; } case v__ast__Kind__enum: { v__ast__EnumDecl* _t21 = (v__ast__EnumDecl*)(map_get_check(ADDR(map, g->table->enum_decls), &(string[]){sym->name})); _option_v__ast__EnumDecl _t20 = {0}; if (_t21) { *((v__ast__EnumDecl*)&_t20.data) = *((v__ast__EnumDecl*)_t21); } else { _t20.state = 2; _t20.err = _v_error(_S("map key does not exist")); } if (_t20.state == 0) { v__ast__EnumDecl enum_decl = (*(v__ast__EnumDecl*)_t20.data); string _t22 = (((*(v__ast__EnumField*)array_get(enum_decl.fields, 0)).expr)._typ == 354 /* v.ast.EmptyExpr */ ? (_S("0")) : (v__gen__c__Gen_expr_string(g, (*(v__ast__EnumField*)array_get(enum_decl.fields, 0)).expr))); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t22; } else { IError err = _t20.err; string _t23 = _S("0"); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t23; } break; } case v__ast__Kind__placeholder: case v__ast__Kind__void: case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__i32: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__isize: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__usize: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__bool: case v__ast__Kind__none: case v__ast__Kind__any: case v__ast__Kind__generic_inst: case v__ast__Kind__function: case v__ast__Kind__float_literal: case v__ast__Kind__int_literal: case v__ast__Kind__aggregate: default: { { string _t24 = _S("0"); // Defer begin if (v__gen__c__Gen_type_default_impl_defer_0) { g->type_default_impl_level--; } // Defer end return _t24; } } } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC Array_string v__gen__c__Gen_get_all_test_function_names(v__gen__c__Gen* g) { Array_string tfuncs = __new_array_with_default(0, 0, sizeof(string), 0); string tsuite_begin = _S(""); string tsuite_end = _S(""); for (int _t1 = 0; _t1 < g->test_function_names.len; ++_t1) { string name = ((string*)g->test_function_names.data)[_t1]; if (string_ends_with(name, _S(".testsuite_begin"))) { tsuite_begin = name; continue; } if (string_contains(name, _S(".test_"))) { array_push((array*)&tfuncs, _MOV((string[]){ string_clone(name) })); continue; } if (string_ends_with(name, _S(".testsuite_end"))) { tsuite_end = name; continue; } } Array_string all_tfuncs = __new_array_with_default(0, 0, sizeof(string), 0); if ((tsuite_begin).len != 0) { array_push((array*)&all_tfuncs, _MOV((string[]){ string_clone(tsuite_begin) })); } _PUSH_MANY(&all_tfuncs, (tfuncs), _t4, Array_string); if ((tsuite_end).len != 0) { array_push((array*)&all_tfuncs, _MOV((string[]){ string_clone(tsuite_end) })); } return all_tfuncs; } inline VV_LOC v__ast__Type v__gen__c__Gen_get_type(v__gen__c__Gen* g, v__ast__Type typ) { return (typ == g->field_data_type ? (g->comptime->comptime_for_field_value.typ) : (typ)); } VV_LOC void v__gen__c__Gen_size_of(v__gen__c__Gen* g, v__ast__SizeOf node) { v__ast__Type typ = v__type_resolver__TypeResolver_typeof_type(&g->type_resolver, node.expr, v__gen__c__Gen_get_type(g, node.typ)); v__ast__Type node_typ = v__gen__c__Gen_unwrap_generic(g, typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, node_typ); if (sym->language == v__ast__Language__v && (sym->kind == v__ast__Kind__placeholder || sym->kind == v__ast__Kind__any)) { v__gen__c__Gen_error(g, str_intp(2, _MOV((StrIntpData[]){{_S("unknown type `"), 0xfe10, {.d_s = sym->name}}, {_S("`"), 0, { .d_c = 0 }}})), node.pos); VUNREACHABLE(); } if ((node.expr)._typ == 384 /* v.ast.StringLiteral */) { if ((*node.expr._v__ast__StringLiteral).language == v__ast__Language__c) { { v__gen__c__Gen_write(g, _S("sizeof(\"")); v__gen__c__Gen_write(g, (*node.expr._v__ast__StringLiteral).val); v__gen__c__Gen_write(g, _S("\")")); } return; } } string styp = v__gen__c__Gen_styp(g, node_typ); { v__gen__c__Gen_write(g, _S("sizeof(")); v__gen__c__Gen_write(g, v__util__no_dots(styp)); v__gen__c__Gen_write(g, _S(")")); } } inline VV_LOC string v__gen__c__Gen_gen_enum_prefix(v__gen__c__Gen* g, v__ast__Type typ) { if (g->pref->translated && v__ast__Type_is_number(typ)) { return _S("_const_main__"); } else { string styp = v__gen__c__Gen_styp(g, v__ast__Table_unaliased_type(g->table, typ)); return str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S("__"), 0, { .d_c = 0 }}})); } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC void v__gen__c__Gen_enum_val(v__gen__c__Gen* g, v__ast__EnumVal node) { { v__gen__c__Gen_write(g, v__gen__c__Gen_gen_enum_prefix(g, node.typ)); v__gen__c__Gen_write(g, node.val); } } VV_LOC void v__gen__c__Gen_as_cast(v__gen__c__Gen* g, v__ast__AsCast node) { v__ast__Type unwrapped_node_typ = v__gen__c__Gen_unwrap_generic(g, node.typ); string styp = v__gen__c__Gen_styp(g, unwrapped_node_typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, unwrapped_node_typ); v__ast__TypeSymbol* expr_type_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, node.expr_type)); if ((expr_type_sym->info)._typ == 544 /* v.ast.SumType */) { string dot = (v__ast__Type_is_ptr(node.expr_type) ? (_S("->")) : (_S("."))); if (v__ast__Expr_has_fn_call(&node.expr) && !g->is_cc_msvc) { string tmp_var = v__gen__c__Gen_new_tmp_var(g); string expr_styp = v__gen__c__Gen_styp(g, node.expr_type); { v__gen__c__Gen_write(g, _S("({ ")); v__gen__c__Gen_write(g, expr_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write(g, _S("; ")); if ((sym->info)._typ == 553 /* v.ast.FnType */) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(")__as_cast(")); } } else if (g->inside_smartcast) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)__as_cast(")); } } else { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)__as_cast(")); } } v__gen__c__Gen_write2(g, tmp_var, dot); v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = sym->cname}}, {_S(","), 0, { .d_c = 0 }}})), tmp_var); v__gen__c__Gen_write(g, dot); string sidx = v__gen__c__Gen_type_sidx(g, unwrapped_node_typ); { v__gen__c__Gen_write(g, _S("_typ, ")); v__gen__c__Gen_write(g, sidx); v__gen__c__Gen_write(g, _S("); })")); } } else { if ((sym->info)._typ == 553 /* v.ast.FnType */) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(")__as_cast(")); } } else if (g->inside_smartcast) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)__as_cast(")); } } else { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)__as_cast(")); } } v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write2(g, _S(")"), dot); v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = sym->cname}}, {_S(","), 0, { .d_c = 0 }}})), _S("(")); v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write2(g, _S(")"), dot); string sidx = v__gen__c__Gen_type_sidx(g, unwrapped_node_typ); { v__gen__c__Gen_write(g, _S("_typ, ")); v__gen__c__Gen_write(g, sidx); v__gen__c__Gen_write(g, _S(")")); } } for (int _t1 = 0; _t1 < (*expr_type_sym->info._v__ast__SumType).variants.len; ++_t1) { v__ast__Type variant = ((v__ast__Type*)(*expr_type_sym->info._v__ast__SumType).variants.data)[_t1]; string idx = u32_str(((u32)(variant))); if (_IN_MAP(ADDR(string, idx), ADDR(map, g->as_cast_type_names))) { continue; } v__ast__TypeSymbol* variant_sym = v__ast__Table_sym(g->table, variant); map_set(&g->as_cast_type_names, &(string[]){idx}, &(string[]) { variant_sym->name }); } } else if (expr_type_sym->kind == v__ast__Kind__interface && sym->kind == v__ast__Kind__interface) { { v__gen__c__Gen_write(g, _S("I_")); v__gen__c__Gen_write(g, expr_type_sym->cname); v__gen__c__Gen_write(g, _S("_as_I_")); v__gen__c__Gen_write(g, sym->cname); v__gen__c__Gen_write(g, _S("(")); } if (v__ast__Type_is_ptr(node.expr_type)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write(g, _S(")")); v__ast__Interface info = *(v__ast__Interface*)__as_cast((expr_type_sym->info)._v__ast__Interface,(expr_type_sym->info)._typ, 542); sync__RwMutex_lock(&info.conversions->mtx); /*lock*/ { if (!_IN_MAP(ADDR(int, node.typ), ADDR(map, info.conversions->val))) { Array_v__ast__Type left_variants = (*(Array_v__ast__Type*)map_get(ADDR(map, g->table->iface_types), &(string[]){expr_type_sym->name}, &(Array_v__ast__Type[]){ __new_array(0, 0, sizeof(v__ast__Type)) })); Array_v__ast__Type right_variants = (*(Array_v__ast__Type*)map_get(ADDR(map, g->table->iface_types), &(string[]){sym->name}, &(Array_v__ast__Type[]){ __new_array(0, 0, sizeof(v__ast__Type)) })); Array_v__ast__Type _t2 = {0}; Array_v__ast__Type _t2_orig = left_variants; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t2_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t2_orig.data)[_t3]; if ((Array_v__ast__Type_contains(right_variants, it))) { array_push((array*)&_t2, &it); } } (*(Array_v__ast__Type*)map_get_and_set((map*)&info.conversions->val, &(int[]){node.typ}, &(Array_v__ast__Type[]){ __new_array(0, 0, sizeof(v__ast__Type)) })) =_t2; } } sync__RwMutex_unlock(&info.conversions->mtx);; expr_type_sym->info = v__ast__Interface_to_sumtype_v__ast__TypeInfo(&info); } else if ((expr_type_sym->info)._typ == 542 /* v.ast.Interface */ && node.expr_type != node.typ) { string dot = (v__ast__Type_is_ptr(node.expr_type) ? (_S("->")) : (_S("."))); if (v__ast__Expr_has_fn_call(&node.expr) && !g->is_cc_msvc) { string tmp_var = v__gen__c__Gen_new_tmp_var(g); string expr_styp = v__gen__c__Gen_styp(g, node.expr_type); { v__gen__c__Gen_write(g, _S("({ ")); v__gen__c__Gen_write(g, expr_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write(g, _S("; ")); if ((sym->info)._typ == 553 /* v.ast.FnType */) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(")__as_cast(")); } } else if (g->inside_smartcast) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)__as_cast(")); } } else { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)__as_cast(")); } } v__gen__c__Gen_write2(g, tmp_var, dot); { v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, sym->cname); v__gen__c__Gen_write(g, _S(",v_typeof_interface_idx_")); v__gen__c__Gen_write(g, expr_type_sym->cname); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_write2(g, tmp_var, dot); string sidx = v__gen__c__Gen_type_sidx(g, unwrapped_node_typ); { v__gen__c__Gen_write(g, _S("_typ), ")); v__gen__c__Gen_write(g, sidx); v__gen__c__Gen_write(g, _S("); })")); } } else { if ((sym->info)._typ == 553 /* v.ast.FnType */) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(")__as_cast(")); } } else if (g->inside_smartcast) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)__as_cast(")); } } else { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)__as_cast(")); } } v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write2(g, _S(")"), dot); v__gen__c__Gen_write2(g, str_intp(3, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = sym->cname}}, {_S(",v_typeof_interface_idx_"), 0xfe10, {.d_s = expr_type_sym->cname}}, {_S("("), 0, { .d_c = 0 }}})), _S("(")); v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write2(g, _S(")"), dot); string sidx = v__gen__c__Gen_type_sidx(g, unwrapped_node_typ); { v__gen__c__Gen_write(g, _S("_typ), ")); v__gen__c__Gen_write(g, sidx); v__gen__c__Gen_write(g, _S(")")); } } for (int _t4 = 0; _t4 < (*expr_type_sym->info._v__ast__Interface).types.len; ++_t4) { v__ast__Type typ = ((v__ast__Type*)(*expr_type_sym->info._v__ast__Interface).types.data)[_t4]; string idx = u32_str(((u32)(typ))); if (_IN_MAP(ADDR(string, idx), ADDR(map, g->as_cast_type_names))) { continue; } v__ast__TypeSymbol* variant_sym = v__ast__Table_sym(g->table, typ); map_set(&g->as_cast_type_names, &(string[]){idx}, &(string[]) { variant_sym->name }); } } else { bool is_optional_ident_var = false; if (g->inside_smartcast) { v__gen__c__Gen_write(g, _S("&")); } if ((node.expr)._typ == 358 /* v.ast.Ident */) { if (((*node.expr._v__ast__Ident).info)._typ == 477 /* v.ast.IdentVar */ && (*(v__ast__IdentVar*)__as_cast(((*node.expr._v__ast__Ident).info)._v__ast__IdentVar,((*node.expr._v__ast__Ident).info)._typ, 477)).is_option && !v__ast__Type_has_flag(unwrapped_node_typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_unwrap_option_type(g, unwrapped_node_typ, (*node.expr._v__ast__Ident).name, v__ast__Ident_is_auto_heap(&(*node.expr._v__ast__Ident))); is_optional_ident_var = true; } } else if ((node.expr)._typ == 379 /* v.ast.SelectorExpr */) { if (((*node.expr._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */ && v__ast__Type_has_flag((*node.expr._v__ast__SelectorExpr).typ, v__ast__TypeFlag__option) && !v__ast__Type_has_flag(unwrapped_node_typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_unwrap_option_type(g, (*node.expr._v__ast__SelectorExpr).typ, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*(*node.expr._v__ast__SelectorExpr).expr._v__ast__Ident).name}}, {_S("."), 0xfe10, {.d_s = (*node.expr._v__ast__SelectorExpr).field_name}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Ident_is_auto_heap(&(*(*node.expr._v__ast__SelectorExpr).expr._v__ast__Ident))); is_optional_ident_var = true; } else if (((*node.expr._v__ast__SelectorExpr).expr)._typ == 379 /* v.ast.SelectorExpr */ && v__ast__Type_has_flag((*node.expr._v__ast__SelectorExpr).typ, v__ast__TypeFlag__option)) { if (((*(*node.expr._v__ast__SelectorExpr).expr._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */) { v__gen__c__Gen_unwrap_option_type(g, (*node.expr._v__ast__SelectorExpr).typ, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*(*(*node.expr._v__ast__SelectorExpr).expr._v__ast__SelectorExpr).expr._v__ast__Ident).name}}, {_S("."), 0xfe10, {.d_s = (*(*node.expr._v__ast__SelectorExpr).expr._v__ast__SelectorExpr).field_name}}, {_S("."), 0xfe10, {.d_s = (*node.expr._v__ast__SelectorExpr).field_name}}, {_SLIT0, 0, { .d_c = 0 }}})), v__ast__Ident_is_auto_heap(&(*(*(*node.expr._v__ast__SelectorExpr).expr._v__ast__SelectorExpr).expr._v__ast__Ident))); is_optional_ident_var = true; } } } if (!is_optional_ident_var) { v__gen__c__Gen_expr(g, node.expr); } } } VV_LOC string v__gen__c__Gen_as_cast_name_table(v__gen__c__Gen* g) { if (g->as_cast_type_names.len == 0) { return _S("new_array_from_c_array(1, 1, sizeof(VCastTypeIndexName), _MOV((VCastTypeIndexName[1]){(VCastTypeIndexName){.tindex = 0,.tname = _S(\"unknown\")}}));\n"); } strings__Builder name_ast = strings__new_builder(1024); int casts_len = (int)(g->as_cast_type_names.len + 1); strings__Builder_writeln(&name_ast, str_intp(4, _MOV((StrIntpData[]){{_S("new_array_from_c_array("), 0xfe07, {.d_i32 = casts_len}}, {_S(", "), 0xfe07, {.d_i32 = casts_len}}, {_S(", sizeof(VCastTypeIndexName), _MOV((VCastTypeIndexName["), 0xfe07, {.d_i32 = casts_len}}, {_S("]){"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&name_ast, _S("\t\t (VCastTypeIndexName){.tindex = 0, .tname = _S(\"unknown\")}")); Map_string_string _t2 = g->as_cast_type_names; int _t4 = _t2.key_values.len; for (int _t3 = 0; _t3 < _t4; ++_t3 ) { int _t5 = _t2.key_values.len - _t4; _t4 = _t2.key_values.len; if (_t5 < 0) { _t3 = -1; continue; } if (!DenseArray_has_index(&_t2.key_values, _t3)) {continue;} string key = *(string*)DenseArray_key(&_t2.key_values, _t3); key = string_clone(key); string value = (*(string*)DenseArray_value(&_t2.key_values, _t3)); strings__Builder_writeln(&name_ast, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t, (VCastTypeIndexName){.tindex = "), 0xfe10, {.d_s = key}}, {_S(", .tname = _S(\""), 0xfe10, {.d_s = value}}, {_S("\")}"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&name_ast, _S("\t}));\n")); return strings__Builder_str(&name_ast); } VV_LOC bool v__gen__c__Gen_has_been_referenced(v__gen__c__Gen* g, string fn_name) { bool referenced = false; sync__RwMutex_lock(&g->referenced_fns->mtx); /*lock*/ { referenced = (*(bool*)map_get(ADDR(map, g->referenced_fns->val), &(string[]){fn_name}, &(bool[]){ 0 })); } sync__RwMutex_unlock(&g->referenced_fns->mtx);; return referenced; } VV_LOC void v__gen__c__Gen_register_iface_return_types(v__gen__c__Gen* g) { Array_v__ast__TypeSymbol_ptr _t1 = {0}; Array_v__ast__TypeSymbol_ptr _t1_orig = g->table->type_symbols; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__TypeSymbol*)); for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__TypeSymbol* it = ((v__ast__TypeSymbol**) _t1_orig.data)[_t2]; if (it->kind == v__ast__Kind__interface && (it->info)._typ == 542 /* v.ast.Interface */) { array_push((array*)&_t1, &it); } } Array_v__ast__TypeSymbol_ptr interfaces =_t1; for (int _t3 = 0; _t3 < interfaces.len; ++_t3) { v__ast__TypeSymbol* isym = ((v__ast__TypeSymbol**)interfaces.data)[_t3]; v__ast__Interface inter_info = *(v__ast__Interface*)__as_cast((isym->info)._v__ast__Interface,(isym->info)._typ, 542); if (inter_info.is_generic) { continue; } Array_string _t4 = v__ast__Interface_get_methods(inter_info); for (int _t5 = 0; _t5 < _t4.len; ++_t5) { string method_name = ((string*)_t4.data)[_t5]; _option_v__ast__Fn _t6 = v__ast__TypeSymbol_find_method_with_generic_parent(isym, method_name); if (_t6.state != 0) { IError err = _t6.err; continue; } v__ast__Fn method = (*(v__ast__Fn*)_t6.data); if (v__ast__Type_has_flag(method.return_type, v__ast__TypeFlag__result)) { if (g->pref->skip_unused && !_IN_MAP(ADDR(int, v__ast__Table_sym(g->table, method.return_type)->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } v__gen__c__Gen_register_result(g, method.return_type); } } } } VV_LOC string v__gen__c__Gen_interface_table(v__gen__c__Gen* g) { bool v__gen__c__Gen_interface_table_defer_0 = false; v__util__timing_start(_S("Gen.interface_table")); v__gen__c__Gen_interface_table_defer_0 = true; strings__Builder sb = strings__new_builder(100); strings__Builder conversion_functions = strings__new_builder(100); Array_v__ast__TypeSymbol_ptr _t1 = {0}; Array_v__ast__TypeSymbol_ptr _t1_orig = g->table->type_symbols; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__TypeSymbol*)); for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__TypeSymbol* it = ((v__ast__TypeSymbol**) _t1_orig.data)[_t2]; if (it->kind == v__ast__Kind__interface && (it->info)._typ == 542 /* v.ast.Interface */) { array_push((array*)&_t1, &it); } } Array_v__ast__TypeSymbol_ptr interfaces =_t1; for (int _t3 = 0; _t3 < interfaces.len; ++_t3) { v__ast__TypeSymbol* isym = ((v__ast__TypeSymbol**)interfaces.data)[_t3]; v__ast__Interface inter_info = *(v__ast__Interface*)__as_cast((isym->info)._v__ast__Interface,(isym->info)._typ, 542); if (inter_info.is_generic) { continue; } if (g->pref->skip_unused && !_IN_MAP(ADDR(int, isym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } string interface_name = isym->cname; string methods_struct_name = str_intp(2, _MOV((StrIntpData[]){{_S("struct _"), 0xfe10, {.d_s = interface_name}}, {_S("_interface_methods"), 0, { .d_c = 0 }}})); strings__Builder methods_struct_def = strings__new_builder(100); strings__Builder_writeln(&methods_struct_def, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = methods_struct_name}}, {_S(" {"), 0, { .d_c = 0 }}}))); Array_string inter_methods = v__ast__Interface_get_methods(inter_info); if (inter_methods.len > 0) { qsort(inter_methods.data, inter_methods.len, inter_methods.element_size, (voidptr)compare_17767866704287204994_string); } ; Map_string_int methodidx = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int k = 0; k < inter_methods.len; ++k) { string method_name = ((string*)inter_methods.data)[k]; _option_v__ast__Fn _t4 = v__ast__TypeSymbol_find_method_with_generic_parent(isym, method_name); if (_t4.state != 0) { IError err = _t4.err; continue; } v__ast__Fn method = (*(v__ast__Fn*)_t4.data); map_set(&methodidx, &(string[]){method.name}, &(int[]) { k }); string ret_styp = (g->pref->skip_unused && !_IN_MAP(ADDR(int, v__ast__Table_sym(g->table, method.return_type)->idx), ADDR(map, g->table->used_features->used_syms)) ? (_S("void")) : (v__gen__c__Gen_ret_styp(g, method.return_type))); { strings__Builder_write_string(&methods_struct_def, _S("\t")); strings__Builder_write_string(&methods_struct_def, ret_styp); strings__Builder_write_string(&methods_struct_def, _S(" (*_method_")); strings__Builder_write_string(&methods_struct_def, v__gen__c__c_fn_name(method.name)); strings__Builder_write_string(&methods_struct_def, _S(")(void* _")); } for (int i = 1; i < method.params.len; ++i) { v__ast__Param arg = (*(v__ast__Param*)array_get(method.params, i)); { strings__Builder_write_string(&methods_struct_def, _S(", ")); strings__Builder_write_string(&methods_struct_def, v__gen__c__Gen_styp(g, arg.typ)); strings__Builder_write_string(&methods_struct_def, _S(" ")); strings__Builder_write_string(&methods_struct_def, arg.name); } } strings__Builder_writeln(&methods_struct_def, _S(");")); } strings__Builder_writeln(&methods_struct_def, _S("};")); strings__Builder methods_struct = strings__new_builder(100); int iname_table_length = inter_info.types.len; if (iname_table_length == 0) { strings__Builder_writeln(&methods_struct, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_modifier}}, {_SLIT0, 0xfe10, {.d_s = methods_struct_name}}, {_S(" "), 0xfe10, {.d_s = interface_name}}, {_S("_name_table[1];"), 0, { .d_c = 0 }}}))); } else { if (g->pref->build_mode != v__pref__BuildMode__build_module) { strings__Builder_writeln(&methods_struct, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_modifier}}, {_SLIT0, 0xfe10, {.d_s = methods_struct_name}}, {_S(" "), 0xfe10, {.d_s = interface_name}}, {_S("_name_table["), 0xfe07, {.d_i32 = iname_table_length}}, {_S("] = {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&methods_struct, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_modifier}}, {_SLIT0, 0xfe10, {.d_s = methods_struct_name}}, {_S(" "), 0xfe10, {.d_s = interface_name}}, {_S("_name_table["), 0xfe07, {.d_i32 = iname_table_length}}, {_S("];"), 0, { .d_c = 0 }}}))); } } strings__Builder cast_functions = strings__new_builder(100); strings__Builder methods_wrapper = strings__new_builder(100); if (!g->pref->is_prod) { strings__Builder_writeln(&methods_wrapper, str_intp(2, _MOV((StrIntpData[]){{_S("// Methods wrapper for interface \""), 0xfe10, {.d_s = interface_name}}, {_S("\""), 0, { .d_c = 0 }}}))); } Map_string_int already_generated_mwrappers = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; int iinidx_minimum_base = 1000; int current_iinidx = iinidx_minimum_base; for (int _t5 = 0; _t5 < inter_info.types.len; ++_t5) { v__ast__Type st = ((v__ast__Type*)inter_info.types.data)[_t5]; v__ast__TypeSymbol* st_sym_info = v__ast__Table_sym(g->table, st); if ((st_sym_info->info)._typ == 518 /* v.ast.Struct */ && v__ast__Struct_is_unresolved_generic(((v__ast__Struct*)__as_cast((st_sym_info->info)._v__ast__Struct,(st_sym_info->info)._typ, 518)))) { continue; } v__ast__TypeSymbol* st_sym = v__ast__Table_sym(g->table, v__ast__mktyp(st)); string cctype = v__gen__c__Gen_cc_type(g, v__ast__mktyp(st), true); string cctype2 = (g->pref->skip_unused && !_IN_MAP(ADDR(int, st_sym_info->idx), ADDR(map, g->table->used_features->used_syms)) ? (_S("voidptr")) : (cctype)); string cctype_param = (string__eq(cctype, cctype2) ? (cctype) : (_S("void"))); #if defined(CUSTOM_DEFINE_debug_interface_table) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S(">> interface name: "), 0xfe10, {.d_s = isym->name}}, {_S(" | concrete type: "), 0xfe10, {.d_s = Array_string_str(v__ast__Type_debug(st))}}, {_S(" | st symname: "), 0xfe10, {.d_s = st_sym->name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif string interface_index_name = str_intp(3, _MOV((StrIntpData[]){{_S("_"), 0xfe10, {.d_s = interface_name}}, {_S("_"), 0xfe10, {.d_s = cctype}}, {_S("_index"), 0, { .d_c = 0 }}})); if ((*(int*)map_get(ADDR(map, already_generated_mwrappers), &(string[]){interface_index_name}, &(int[]){ 0 })) > 0) { continue; } map_set(&already_generated_mwrappers, &(string[]){interface_index_name}, &(int[]) { current_iinidx }); current_iinidx++; strings__Builder_writeln(&sb, str_intp(5, _MOV((StrIntpData[]){{_S("static "), 0xfe10, {.d_s = interface_name}}, {_S(" I_"), 0xfe10, {.d_s = cctype}}, {_S("_to_Interface_"), 0xfe10, {.d_s = interface_name}}, {_S("("), 0xfe10, {.d_s = cctype_param}}, {_S("* x);"), 0, { .d_c = 0 }}}))); strings__Builder cast_struct = strings__new_builder(100); strings__Builder_writeln(&cast_struct, str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = interface_name}}, {_S(") {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&cast_struct, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t._"), 0xfe10, {.d_s = cctype2}}, {_S(" = x,"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&cast_struct, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t._typ = "), 0xfe10, {.d_s = interface_index_name}}, {_S(","), 0, { .d_c = 0 }}}))); if (string__eq(cctype, cctype2)) { for (int _t7 = 0; _t7 < inter_info.fields.len; ++_t7) { v__ast__StructField field = ((v__ast__StructField*)inter_info.fields.data)[_t7]; string cname = v__gen__c__c_name(field.name); string field_styp = v__gen__c__Gen_styp(g, field.typ); _option_v__ast__StructField _t8; if (_t8 = v__ast__TypeSymbol_find_field(st_sym, field.name), _t8.state == 0) { strings__Builder_writeln(&cast_struct, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t."), 0xfe10, {.d_s = cname}}, {_S(" = ("), 0xfe10, {.d_s = field_styp}}, {_S("*)((char*)x + __offsetof_ptr(x, "), 0xfe10, {.d_s = cctype2}}, {_S(", "), 0xfe10, {.d_s = cname}}, {_S(")),"), 0, { .d_c = 0 }}}))); } else if (st_sym->kind == v__ast__Kind__array && (fast_string_eq(field.name, _S("element_size")) || fast_string_eq(field.name, _S("data")) || fast_string_eq(field.name, _S("offset")) || fast_string_eq(field.name, _S("len")) || fast_string_eq(field.name, _S("cap")) || fast_string_eq(field.name, _S("flags")))) { strings__Builder_writeln(&cast_struct, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t."), 0xfe10, {.d_s = cname}}, {_S(" = ("), 0xfe10, {.d_s = field_styp}}, {_S("*)((char*)x + __offsetof_ptr(x, "), 0xfe10, {.d_s = cctype2}}, {_S(", "), 0xfe10, {.d_s = cname}}, {_S(")),"), 0, { .d_c = 0 }}}))); } else { { strings__Builder_write_string(&cast_struct, _S("\t\t.")); strings__Builder_write_string(&cast_struct, cname); strings__Builder_write_string(&cast_struct, _S(" = (")); strings__Builder_write_string(&cast_struct, field_styp); strings__Builder_write_string(&cast_struct, _S("*)((char*)x")); } if (st != _const_v__ast__voidptr_type && st != _const_v__ast__nil_type) { if (st_sym->kind == v__ast__Kind__struct) { _result_multi_return_v__ast__StructField_Array_v__ast__Type _t9; if (_t9 = v__ast__Table_find_field_from_embeds(g->table, st_sym, field.name), !_t9.is_error) { Array_v__ast__Type embeds = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t9.data).arg1; string typ_name = _S(""); for (int i = 0; i < embeds.len; ++i) { v__ast__Type embed = ((v__ast__Type*)embeds.data)[i]; v__ast__TypeSymbol* esym = v__ast__Table_sym(g->table, embed); if (i == 0) { { strings__Builder_write_string(&cast_struct, _S(" + __offsetof_ptr(x, ")); strings__Builder_write_string(&cast_struct, cctype); strings__Builder_write_string(&cast_struct, _S(", ")); strings__Builder_write_string(&cast_struct, v__ast__TypeSymbol_embed_name(esym)); strings__Builder_write_string(&cast_struct, _S(")")); } } else { { strings__Builder_write_string(&cast_struct, _S(" + __offsetof_ptr(x, ")); strings__Builder_write_string(&cast_struct, typ_name); strings__Builder_write_string(&cast_struct, _S(", ")); strings__Builder_write_string(&cast_struct, v__ast__TypeSymbol_embed_name(esym)); strings__Builder_write_string(&cast_struct, _S(")")); } } typ_name = esym->cname; } if (embeds.len > 0) { { strings__Builder_write_string(&cast_struct, _S(" + __offsetof_ptr(x, ")); strings__Builder_write_string(&cast_struct, typ_name); strings__Builder_write_string(&cast_struct, _S(", ")); strings__Builder_write_string(&cast_struct, cname); strings__Builder_write_string(&cast_struct, _S(")")); } } } } } strings__Builder_writeln(&cast_struct, _S("),")); } } } strings__Builder_write_string(&cast_struct, _S("\t}")); string cast_struct_str = strings__Builder_str(&cast_struct); if (!g->pref->is_prod) { strings__Builder_writeln(&cast_functions, str_intp(3, _MOV((StrIntpData[]){{_S("\n// Casting functions for converting \""), 0xfe10, {.d_s = cctype}}, {_S("\" to interface \""), 0xfe10, {.d_s = interface_name}}, {_S("\""), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&cast_functions, str_intp(6, _MOV((StrIntpData[]){{_S("\nstatic inline "), 0xfe10, {.d_s = interface_name}}, {_S(" I_"), 0xfe10, {.d_s = cctype}}, {_S("_to_Interface_"), 0xfe10, {.d_s = interface_name}}, {_S("("), 0xfe10, {.d_s = cctype_param}}, {_S("* x) {\nreturn "), 0xfe10, {.d_s = cast_struct_str}}, {_S(";\n}"), 0, { .d_c = 0 }}}))); string shared_fn_name = str_intp(3, _MOV((StrIntpData[]){{_S("I___shared__"), 0xfe10, {.d_s = cctype}}, {_S("_to_shared_Interface___shared__"), 0xfe10, {.d_s = interface_name}}, {_SLIT0, 0, { .d_c = 0 }}})); if (v__gen__c__Gen_has_been_referenced(g, shared_fn_name)) { strings__Builder cast_shared_struct = strings__new_builder(100); strings__Builder_writeln(&cast_shared_struct, str_intp(2, _MOV((StrIntpData[]){{_S("(__shared__"), 0xfe10, {.d_s = interface_name}}, {_S(") {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&cast_shared_struct, _S("\t\t.mtx = {0},")); strings__Builder_writeln(&cast_shared_struct, _S("\t\t.val = {")); strings__Builder_writeln(&cast_shared_struct, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\t._"), 0xfe10, {.d_s = cctype}}, {_S(" = &x->val,"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&cast_shared_struct, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\t._typ = "), 0xfe10, {.d_s = interface_index_name}}, {_S(","), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&cast_shared_struct, _S("\t\t}")); strings__Builder_write_string(&cast_shared_struct, _S("\t}")); string cast_shared_struct_str = strings__Builder_str(&cast_shared_struct); strings__Builder_writeln(&cast_functions, str_intp(7, _MOV((StrIntpData[]){{_S("\n// Casting functions for converting \"__shared__"), 0xfe10, {.d_s = cctype}}, {_S("\" to interface \"__shared__"), 0xfe10, {.d_s = interface_name}}, {_S("\"\nstatic inline __shared__"), 0xfe10, {.d_s = interface_name}}, {_S(" "), 0xfe10, {.d_s = shared_fn_name}}, {_S("(__shared__"), 0xfe10, {.d_s = cctype}}, {_S("* x) {\nreturn "), 0xfe10, {.d_s = cast_shared_struct_str}}, {_S(";\n}"), 0, { .d_c = 0 }}}))); } if (g->pref->build_mode != v__pref__BuildMode__build_module) { strings__Builder_writeln(&methods_struct, _S("\t{")); } if (st == _const_v__ast__voidptr_type || st == _const_v__ast__nil_type) { Array_string mnames = map_keys(&methodidx); if (mnames.len > 0) { qsort(mnames.data, mnames.len, mnames.element_size, (voidptr)compare_17767866704287204994_string); } ; for (int _t10 = 0; _t10 < mnames.len; ++_t10) { string mname = ((string*)mnames.data)[_t10]; if (g->pref->build_mode != v__pref__BuildMode__build_module) { strings__Builder_writeln(&methods_struct, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t._method_"), 0xfe10, {.d_s = v__gen__c__c_fn_name(mname)}}, {_S(" = (void*) 0,"), 0, { .d_c = 0 }}}))); } } } Array_v__ast__Fn methods = array_clone_to_depth(&st_sym->methods, 0); Array_string aliased_method_names = __new_array_with_default(0, 0, sizeof(string), 0); Array_string _t11 = {0}; Array_v__ast__Fn _t11_orig = methods; int _t11_len = _t11_orig.len; _t11 = __new_array(0, _t11_len, sizeof(string)); for (int _t13 = 0; _t13 < _t11_len; ++_t13) { v__ast__Fn it = ((v__ast__Fn*) _t11_orig.data)[_t13]; string _t12 = it.name; array_push((array*)&_t11, &_t12); } Array_string method_names =_t11; if (st_sym->info._typ == 518 /* v.ast.Struct */) { if (v__ast__Type_has_flag((*st_sym->info._v__ast__Struct).parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(g->table, (*st_sym->info._v__ast__Struct).parent_type); for (int _t14 = 0; _t14 < parent_sym->methods.len; ++_t14) { v__ast__Fn method = ((v__ast__Fn*)parent_sym->methods.data)[_t14]; if (_IN_MAP(ADDR(string, method.name), ADDR(map, methodidx))) { _option_v__ast__Fn _t16 = v__ast__TypeSymbol_find_method_with_generic_parent(st_sym, method.name); if (_t16.state != 0) { IError err = _t16.err; continue; } array_push((array*)&methods, _MOV((v__ast__Fn[]){ (*(v__ast__Fn*)_t16.data) })); } } } } else if (st_sym->info._typ == 542 /* v.ast.Interface */) { if (v__ast__Type_has_flag((*st_sym->info._v__ast__Interface).parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(g->table, (*st_sym->info._v__ast__Interface).parent_type); for (int _t17 = 0; _t17 < parent_sym->methods.len; ++_t17) { v__ast__Fn method = ((v__ast__Fn*)parent_sym->methods.data)[_t17]; if (_IN_MAP(ADDR(string, method.name), ADDR(map, methodidx))) { _option_v__ast__Fn _t19 = v__ast__TypeSymbol_find_method_with_generic_parent(st_sym, method.name); if (_t19.state != 0) { IError err = _t19.err; continue; } array_push((array*)&methods, _MOV((v__ast__Fn[]){ (*(v__ast__Fn*)_t19.data) })); } } } } else if (st_sym->info._typ == 544 /* v.ast.SumType */) { if (v__ast__Type_has_flag((*st_sym->info._v__ast__SumType).parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(g->table, (*st_sym->info._v__ast__SumType).parent_type); for (int _t20 = 0; _t20 < parent_sym->methods.len; ++_t20) { v__ast__Fn method = ((v__ast__Fn*)parent_sym->methods.data)[_t20]; if (_IN_MAP(ADDR(string, method.name), ADDR(map, methodidx))) { _option_v__ast__Fn _t22 = v__ast__TypeSymbol_find_method_with_generic_parent(st_sym, method.name); if (_t22.state != 0) { IError err = _t22.err; continue; } array_push((array*)&methods, _MOV((v__ast__Fn[]){ (*(v__ast__Fn*)_t22.data) })); } } } } else if (st_sym->info._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(g->table, (*st_sym->info._v__ast__Alias).parent_type); if (parent_sym->info._typ == 518 /* v.ast.Struct */) { Array_string _t23 = {0}; Array_v__ast__Fn _t23_orig = methods; int _t23_len = _t23_orig.len; _t23 = __new_array(0, _t23_len, sizeof(string)); for (int _t25 = 0; _t25 < _t23_len; ++_t25) { v__ast__Fn it = ((v__ast__Fn*) _t23_orig.data)[_t25]; string _t24 = it.name; array_push((array*)&_t23, &_t24); } Array_string t_method_names =_t23; for (int _t26 = 0; _t26 < parent_sym->methods.len; ++_t26) { v__ast__Fn method = ((v__ast__Fn*)parent_sym->methods.data)[_t26]; if (_IN_MAP(ADDR(string, method.name), ADDR(map, methodidx))) { _option_v__ast__Fn _t27 = v__ast__TypeSymbol_find_method_with_generic_parent(parent_sym, method.name); if (_t27.state != 0) { IError err = _t27.err; continue; } v__ast__Fn parent_method = (*(v__ast__Fn*)_t27.data); if (!_IN_MAP(ADDR(string, parent_method.name), ADDR(map, methodidx))) { continue; } if (!(Array_string_contains(t_method_names, parent_method.name))) { array_push((array*)&methods, _MOV((v__ast__Fn[]){ parent_method })); array_push((array*)&aliased_method_names, _MOV((string[]){ string_clone(parent_method.name) })); array_push((array*)&t_method_names, _MOV((string[]){ string_clone(parent_method.name) })); } } } } else if (parent_sym->info._typ == 542 /* v.ast.Interface */) { Array_string _t31 = {0}; Array_v__ast__Fn _t31_orig = methods; int _t31_len = _t31_orig.len; _t31 = __new_array(0, _t31_len, sizeof(string)); for (int _t33 = 0; _t33 < _t31_len; ++_t33) { v__ast__Fn it = ((v__ast__Fn*) _t31_orig.data)[_t33]; string _t32 = it.name; array_push((array*)&_t31, &_t32); } Array_string t_method_names =_t31; for (int _t34 = 0; _t34 < parent_sym->methods.len; ++_t34) { v__ast__Fn method = ((v__ast__Fn*)parent_sym->methods.data)[_t34]; if (_IN_MAP(ADDR(string, method.name), ADDR(map, methodidx))) { _option_v__ast__Fn _t35 = v__ast__TypeSymbol_find_method_with_generic_parent(parent_sym, method.name); if (_t35.state != 0) { IError err = _t35.err; continue; } v__ast__Fn parent_method = (*(v__ast__Fn*)_t35.data); if (!_IN_MAP(ADDR(string, parent_method.name), ADDR(map, methodidx))) { continue; } if (!(Array_string_contains(t_method_names, parent_method.name))) { array_push((array*)&methods, _MOV((v__ast__Fn[]){ parent_method })); array_push((array*)&aliased_method_names, _MOV((string[]){ string_clone(parent_method.name) })); array_push((array*)&t_method_names, _MOV((string[]){ string_clone(parent_method.name) })); } } } } else if (parent_sym->info._typ == 544 /* v.ast.SumType */) { Array_string _t39 = {0}; Array_v__ast__Fn _t39_orig = methods; int _t39_len = _t39_orig.len; _t39 = __new_array(0, _t39_len, sizeof(string)); for (int _t41 = 0; _t41 < _t39_len; ++_t41) { v__ast__Fn it = ((v__ast__Fn*) _t39_orig.data)[_t41]; string _t40 = it.name; array_push((array*)&_t39, &_t40); } Array_string t_method_names =_t39; for (int _t42 = 0; _t42 < parent_sym->methods.len; ++_t42) { v__ast__Fn method = ((v__ast__Fn*)parent_sym->methods.data)[_t42]; if (_IN_MAP(ADDR(string, method.name), ADDR(map, methodidx))) { _option_v__ast__Fn _t43 = v__ast__TypeSymbol_find_method_with_generic_parent(parent_sym, method.name); if (_t43.state != 0) { IError err = _t43.err; continue; } v__ast__Fn parent_method = (*(v__ast__Fn*)_t43.data); if (!_IN_MAP(ADDR(string, parent_method.name), ADDR(map, methodidx))) { continue; } if (!(Array_string_contains(t_method_names, parent_method.name))) { array_push((array*)&methods, _MOV((v__ast__Fn[]){ parent_method })); array_push((array*)&aliased_method_names, _MOV((string[]){ string_clone(parent_method.name) })); array_push((array*)&t_method_names, _MOV((string[]){ string_clone(parent_method.name) })); } } } } else { } } else { } Array_v__ast__Fn t_methods = v__ast__Table_get_embed_methods(g->table, st_sym); Array_string _t47 = {0}; Array_v__ast__Fn _t47_orig = methods; int _t47_len = _t47_orig.len; _t47 = __new_array(0, _t47_len, sizeof(string)); for (int _t49 = 0; _t49 < _t47_len; ++_t49) { v__ast__Fn it = ((v__ast__Fn*) _t47_orig.data)[_t49]; string _t48 = it.name; array_push((array*)&_t47, &_t48); } Array_string t_method_names =_t47; for (int _t50 = 0; _t50 < t_methods.len; ++_t50) { v__ast__Fn t_method = ((v__ast__Fn*)t_methods.data)[_t50]; if (!(Array_string_contains(t_method_names, t_method.name))) { array_push((array*)&methods, _MOV((v__ast__Fn[]){ t_method })); array_push((array*)&t_method_names, _MOV((string[]){ string_clone(t_method.name) })); } } Array_v__ast__Fn ordered_methods = array_clone_to_depth(&methods, 0); if (ordered_methods.len > 0) { qsort(ordered_methods.data, ordered_methods.len, ordered_methods.element_size, (voidptr)compare_17767866704287204994_v__ast__Fn_by_name); } ; for (int _t53 = 0; _t53 < ordered_methods.len; ++_t53) { v__ast__Fn method = ((v__ast__Fn*)ordered_methods.data)[_t53]; string name = method.name; if (method.generic_names.len > 0 && v__ast__Type_has_flag(inter_info.parent_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(g->table, inter_info.parent_type); if (parent_sym->info._typ == 518 /* v.ast.Struct */) { name = v__gen__c__Gen_generic_fn_name(g, (*parent_sym->info._v__ast__Struct).concrete_types, method.name); } else if (parent_sym->info._typ == 542 /* v.ast.Interface */) { name = v__gen__c__Gen_generic_fn_name(g, (*parent_sym->info._v__ast__Interface).concrete_types, method.name); } else if (parent_sym->info._typ == 544 /* v.ast.SumType */) { name = v__gen__c__Gen_generic_fn_name(g, (*parent_sym->info._v__ast__SumType).concrete_types, method.name); } else { } } if (!_IN_MAP(ADDR(string, method.name), ADDR(map, methodidx))) { continue; } if ((st_sym->info)._typ == 518 /* v.ast.Struct */) { if (method.generic_names.len > 0 && v__ast__Type_has_flag((*st_sym->info._v__ast__Struct).parent_type, v__ast__TypeFlag__generic)) { name = v__gen__c__Gen_generic_fn_name(g, (*st_sym->info._v__ast__Struct).concrete_types, method.name); } } string styp = v__gen__c__Gen_cc_type(g, (*(v__ast__Param*)array_get(method.params, 0)).typ, true); string method_call = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S("_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); if (string__eq(cctype, cctype2) && !v__ast__Type_is_ptr((*(v__ast__Param*)array_get(method.params, 0)).typ)) { if (!(Array_string_contains(aliased_method_names, method.name))) { method_call = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = cctype}}, {_S("_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); } else { method_call = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S("_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); } string iwpostfix = str_intp(2, _MOV((StrIntpData[]){{_S("_Interface_"), 0xfe10, {.d_s = interface_name}}, {_S("_method_wrapper"), 0, { .d_c = 0 }}})); { strings__Builder_write_string(&methods_wrapper, _S("static inline ")); strings__Builder_write_string(&methods_wrapper, v__gen__c__Gen_ret_styp(g, method.return_type)); strings__Builder_write_string(&methods_wrapper, _S(" ")); strings__Builder_write_string(&methods_wrapper, cctype); strings__Builder_write_string(&methods_wrapper, _S("_")); strings__Builder_write_string(&methods_wrapper, name); strings__Builder_write_string(&methods_wrapper, iwpostfix); strings__Builder_write_string(&methods_wrapper, _S("(")); } int params_start_pos = g->out.len; Array_v__ast__Param params = array_clone_to_depth(&method.params, 0); array_set(¶ms, 0, &(v__ast__Param[]) { ((v__ast__Param){.pos = ((*(v__ast__Param*)array_get(params, 0))).pos,.name = ((*(v__ast__Param*)array_get(params, 0))).name,.is_mut = ((*(v__ast__Param*)array_get(params, 0))).is_mut,.is_shared = ((*(v__ast__Param*)array_get(params, 0))).is_shared,.is_atomic = ((*(v__ast__Param*)array_get(params, 0))).is_atomic,.type_pos = ((*(v__ast__Param*)array_get(params, 0))).type_pos,.is_hidden = ((*(v__ast__Param*)array_get(params, 0))).is_hidden,.on_newline = ((*(v__ast__Param*)array_get(params, 0))).on_newline,.typ = v__ast__Type_set_nr_muls(st, 1),}) }); multi_return_Array_string_Array_string_Array_bool mr_262431 = v__gen__c__Gen_fn_decl_params(g, params, ((void*)0), false, false); Array_string fargs = mr_262431.arg0; string parameter_name = strings__Builder_cut_last(&g->out, (int)(g->out.len - params_start_pos)); if (v__ast__Type_is_ptr(st)) { parameter_name = string_trim_string_left(parameter_name, _S("__shared__")); } strings__Builder_write_string(&methods_wrapper, parameter_name); strings__Builder_writeln(&methods_wrapper, _S(") {")); strings__Builder_write_string(&methods_wrapper, _S("\t")); if (method.return_type != _const_v__ast__void_type) { strings__Builder_write_string(&methods_wrapper, _S("return ")); } _result_multi_return_v__ast__Fn_Array_v__ast__Type _t54 = v__ast__Table_find_method_from_embeds(g->table, st_sym, method.name); if (_t54.is_error) { IError err = _t54.err; *(multi_return_v__ast__Fn_Array_v__ast__Type*) _t54.data = (multi_return_v__ast__Fn_Array_v__ast__Type){.arg0=((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } multi_return_v__ast__Fn_Array_v__ast__Type mr_262906 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t54.data); Array_v__ast__Type embed_types = mr_262906.arg1; if (embed_types.len > 0 && !(Array_string_contains(method_names, method.name))) { v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_last(embed_types))); string method_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = embed_sym->cname}}, {_S("_"), 0xfe10, {.d_s = method.name}}, {_SLIT0, 0, { .d_c = 0 }}})); { strings__Builder_write_string(&methods_wrapper, method_name); strings__Builder_write_string(&methods_wrapper, _S("(")); strings__Builder_write_string(&methods_wrapper, (*(string*)array_get(fargs, 0))); } for (int idx_embed = 0; idx_embed < embed_types.len; ++idx_embed) { v__ast__Type embed = ((v__ast__Type*)embed_types.data)[idx_embed]; v__ast__TypeSymbol* esym = v__ast__Table_sym(g->table, embed); if (idx_embed == 0 || v__ast__Type_is_any_kind_of_pointer((*(v__ast__Type*)array_get(embed_types, (int)(idx_embed - 1))))) { { strings__Builder_write_string(&methods_wrapper, _S("->")); strings__Builder_write_string(&methods_wrapper, v__ast__TypeSymbol_embed_name(esym)); } } else { { strings__Builder_write_string(&methods_wrapper, _S(".")); strings__Builder_write_string(&methods_wrapper, v__ast__TypeSymbol_embed_name(esym)); } } } if (fargs.len > 1) { strings__Builder_write_string(&methods_wrapper, _S(", ")); } string args = Array_string_join(array_slice(fargs, 1, 2147483647), _S(", ")); strings__Builder_writeln(&methods_wrapper, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = args}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { if (string_starts_with(parameter_name, _S("__shared__"))) { strings__Builder_writeln(&methods_wrapper, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = method_call}}, {_S("("), 0xfe10, {.d_s = Array_string_join(fargs, _S(", "))}}, {_S("->val);"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&methods_wrapper, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = method_call}}, {_S("(*"), 0xfe10, {.d_s = Array_string_join(fargs, _S(", "))}}, {_S(");"), 0, { .d_c = 0 }}}))); } } strings__Builder_writeln(&methods_wrapper, _S("}")); method_call = string__plus(method_call, iwpostfix); } if (g->pref->build_mode != v__pref__BuildMode__build_module && st != _const_v__ast__voidptr_type && st != _const_v__ast__nil_type) { strings__Builder_writeln(&methods_struct, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t._method_"), 0xfe10, {.d_s = v__gen__c__c_fn_name(method.name)}}, {_S(" = (void*) "), 0xfe10, {.d_s = method_call}}, {_S(","), 0, { .d_c = 0 }}}))); } } if (g->pref->build_mode != v__pref__BuildMode__build_module) { strings__Builder_writeln(&methods_struct, _S("\t},")); } int iin_idx = (int)((*(int*)map_get(ADDR(map, already_generated_mwrappers), &(string[]){interface_index_name}, &(int[]){ 0 })) - iinidx_minimum_base); if (g->pref->build_mode != v__pref__BuildMode__build_module) { strings__Builder_writeln(&sb, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_modifier}}, {_S("const int "), 0xfe10, {.d_s = interface_index_name}}, {_S(" = "), 0xfe07, {.d_i32 = iin_idx}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&sb, str_intp(2, _MOV((StrIntpData[]){{_S("extern const int "), 0xfe10, {.d_s = interface_index_name}}, {_S(";"), 0, { .d_c = 0 }}}))); } } __shared__Map_int_Array_v__ast__Type* _t55 = inter_info.conversions; int _t57 = _t55->val.key_values.len; for (int _t56 = 0; _t56 < _t57; ++_t56 ) { int _t58 = _t55->val.key_values.len - _t57; _t57 = _t55->val.key_values.len; if (_t58 < 0) { _t56 = -1; continue; } if (!DenseArray_has_index(&_t55->val.key_values, _t56)) {continue;} int vtyp = *(int*)DenseArray_key(&_t55->val.key_values, _t56); Array_v__ast__Type variants = (*(Array_v__ast__Type*)DenseArray_value(&_t55->val.key_values, _t56)); v__ast__TypeSymbol* vsym = v__ast__Table_sym(g->table, v__ast__idx_to_type(vtyp)); if (variants.len > 0) { { strings__Builder_write_string(&conversion_functions, _S("static inline bool I_")); strings__Builder_write_string(&conversion_functions, interface_name); strings__Builder_write_string(&conversion_functions, _S("_is_I_")); strings__Builder_write_string(&conversion_functions, vsym->cname); strings__Builder_write_string(&conversion_functions, _S("(")); strings__Builder_write_string(&conversion_functions, interface_name); strings__Builder_write_string(&conversion_functions, _S(" x) {\n\treturn ")); } for (int i = 0; i < variants.len; ++i) { v__ast__Type variant = ((v__ast__Type*)variants.data)[i]; v__ast__TypeSymbol* variant_sym = v__ast__Table_sym(g->table, variant); if (g->pref->skip_unused && variant_sym->kind == v__ast__Kind__struct && !_IN_MAP(ADDR(int, variant_sym->idx), ADDR(map, g->table->used_features->used_syms))) { continue; } if (i > 0) { strings__Builder_write_string(&conversion_functions, _S(" || ")); } { strings__Builder_write_string(&conversion_functions, _S("(x._typ == _")); strings__Builder_write_string(&conversion_functions, interface_name); strings__Builder_write_string(&conversion_functions, _S("_")); strings__Builder_write_string(&conversion_functions, variant_sym->cname); strings__Builder_write_string(&conversion_functions, _S("_index)")); } } strings__Builder_writeln(&conversion_functions, _S(";\n}")); } strings__Builder_writeln(&conversion_functions, str_intp(5, _MOV((StrIntpData[]){{_S("static inline "), 0xfe10, {.d_s = vsym->cname}}, {_S(" I_"), 0xfe10, {.d_s = interface_name}}, {_S("_as_I_"), 0xfe10, {.d_s = vsym->cname}}, {_S("("), 0xfe10, {.d_s = interface_name}}, {_S(" x) {"), 0, { .d_c = 0 }}}))); for (int _t59 = 0; _t59 < variants.len; ++_t59) { v__ast__Type variant = ((v__ast__Type*)variants.data)[_t59]; v__ast__TypeSymbol* variant_sym = v__ast__Table_sym(g->table, variant); strings__Builder_writeln(&conversion_functions, str_intp(6, _MOV((StrIntpData[]){{_S("\tif (x._typ == _"), 0xfe10, {.d_s = interface_name}}, {_S("_"), 0xfe10, {.d_s = variant_sym->cname}}, {_S("_index) return I_"), 0xfe10, {.d_s = variant_sym->cname}}, {_S("_to_Interface_"), 0xfe10, {.d_s = vsym->cname}}, {_S("(x._"), 0xfe10, {.d_s = variant_sym->cname}}, {_S(");"), 0, { .d_c = 0 }}}))); } string pmessage = str_intp(3, _MOV((StrIntpData[]){{_S("string__plus(string__plus(tos3(\"`as_cast`: cannot convert \"), tos3(v_typeof_interface_"), 0xfe10, {.d_s = interface_name}}, {_S("(x._typ))), tos3(\" to "), 0xfe10, {.d_s = v__util__strip_main_name(vsym->name)}}, {_S("\"))"), 0, { .d_c = 0 }}})); if (g->pref->is_debug) { strings__Builder_write_string2(&conversion_functions, _S("\tpanic_debug(1, tos3(\"builtin.v\"), tos3(\"builtin\"), tos3(\"__as_cast\"), "), pmessage); strings__Builder_writeln(&conversion_functions, _S(");")); } else { strings__Builder_write_string2(&conversion_functions, _S("\t_v_panic("), pmessage); strings__Builder_writeln(&conversion_functions, _S(");")); } strings__Builder_writeln2(&conversion_functions, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn ("), 0xfe10, {.d_s = vsym->cname}}, {_S("){0};"), 0, { .d_c = 0 }}})), _S("}")); } if (!g->pref->is_prod) { strings__Builder_writeln(&sb, str_intp(3, _MOV((StrIntpData[]){{_S("// ^^^ number of types for interface "), 0xfe10, {.d_s = interface_name}}, {_S(": "), 0xfe07, {.d_i32 = (int)(current_iinidx - iinidx_minimum_base)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (iname_table_length == 0) { strings__Builder_writeln(&methods_struct, _S("")); } else { if (g->pref->build_mode != v__pref__BuildMode__build_module) { strings__Builder_writeln(&methods_struct, _S("};")); } } strings__Builder_writeln(&sb, _S("")); if (inter_methods.len > 0) { strings__Builder_writeln2(&sb, strings__Builder_str(&methods_wrapper), strings__Builder_str(&methods_struct_def)); strings__Builder_writeln(&sb, strings__Builder_str(&methods_struct)); } if (cast_functions.len > 0) { strings__Builder_writeln(&sb, strings__Builder_str(&cast_functions)); } } if (conversion_functions.len > 0) { strings__Builder_writeln(&sb, strings__Builder_str(&conversion_functions)); } string _t60 = strings__Builder_str(&sb); // Defer begin if (v__gen__c__Gen_interface_table_defer_0) { v__util__timing_measure(_S("Gen.interface_table")); } // Defer end return _t60; } VV_LOC multi_return_int_string_string_string v__gen__c__Gen_panic_debug_info(v__gen__c__Gen* g, v__token__Pos pos) { int paline = (int)(pos.line_nr + 1); if (g->fn_decl == ((void*)0)) { return (multi_return_int_string_string_string){.arg0=paline, .arg1=_S(""), .arg2=_S("main"), .arg3=_S("C._vinit")}; } string pafile = string_replace(g->fn_decl->file, _S("\\"), _S("/")); string pafn = string_after(g->fn_decl->name, _S(".")); string pamod = v__ast__FnDecl_modname(g->fn_decl); return (multi_return_int_string_string_string){.arg0=paline, .arg1=pafile, .arg2=pamod, .arg3=pafn}; } string v__gen__c__get_guarded_include_text(string iname, string imessage) { string res = string_strip_margin(str_intp(5, _MOV((StrIntpData[]){{_S("\n\011|#if defined(__has_include)\n\011|\n\011|#if __has_include("), 0xfe10, {.d_s = iname}}, {_S(")\n\011|#include "), 0xfe10, {.d_s = iname}}, {_S("\n\011|#else\n\011|#error VERROR_MESSAGE "), 0xfe10, {.d_s = imessage}}, {_S("\n\011|#endif\n\011|\n\011|#else\n\011|#include "), 0xfe10, {.d_s = iname}}, {_S("\n\011|#endif\n\011"), 0, { .d_c = 0 }}}))); return res; } string v__gen__c__Gen_ret_styp(v__gen__c__Gen* g, v__ast__Type typ) { string ret_styp = v__gen__c__Gen_styp(g, typ); if (!v__ast__Type_has_option_or_result(typ)) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(g->table, typ); if ((ret_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && !(*(v__ast__ArrayFixed*)__as_cast((ret_sym->info)._v__ast__ArrayFixed,(ret_sym->info)._typ, 549)).is_fn_ret) { ret_styp = str_intp(2, _MOV((StrIntpData[]){{_S("_v_"), 0xfe10, {.d_s = ret_styp}}, {_SLIT0, 0, { .d_c = 0 }}})); } else if ((ret_sym->info)._typ == 539 /* v.ast.Alias */) { v__ast__TypeSymbol* unalias_sym = v__ast__Table_sym(g->table, (*ret_sym->info._v__ast__Alias).parent_type); if ((unalias_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && !(*(v__ast__ArrayFixed*)__as_cast((unalias_sym->info)._v__ast__ArrayFixed,(unalias_sym->info)._typ, 549)).is_fn_ret) { ret_styp = str_intp(2, _MOV((StrIntpData[]){{_S("_v_"), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, (*ret_sym->info._v__ast__Alias).parent_type)}}, {_SLIT0, 0, { .d_c = 0 }}})); } } } return ret_styp; } int v__gen__c__Gen_get_array_depth(v__gen__c__Gen* g, v__ast__Type el_typ) { v__ast__Type typ = v__gen__c__Gen_unwrap_generic(g, el_typ); v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, typ); if (sym->kind == v__ast__Kind__array) { v__ast__Array info = *(v__ast__Array*)__as_cast((sym->info)._v__ast__Array,(sym->info)._typ, 513); return (int)(1 + v__gen__c__Gen_get_array_depth(g, info.elem_type)); } else { return 0; } return 0; } bool v__gen__c__Gen_contains_ptr(v__gen__c__Gen* g, v__ast__Type el_typ) { bool* _t2 = (bool*)(map_get_check(ADDR(map, g->contains_ptr_cache), &(v__ast__Type[]){el_typ})); _option_bool _t1 = {0}; if (_t2) { *((bool*)&_t1.data) = *((bool*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { bool t_typ = (*(bool*)_t1.data); return t_typ; } if (v__ast__Type_is_any_kind_of_pointer(el_typ)) { map_set(&g->contains_ptr_cache, &(v__ast__Type[]){el_typ}, &(bool[]) { true }); return true; } v__ast__Type typ = v__gen__c__Gen_unwrap_generic(g, el_typ); if (v__ast__Type_is_ptr(typ)) { return true; } v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, typ); if (sym->language != v__ast__Language__v) { map_set(&g->contains_ptr_cache, &(v__ast__Type[]){typ}, &(bool[]) { true }); return true; } switch (sym->kind) { case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__bool: case v__ast__Kind__enum: { map_set(&g->contains_ptr_cache, &(v__ast__Type[]){typ}, &(bool[]) { false }); return false; } case v__ast__Kind__array_fixed: { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549); return v__gen__c__Gen_contains_ptr(g, info.elem_type); } case v__ast__Kind__struct: { v__ast__Struct info = *(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518); for (int _t9 = 0; _t9 < info.embeds.len; ++_t9) { v__ast__Type embed = ((v__ast__Type*)info.embeds.data)[_t9]; if (v__gen__c__Gen_contains_ptr(g, embed)) { return true; } } for (int _t11 = 0; _t11 < info.fields.len; ++_t11) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[_t11]; if (v__gen__c__Gen_contains_ptr(g, field.typ)) { return true; } } return false; } case v__ast__Kind__aggregate: { v__ast__Aggregate info = *(v__ast__Aggregate*)__as_cast((sym->info)._v__ast__Aggregate,(sym->info)._typ, 537); for (int _t14 = 0; _t14 < info.types.len; ++_t14) { v__ast__Type atyp = ((v__ast__Type*)info.types.data)[_t14]; if (v__gen__c__Gen_contains_ptr(g, atyp)) { return true; } } return false; } case v__ast__Kind__multi_return: { v__ast__MultiReturn info = *(v__ast__MultiReturn*)__as_cast((sym->info)._v__ast__MultiReturn,(sym->info)._typ, 552); for (int _t17 = 0; _t17 < info.types.len; ++_t17) { v__ast__Type mrtyp = ((v__ast__Type*)info.types.data)[_t17]; if (v__gen__c__Gen_contains_ptr(g, mrtyp)) { return true; } } return false; } case v__ast__Kind__placeholder: case v__ast__Kind__void: case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__i32: case v__ast__Kind__isize: case v__ast__Kind__usize: case v__ast__Kind__none: case v__ast__Kind__string: case v__ast__Kind__array: case v__ast__Kind__map: case v__ast__Kind__chan: case v__ast__Kind__any: case v__ast__Kind__generic_inst: case v__ast__Kind__sum_type: case v__ast__Kind__alias: case v__ast__Kind__function: case v__ast__Kind__interface: case v__ast__Kind__float_literal: case v__ast__Kind__int_literal: case v__ast__Kind__thread: default: { { map_set(&g->contains_ptr_cache, &(v__ast__Type[]){typ}, &(bool[]) { true }); return true; } } } return 0; } VV_LOC string v__gen__c__Gen_check_noscan(v__gen__c__Gen* g, v__ast__Type elem_typ) { if (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full_opt || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt) { if (!v__gen__c__Gen_contains_ptr(g, elem_typ)) { return _S("_noscan"); } } return _S(""); } void v__gen__c__Gen_gen_c_main(v__gen__c__Gen* g) { if (!g->has_main) { return; } if (g->pref->is_liveshared) { return; } if (g->pref->is_o) { return; } if ((Array_string_contains(g->pref->compile_defines, _S("no_main")))) { return; } strings__Builder_writeln(&g->out, _S("")); int main_fn_start_pos = g->out.len; bool is_sokol = (Array_string_contains(g->table->imports, _S("sokol"))); if ((g->pref->os == v__pref__OS__android && g->pref->is_apk) || (g->pref->os == v__pref__OS__ios && is_sokol)) { v__gen__c__Gen_gen_c_android_sokol_main(g); } else { v__gen__c__Gen_gen_c_main_header(g); v__gen__c__Gen_writeln(g, _S("\tmain__main();")); v__gen__c__Gen_gen_c_main_footer(g); if (g->pref->printfn_list.len > 0 && (Array_string_contains(g->pref->printfn_list, _S("main")))) { println(strings__Builder_after(&g->out, main_fn_start_pos)); } } } VV_LOC void v__gen__c__Gen_gen_vlines_reset(v__gen__c__Gen* g) { if (g->pref->is_vlines) { g->vlines_path = v__util__vlines_escape_path(g->pref->out_name_c, g->pref->ccompiler); v__gen__c__Gen_writeln2(g, _S(""), _S("// Reset the C file/line numbers")); v__gen__c__Gen_writeln2(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__reset_dbg_line}}, {_S(" \""), 0xfe10, {.d_s = g->vlines_path}}, {_S("\""), 0, { .d_c = 0 }}})), _S("")); } } strings__Builder v__gen__c__fix_reset_dbg_line(strings__Builder src, string out_file) { bool v__gen__c__fix_reset_dbg_line_defer_0 = false; v__util__timing_start(_S("fix_reset_dbg_line")); v__gen__c__fix_reset_dbg_line_defer_0 = true; int dbg_reset_line_idx = 0; int lines = 2; for (int idx = 0; idx < src.len; ++idx) { u8 ob = ((u8*)src.data)[idx]; if (ob == '\n') { lines++; if (vmemcmp(((u8*)(src.data)) + idx + 1, _const_v__gen__c__reset_dbg_line.str, _const_v__gen__c__reset_dbg_line.len) == 0) { dbg_reset_line_idx = (int)(idx + 1); break; } } } int first_quote_idx = 0; for (int idx = dbg_reset_line_idx; idx < src.len; idx++) { if (((u8*)(src.data))[idx] == '"') { first_quote_idx = idx; break; } } strings__Builder sb = strings__new_builder(src.len); { // Unsafe block strings__Builder_write_ptr(&sb, ((u8*)(src.data)), dbg_reset_line_idx); strings__Builder_write_string(&sb, _S("#line ")); strings__Builder_write_decimal(&sb, lines); strings__Builder_write_ptr(&sb, ((u8*)(src.data)) + first_quote_idx - 1, (int)(src.len - first_quote_idx)); } #if defined(CUSTOM_DEFINE_trace_reset_dbg_line) { eprintln(str_intp(7, _MOV((StrIntpData[]){{_S("> reset_dbg_line: "), 0xfe10, {.d_s = out_file}}, {_S(":"), 0xfe07, {.d_i32 = lines}}, {_S(" | first_quote_idx: "), 0xfe07, {.d_i32 = first_quote_idx}}, {_S(" | src.len: "), 0xfe07, {.d_i32 = src.len}}, {_S(" | sb.len: "), 0xfe07, {.d_i32 = sb.len}}, {_S(" | sb.cap: "), 0xfe07, {.d_i32 = sb.cap}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif strings__Builder _t2 = sb; // Defer begin if (v__gen__c__fix_reset_dbg_line_defer_0) { v__util__timing_measure(_S("fix_reset_dbg_line")); } // Defer end return _t2; } VV_LOC void v__gen__c__Gen_gen_c_main_function_only_header(v__gen__c__Gen* g) { if ((g->pref->cmain).len != 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("int "), 0xfe10, {.d_s = g->pref->cmain}}, {_S("(int ___argc, char** ___argv){"), 0, { .d_c = 0 }}}))); return; } if (g->pref->os == v__pref__OS__windows) { if (v__gen__c__Gen_is_gui_app(g)) { #if defined(_MSC_VER) { v__gen__c__Gen_writeln(g, _S("#pragma comment(linker, \"/SUBSYSTEM:WINDOWS\")")); } #endif v__gen__c__Gen_writeln(g, _S("int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, LPWSTR cmd_line, int show_cmd){")); v__gen__c__Gen_writeln(g, _S("\tLPWSTR full_cmd_line = GetCommandLineW(); // Note: do not use cmd_line")); v__gen__c__Gen_writeln(g, _S("\ttypedef LPWSTR*(WINAPI *cmd_line_to_argv)(LPCWSTR, int*);")); v__gen__c__Gen_writeln(g, _S("\tHMODULE shell32_module = LoadLibrary(L\"shell32.dll\");")); v__gen__c__Gen_writeln(g, _S("\tcmd_line_to_argv CommandLineToArgvW = (cmd_line_to_argv)GetProcAddress(shell32_module, \"CommandLineToArgvW\");")); v__gen__c__Gen_writeln(g, _S("\tint ___argc;")); v__gen__c__Gen_writeln(g, _S("\twchar_t** ___argv = CommandLineToArgvW(full_cmd_line, &___argc);")); v__gen__c__Gen_writeln(g, _S("BOOL con_valid = FALSE;")); if (g->force_main_console) { v__gen__c__Gen_writeln(g, _S("con_valid = AllocConsole();")); } else { v__gen__c__Gen_writeln(g, _S("con_valid = AttachConsole(ATTACH_PARENT_PROCESS);")); } v__gen__c__Gen_writeln(g, _S("if (con_valid) {")); v__gen__c__Gen_writeln(g, _S("\tFILE* res_fp = 0;")); v__gen__c__Gen_writeln(g, _S("\terrno_t err;")); v__gen__c__Gen_writeln(g, _S("\terr = freopen_s(&res_fp, \"CON\", \"w\", stdout);")); v__gen__c__Gen_writeln(g, _S("\terr = freopen_s(&res_fp, \"CON\", \"w\", stderr);")); v__gen__c__Gen_writeln(g, _S("\t(void)err;")); v__gen__c__Gen_writeln(g, _S("}")); return; } v__gen__c__Gen_writeln(g, _S("int wmain(int ___argc, wchar_t* ___argv[], wchar_t* ___envp[]){")); return; } v__gen__c__Gen_writeln(g, _S("int main(int ___argc, char** ___argv){")); } VV_LOC void v__gen__c__Gen_gen_c_main_function_header(v__gen__c__Gen* g) { v__gen__c__Gen_gen_c_main_function_only_header(g); v__gen__c__Gen_gen_c_main_trace_calls_hook(g); if (!g->pref->no_builtin) { _option_v__ast__GlobalField_ptr _t1; if (_t1 = v__ast__Scope_find_global(g->table->global_scope, _S("g_main_argc")), _t1.state == 0) { v__gen__c__Gen_writeln(g, _S("\tg_main_argc = ___argc;")); } _option_v__ast__GlobalField_ptr _t2; if (_t2 = v__ast__Scope_find_global(g->table->global_scope, _S("g_main_argv")), _t2.state == 0) { v__gen__c__Gen_writeln(g, _S("\tg_main_argv = ___argv;")); } } } VV_LOC void v__gen__c__Gen_gen_c_main_header(v__gen__c__Gen* g) { v__gen__c__Gen_gen_c_main_function_header(g); if (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full_opt || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_leak) { v__gen__c__Gen_writeln(g, _S("#if defined(_VGCBOEHM)")); if (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_leak) { v__gen__c__Gen_writeln(g, _S("\tGC_set_find_leak(1);")); } v__gen__c__Gen_writeln(g, _S("\tGC_set_pages_executable(0);")); if (g->pref->use_coroutines) { v__gen__c__Gen_writeln(g, _S("\tGC_allow_register_threads();")); } v__gen__c__Gen_writeln(g, _S("\tGC_INIT();")); if (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt) { v__gen__c__Gen_writeln(g, _S("\tGC_enable_incremental();")); } v__gen__c__Gen_writeln(g, _S("#endif")); } if (!g->pref->no_builtin) { v__gen__c__Gen_writeln(g, _S("\t_vinit(___argc, (voidptr)___argv);")); } v__gen__c__Gen_gen_c_main_profile_hook(g); if (g->pref->is_livemain) { v__gen__c__Gen_generate_hotcode_reloading_main_caller(g); } } void v__gen__c__Gen_gen_c_main_footer(v__gen__c__Gen* g) { if (!g->pref->no_builtin) { v__gen__c__Gen_writeln(g, _S("\t_vcleanup();")); } v__gen__c__Gen_writeln2(g, _S("\treturn 0;"), _S("}")); } void v__gen__c__Gen_gen_c_android_sokol_main(v__gen__c__Gen* g) { if (g->is_autofree) { v__gen__c__Gen_writeln(g, _S("// Wrapping cleanup/free callbacks for sokol to include _vcleanup()\nvoid (*_vsokol_user_cleanup_ptr)(void);\nvoid (*_vsokol_user_cleanup_cb_ptr)(void *);\n\nvoid (_vsokol_cleanup_cb)(void) {\n\011if (_vsokol_user_cleanup_ptr) {\n\011\011_vsokol_user_cleanup_ptr();\n\011}\n\011_vcleanup();\n}\n\nvoid (_vsokol_cleanup_userdata_cb)(void* user_data) {\n\011if (_vsokol_user_cleanup_cb_ptr) {\n\011\011_vsokol_user_cleanup_cb_ptr(g_desc.user_data);\n\011}\n\011_vcleanup();\n}\n")); } v__gen__c__Gen_writeln(g, _S("// The sokol_main entry point on Android\nsapp_desc sokol_main(int argc, char* argv[]) {\n\011(void)argc; (void)argv;")); v__gen__c__Gen_gen_c_main_trace_calls_hook(g); if (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full_opt || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_leak) { v__gen__c__Gen_writeln(g, _S("#if defined(_VGCBOEHM)")); if (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_leak) { v__gen__c__Gen_writeln(g, _S("\tGC_set_find_leak(1);")); } v__gen__c__Gen_writeln2(g, _S("\tGC_set_pages_executable(0);"), _S("\tGC_INIT();")); if (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt) { v__gen__c__Gen_writeln(g, _S("\tGC_enable_incremental();")); } v__gen__c__Gen_writeln(g, _S("#endif")); } if (!g->pref->no_builtin) { v__gen__c__Gen_writeln(g, _S("\t_vinit(argc, (voidptr)argv);")); } v__gen__c__Gen_gen_c_main_profile_hook(g); v__gen__c__Gen_writeln(g, _S("\tmain__main();")); if (g->is_autofree) { v__gen__c__Gen_writeln(g, _S("\011// Wrap user provided cleanup/free functions for sokol to be able to call _vcleanup()\n\011if (g_desc.cleanup_cb) {\n\011\011_vsokol_user_cleanup_ptr = g_desc.cleanup_cb;\n\011\011g_desc.cleanup_cb = _vsokol_cleanup_cb;\n\011}\n\011else if (g_desc.cleanup_userdata_cb) {\n\011\011_vsokol_user_cleanup_cb_ptr = g_desc.cleanup_userdata_cb;\n\011\011g_desc.cleanup_userdata_cb = _vsokol_cleanup_userdata_cb;\n\011}\n")); } v__gen__c__Gen_writeln2(g, _S("\011return g_desc;"), _S("}")); } void v__gen__c__Gen_write_tests_definitions(v__gen__c__Gen* g) { strings__Builder_writeln(&g->includes, _S("#include // write_tests_main")); strings__Builder_writeln(&g->definitions, _S("jmp_buf g_jump_buffer;")); } void v__gen__c__Gen_gen_failing_error_propagation_for_test_fn(v__gen__c__Gen* g, v__ast__OrExpr or_block, string cvar_name) { multi_return_int_string_string_string mr_7587 = v__gen__c__Gen_panic_debug_info(g, or_block.pos); int paline = mr_7587.arg0; string pafile = mr_7587.arg1; string pamod = mr_7587.arg2; string pafn = mr_7587.arg3; string dot_or_ptr = (_IN_MAP(ADDR(string, cvar_name), ADDR(map, g->tmp_var_ptr)) ? (_S("->")) : (_S("."))); string err_msg = str_intp(5, _MOV((StrIntpData[]){{_S("IError_name_table["), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("err._typ]._method_msg("), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("err._object)"), 0, { .d_c = 0 }}})); v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("\tmain__TestRunner_name_table[test_runner._typ]._method_fn_error(test_runner._object, "), 0xfe07, {.d_i32 = paline}}, {_S(", tos3(\""), 0xfe10, {.d_s = pafile}}, {_S("\"), tos3(\""), 0xfe10, {.d_s = pamod}}, {_S("\"), tos3(\""), 0xfe10, {.d_s = pafn}}, {_S("\"), "), 0xfe10, {.d_s = err_msg}}, {_S(" );"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\tlongjmp(g_jump_buffer, 1);")); } void v__gen__c__Gen_gen_failing_return_error_for_test_fn(v__gen__c__Gen* g, v__ast__Return return_stmt, string cvar_name) { multi_return_int_string_string_string mr_8379 = v__gen__c__Gen_panic_debug_info(g, return_stmt.pos); int paline = mr_8379.arg0; string pafile = mr_8379.arg1; string pamod = mr_8379.arg2; string pafn = mr_8379.arg3; string dot_or_ptr = (_IN_MAP(ADDR(string, cvar_name), ADDR(map, g->tmp_var_ptr)) ? (_S("->")) : (_S("."))); string err_msg = str_intp(5, _MOV((StrIntpData[]){{_S("IError_name_table["), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("err._typ]._method_msg("), 0xfe10, {.d_s = cvar_name}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("err._object)"), 0, { .d_c = 0 }}})); v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("\tmain__TestRunner_name_table[test_runner._typ]._method_fn_error(test_runner._object, "), 0xfe07, {.d_i32 = paline}}, {_S(", tos3(\""), 0xfe10, {.d_s = pafile}}, {_S("\"), tos3(\""), 0xfe10, {.d_s = pamod}}, {_S("\"), tos3(\""), 0xfe10, {.d_s = pafn}}, {_S("\"), "), 0xfe10, {.d_s = err_msg}}, {_S(" );"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\tlongjmp(g_jump_buffer, 1);")); } void v__gen__c__Gen_gen_c_main_profile_hook(v__gen__c__Gen* g) { if (g->pref->is_prof) { v__gen__c__Gen_writeln2(g, _S(""), _S("\tsignal(SIGINT, vprint_profile_stats_on_signal);")); v__gen__c__Gen_writeln(g, _S("\tsignal(SIGTERM, vprint_profile_stats_on_signal);")); v__gen__c__Gen_writeln2(g, _S("\tatexit(vprint_profile_stats);"), _S("")); } if ((g->pref->profile_file).len != 0) { if ((Array_string_contains(g->pref->compile_defines, _S("no_profile_startup")))) { v__gen__c__Gen_writeln(g, _S("vreset_profile_stats();")); } if (g->pref->profile_fns.len > 0) { v__gen__c__Gen_writeln(g, _S("vreset_profile_stats();")); v__gen__c__Gen_writeln(g, _S("v__profile_enabled = false;")); } } } void v__gen__c__Gen_gen_c_main_for_tests(v__gen__c__Gen* g) { int main_fn_start_pos = g->out.len; v__gen__c__Gen_writeln(g, _S("")); v__gen__c__Gen_gen_c_main_function_header(g); if (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full_opt || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_leak) { v__gen__c__Gen_writeln(g, _S("#if defined(_VGCBOEHM)")); if (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_leak) { v__gen__c__Gen_writeln(g, _S("\tGC_set_find_leak(1);")); } v__gen__c__Gen_writeln(g, _S("\tGC_set_pages_executable(0);")); if (g->pref->use_coroutines) { v__gen__c__Gen_writeln(g, _S("\tGC_allow_register_threads();")); } v__gen__c__Gen_writeln(g, _S("\tGC_INIT();")); if (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt) { v__gen__c__Gen_writeln(g, _S("\tGC_enable_incremental();")); } v__gen__c__Gen_writeln(g, _S("#endif")); } v__gen__c__Gen_writeln(g, _S("\tmain__vtest_init();")); if (!g->pref->no_builtin) { v__gen__c__Gen_writeln(g, _S("\t_vinit(___argc, (voidptr)___argv);")); } v__gen__c__Gen_gen_c_main_profile_hook(g); Array_string all_tfuncs = v__gen__c__Gen_get_all_test_function_names(g); all_tfuncs = v__gen__c__Gen_filter_only_matching_fn_names(g, all_tfuncs); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tstring v_test_file = "), 0xfe10, {.d_s = v__gen__c__ctoslit(g->pref->path)}}, {_S(";"), 0, { .d_c = 0 }}}))); if (g->pref->show_asserts) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tmain__BenchedTests bt = main__start_testing("), 0xfe07, {.d_i32 = all_tfuncs.len}}, {_S(", v_test_file);"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln2(g, _S(""), _S("\tstruct _main__TestRunner_interface_methods _vtrunner = main__TestRunner_name_table[test_runner._typ];")); v__gen__c__Gen_writeln2(g, _S("\tvoid * _vtobj = test_runner._object;"), _S("")); v__gen__c__Gen_writeln(g, _S("\tmain__VTestFileMetaInfo_free(test_runner.file_test_info);")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t*(test_runner.file_test_info) = main__vtest_new_filemetainfo(v_test_file, "), 0xfe07, {.d_i32 = all_tfuncs.len}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln2(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t_vtrunner._method_start(_vtobj, "), 0xfe07, {.d_i32 = all_tfuncs.len}}, {_S(");"), 0, { .d_c = 0 }}})), _S("")); for (int tnumber = 0; tnumber < all_tfuncs.len; ++tnumber) { string tname = ((string*)all_tfuncs.data)[tnumber]; string tcname = v__util__no_dots(tname); v__ast__Fn testfn = (*(v__ast__Fn*)map_get(ADDR(map, g->table->fns), &(string[]){tname}, &(v__ast__Fn[]){ (v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,} })); int lnum = (int)(testfn.pos.line_nr + 1); v__gen__c__Gen_writeln(g, _S("\tmain__VTestFnMetaInfo_free(test_runner.fn_test_info);")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\tstring tcname_"), 0xfe07, {.d_i32 = tnumber}}, {_S(" = _S(\""), 0xfe10, {.d_s = tcname}}, {_S("\");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\tstring tcmod_"), 0xfe07, {.d_i32 = tnumber}}, {_S(" = _S(\""), 0xfe10, {.d_s = testfn.mod}}, {_S("\");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\tstring tcfile_"), 0xfe07, {.d_i32 = tnumber}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__ctoslit(testfn.file)}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\t*(test_runner.fn_test_info) = main__vtest_new_metainfo(tcname_"), 0xfe07, {.d_i32 = tnumber}}, {_S(", tcmod_"), 0xfe07, {.d_i32 = tnumber}}, {_S(", tcfile_"), 0xfe07, {.d_i32 = tnumber}}, {_S(", "), 0xfe07, {.d_i32 = lnum}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\t_vtrunner._method_fn_start(_vtobj);")); v__gen__c__Gen_writeln(g, _S("\tif (!setjmp(g_jump_buffer)) {")); if (g->pref->show_asserts) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tmain__BenchedTests_testing_step_start(&bt, tcname_"), 0xfe07, {.d_i32 = tnumber}}, {_S(");"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = tcname}}, {_S("();"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\t\t_vtrunner._method_fn_pass(_vtobj);")); v__gen__c__Gen_writeln(g, _S("\t}else{")); v__gen__c__Gen_writeln(g, _S("\t\t_vtrunner._method_fn_fail(_vtobj);")); v__gen__c__Gen_writeln(g, _S("\t}")); if (g->pref->show_asserts) { v__gen__c__Gen_writeln(g, _S("\tmain__BenchedTests_testing_step_end(&bt);")); } v__gen__c__Gen_writeln(g, _S("")); } if (g->pref->show_asserts) { v__gen__c__Gen_writeln(g, _S("\tmain__BenchedTests_end_testing(&bt);")); } v__gen__c__Gen_writeln2(g, _S(""), _S("\t_vtrunner._method_finish(_vtobj);")); v__gen__c__Gen_writeln(g, _S("\tint test_exit_code = _vtrunner._method_exit_code(_vtobj);")); v__gen__c__Gen_writeln2(g, _S("\t_vtrunner._method__v_free(_vtobj);"), _S("")); v__gen__c__Gen_writeln2(g, _S("\t_vcleanup();"), _S("")); v__gen__c__Gen_writeln2(g, _S("\treturn test_exit_code;"), _S("}")); if (g->pref->printfn_list.len > 0 && (Array_string_contains(g->pref->printfn_list, _S("main")))) { println(strings__Builder_after(&g->out, main_fn_start_pos)); } } Array_string v__gen__c__Gen_filter_only_matching_fn_names(v__gen__c__Gen* g, Array_string fnames) { if (g->pref->run_only.len == 0) { return fnames; } Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t2 = 0; _t2 < fnames.len; ++_t2) { string tname = ((string*)fnames.data)[_t2]; if (string_contains(tname, _S("testsuite_"))) { array_push((array*)&res, _MOV((string[]){ string_clone(tname) })); continue; } bool is_matching = false; for (int _t4 = 0; _t4 < g->pref->run_only.len; ++_t4) { string fn_glob_pattern = ((string*)g->pref->run_only.data)[_t4]; if (string_match_glob(tname, fn_glob_pattern)) { is_matching = true; break; } } if (!is_matching) { continue; } array_push((array*)&res, _MOV((string[]){ string_clone(tname) })); } return res; } void v__gen__c__Gen_gen_c_main_trace_calls_hook(v__gen__c__Gen* g) { if (!g->pref->trace_calls) { return; } bool should_trace_c_main = v__pref__Preferences_should_trace_fn_name(g->pref, _S("C.main")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tu8 bottom_of_stack = 0; g_stack_base = &bottom_of_stack; v__trace_calls__on_c_main("), 0xfe10, {.d_s = should_trace_c_main ? _S("true") : _S("false")}}, {_S(");"), 0, { .d_c = 0 }}}))); } void v__gen__c__Gen_gen_dll_main(v__gen__c__Gen* g) { v__gen__c__Gen_writeln(g, _S("VV_EXP BOOL DllMain(HINSTANCE hinst,DWORD fdwReason,LPVOID lpvReserved) {\n\011switch (fdwReason) {\n\011\011case DLL_PROCESS_ATTACH : {\n#if defined(_VGCBOEHM)\n\011\011\011GC_set_pages_executable(0);\n\011\011\011GC_INIT();\n#endif\n\011\011\011_vinit_caller();\n\011\011\011break;\n\011\011}\n\011\011case DLL_THREAD_ATTACH : {\n\011\011\011break;\n\011\011}\n\011\011case DLL_THREAD_DETACH : {\n\011\011\011break;\n\011\011}\n\011\011case DLL_PROCESS_DETACH : {\n\011\011\011_vcleanup_caller();\n\011\011\011break;\n\011\011}\n\011\011default:\n\011\011\011return false;\n\011}\n\011return true;\n}\n\011")); } VV_LOC void v__gen__c__Gen_comptime_selector(v__gen__c__Gen* g, v__ast__ComptimeSelector node) { bool is_interface_field = v__ast__Table_sym(g->table, node.left_type)->kind == v__ast__Kind__interface; if (is_interface_field) { v__gen__c__Gen_write(g, _S("*(")); } v__gen__c__Gen_expr(g, node.left); if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } if (node.is_name && (node.field_expr)._typ == 379 /* v.ast.SelectorExpr */) { if (((*node.field_expr._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */) { if (string__eq((*(*node.field_expr._v__ast__SelectorExpr).expr._v__ast__Ident).name, g->comptime->comptime_for_field_var)) { multi_return_v__ast__StructField_string mr_737 = v__type_resolver__TypeResolver_get_comptime_selector_var_type(&g->type_resolver, node); string field_name = mr_737.arg1; v__gen__c__Gen_write(g, v__gen__c__c_name(field_name)); if (is_interface_field) { v__gen__c__Gen_write(g, _S(")")); } return; } } } v__gen__c__Gen_expr(g, node.field_expr); if (is_interface_field) { v__gen__c__Gen_write(g, _S(")")); } } VV_LOC string v__gen__c__Gen_gen_comptime_selector(v__gen__c__Gen* g, v__ast__ComptimeSelector expr) { string arrow_or_dot = (v__ast__Type_is_ptr(expr.left_type) ? (_S("->")) : (_S("."))); return str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&expr.left)}}, {_SLIT0, 0xfe10, {.d_s = arrow_or_dot}}, {_SLIT0, 0xfe10, {.d_s = g->comptime->comptime_for_field_value.name}}, {_SLIT0, 0, { .d_c = 0 }}})); } VV_LOC void v__gen__c__Gen_comptime_call(v__gen__c__Gen* g, v__ast__ComptimeCall* node) { if (node->kind == v__ast__ComptimeCallKind__embed_file) { v__gen__c__Gen_gen_embed_file_init(g, node); return; } if (node->kind == v__ast__ComptimeCallKind__env) { string val = v__util__cescaped_path(os__getenv(node->args_var)); { v__gen__c__Gen_write(g, _S("_S(\"")); v__gen__c__Gen_write(g, val); v__gen__c__Gen_write(g, _S("\")")); } return; } if (node->kind == v__ast__ComptimeCallKind__d) { string val = v__util__cescaped_path(node->compile_value); if (node->result_type == _const_v__ast__string_type) { { v__gen__c__Gen_write(g, _S("_S(\"")); v__gen__c__Gen_write(g, val); v__gen__c__Gen_write(g, _S("\")")); } } else if (node->result_type == _const_v__ast__char_type) { { v__gen__c__Gen_write(g, _S("'")); v__gen__c__Gen_write(g, val); v__gen__c__Gen_write(g, _S("'")); } } else { { v__gen__c__Gen_write(g, val); } } return; } if (node->kind == v__ast__ComptimeCallKind__res) { if ((node->args_var).len != 0) { { v__gen__c__Gen_write(g, g->defer_return_tmp_var); v__gen__c__Gen_write(g, _S(".arg")); v__gen__c__Gen_write(g, node->args_var); } return; } { v__gen__c__Gen_write(g, g->defer_return_tmp_var); } return; } if (node->is_vweb) { bool is_html = node->kind == v__ast__ComptimeCallKind__html; string cur_line = _S(""); if (!is_html) { cur_line = v__gen__c__Gen_go_before_last_stmt(g); } v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(g->table, g->fn_decl->return_type); string fn_name = string__plus(string_replace(g->fn_decl->name, _S("."), _S("__")), int_str(node->pos.pos)); bool is_x_vweb = fast_string_eq(ret_sym->cname, _S("x__vweb__Result")); bool is_veb = fast_string_eq(ret_sym->cname, _S("veb__Result")); for (int _t1 = 0; _t1 < node->veb_tmpl.stmts.len; ++_t1) { v__ast__Stmt stmt = ((v__ast__Stmt*)node->veb_tmpl.stmts.data)[_t1]; if ((stmt)._typ == 237 /* v.ast.FnDecl */) { if (string_starts_with((*stmt._v__ast__FnDecl).name, _S("main.veb_tmpl"))) { if (is_html) { g->inside_vweb_tmpl = true; if (is_veb) { g->vweb_filter_fn_name = _S("veb__filter"); } else if (is_x_vweb) { g->vweb_filter_fn_name = _S("x__vweb__filter"); } else { g->vweb_filter_fn_name = _S("vweb__filter"); } } Array_v__ast__Stmt _t2 = {0}; Array_v__ast__Stmt _t2_orig = (*stmt._v__ast__FnDecl).stmts; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(v__ast__Stmt)); for (int _t3 = 0; _t3 < _t2_len; ++_t3) { v__ast__Stmt it = ((v__ast__Stmt*) _t2_orig.data)[_t3]; if ((it)._typ != 412 /* v.ast.Return */) { array_push((array*)&_t2, &it); } } v__gen__c__Gen_stmts(g,_t2); g->inside_vweb_tmpl = false; g->vweb_filter_fn_name = _S(""); break; } } } if (is_html) { if (is_veb) { string ctx_name = (*(v__ast__Param*)array_get(g->fn_decl->params, 1)).name; v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("veb__Context_html("), 0xfe10, {.d_s = ctx_name}}, {_S(", _tmpl_res_"), 0xfe10, {.d_s = fn_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (is_x_vweb) { string ctx_name = (*(v__ast__Param*)array_get(g->fn_decl->params, 1)).name; v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("x__vweb__Context_html("), 0xfe10, {.d_s = ctx_name}}, {_S(", _tmpl_res_"), 0xfe10, {.d_s = fn_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { string app_name = (*(v__ast__Param*)array_get(g->fn_decl->params, 0)).name; v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("vweb__Context_html(&"), 0xfe10, {.d_s = app_name}}, {_S("->Context, _tmpl_res_"), 0xfe10, {.d_s = fn_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("strings__Builder_free(&sb_"), 0xfe10, {.d_s = fn_name}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("string_free(&_tmpl_res_"), 0xfe10, {.d_s = fn_name}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_write(g, cur_line); if (g->inside_return_tmpl) { v__gen__c__Gen_write(g, _S("return ")); } { v__gen__c__Gen_write(g, _S("_tmpl_res_")); v__gen__c__Gen_write(g, fn_name); } } return; } v__ast__Type left_type = v__gen__c__Gen_unwrap_generic(g, node->left_type); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, left_type); ; if (fast_string_eq(node->method_name, _S("method"))) { _option_v__ast__Fn _t4 = v__ast__TypeSymbol_find_method(sym, g->comptime->comptime_for_method->name); if (_t4.state != 0) { IError err = _t4.err; return; } v__ast__Fn m = (*(v__ast__Fn*)_t4.data); if (g->inside_call && m.return_type == _const_v__ast__void_type) { v__gen__c__Gen_error(g, str_intp(2, _MOV((StrIntpData[]){{_S("method `"), 0xfe10, {.d_s = m.name}}, {_S("()` (no value) used as value"), 0, { .d_c = 0 }}})), node->pos); VUNREACHABLE(); } bool _t5; /* if prepend */ if (node->args.len > 0 && (int)(m.params.len - 1) >= node->args.len) { v__ast__CallArg arg = (*(v__ast__CallArg*)array_last(node->args)); v__ast__Param param = (*(v__ast__Param*)array_get(m.params, node->args.len)); _t5 = ((arg.expr)._typ == 361 /* v.ast.IndexExpr */ || (arg.expr)._typ == 358 /* v.ast.Ident */) && string__eq(v__ast__Table_type_to_str(g->table, arg.typ), _S("[]string")) && !string__eq(v__ast__Table_type_to_str(g->table, param.typ), _S("[]string")); } else { _t5 = false; } bool expand_strs = _t5; bool _t6 = (!m.is_variadic); bool _t7 = false; if (_t6) { Array_v__ast__CallArg _t7_orig = node->args; int _t7_len = _t7_orig.len; for (int _t8 = 0; _t8 < _t7_len; ++_t8) { v__ast__CallArg it = ((v__ast__CallArg*) _t7_orig.data)[_t8]; if ((it.expr)._typ == 337 /* v.ast.ArrayDecompose */) { _t7 = true; break; } } } bool has_decompose = _t6 &&_t7; if ((int)(m.params.len - 1) != node->args.len && !expand_strs) { if (g->inside_call) { v__gen__c__Gen_error(g, str_intp(5, _MOV((StrIntpData[]){{_S("expected "), 0xfe07, {.d_i32 = (int)(m.params.len - 1)}}, {_S(" arguments to method "), 0xfe10, {.d_s = sym->name}}, {_S("."), 0xfe10, {.d_s = m.name}}, {_S(", but got "), 0xfe07, {.d_i32 = node->args.len}}, {_SLIT0, 0, { .d_c = 0 }}})), node->pos); VUNREACHABLE(); } else { if (!has_decompose) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("/* skipping "), 0xfe10, {.d_s = sym->name}}, {_S("."), 0xfe10, {.d_s = m.name}}, {_S(" due to mismatched arguments list: node.args="), 0xfe07, {.d_i32 = node->args.len}}, {_S(" m.params="), 0xfe07, {.d_i32 = m.params.len}}, {_S(" */"), 0, { .d_c = 0 }}}))); return; } } } bool has_unwrap = false; if (!g->inside_call && node->or_block.kind != v__ast__OrKind__block && v__ast__Type_has_option_or_result(m.return_type)) { if (!(g->assign_ct_type != 0 && v__ast__Type_has_option_or_result(g->assign_ct_type))) { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, m.return_type)); v__gen__c__Gen_write(g, _S("*)")); } has_unwrap = true; } } { v__gen__c__Gen_write(g, v__gen__c__Gen_cc_type(g, left_type, false)); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, g->comptime->comptime_for_method->name); v__gen__c__Gen_write(g, _S("(")); } if ((node->left)._typ == 358 /* v.ast.Ident */) { if (((*node->left._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { if (v__ast__Type_is_ptr((*(v__ast__Param*)array_get(m.params, 0)).typ) && !v__ast__Type_is_ptr((*(*node->left._v__ast__Ident).obj._v__ast__Var).typ)) { v__gen__c__Gen_write(g, _S("&")); } } } v__gen__c__Gen_expr(g, node->left); if (m.params.len > 1) { v__gen__c__Gen_write(g, _S(", ")); } for (int i = 1; i < m.params.len; ++i) { if ((node->left)._typ == 358 /* v.ast.Ident */) { if (string__eq((*(v__ast__Param*)array_get(m.params, i)).name, (*node->left._v__ast__Ident).name)) { continue; } } if ((int_literal)(i - 1) <= (int)(node->args.len - 1) && has_decompose && ((*(v__ast__CallArg*)array_get(node->args, (int_literal)(i - 1))).expr)._typ == 337 /* v.ast.ArrayDecompose */) { int d_count = 0; for (int d_i = i; d_i < m.params.len; ++d_i) { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, (*(v__ast__Param*)array_get(m.params, i)).typ)); v__gen__c__Gen_write(g, _S("*)array_get(")); } v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node->args, (int_literal)(i - 1))).expr); { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, d_count); v__gen__c__Gen_write(g, _S(")")); } if (d_i < (int)(m.params.len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } d_count++; } break; } else if ((int_literal)(i - 1) < (int)(node->args.len - 1)) { v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node->args, (int_literal)(i - 1))).expr); v__gen__c__Gen_write(g, _S(", ")); } else if (!expand_strs && i == node->args.len) { v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node->args, (int_literal)(i - 1))).expr); break; } else { int idx = (int)(i - node->args.len); string last_arg = v__gen__c__Gen_expr_string(g, (*(v__ast__CallArg*)array_last(node->args)).expr); if (v__ast__Type_is_int((*(v__ast__Param*)array_get(m.params, i)).typ) || v__ast__Type_idx((*(v__ast__Param*)array_get(m.params, i)).typ) == 19) { string type_name = v__ast__TypeSymbol_str((*(v__ast__TypeSymbol**)array_get(g->table->type_symbols, ((int)((*(v__ast__Param*)array_get(m.params, i)).typ))))); { v__gen__c__Gen_write(g, _S("string_")); v__gen__c__Gen_write(g, type_name); v__gen__c__Gen_write(g, _S("(((string*)")); v__gen__c__Gen_write(g, last_arg); v__gen__c__Gen_write(g, _S(".data) [")); v__gen__c__Gen_write_decimal(g, idx); v__gen__c__Gen_write(g, _S("])")); } } else { { v__gen__c__Gen_write(g, _S("((string*)")); v__gen__c__Gen_write(g, last_arg); v__gen__c__Gen_write(g, _S(".data) [")); v__gen__c__Gen_write_decimal(g, idx); v__gen__c__Gen_write(g, _S("] ")); } } if (i < (int)(m.params.len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } } } v__gen__c__Gen_write(g, _S(")")); if (has_unwrap) { v__gen__c__Gen_write(g, _S(".data)")); } if (node->or_block.kind != v__ast__OrKind__absent && v__ast__Type_has_option_or_result(m.return_type)) { if (!g->inside_assign) { string cur_line = v__gen__c__Gen_go_before_last_stmt(g); string tmp_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_write2(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, m.return_type)}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(" = "), 0, { .d_c = 0 }}})), cur_line); v__gen__c__Gen_or_block(g, tmp_var, node->or_block, m.return_type); } } return; } int j = 0; for (int _t9 = 0; _t9 < sym->methods.len; ++_t9) { v__ast__Fn method = ((v__ast__Fn*)sym->methods.data)[_t9]; if (method.return_type != node->result_type) { continue; } if (method.params.len != 1) { continue; } string amp = _S(""); if (node->is_vweb) { if (j > 0) { v__gen__c__Gen_write(g, _S(" else ")); } { v__gen__c__Gen_write(g, _S("if (string__eq(")); v__gen__c__Gen_write(g, node->method_name); v__gen__c__Gen_write(g, _S(", _S(\"")); v__gen__c__Gen_write(g, method.name); v__gen__c__Gen_write(g, _S("\"))) ")); } } { v__gen__c__Gen_write(g, v__gen__c__Gen_cc_type(g, left_type, false)); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, method.name); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, amp); v__gen__c__Gen_write(g, _S(" ")); } v__gen__c__Gen_expr(g, node->left); v__gen__c__Gen_writeln(g, _S(");")); j++; } } VV_LOC Array_string v__gen__c__cgen_attrs(Array_v__ast__Attr attrs) { Array_string res = __new_array_with_default(0, attrs.len, sizeof(string), 0); for (int _t1 = 0; _t1 < attrs.len; ++_t1) { v__ast__Attr attr = ((v__ast__Attr*)attrs.data)[_t1]; string s = attr.name; if (attr.arg.len > 0) { s = string__plus(s, str_intp(2, _MOV((StrIntpData[]){{_S(": "), 0xfe10, {.d_s = attr.arg}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (attr.kind == v__ast__AttrKind__string) { s = v__gen__c__escape_quotes(s); } array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("_S(\""), 0xfe10, {.d_s = s}}, {_S("\")"), 0, { .d_c = 0 }}})) })); } return res; } VV_LOC void v__gen__c__Gen_comptime_at(v__gen__c__Gen* g, v__ast__AtExpr node) { if (node.kind == v__token__AtKind__vmod_file) { string val = v__gen__c__cescape_nonascii(v__util__smart_quote(node.val, false)); { v__gen__c__Gen_write(g, _S("_S(\"")); v__gen__c__Gen_write(g, val); v__gen__c__Gen_write(g, _S("\")")); } } else { string val = string_replace(node.val, _S("\\"), _S("\\\\")); { v__gen__c__Gen_write(g, _S("_S(\"")); v__gen__c__Gen_write(g, val); v__gen__c__Gen_write(g, _S("\")")); } } } VV_LOC void v__gen__c__Gen_comptime_if(v__gen__c__Gen* g, v__ast__IfExpr node) { if (!node.is_expr && !node.has_else && node.branches.len == 1) { if ((*(v__ast__IfBranch*)array_get(node.branches, 0)).stmts.len == 0) { return; } if (!g->pref->output_cross_c) { if (((*(v__ast__IfBranch*)array_get(node.branches, 0)).cond)._typ == 358 /* v.ast.Ident */) { _result_v__pref__OS _t1 = v__pref__os_from_string((*(*(v__ast__IfBranch*)array_get(node.branches, 0)).cond._v__ast__Ident).name); if (_t1.is_error) { IError err = _t1.err; *(v__pref__OS*) _t1.data = v__pref__OS___auto; } if (g->pref->os == ((*(v__pref__OS*)_t1.data))) { g->indent--; v__gen__c__Gen_stmts(g, (*(v__ast__IfBranch*)array_get(node.branches, 0)).stmts); g->indent++; return; } } } } string tmp_var = v__gen__c__Gen_new_tmp_var(g); bool is_opt_or_result = v__ast__Type_has_option_or_result(node.typ); string _t2; /* if prepend */ if (node.is_expr) { string stmt_str = v__gen__c__Gen_go_before_last_stmt(g); v__gen__c__Gen_write(g, v__util__tabs(g->indent)); string styp = v__gen__c__Gen_styp(g, node.typ); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); _t2 = stmt_str; } else { _t2 = _S(""); } string line = _t2; bool comptime_if_stmts_skip = false; bool comptime_may_skip_else = false; for (int i = 0; i < node.branches.len; ++i) { v__ast__IfBranch branch = ((v__ast__IfBranch*)node.branches.data)[i]; int start_pos = g->out.len; if (comptime_may_skip_else) { continue; } if (i == (int)(node.branches.len - 1) && node.has_else) { v__gen__c__Gen_writeln(g, _S("#else")); comptime_if_stmts_skip = comptime_may_skip_else; } else { if (i == 0) { v__gen__c__Gen_write(g, _S("#if ")); } else { v__gen__c__Gen_write(g, _S("#elif ")); } multi_return_bool_bool mr_10563 = v__gen__c__Gen_comptime_if_cond(g, branch.cond, branch.pkg_exist); comptime_if_stmts_skip = mr_10563.arg0; comptime_may_skip_else = mr_10563.arg1; if (!comptime_if_stmts_skip && comptime_may_skip_else) { comptime_may_skip_else = false; } comptime_if_stmts_skip = !comptime_if_stmts_skip; v__gen__c__Gen_writeln(g, _S("")); } string expr_str = string_trim_space(strings__Builder_last_n(&g->out, (int)(g->out.len - start_pos))); if ((expr_str).len != 0) { if ((g->defer_ifdef).len != 0) { g->defer_ifdef = string__plus(g->defer_ifdef, string__plus(_S("\n"), string_repeat(_S("\t"), (int)(g->indent + 1)))); } g->defer_ifdef = string__plus(g->defer_ifdef, expr_str); } if (node.is_expr) { int len = branch.stmts.len; if (len > 0) { v__ast__ExprStmt last = ({ v__ast__Stmt _t3 = (*(v__ast__Stmt*)array_last(branch.stmts)); *(v__ast__ExprStmt*)__as_cast(_t3._v__ast__ExprStmt,_t3._typ, 401); }); if (len > 1) { g->indent++; v__gen__c__Gen_writeln(g, _S("{")); v__gen__c__Gen_stmts(g, array_slice(branch.stmts, 0, (int)(len - 1))); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); bool prev_skip_stmt_pos = g->skip_stmt_pos; g->skip_stmt_pos = true; if (is_opt_or_result) { string tmp_var2 = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, _S("{ ")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, node.typ)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var2); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_stmt(g, v__ast__ExprStmt_to_sumtype_v__ast__Stmt(&last)); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("_result_ok(&("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, node.typ)}}, {_S("[]) { "), 0xfe10, {.d_s = tmp_var2}}, {_S(" }, (_result*)(&"), 0xfe10, {.d_s = tmp_var}}, {_S("), sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, node.typ)}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("}")); } else { { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_stmt(g, v__ast__ExprStmt_to_sumtype_v__ast__Stmt(&last)); } g->skip_stmt_pos = prev_skip_stmt_pos; v__gen__c__Gen_writeln2(g, _S(";"), _S("}")); g->indent--; } else { g->indent++; v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); bool prev_skip_stmt_pos = g->skip_stmt_pos; g->skip_stmt_pos = true; if (is_opt_or_result) { string tmp_var2 = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, _S("{ ")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, node.typ)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var2); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_stmt(g, v__ast__ExprStmt_to_sumtype_v__ast__Stmt(&last)); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("_result_ok(&("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, node.typ)}}, {_S("[]) { "), 0xfe10, {.d_s = tmp_var2}}, {_S(" }, (_result*)(&"), 0xfe10, {.d_s = tmp_var}}, {_S("), sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, node.typ)}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("}")); } else { { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_stmt(g, v__ast__ExprStmt_to_sumtype_v__ast__Stmt(&last)); } g->skip_stmt_pos = prev_skip_stmt_pos; v__gen__c__Gen_writeln(g, _S(";")); g->indent--; } } } else { bool should_create_scope = g->fn_decl != 0; if (should_create_scope) { v__gen__c__Gen_writeln(g, _S("{")); } if (!comptime_if_stmts_skip) { v__gen__c__Gen_stmts(g, branch.stmts); } if (should_create_scope) { v__gen__c__Gen_writeln(g, _S("}")); } } } g->defer_ifdef = _S(""); v__gen__c__Gen_writeln(g, _S("#endif")); if (node.is_expr) { { v__gen__c__Gen_write(g, line); v__gen__c__Gen_write(g, tmp_var); } } } VV_LOC v__ast__Type v__gen__c__Gen_get_expr_type(v__gen__c__Gen* g, v__ast__Expr cond) { if (cond._typ == 358 /* v.ast.Ident */) { return v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, v__ast__Ident_to_sumtype_v__ast__Expr(&(*cond._v__ast__Ident)), (*((*cond._v__ast__Ident).obj.typ)))); } else if (cond._typ == 386 /* v.ast.TypeNode */) { return v__gen__c__Gen_unwrap_generic(g, (*cond._v__ast__TypeNode).typ); } else if (cond._typ == 379 /* v.ast.SelectorExpr */) { if ((*cond._v__ast__SelectorExpr).gkind_field == v__ast__GenericKindField__typ) { return v__gen__c__Gen_unwrap_generic(g, (*cond._v__ast__SelectorExpr).name_type); } else if ((*cond._v__ast__SelectorExpr).gkind_field == v__ast__GenericKindField__unaliased_typ) { return v__ast__Table_unaliased_type(g->table, v__gen__c__Gen_unwrap_generic(g, (*cond._v__ast__SelectorExpr).name_type)); } else if ((*cond._v__ast__SelectorExpr).gkind_field == v__ast__GenericKindField__indirections) { return _const_v__ast__int_type; } else { if (((*cond._v__ast__SelectorExpr).expr)._typ == 387 /* v.ast.TypeOf */) { return v__type_resolver__TypeResolver_typeof_field_type(&g->type_resolver, v__type_resolver__TypeResolver_typeof_type(&g->type_resolver, (*(*cond._v__ast__SelectorExpr).expr._v__ast__TypeOf).expr, (*cond._v__ast__SelectorExpr).name_type), (*cond._v__ast__SelectorExpr).field_name); } string name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&(*cond._v__ast__SelectorExpr).expr)}}, {_S("."), 0xfe10, {.d_s = (*cond._v__ast__SelectorExpr).field_name}}, {_SLIT0, 0, { .d_c = 0 }}})); if (_IN_MAP(ADDR(string, name), ADDR(map, g->type_resolver.type_map))) { return v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, name, _const_v__ast__void_type); } else { return v__gen__c__Gen_unwrap_generic(g, (*cond._v__ast__SelectorExpr).typ); } } } else if (cond._typ == 363 /* v.ast.IntegerLiteral */) { return _const_v__ast__int_type; } else if (cond._typ == 342 /* v.ast.BoolLiteral */) { return _const_v__ast__bool_type; } else if (cond._typ == 384 /* v.ast.StringLiteral */) { return _const_v__ast__string_type; } else if (cond._typ == 347 /* v.ast.CharLiteral */) { return _const_v__ast__char_type; } else if (cond._typ == 356 /* v.ast.FloatLiteral */) { return _const_v__ast__f64_type; } else { return _const_v__ast__void_type; } return 0; } VV_LOC multi_return_bool_bool v__gen__c__Gen_comptime_if_cond(v__gen__c__Gen* g, v__ast__Expr cond, bool pkg_exist) { if (cond._typ == 342 /* v.ast.BoolLiteral */) { v__gen__c__Gen_expr(g, cond); return (multi_return_bool_bool){.arg0=(*cond._v__ast__BoolLiteral).val, .arg1=true}; } else if (cond._typ == 374 /* v.ast.ParExpr */) { v__gen__c__Gen_write(g, _S("(")); multi_return_bool_bool mr_14429 = v__gen__c__Gen_comptime_if_cond(g, (*cond._v__ast__ParExpr).expr, pkg_exist); bool is_cond_true = mr_14429.arg0; bool may_discard = mr_14429.arg1; v__gen__c__Gen_write(g, _S(")")); return (multi_return_bool_bool){.arg0=is_cond_true, .arg1=may_discard}; } else if (cond._typ == 376 /* v.ast.PrefixExpr */) { v__gen__c__Gen_write(g, v__token__Kind_str((*cond._v__ast__PrefixExpr).op)); multi_return_bool_bool mr_14593 = v__gen__c__Gen_comptime_if_cond(g, (*cond._v__ast__PrefixExpr).right, pkg_exist); bool is_cond_true = mr_14593.arg0; if ((*cond._v__ast__PrefixExpr).op == v__token__Kind__not) { if (((*cond._v__ast__PrefixExpr).right)._typ == 342 /* v.ast.BoolLiteral */ || ((*cond._v__ast__PrefixExpr).right)._typ == 379 /* v.ast.SelectorExpr */) { return (multi_return_bool_bool){.arg0=!is_cond_true, .arg1=true}; } } return (multi_return_bool_bool){.arg0=is_cond_true, .arg1=false}; } else if (cond._typ == 375 /* v.ast.PostfixExpr */) { string dname = (*(v__ast__Ident*)__as_cast(((*cond._v__ast__PostfixExpr).expr)._v__ast__Ident,((*cond._v__ast__PostfixExpr).expr)._typ, 358)).name; _result_string _t5 = v__gen__c__Gen_comptime_if_to_ifdef(g, dname, true); if (_t5.is_error) { IError err = _t5.err; v__gen__c__verror(IError_str(err)); VUNREACHABLE(); return (multi_return_bool_bool){.arg0=false, .arg1=true}; } string ifdef = (*(string*)_t5.data); { v__gen__c__Gen_write(g, _S("defined(")); v__gen__c__Gen_write(g, ifdef); v__gen__c__Gen_write(g, _S(")")); } if ((Array_string_contains(g->pref->compile_defines_all, dname)) && !(Array_string_contains(g->pref->compile_defines, dname))) { return (multi_return_bool_bool){.arg0=false, .arg1=true}; } else { return (multi_return_bool_bool){.arg0=true, .arg1=false}; } } else if (cond._typ == 362 /* v.ast.InfixExpr */) { switch ((*cond._v__ast__InfixExpr).op) { case v__token__Kind__and: case v__token__Kind__logical_or: { multi_return_bool_bool mr_15214 = v__gen__c__Gen_comptime_if_cond(g, (*cond._v__ast__InfixExpr).left, pkg_exist); bool l = mr_15214.arg0; bool d1 = mr_15214.arg1; v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = v__token__Kind_str((*cond._v__ast__InfixExpr).op)}}, {_S(" "), 0, { .d_c = 0 }}}))); multi_return_bool_bool mr_15298 = v__gen__c__Gen_comptime_if_cond(g, (*cond._v__ast__InfixExpr).right, pkg_exist); bool r = mr_15298.arg0; bool d2 = mr_15298.arg1; return (multi_return_bool_bool){.arg0=((*cond._v__ast__InfixExpr).op == v__token__Kind__and ? (l && r) : (l || r)), .arg1=d1 && d1 == d2}; } case v__token__Kind__key_is: case v__token__Kind__not_is: { if ((((*cond._v__ast__InfixExpr).left)._typ == 386 /* v.ast.TypeNode */ || ((*cond._v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ || ((*cond._v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */) && (((*cond._v__ast__InfixExpr).right)._typ == 351 /* v.ast.ComptimeType */ || ((*cond._v__ast__InfixExpr).right)._typ == 386 /* v.ast.TypeNode */)) { v__ast__Type exp_type = v__gen__c__Gen_get_expr_type(g, (*cond._v__ast__InfixExpr).left); if (((*cond._v__ast__InfixExpr).right)._typ == 351 /* v.ast.ComptimeType */) { bool is_true = v__type_resolver__TypeResolver_is_comptime_type(&g->type_resolver, exp_type, (*(*cond._v__ast__InfixExpr).right._v__ast__ComptimeType)); if ((*cond._v__ast__InfixExpr).op == v__token__Kind__key_is) { if (is_true) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=is_true, .arg1=true}; } else { if (is_true) { v__gen__c__Gen_write(g, _S("0")); } else { v__gen__c__Gen_write(g, _S("1")); } return (multi_return_bool_bool){.arg0=!is_true, .arg1=true}; } } else { v__ast__Type got_type = v__gen__c__Gen_unwrap_generic(g, (*(v__ast__TypeNode*)__as_cast(((*cond._v__ast__InfixExpr).right)._v__ast__TypeNode,((*cond._v__ast__InfixExpr).right)._typ, 386)).typ); v__ast__TypeSymbol* got_sym = v__ast__Table_sym(g->table, got_type); if (got_sym->kind == v__ast__Kind__interface && (got_sym->info)._typ == 542 /* v.ast.Interface */) { bool is_true = v__ast__Type_has_flag(exp_type, v__ast__TypeFlag__option) == v__ast__Type_has_flag(got_type, v__ast__TypeFlag__option) && v__ast__Table_does_type_implement_interface(g->table, exp_type, got_type); if ((*cond._v__ast__InfixExpr).op == v__token__Kind__key_is) { if (is_true) { v__gen__c__Gen_write(g, str_intp(3, _MOV((StrIntpData[]){{_S("1 && "), 0xfe10, {.d_s = v__ast__Type_has_flag(exp_type, v__ast__TypeFlag__option) ? _S("true") : _S("false")}}, {_S(" == "), 0xfe10, {.d_s = v__ast__Type_has_flag(got_type, v__ast__TypeFlag__option) ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=is_true, .arg1=true}; } else if ((*cond._v__ast__InfixExpr).op == v__token__Kind__not_is) { if (is_true) { v__gen__c__Gen_write(g, _S("0")); } else { v__gen__c__Gen_write(g, _S("1")); } return (multi_return_bool_bool){.arg0=!is_true, .arg1=true}; } } if ((got_sym->info)._typ == 553 /* v.ast.FnType */ && ((*cond._v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */ && string__eq(g->comptime->comptime_for_method_var, (*(v__ast__Ident*)__as_cast(((*cond._v__ast__InfixExpr).left)._v__ast__Ident,((*cond._v__ast__InfixExpr).left)._typ, 358)).name)) { bool is_compatible = string__eq(v__ast__Table_fn_signature(g->table, (voidptr)&(*got_sym->info._v__ast__FnType).func, ((v__ast__FnSignatureOpts){.skip_receiver = true,.type_only = true,})), v__ast__Table_fn_signature(g->table, g->comptime->comptime_for_method, ((v__ast__FnSignatureOpts){.skip_receiver = true,.type_only = true,}))); if ((*cond._v__ast__InfixExpr).op == v__token__Kind__key_is) { v__gen__c__Gen_write(g, int_str((int[]){(is_compatible)?1:0}[0])); return (multi_return_bool_bool){.arg0=is_compatible, .arg1=true}; } else { v__gen__c__Gen_write(g, int_str((int[]){(!is_compatible)?1:0}[0])); return (multi_return_bool_bool){.arg0=!is_compatible, .arg1=true}; } } else if ((*cond._v__ast__InfixExpr).op == v__token__Kind__key_is) { v__gen__c__Gen_write(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = ((int)(v__ast__Type_idx(exp_type)))}}, {_S(" == "), 0xfe07, {.d_i32 = ((int)(v__ast__Type_idx(got_type)))}}, {_S(" && "), 0xfe10, {.d_s = v__ast__Type_has_flag(exp_type, v__ast__TypeFlag__option) ? _S("true") : _S("false")}}, {_S(" == "), 0xfe10, {.d_s = v__ast__Type_has_flag(got_type, v__ast__TypeFlag__option) ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); return (multi_return_bool_bool){.arg0=exp_type == got_type, .arg1=true}; } else { { v__gen__c__Gen_write_decimal(g, ((int)(v__ast__Type_idx(exp_type)))); v__gen__c__Gen_write(g, _S(" != ")); v__gen__c__Gen_write_decimal(g, ((int)(v__ast__Type_idx(got_type)))); } return (multi_return_bool_bool){.arg0=exp_type != got_type, .arg1=true}; } } } break; } case v__token__Kind__eq: case v__token__Kind__ne: { if (((*cond._v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ && (g->comptime->comptime_for_field_var.len > 0 || g->comptime->comptime_for_method != ((void*)0) || (*(v__ast__SelectorExpr*)__as_cast(((*cond._v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*cond._v__ast__InfixExpr).left)._typ, 379)).name_type != 0)) { if (((*cond._v__ast__InfixExpr).right)._typ == 384 /* v.ast.StringLiteral */) { if (((*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */ && fast_string_eq((*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr).field_name, _S("name"))) { if (g->comptime->comptime_for_method_var.len > 0 && string__eq((*(*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr).expr._v__ast__Ident).name, g->comptime->comptime_for_method_var)) { bool is_true = ((*cond._v__ast__InfixExpr).op == v__token__Kind__eq ? (string__eq(g->comptime->comptime_for_method->name, (*(*cond._v__ast__InfixExpr).right._v__ast__StringLiteral).val)) : (!string__eq(g->comptime->comptime_for_method->name, (*(*cond._v__ast__InfixExpr).right._v__ast__StringLiteral).val))); if (is_true) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=is_true, .arg1=true}; } else if (g->comptime->comptime_for_field_var.len > 0 && string__eq((*(*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr).expr._v__ast__Ident).name, g->comptime->comptime_for_field_var)) { bool is_true = ((*cond._v__ast__InfixExpr).op == v__token__Kind__eq ? (string__eq(g->comptime->comptime_for_field_value.name, (*(*cond._v__ast__InfixExpr).right._v__ast__StringLiteral).val)) : (!string__eq(g->comptime->comptime_for_field_value.name, (*(*cond._v__ast__InfixExpr).right._v__ast__StringLiteral).val))); if (is_true) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=is_true, .arg1=true}; } } } else if (((*cond._v__ast__InfixExpr).right)._typ == 363 /* v.ast.IntegerLiteral */) { if (v__type_resolver__ResolverInfo_is_comptime_selector_field_name(g->comptime, (*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr), _S("indirections"))) { int left_muls = ((*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr).name_type != 0 ? (v__ast__Type_nr_muls(v__gen__c__Gen_unwrap_generic(g, (*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr).name_type))) : (v__ast__Type_nr_muls(g->comptime->comptime_for_field_type))); bool is_true = (((*cond._v__ast__InfixExpr).op == (v__token__Kind__eq))? (left_muls == string_i64((*(*cond._v__ast__InfixExpr).right._v__ast__IntegerLiteral).val)) : ((*cond._v__ast__InfixExpr).op == (v__token__Kind__ne))? (left_muls != string_i64((*(*cond._v__ast__InfixExpr).right._v__ast__IntegerLiteral).val)) : (false)); if (is_true) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=is_true, .arg1=true}; } else if ((g->comptime->comptime_for_method_var).len != 0 && ((*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */ && string__eq((*(v__ast__Ident*)__as_cast(((*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr).expr)._v__ast__Ident,((*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr).expr)._typ, 358)).name, g->comptime->comptime_for_method_var) && fast_string_eq((*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr).field_name, _S("return_type"))) { bool is_true = (((*cond._v__ast__InfixExpr).op == (v__token__Kind__eq))? (v__ast__Type_idx(g->comptime->comptime_for_method_ret_type) == string_i64((*(*cond._v__ast__InfixExpr).right._v__ast__IntegerLiteral).val)) : ((*cond._v__ast__InfixExpr).op == (v__token__Kind__ne))? (v__ast__Type_idx(g->comptime->comptime_for_method_ret_type) != string_i64((*(*cond._v__ast__InfixExpr).right._v__ast__IntegerLiteral).val)) : (false)); if (is_true) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=is_true, .arg1=true}; } } } if (((*cond._v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ || ((*cond._v__ast__InfixExpr).right)._typ == 379 /* v.ast.SelectorExpr */) { multi_return_bool_bool mr_20359 = v__gen__c__Gen_comptime_if_cond(g, (*cond._v__ast__InfixExpr).left, pkg_exist); bool l = mr_20359.arg0; bool d1 = mr_20359.arg1; v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = v__token__Kind_str((*cond._v__ast__InfixExpr).op)}}, {_S(" "), 0, { .d_c = 0 }}}))); multi_return_bool_bool mr_20445 = v__gen__c__Gen_comptime_if_cond(g, (*cond._v__ast__InfixExpr).right, pkg_exist); bool r = mr_20445.arg0; bool d2 = mr_20445.arg1; return (multi_return_bool_bool){.arg0=((*cond._v__ast__InfixExpr).op == v__token__Kind__eq ? (l == r) : (l != r)), .arg1=d1 && d1 == d2}; } if (((*cond._v__ast__InfixExpr).left)._typ == 380 /* v.ast.SizeOf */ && (*(v__ast__SizeOf*)__as_cast(((*cond._v__ast__InfixExpr).left)._v__ast__SizeOf,((*cond._v__ast__InfixExpr).left)._typ, 380)).typ != 0 && ((*cond._v__ast__InfixExpr).right)._typ == 363 /* v.ast.IntegerLiteral */) { multi_return_int_int mr_20720 = v__ast__Table_type_size(g->table, v__gen__c__Gen_unwrap_generic(g, (*(*cond._v__ast__InfixExpr).left._v__ast__SizeOf).typ)); int s = mr_20720.arg0; v__ast__IntegerLiteral right = (*(*cond._v__ast__InfixExpr).right._v__ast__IntegerLiteral); bool is_true = (((*cond._v__ast__InfixExpr).op == (v__token__Kind__eq))? (s == string_i64(right.val)) : ((*cond._v__ast__InfixExpr).op == (v__token__Kind__ne))? (s != string_i64(right.val)) : (false)); if (is_true) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=is_true, .arg1=true}; } else { v__gen__c__Gen_write(g, _S("1")); return (multi_return_bool_bool){.arg0=true, .arg1=true}; } break; } case v__token__Kind__key_in: case v__token__Kind__not_in: { if ((((*cond._v__ast__InfixExpr).left)._typ == 386 /* v.ast.TypeNode */ || ((*cond._v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ || ((*cond._v__ast__InfixExpr).left)._typ == 358 /* v.ast.Ident */) && ((*cond._v__ast__InfixExpr).right)._typ == 338 /* v.ast.ArrayInit */) { v__ast__Type checked_type = v__gen__c__Gen_get_expr_type(g, (*cond._v__ast__InfixExpr).left); for (int _t25 = 0; _t25 < (*(*cond._v__ast__InfixExpr).right._v__ast__ArrayInit).exprs.len; ++_t25) { v__ast__Expr expr = ((v__ast__Expr*)(*(*cond._v__ast__InfixExpr).right._v__ast__ArrayInit).exprs.data)[_t25]; if ((expr)._typ == 351 /* v.ast.ComptimeType */) { if (v__type_resolver__TypeResolver_is_comptime_type(&g->type_resolver, checked_type, (*expr._v__ast__ComptimeType))) { if ((*cond._v__ast__InfixExpr).op == v__token__Kind__key_in) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=(*cond._v__ast__InfixExpr).op == v__token__Kind__key_in, .arg1=true}; } } else if ((expr)._typ == 386 /* v.ast.TypeNode */) { v__ast__Type got_type = v__gen__c__Gen_unwrap_generic(g, (*expr._v__ast__TypeNode).typ); if (v__ast__Type_idx(checked_type) == v__ast__Type_idx(got_type) && v__ast__Type_has_flag(checked_type, v__ast__TypeFlag__option) == v__ast__Type_has_flag(got_type, v__ast__TypeFlag__option)) { if ((*cond._v__ast__InfixExpr).op == v__token__Kind__key_in) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=(*cond._v__ast__InfixExpr).op == v__token__Kind__key_in, .arg1=true}; } } } if ((*cond._v__ast__InfixExpr).op == v__token__Kind__not_in) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=(*cond._v__ast__InfixExpr).op == v__token__Kind__not_in, .arg1=true}; } break; } case v__token__Kind__gt: case v__token__Kind__lt: case v__token__Kind__ge: case v__token__Kind__le: { if (((*cond._v__ast__InfixExpr).left)._typ == 379 /* v.ast.SelectorExpr */ && ((*cond._v__ast__InfixExpr).right)._typ == 363 /* v.ast.IntegerLiteral */ && v__type_resolver__ResolverInfo_is_comptime_selector_field_name(g->comptime, *(v__ast__SelectorExpr*)__as_cast(((*cond._v__ast__InfixExpr).left)._v__ast__SelectorExpr,((*cond._v__ast__InfixExpr).left)._typ, 379), _S("indirections"))) { v__ast__SelectorExpr left = (*(*cond._v__ast__InfixExpr).left._v__ast__SelectorExpr); int left_muls = (left.name_type != 0 ? (v__ast__Type_nr_muls(v__gen__c__Gen_unwrap_generic(g, left.name_type))) : (v__ast__Type_nr_muls(g->comptime->comptime_for_field_type))); bool is_true = (((*cond._v__ast__InfixExpr).op == (v__token__Kind__gt))? (left_muls > string_i64((*(*cond._v__ast__InfixExpr).right._v__ast__IntegerLiteral).val)) : ((*cond._v__ast__InfixExpr).op == (v__token__Kind__lt))? (left_muls < string_i64((*(*cond._v__ast__InfixExpr).right._v__ast__IntegerLiteral).val)) : ((*cond._v__ast__InfixExpr).op == (v__token__Kind__ge))? (left_muls >= string_i64((*(*cond._v__ast__InfixExpr).right._v__ast__IntegerLiteral).val)) : ((*cond._v__ast__InfixExpr).op == (v__token__Kind__le))? (left_muls <= string_i64((*(*cond._v__ast__InfixExpr).right._v__ast__IntegerLiteral).val)) : (false)); if (is_true) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=is_true, .arg1=true}; } if (((*cond._v__ast__InfixExpr).left)._typ == 380 /* v.ast.SizeOf */ && (*(v__ast__SizeOf*)__as_cast(((*cond._v__ast__InfixExpr).left)._v__ast__SizeOf,((*cond._v__ast__InfixExpr).left)._typ, 380)).typ != 0 && ((*cond._v__ast__InfixExpr).right)._typ == 363 /* v.ast.IntegerLiteral */) { multi_return_int_int mr_23077 = v__ast__Table_type_size(g->table, v__gen__c__Gen_unwrap_generic(g, (*(*cond._v__ast__InfixExpr).left._v__ast__SizeOf).typ)); int s = mr_23077.arg0; v__ast__IntegerLiteral right = (*(*cond._v__ast__InfixExpr).right._v__ast__IntegerLiteral); bool is_true = (((*cond._v__ast__InfixExpr).op == (v__token__Kind__gt))? (s > string_i64(right.val)) : ((*cond._v__ast__InfixExpr).op == (v__token__Kind__lt))? (s < string_i64(right.val)) : ((*cond._v__ast__InfixExpr).op == (v__token__Kind__ge))? (s >= string_i64(right.val)) : ((*cond._v__ast__InfixExpr).op == (v__token__Kind__le))? (s <= string_i64(right.val)) : (false)); if (is_true) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } return (multi_return_bool_bool){.arg0=is_true, .arg1=true}; } else { return (multi_return_bool_bool){.arg0=true, .arg1=false}; } break; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__plus: case v__token__Kind__minus: case v__token__Kind__mul: case v__token__Kind__div: case v__token__Kind__mod: case v__token__Kind__xor: case v__token__Kind__pipe: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__amp: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__left_shift: case v__token__Kind__right_shift: case v__token__Kind__unsigned_right_shift: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_interface: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { return (multi_return_bool_bool){.arg0=true, .arg1=false}; } } } } else if (cond._typ == 358 /* v.ast.Ident */) { _result_string _t33 = v__gen__c__Gen_comptime_if_to_ifdef(g, (*cond._v__ast__Ident).name, false); if (_t33.is_error) { IError err = _t33.err; *(string*) _t33.data = _S("true"); } string ifdef = (*(string*)_t33.data); { v__gen__c__Gen_write(g, _S("defined(")); v__gen__c__Gen_write(g, ifdef); v__gen__c__Gen_write(g, _S(")")); } return (multi_return_bool_bool){.arg0=true, .arg1=false}; } else if (cond._typ == 349 /* v.ast.ComptimeCall */) { if ((*cond._v__ast__ComptimeCall).kind == v__ast__ComptimeCallKind__pkgconfig) { v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = pkg_exist ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); return (multi_return_bool_bool){.arg0=true, .arg1=false}; } if ((*cond._v__ast__ComptimeCall).kind == v__ast__ComptimeCallKind__d) { if ((*cond._v__ast__ComptimeCall).result_type == _const_v__ast__bool_type) { if (fast_string_eq((*cond._v__ast__ComptimeCall).compile_value, _S("true"))) { v__gen__c__Gen_write(g, _S("1")); } else { v__gen__c__Gen_write(g, _S("0")); } } else { { v__gen__c__Gen_write(g, _S("defined(CUSTOM_DEFINE_")); v__gen__c__Gen_write(g, (*cond._v__ast__ComptimeCall).args_var); v__gen__c__Gen_write(g, _S(")")); } } return (multi_return_bool_bool){.arg0=true, .arg1=false}; } return (multi_return_bool_bool){.arg0=true, .arg1=false}; } else if (cond._typ == 379 /* v.ast.SelectorExpr */) { if ((g->comptime->comptime_for_field_var).len != 0 && ((*cond._v__ast__SelectorExpr).expr)._typ == 358 /* v.ast.Ident */ && string__eq((*(v__ast__Ident*)__as_cast(((*cond._v__ast__SelectorExpr).expr)._v__ast__Ident,((*cond._v__ast__SelectorExpr).expr)._typ, 358)).name, g->comptime->comptime_for_field_var) && (fast_string_eq((*cond._v__ast__SelectorExpr).field_name, _S("is_mut")) || fast_string_eq((*cond._v__ast__SelectorExpr).field_name, _S("is_pub")) || fast_string_eq((*cond._v__ast__SelectorExpr).field_name, _S("is_shared")) || fast_string_eq((*cond._v__ast__SelectorExpr).field_name, _S("is_atomic")) || fast_string_eq((*cond._v__ast__SelectorExpr).field_name, _S("is_option")) || fast_string_eq((*cond._v__ast__SelectorExpr).field_name, _S("is_array")) || fast_string_eq((*cond._v__ast__SelectorExpr).field_name, _S("is_map")) || fast_string_eq((*cond._v__ast__SelectorExpr).field_name, _S("is_chan")) || fast_string_eq((*cond._v__ast__SelectorExpr).field_name, _S("is_struct")) || fast_string_eq((*cond._v__ast__SelectorExpr).field_name, _S("is_alias")) || fast_string_eq((*cond._v__ast__SelectorExpr).field_name, _S("is_enum")))) { bool ret_bool = v__type_resolver__TypeResolver_get_comptime_selector_bool_field(&g->type_resolver, (*cond._v__ast__SelectorExpr).field_name); v__gen__c__Gen_write(g, bool_str(ret_bool)); return (multi_return_bool_bool){.arg0=ret_bool, .arg1=true}; } else { v__gen__c__Gen_write(g, _S("1")); return (multi_return_bool_bool){.arg0=true, .arg1=true}; } } else { v__gen__c__Gen_write(g, _S("1")); return (multi_return_bool_bool){.arg0=true, .arg1=true}; } return (multi_return_bool_bool){0}; } VV_LOC void v__gen__c__Gen_push_new_comptime_info(v__gen__c__Gen* g) { array_push((array*)&g->type_resolver.info_stack, _MOV((v__type_resolver__ResolverInfo[]){ ((v__type_resolver__ResolverInfo){ .saved_type_map = map_clone(&g->type_resolver.type_map), .comptime_loop_id = g->comptime->comptime_loop_id++, .inside_comptime_for = g->comptime->inside_comptime_for, .inside_comptime_if = 0, .has_different_types = 0, .comptime_for_variant_var = g->comptime->comptime_for_variant_var, .comptime_for_field_var = g->comptime->comptime_for_field_var, .comptime_for_field_type = g->comptime->comptime_for_field_type, .comptime_for_field_value = g->comptime->comptime_for_field_value, .comptime_for_enum_var = g->comptime->comptime_for_enum_var, .comptime_for_attr_var = (string){.str=(byteptr)"", .is_lit=1}, .comptime_for_method_var = g->comptime->comptime_for_method_var, .comptime_for_method = g->comptime->comptime_for_method, .comptime_for_method_ret_type = g->comptime->comptime_for_method_ret_type, .comptime_for_method_param_var = (string){.str=(byteptr)"", .is_lit=1}, }) })); } VV_LOC void v__gen__c__Gen_pop_comptime_info(v__gen__c__Gen* g) { v__type_resolver__ResolverInfo old = (*(v__type_resolver__ResolverInfo*)array_pop(&g->type_resolver.info_stack)); g->type_resolver.type_map = map_clone(&old.saved_type_map); g->comptime->inside_comptime_for = old.inside_comptime_for; g->comptime->comptime_for_variant_var = old.comptime_for_variant_var; g->comptime->comptime_for_field_var = old.comptime_for_field_var; g->comptime->comptime_for_field_type = old.comptime_for_field_type; g->comptime->comptime_for_field_value = old.comptime_for_field_value; g->comptime->comptime_for_enum_var = old.comptime_for_enum_var; g->comptime->comptime_for_method_var = old.comptime_for_method_var; g->comptime->comptime_for_method = old.comptime_for_method; g->comptime->comptime_for_method_ret_type = old.comptime_for_method_ret_type; } VV_LOC void v__gen__c__Gen_comptime_for(v__gen__c__Gen* g, v__ast__ComptimeFor node) { v__ast__TypeSymbol* sym = (node.typ != g->field_data_type ? (v__ast__Table_final_sym(g->table, v__gen__c__Gen_unwrap_generic(g, node.typ))) : (v__ast__Table_final_sym(g->table, g->comptime->comptime_for_field_type))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("/* $for "), 0xfe10, {.d_s = node.val_var}}, {_S(" in "), 0xfe10, {.d_s = sym->name}}, {_S("."), 0xfe10, {.d_s = v__ast__ComptimeForKind_str(node.kind)}}, {_S(" */ {"), 0, { .d_c = 0 }}}))); g->indent++; int i = 0; if (node.kind == v__ast__ComptimeForKind__methods) { Array_v__ast__Fn methods = v__ast__TypeSymbol_get_methods(sym); if (methods.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("FunctionData "), 0xfe10, {.d_s = node.val_var}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); } v__ast__Type typ_vweb_result = v__ast__Table_find_type(g->table, _S("vweb.Result")); for (int _t1 = 0; _t1 < methods.len; ++_t1) { v__ast__Fn method = ((v__ast__Fn*)methods.data)[_t1]; v__gen__c__Gen_push_new_comptime_info(g); if (method.receiver_type != 0 && method.return_type == typ_vweb_result) { v__ast__TypeSymbol* rec_sym = v__ast__Table_sym(g->table, method.receiver_type); if (rec_sym->kind == v__ast__Kind__struct) { _result_v__ast__StructField _t2; if (_t2 = v__ast__Table_find_field_with_embeds(g->table, rec_sym, _S("Context")), !_t2.is_error) { if (method.generic_names.len > 0 || (method.params.len > 1 && method.attrs.len == 0)) { v__gen__c__Gen_pop_comptime_info(g); continue; } } } } g->comptime->comptime_for_method = &method; g->comptime->comptime_for_method_var = node.val_var; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("/* method "), 0xfe07, {.d_i32 = i}}, {_S(" */ {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".name = _S(\""), 0xfe10, {.d_s = method.name}}, {_S("\");"), 0, { .d_c = 0 }}}))); if (method.attrs.len == 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".attrs = __new_array_with_default(0, 0, sizeof(string), 0);"), 0, { .d_c = 0 }}}))); } else { Array_string attrs = v__gen__c__cgen_attrs(method.attrs); v__gen__c__Gen_writeln(g, string__plus(string__plus(str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".attrs = new_array_from_c_array("), 0xfe07, {.d_i32 = attrs.len}}, {_S(", "), 0xfe07, {.d_i32 = attrs.len}}, {_S(", sizeof(string), _MOV((string["), 0xfe07, {.d_i32 = attrs.len}}, {_S("]){"), 0, { .d_c = 0 }}})), Array_string_join(attrs, _S(", "))), _S("}));\n"))); } if (method.params.len < 2) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".args = __new_array_with_default(0, 0, sizeof(MethodParam), 0);"), 0, { .d_c = 0 }}}))); } else { int len = (int)(method.params.len - 1); { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, node.val_var); v__gen__c__Gen_write(g, _S(".args = new_array_from_c_array(")); v__gen__c__Gen_write_decimal(g, len); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, len); v__gen__c__Gen_write(g, _S(", sizeof(MethodParam), _MOV((MethodParam[")); v__gen__c__Gen_write_decimal(g, len); v__gen__c__Gen_write(g, _S("]){")); } Array_v__ast__Param _t3 = array_slice(method.params, 1, 2147483647); for (int j = 0; j < _t3.len; ++j) { v__ast__Param arg = ((v__ast__Param*)_t3.data)[j]; int typ = v__ast__Type_idx(arg.typ); { v__gen__c__Gen_write(g, _S("{")); v__gen__c__Gen_write(g, int_str(typ)); v__gen__c__Gen_write(g, _S(", _S(\"")); v__gen__c__Gen_write(g, arg.name); v__gen__c__Gen_write(g, _S("\")}")); } if (j < (int)(len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.val_var}}, {_S(".args["), 0xfe07, {.d_i32 = j}}, {_S("].typ"), 0, { .d_c = 0 }}})), typ); } v__gen__c__Gen_writeln(g, _S("}));\n")); } string sig = _S("fn ("); Array_v__ast__Param _t4 = array_slice(method.params, 1, 2147483647); for (int j = 0; j < _t4.len; ++j) { v__ast__Param arg = ((v__ast__Param*)_t4.data)[j]; v__ast__Type typ = v__ast__Type_set_nr_muls(arg.typ, 0); sig = string__plus(sig, v__ast__Table_sym(g->table, typ)->name); if (j < (int)(method.params.len - 2)) { sig = string__plus(sig, _S(", ")); } } sig = string__plus(sig, _S(")")); string ret_type = v__ast__Table_sym(g->table, method.return_type)->name; if (_SLIT_NE(ret_type.str, ret_type.len, "void")) { sig = string__plus(sig, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = ret_type}}, {_SLIT0, 0, { .d_c = 0 }}}))); } v__ast__Type typ = v__ast__Table_find_type(g->table, sig); v__ast__Type ret_typ = method.return_type; v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".typ = "), 0xfe07, {.d_i32 = ((int)(typ))}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".return_type = "), 0xfe07, {.d_i32 = ((int)(v__ast__Type_idx(ret_typ)))}}, {_S(";"), 0, { .d_c = 0 }}}))); v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.val_var}}, {_S(".return_type"), 0, { .d_c = 0 }}})), ret_typ); v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.val_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), typ); v__gen__c__Gen_stmts(g, node.stmts); i++; v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_pop_comptime_info(g); } } else if (node.kind == v__ast__ComptimeForKind__fields) { if (sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__interface) { Array_v__ast__StructField _t5 = __new_array(0, 0, sizeof(v__ast__StructField)); if (sym->info._typ == 518 /* v.ast.Struct */) { _t5 = (*sym->info._v__ast__Struct).fields; } else if (sym->info._typ == 542 /* v.ast.Interface */) { _t5 = (*sym->info._v__ast__Interface).fields; } else { v__gen__c__Gen_error(g, str_intp(2, _MOV((StrIntpData[]){{_S("comptime field lookup is supported only for structs and interfaces, and "), 0xfe10, {.d_s = sym->name}}, {_S(" is neither"), 0, { .d_c = 0 }}})), node.pos); VUNREACHABLE(); v__ast__StructField* _t6 = (v__ast__StructField*) _v_malloc((0) * sizeof(v__ast__StructField)); for (int _t7=0; _t7<0; _t7++) { _t6[_t7] = (v__ast__StructField){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.option_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = (v__ast__StructDecl){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,},}; } _t5 = __new_array_with_multi_default(0, 0, sizeof(v__ast__StructField), (voidptr)_t6); } Array_v__ast__StructField fields = _t5; if (fields.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tFieldData "), 0xfe10, {.d_s = node.val_var}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_push_new_comptime_info(g); for (int _t8 = 0; _t8 < fields.len; ++_t8) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t8]; g->comptime->inside_comptime_for = true; g->comptime->comptime_for_field_var = node.val_var; g->comptime->comptime_for_field_value = field; g->comptime->comptime_for_field_type = field.typ; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("/* field "), 0xfe07, {.d_i32 = i}}, {_S(" */ {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".name = _S(\""), 0xfe10, {.d_s = field.name}}, {_S("\");"), 0, { .d_c = 0 }}}))); if (field.attrs.len == 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".attrs = __new_array_with_default(0, 0, sizeof(string), 0);"), 0, { .d_c = 0 }}}))); } else { Array_string attrs = v__gen__c__cgen_attrs(field.attrs); v__gen__c__Gen_writeln(g, string__plus(string__plus(str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".attrs = new_array_from_c_array("), 0xfe07, {.d_i32 = attrs.len}}, {_S(", "), 0xfe07, {.d_i32 = attrs.len}}, {_S(", sizeof(string), _MOV((string["), 0xfe07, {.d_i32 = attrs.len}}, {_S("]){"), 0, { .d_c = 0 }}})), Array_string_join(attrs, _S(", "))), _S("}));\n"))); } v__ast__TypeSymbol* field_sym = v__ast__Table_sym(g->table, field.typ); v__ast__Type styp = field.typ; v__ast__Type unaliased_styp = v__ast__Table_unaliased_type(g->table, styp); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".typ = "), 0xfe07, {.d_i32 = ((int)(v__ast__Type_idx(styp)))}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".unaliased_typ = "), 0xfe07, {.d_i32 = ((int)(v__ast__Type_idx(unaliased_styp)))}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".is_pub = "), 0xfe10, {.d_s = field.is_pub ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".is_mut = "), 0xfe10, {.d_s = field.is_mut ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".is_shared = "), 0xfe10, {.d_s = v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__shared_f) ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".is_atomic = "), 0xfe10, {.d_s = v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__atomic_f) ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".is_option = "), 0xfe10, {.d_s = v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option) ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".is_array = "), 0xfe10, {.d_s = (field_sym->kind == v__ast__Kind__array || field_sym->kind == v__ast__Kind__array_fixed) ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".is_map = "), 0xfe10, {.d_s = field_sym->kind == v__ast__Kind__map ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".is_chan = "), 0xfe10, {.d_s = field_sym->kind == v__ast__Kind__chan ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".is_struct = "), 0xfe10, {.d_s = field_sym->kind == v__ast__Kind__struct ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".is_alias = "), 0xfe10, {.d_s = field_sym->kind == v__ast__Kind__alias ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".is_enum = "), 0xfe10, {.d_s = field_sym->kind == v__ast__Kind__enum ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".indirections = "), 0xfe07, {.d_i32 = v__ast__Type_nr_muls(field.typ)}}, {_S(";"), 0, { .d_c = 0 }}}))); v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.val_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), field.typ); v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.val_var}}, {_S(".unaliased_typ"), 0, { .d_c = 0 }}})), unaliased_styp); v__gen__c__Gen_stmts(g, node.stmts); i++; v__gen__c__Gen_writeln(g, _S("}")); } v__gen__c__Gen_pop_comptime_info(g); } } else if (node.kind == v__ast__ComptimeForKind__values) { if (sym->kind == v__ast__Kind__enum) { if ((sym->info)._typ == 548 /* v.ast.Enum */) { if ((*sym->info._v__ast__Enum).vals.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tEnumData "), 0xfe10, {.d_s = node.val_var}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_push_new_comptime_info(g); for (int _t9 = 0; _t9 < (*sym->info._v__ast__Enum).vals.len; ++_t9) { string val = ((string*)(*sym->info._v__ast__Enum).vals.data)[_t9]; g->comptime->comptime_for_enum_var = node.val_var; v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.val_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), node.typ); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("/* enum vals "), 0xfe07, {.d_i32 = i}}, {_S(" */ {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".name = _S(\""), 0xfe10, {.d_s = val}}, {_S("\");"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, node.val_var); v__gen__c__Gen_write(g, _S(".value = ")); } if (g->pref->translated && v__ast__Type_is_number(node.typ)) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_const_main__"), 0xfe10, {.d_s = val}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, node.typ)}}, {_S("__"), 0xfe10, {.d_s = val}}, {_S(";"), 0, { .d_c = 0 }}}))); } Array_v__ast__Attr enum_attrs = (*(Array_v__ast__Attr*)map_get(ADDR(map, (*sym->info._v__ast__Enum).attrs), &(string[]){val}, &(Array_v__ast__Attr[]){ __new_array(0, 0, sizeof(v__ast__Attr)) })); if (enum_attrs.len == 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".attrs = __new_array_with_default(0, 0, sizeof(string), 0);"), 0, { .d_c = 0 }}}))); } else { Array_string attrs = v__gen__c__cgen_attrs(enum_attrs); v__gen__c__Gen_writeln(g, string__plus(string__plus(str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".attrs = new_array_from_c_array("), 0xfe07, {.d_i32 = attrs.len}}, {_S(", "), 0xfe07, {.d_i32 = attrs.len}}, {_S(", sizeof(string), _MOV((string["), 0xfe07, {.d_i32 = attrs.len}}, {_S("]){"), 0, { .d_c = 0 }}})), Array_string_join(attrs, _S(", "))), _S("}));\n"))); } v__gen__c__Gen_stmts(g, node.stmts); v__gen__c__Gen_writeln(g, _S("}")); i++; } v__gen__c__Gen_pop_comptime_info(g); } } } else if (node.kind == v__ast__ComptimeForKind__attributes) { Array_v__ast__Attr attrs = v__ast__Table_get_attrs(g->table, *sym); if (attrs.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tVAttribute "), 0xfe10, {.d_s = node.val_var}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); for (int _t10 = 0; _t10 < attrs.len; ++_t10) { v__ast__Attr attr = ((v__ast__Attr*)attrs.data)[_t10]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("/* attribute "), 0xfe07, {.d_i32 = i}}, {_S(" */ {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".name = _S(\""), 0xfe10, {.d_s = attr.name}}, {_S("\");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".has_arg = "), 0xfe10, {.d_s = attr.has_arg ? _S("true") : _S("false")}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".arg = _S(\""), 0xfe10, {.d_s = v__util__smart_quote(attr.arg, false)}}, {_S("\");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".kind = AttributeKind__"), 0xfe10, {.d_s = v__ast__AttrKind_str(attr.kind)}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_stmts(g, node.stmts); v__gen__c__Gen_writeln(g, _S("}")); i++; } } } else if (node.kind == v__ast__ComptimeForKind__variants) { if ((sym->info)._typ == 544 /* v.ast.SumType */) { if ((*sym->info._v__ast__SumType).variants.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tVariantData "), 0xfe10, {.d_s = node.val_var}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); } g->comptime->inside_comptime_for = true; v__gen__c__Gen_push_new_comptime_info(g); for (int _t11 = 0; _t11 < (*sym->info._v__ast__SumType).variants.len; ++_t11) { v__ast__Type variant = ((v__ast__Type*)(*sym->info._v__ast__SumType).variants.data)[_t11]; g->comptime->comptime_for_variant_var = node.val_var; v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.val_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), variant); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("/* variant "), 0xfe07, {.d_i32 = i}}, {_S(" */ {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".typ = "), 0xfe07, {.d_i32 = ((int)(variant))}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_stmts(g, node.stmts); v__gen__c__Gen_writeln(g, _S("}")); i++; } v__gen__c__Gen_pop_comptime_info(g); } } else if (node.kind == v__ast__ComptimeForKind__params) { v__ast__Fn* method = g->comptime->comptime_for_method; if (method->params.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tMethodParam "), 0xfe10, {.d_s = node.val_var}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_push_new_comptime_info(g); g->comptime->inside_comptime_for = true; g->comptime->comptime_for_method_param_var = node.val_var; Array_v__ast__Param _t12 = array_slice(method->params, 1, 2147483647); for (int _t13 = 0; _t13 < _t12.len; ++_t13) { v__ast__Param param = ((v__ast__Param*)_t12.data)[_t13]; v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.val_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), param.typ); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("/* method param "), 0xfe07, {.d_i32 = i}}, {_S(" */ {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".typ = "), 0xfe07, {.d_i32 = ((int)(param.typ))}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.val_var}}, {_S(".name = _S(\""), 0xfe10, {.d_s = param.name}}, {_S("\");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_stmts(g, node.stmts); v__gen__c__Gen_writeln(g, _S("}")); i++; } v__gen__c__Gen_pop_comptime_info(g); } g->indent--; v__gen__c__Gen_writeln(g, _S("}// $for")); } VV_LOC v__ast__Type v__gen__c__Gen_comptime_selector_type(v__gen__c__Gen* g, v__ast__SelectorExpr node) { if (!((node.expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node.expr)._v__ast__Ident,(node.expr)._typ, 358)).ct_expr)) { return node.expr_type; } bool prevent_sum_type_unwrapping_once = g->prevent_sum_type_unwrapping_once; g->prevent_sum_type_unwrapping_once = false; v__ast__Type typ = v__type_resolver__TypeResolver_get_type(&g->type_resolver, node.expr); if (v__ast__Expr_is_auto_deref_var(node.expr)) { if ((node.expr)._typ == 358 /* v.ast.Ident */) { if (((*node.expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { typ = (*(*node.expr._v__ast__Ident).obj._v__ast__Var).typ; } } } if (g->comptime->inside_comptime_for && typ == g->enum_data_type && fast_string_eq(node.field_name, _S("value"))) { return v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->comptime->comptime_for_enum_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), _const_v__ast__void_type); } string field_name = node.field_name; v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); v__ast__TypeSymbol* final_sym = v__ast__Table_final_sym(g->table, typ); if ((v__ast__Type_has_flag(typ, v__ast__TypeFlag__variadic) || final_sym->kind == v__ast__Kind__array_fixed) && _SLIT_EQ(field_name.str, field_name.len, "len")) { return _const_v__ast__int_type; } if (sym->kind == v__ast__Kind__chan) { if (_SLIT_EQ(field_name.str, field_name.len, "closed")) { return _const_v__ast__bool_type; } else if (_SLIT_EQ(field_name.str, field_name.len, "len") || _SLIT_EQ(field_name.str, field_name.len, "cap")) { return _const_v__ast__u32_type; } } bool has_field = false; v__ast__StructField field = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}); if (field_name.len > 0 && u8_is_capital(string_at(field_name, 0)) && (sym->info)._typ == 518 /* v.ast.Struct */ && sym->language == v__ast__Language__v) { for (int _t6 = 0; _t6 < (*sym->info._v__ast__Struct).embeds.len; ++_t6) { v__ast__Type embed = ((v__ast__Type*)(*sym->info._v__ast__Struct).embeds.data)[_t6]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(g->table, embed); if (string__eq(v__ast__TypeSymbol_embed_name(embed_sym), field_name)) { return embed; } } } else { _result_v__ast__StructField _t8; if (_t8 = v__ast__Table_find_field(g->table, sym, field_name), !_t8.is_error) { v__ast__StructField f = *(v__ast__StructField*)_t8.data; has_field = true; field = f; } else { IError err = _t8.err; has_field = true; _result_multi_return_v__ast__StructField_Array_v__ast__Type _t9 = v__ast__Table_find_field_from_embeds(g->table, sym, field_name); if (_t9.is_error) { IError err = _t9.err; has_field = false; } ; } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic) && !has_field) { v__ast__TypeSymbol* gs = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, typ)); _result_v__ast__StructField _t10; if (_t10 = v__ast__Table_find_field(g->table, gs, field_name), !_t10.is_error) { v__ast__StructField f = *(v__ast__StructField*)_t10.data; has_field = true; field = f; } else { IError err = _t10.err; has_field = true; _result_multi_return_v__ast__StructField_Array_v__ast__Type _t11 = v__ast__Table_find_field_from_embeds(g->table, gs, field_name); if (_t11.is_error) { IError err = _t11.err; has_field = false; } ; } } } if (has_field) { v__ast__TypeSymbol* field_sym = v__ast__Table_sym(g->table, field.typ); if (field_sym->kind == v__ast__Kind__sum_type || field_sym->kind == v__ast__Kind__interface) { if (!prevent_sum_type_unwrapping_once) { v__ast__ScopeStructField* scope_field = v__ast__Scope_find_struct_field(node.scope, v__ast__Expr_str(&node.expr), typ, field_name); if (scope_field != ((void*)0)) { return (*(v__ast__Type*)array_last(scope_field->smartcasts)); } } } return field.typ; } _option_v__ast__Fn _t14; if (_t14 = v__ast__TypeSymbol_find_method_with_generic_parent(v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, typ)), field_name), _t14.state == 0) { v__ast__Fn method = *(v__ast__Fn*)_t14.data; method.params = array_slice(method.params, 1, 2147483647); method.name = _S(""); v__ast__Type fn_type = v__ast__new_type(v__ast__Table_find_or_register_fn_type(g->table, method, false, true)); return fn_type; } if (!(sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__aggregate || sym->kind == v__ast__Kind__interface || sym->kind == v__ast__Kind__sum_type)) { if (sym->kind != v__ast__Kind__placeholder) { v__ast__TypeSymbol* unwrapped_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, typ)); if (unwrapped_sym->kind == v__ast__Kind__array_fixed && fast_string_eq(node.field_name, _S("len"))) { return _const_v__ast__int_type; } } } return node.expr_type; } VV_LOC _result_string v__gen__c__Gen_comptime_if_to_ifdef(v__gen__c__Gen* g, string name, bool is_comptime_option) { if (_SLIT_EQ(name.str, name.len, "windows")) { _result_string _t1 = {0}; _result_ok(&(string[]) { _S("_WIN32") }, (_result*)(&_t1), sizeof(string)); return _t1; } else if (_SLIT_EQ(name.str, name.len, "ios")) { _result_string _t2 = {0}; _result_ok(&(string[]) { _S("__TARGET_IOS__") }, (_result*)(&_t2), sizeof(string)); return _t2; } else if (_SLIT_EQ(name.str, name.len, "macos")) { _result_string _t3 = {0}; _result_ok(&(string[]) { _S("__APPLE__") }, (_result*)(&_t3), sizeof(string)); return _t3; } else if (_SLIT_EQ(name.str, name.len, "mach")) { _result_string _t4 = {0}; _result_ok(&(string[]) { _S("__MACH__") }, (_result*)(&_t4), sizeof(string)); return _t4; } else if (_SLIT_EQ(name.str, name.len, "darwin")) { _result_string _t5 = {0}; _result_ok(&(string[]) { _S("__DARWIN__") }, (_result*)(&_t5), sizeof(string)); return _t5; } else if (_SLIT_EQ(name.str, name.len, "hpux")) { _result_string _t6 = {0}; _result_ok(&(string[]) { _S("__HPUX__") }, (_result*)(&_t6), sizeof(string)); return _t6; } else if (_SLIT_EQ(name.str, name.len, "gnu")) { _result_string _t7 = {0}; _result_ok(&(string[]) { _S("__GNU__") }, (_result*)(&_t7), sizeof(string)); return _t7; } else if (_SLIT_EQ(name.str, name.len, "qnx")) { _result_string _t8 = {0}; _result_ok(&(string[]) { _S("__QNX__") }, (_result*)(&_t8), sizeof(string)); return _t8; } else if (_SLIT_EQ(name.str, name.len, "linux")) { _result_string _t9 = {0}; _result_ok(&(string[]) { _S("__linux__") }, (_result*)(&_t9), sizeof(string)); return _t9; } else if (_SLIT_EQ(name.str, name.len, "serenity")) { _result_string _t10 = {0}; _result_ok(&(string[]) { _S("__serenity__") }, (_result*)(&_t10), sizeof(string)); return _t10; } else if (_SLIT_EQ(name.str, name.len, "plan9")) { _result_string _t11 = {0}; _result_ok(&(string[]) { _S("__plan9__") }, (_result*)(&_t11), sizeof(string)); return _t11; } else if (_SLIT_EQ(name.str, name.len, "vinix")) { _result_string _t12 = {0}; _result_ok(&(string[]) { _S("__vinix__") }, (_result*)(&_t12), sizeof(string)); return _t12; } else if (_SLIT_EQ(name.str, name.len, "freebsd")) { _result_string _t13 = {0}; _result_ok(&(string[]) { _S("__FreeBSD__") }, (_result*)(&_t13), sizeof(string)); return _t13; } else if (_SLIT_EQ(name.str, name.len, "openbsd")) { _result_string _t14 = {0}; _result_ok(&(string[]) { _S("__OpenBSD__") }, (_result*)(&_t14), sizeof(string)); return _t14; } else if (_SLIT_EQ(name.str, name.len, "netbsd")) { _result_string _t15 = {0}; _result_ok(&(string[]) { _S("__NetBSD__") }, (_result*)(&_t15), sizeof(string)); return _t15; } else if (_SLIT_EQ(name.str, name.len, "bsd")) { _result_string _t16 = {0}; _result_ok(&(string[]) { _S("__BSD__") }, (_result*)(&_t16), sizeof(string)); return _t16; } else if (_SLIT_EQ(name.str, name.len, "dragonfly")) { _result_string _t17 = {0}; _result_ok(&(string[]) { _S("__DragonFly__") }, (_result*)(&_t17), sizeof(string)); return _t17; } else if (_SLIT_EQ(name.str, name.len, "android")) { _result_string _t18 = {0}; _result_ok(&(string[]) { _S("__ANDROID__") }, (_result*)(&_t18), sizeof(string)); return _t18; } else if (_SLIT_EQ(name.str, name.len, "termux")) { _result_string _t19 = {0}; _result_ok(&(string[]) { _S("__TERMUX__") }, (_result*)(&_t19), sizeof(string)); return _t19; } else if (_SLIT_EQ(name.str, name.len, "solaris")) { _result_string _t20 = {0}; _result_ok(&(string[]) { _S("__sun") }, (_result*)(&_t20), sizeof(string)); return _t20; } else if (_SLIT_EQ(name.str, name.len, "haiku")) { _result_string _t21 = {0}; _result_ok(&(string[]) { _S("__HAIKU__") }, (_result*)(&_t21), sizeof(string)); return _t21; } else if (_SLIT_EQ(name.str, name.len, "js")) { _result_string _t22 = {0}; _result_ok(&(string[]) { _S("_VJS") }, (_result*)(&_t22), sizeof(string)); return _t22; } else if (_SLIT_EQ(name.str, name.len, "wasm32_emscripten")) { _result_string _t23 = {0}; _result_ok(&(string[]) { _S("__EMSCRIPTEN__") }, (_result*)(&_t23), sizeof(string)); return _t23; } else if (_SLIT_EQ(name.str, name.len, "native")) { _result_string _t24 = {0}; _result_ok(&(string[]) { _S("_VNATIVE") }, (_result*)(&_t24), sizeof(string)); return _t24; } else if (_SLIT_EQ(name.str, name.len, "gcc")) { _result_string _t25 = {0}; _result_ok(&(string[]) { _S("__V_GCC__") }, (_result*)(&_t25), sizeof(string)); return _t25; } else if (_SLIT_EQ(name.str, name.len, "tinyc")) { _result_string _t26 = {0}; _result_ok(&(string[]) { _S("__TINYC__") }, (_result*)(&_t26), sizeof(string)); return _t26; } else if (_SLIT_EQ(name.str, name.len, "clang")) { _result_string _t27 = {0}; _result_ok(&(string[]) { _S("__clang__") }, (_result*)(&_t27), sizeof(string)); return _t27; } else if (_SLIT_EQ(name.str, name.len, "mingw")) { _result_string _t28 = {0}; _result_ok(&(string[]) { _S("__MINGW32__") }, (_result*)(&_t28), sizeof(string)); return _t28; } else if (_SLIT_EQ(name.str, name.len, "msvc")) { _result_string _t29 = {0}; _result_ok(&(string[]) { _S("_MSC_VER") }, (_result*)(&_t29), sizeof(string)); return _t29; } else if (_SLIT_EQ(name.str, name.len, "cplusplus")) { _result_string _t30 = {0}; _result_ok(&(string[]) { _S("__cplusplus") }, (_result*)(&_t30), sizeof(string)); return _t30; } else if (_SLIT_EQ(name.str, name.len, "threads")) { _result_string _t31 = {0}; _result_ok(&(string[]) { _S("__VTHREADS__") }, (_result*)(&_t31), sizeof(string)); return _t31; } else if (_SLIT_EQ(name.str, name.len, "gcboehm")) { _result_string _t32 = {0}; _result_ok(&(string[]) { _S("_VGCBOEHM") }, (_result*)(&_t32), sizeof(string)); return _t32; } else if (_SLIT_EQ(name.str, name.len, "debug")) { _result_string _t33 = {0}; _result_ok(&(string[]) { _S("_VDEBUG") }, (_result*)(&_t33), sizeof(string)); return _t33; } else if (_SLIT_EQ(name.str, name.len, "prod")) { _result_string _t34 = {0}; _result_ok(&(string[]) { _S("_VPROD") }, (_result*)(&_t34), sizeof(string)); return _t34; } else if (_SLIT_EQ(name.str, name.len, "profile")) { _result_string _t35 = {0}; _result_ok(&(string[]) { _S("_VPROFILE") }, (_result*)(&_t35), sizeof(string)); return _t35; } else if (_SLIT_EQ(name.str, name.len, "test")) { _result_string _t36 = {0}; _result_ok(&(string[]) { _S("_VTEST") }, (_result*)(&_t36), sizeof(string)); return _t36; } else if (_SLIT_EQ(name.str, name.len, "glibc")) { _result_string _t37 = {0}; _result_ok(&(string[]) { _S("__GLIBC__") }, (_result*)(&_t37), sizeof(string)); return _t37; } else if (_SLIT_EQ(name.str, name.len, "prealloc")) { _result_string _t38 = {0}; _result_ok(&(string[]) { _S("_VPREALLOC") }, (_result*)(&_t38), sizeof(string)); return _t38; } else if (_SLIT_EQ(name.str, name.len, "no_bounds_checking")) { _result_string _t39 = {0}; _result_ok(&(string[]) { _S("CUSTOM_DEFINE_no_bounds_checking") }, (_result*)(&_t39), sizeof(string)); return _t39; } else if (_SLIT_EQ(name.str, name.len, "freestanding")) { _result_string _t40 = {0}; _result_ok(&(string[]) { _S("_VFREESTANDING") }, (_result*)(&_t40), sizeof(string)); return _t40; } else if (_SLIT_EQ(name.str, name.len, "autofree")) { _result_string _t41 = {0}; _result_ok(&(string[]) { _S("_VAUTOFREE") }, (_result*)(&_t41), sizeof(string)); return _t41; } else if (_SLIT_EQ(name.str, name.len, "amd64")) { _result_string _t42 = {0}; _result_ok(&(string[]) { _S("__V_amd64") }, (_result*)(&_t42), sizeof(string)); return _t42; } else if (_SLIT_EQ(name.str, name.len, "aarch64") || _SLIT_EQ(name.str, name.len, "arm64")) { _result_string _t43 = {0}; _result_ok(&(string[]) { _S("__V_arm64") }, (_result*)(&_t43), sizeof(string)); return _t43; } else if (_SLIT_EQ(name.str, name.len, "arm32")) { _result_string _t44 = {0}; _result_ok(&(string[]) { _S("__V_arm32") }, (_result*)(&_t44), sizeof(string)); return _t44; } else if (_SLIT_EQ(name.str, name.len, "i386")) { _result_string _t45 = {0}; _result_ok(&(string[]) { _S("__V_x86") }, (_result*)(&_t45), sizeof(string)); return _t45; } else if (_SLIT_EQ(name.str, name.len, "rv64") || _SLIT_EQ(name.str, name.len, "riscv64")) { _result_string _t46 = {0}; _result_ok(&(string[]) { _S("__V_rv64") }, (_result*)(&_t46), sizeof(string)); return _t46; } else if (_SLIT_EQ(name.str, name.len, "s390x")) { _result_string _t47 = {0}; _result_ok(&(string[]) { _S("__V_s390x") }, (_result*)(&_t47), sizeof(string)); return _t47; } else if (_SLIT_EQ(name.str, name.len, "ppc64le")) { _result_string _t48 = {0}; _result_ok(&(string[]) { _S("__V_ppc64le") }, (_result*)(&_t48), sizeof(string)); return _t48; } else if (_SLIT_EQ(name.str, name.len, "loongarch64")) { _result_string _t49 = {0}; _result_ok(&(string[]) { _S("__V_loongarch64") }, (_result*)(&_t49), sizeof(string)); return _t49; } else if (_SLIT_EQ(name.str, name.len, "x64")) { _result_string _t50 = {0}; _result_ok(&(string[]) { _S("TARGET_IS_64BIT") }, (_result*)(&_t50), sizeof(string)); return _t50; } else if (_SLIT_EQ(name.str, name.len, "x32")) { _result_string _t51 = {0}; _result_ok(&(string[]) { _S("TARGET_IS_32BIT") }, (_result*)(&_t51), sizeof(string)); return _t51; } else if (_SLIT_EQ(name.str, name.len, "little_endian")) { _result_string _t52 = {0}; _result_ok(&(string[]) { _S("TARGET_ORDER_IS_LITTLE") }, (_result*)(&_t52), sizeof(string)); return _t52; } else if (_SLIT_EQ(name.str, name.len, "big_endian")) { _result_string _t53 = {0}; _result_ok(&(string[]) { _S("TARGET_ORDER_IS_BIG") }, (_result*)(&_t53), sizeof(string)); return _t53; } else if (_SLIT_EQ(name.str, name.len, "fast_math")) { if (g->pref->ccompiler_type == v__pref__CompilerType__msvc) { _result_string _t54 = {0}; _result_ok(&(string[]) { _S("_M_FP_FAST") }, (_result*)(&_t54), sizeof(string)); return _t54; } _result_string _t55 = {0}; _result_ok(&(string[]) { _S("__FAST_MATH__") }, (_result*)(&_t55), sizeof(string)); return _t55; } else { if (is_comptime_option || (g->pref->compile_defines_all.len > 0 && (Array_string_contains(g->pref->compile_defines_all, name)))) { _result_string _t56 = {0}; _result_ok(&(string[]) { str_intp(2, _MOV((StrIntpData[]){{_S("CUSTOM_DEFINE_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})) }, (_result*)(&_t56), sizeof(string)); return _t56; } return (_result_string){ .is_error=true, .err=_v_error(str_intp(2, _MOV((StrIntpData[]){{_S("bad os ifdef name \""), 0xfe10, {.d_s = name}}, {_S("\""), 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } return (_result_string){ .is_error=true, .err=_v_error(_S("none")), .data={E_STRUCT} }; } VV_LOC void v__gen__c__Gen_const_decl(v__gen__c__Gen* g, v__ast__ConstDecl node) { bool v__gen__c__Gen_const_decl_defer_0 = false; g->inside_const = true; v__gen__c__Gen_const_decl_defer_0 = true; for (int _t1 = 0; _t1 < node.fields.len; ++_t1) { v__ast__ConstField field = ((v__ast__ConstField*)node.fields.data)[_t1]; if (g->pref->skip_unused) { if (!_IN_MAP(ADDR(string, field.name), ADDR(map, g->table->used_features->used_consts))) { #if defined(CUSTOM_DEFINE_trace_skip_unused_consts) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">> skipping unused const name: "), 0xfe10, {.d_s = field.name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif continue; } } string name = v__gen__c__c_name(field.name); string const_name = string__plus(_S("_const_"), name); if (g->pref->translated && !g->is_builtin_mod && !v__util__module_is_builtin(string_all_before_last(field.name, _S(".")))) { if (string_starts_with(name, _S("main__"))) { const_name = string_all_after_first(name, _S("main__")); } } if (!g->is_builtin_mod) { _option_v__ast__Attr _t3; if (_t3 = Array_v__ast__Attr_find_first(node.attrs, _S("export")), _t3.state == 0) { v__ast__Attr cattr = *(v__ast__Attr*)_t3.data; const_name = cattr.arg; } } v__ast__Expr field_expr = field.expr; if (field.expr._typ == 338 /* v.ast.ArrayInit */) { bool _t4 = true; Array_v__ast__Expr _t4_orig = (*field.expr._v__ast__ArrayInit).exprs; int _t4_len = _t4_orig.len; for (int _t5 = 0; _t5 < _t4_len; ++_t5) { v__ast__Expr it = ((v__ast__Expr*) _t4_orig.data)[_t5]; if (!(v__gen__c__Gen_check_expr_is_const(g, it))) { _t4 = false; break; } } bool elems_are_const =_t4; if ((*field.expr._v__ast__ArrayInit).is_fixed && !(*field.expr._v__ast__ArrayInit).has_index && g->pref->build_mode != v__pref__BuildMode__build_module && (!g->is_cc_msvc || (*field.expr._v__ast__ArrayInit).elem_type != _const_v__ast__string_type) && elems_are_const) { string styp = v__gen__c__Gen_styp(g, (*field.expr._v__ast__ArrayInit).typ); string val = v__gen__c__Gen_expr_string(g, field.expr); (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){name}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = field.mod,.def = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = const_name}}, {_S(" = "), 0xfe10, {.d_s = val}}, {_S("; // fixed array const"), 0, { .d_c = 0 }}})),.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = v__ast__Table_dependent_names_in_expr(g->table, field_expr),.order = 0,.is_precomputed = 0,}); } else if ((*field.expr._v__ast__ArrayInit).is_fixed && !(*field.expr._v__ast__ArrayInit).has_index && ((g->is_cc_msvc && (*field.expr._v__ast__ArrayInit).elem_type == _const_v__ast__string_type) || !elems_are_const)) { v__gen__c__Gen_const_decl_init_later_msvc_string_fixed_array(g, field.mod, name, (*field.expr._v__ast__ArrayInit), field.typ); } else { v__gen__c__Gen_const_decl_init_later(g, field.mod, name, field.expr, field.typ, false); } } else if (field.expr._typ == 384 /* v.ast.StringLiteral */) { string val = v__gen__c__Gen_expr_string(g, field.expr); string typ = ((*field.expr._v__ast__StringLiteral).language == v__ast__Language__c ? (_S("char*")) : (_S("string"))); (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){name}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = field.mod,.def = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = typ}}, {_S(" "), 0xfe10, {.d_s = const_name}}, {_S("; // a string literal, inited later"), 0, { .d_c = 0 }}})),.init = str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = const_name}}, {_S(" = "), 0xfe10, {.d_s = val}}, {_S(";"), 0, { .d_c = 0 }}})),.dep_names = __new_array(0, 0, sizeof(string)),.order = -1,.is_precomputed = 0,}); } else if (field.expr._typ == 344 /* v.ast.CallExpr */) { if (v__ast__Type_has_flag((*field.expr._v__ast__CallExpr).return_type, v__ast__TypeFlag__option) || v__ast__Type_has_flag((*field.expr._v__ast__CallExpr).return_type, v__ast__TypeFlag__result)) { bool old_inside_const_opt_or_res = g->inside_const_opt_or_res; g->inside_const_opt_or_res = true; bool unwrap_opt_res = (*field.expr._v__ast__CallExpr).or_block.kind != v__ast__OrKind__absent; v__gen__c__Gen_const_decl_init_later(g, field.mod, name, field.expr, field.typ, unwrap_opt_res); g->inside_const_opt_or_res = old_inside_const_opt_or_res; } else { v__gen__c__Gen_const_decl_init_later(g, field.mod, name, field.expr, field.typ, false); } } else { bool use_cache_mode = g->pref->build_mode == v__pref__BuildMode__build_module || g->pref->use_cache; if (!use_cache_mode) { _option_v__ast__ComptTimeConstValue _t6; if (_t6 = v__ast__ConstField_comptime_expr_value(field), _t6.state == 0) { v__ast__ComptTimeConstValue ct_value = *(v__ast__ComptTimeConstValue*)_t6.data; if (v__gen__c__Gen_const_decl_precomputed(g, field.mod, name, field.name, ct_value, field.typ)) { continue; } } } if (v__ast__ConstField_is_simple_define_const(field)) { v__gen__c__Gen_const_decl_simple_define(g, field.mod, field.name, v__gen__c__Gen_expr_string(g, field_expr)); } else if ((field.expr)._typ == 345 /* v.ast.CastExpr */) { if (((*field.expr._v__ast__CastExpr).expr)._typ == 338 /* v.ast.ArrayInit */) { if ((*(*field.expr._v__ast__CastExpr).expr._v__ast__ArrayInit).is_fixed && g->pref->build_mode != v__pref__BuildMode__build_module) { string styp = v__gen__c__Gen_styp(g, (*field.expr._v__ast__CastExpr).typ); string val = v__gen__c__Gen_expr_string(g, (*field.expr._v__ast__CastExpr).expr); (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){name}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = field.mod,.def = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = const_name}}, {_S(" = "), 0xfe10, {.d_s = val}}, {_S("; // fixed array const"), 0, { .d_c = 0 }}})),.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = v__ast__Table_dependent_names_in_expr(g->table, field_expr),.order = 0,.is_precomputed = 0,}); continue; } } bool should_surround = ((*field.expr._v__ast__CastExpr).expr)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast(((*field.expr._v__ast__CastExpr).expr)._v__ast__CallExpr,((*field.expr._v__ast__CastExpr).expr)._typ, 344)).or_block.kind != v__ast__OrKind__absent; v__gen__c__Gen_const_decl_init_later(g, field.mod, name, field.expr, field.typ, should_surround); } else if ((field.expr)._typ == 362 /* v.ast.InfixExpr */) { bool has_unwrap_opt_res = false; if (((*field.expr._v__ast__InfixExpr).left)._typ == 344 /* v.ast.CallExpr */) { has_unwrap_opt_res = (*(*field.expr._v__ast__InfixExpr).left._v__ast__CallExpr).or_block.kind != v__ast__OrKind__absent; } else if (((*field.expr._v__ast__InfixExpr).right)._typ == 344 /* v.ast.CallExpr */) { has_unwrap_opt_res = (*(*field.expr._v__ast__InfixExpr).right._v__ast__CallExpr).or_block.kind != v__ast__OrKind__absent; } v__gen__c__Gen_const_decl_init_later(g, field.mod, name, field.expr, field.typ, has_unwrap_opt_res); } else { v__gen__c__Gen_const_decl_init_later(g, field.mod, name, field.expr, field.typ, true); } } } // Defer begin if (v__gen__c__Gen_const_decl_defer_0) { g->inside_const = false; } // Defer end } VV_LOC bool v__gen__c__Gen_const_decl_precomputed(v__gen__c__Gen* g, string mod, string name, string field_name, v__ast__ComptTimeConstValue ct_value, v__ast__Type typ) { string styp = v__gen__c__Gen_styp(g, typ); string cname = (g->pref->translated && !g->is_builtin_mod ? (name) : (str_intp(2, _MOV((StrIntpData[]){{_S("_const_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})))); #if defined(CUSTOM_DEFINE_trace_const_precomputed) { eprintln(str_intp(5, _MOV((StrIntpData[]){{_S("> styp: "), 0xfe10, {.d_s = styp}}, {_S(" | cname: "), 0xfe10, {.d_s = cname}}, {_S(" | ct_value: "), 0xfe10, {.d_s = v__ast__ComptTimeConstValue_str(ct_value)}}, {_S(" | "), 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_sumtype_v__ast__ComptTimeConstValue( (ct_value)._typ ))}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif if (ct_value._typ == 5 /* i8 */) { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, i8_str((*ct_value._i8))); } else if (ct_value._typ == 6 /* i16 */) { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, i16_str((*ct_value._i16))); } else if (ct_value._typ == 7 /* i32 */) { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, i32_str((*ct_value._i32))); } else if (ct_value._typ == 9 /* i64 */) { if (typ == _const_v__ast__i64_type) { return false; } if (typ == _const_v__ast__int_type) { v__gen__c__Gen_const_decl_simple_define(g, mod, name, i64_str((*ct_value._i64))); return true; } if (typ == _const_v__ast__u64_type) { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, string__plus(i64_str((*ct_value._i64)), _S("U"))); } else { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, i64_str((*ct_value._i64))); } } else if (ct_value._typ == 11 /* u8 */) { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, u8_str((*ct_value._u8))); } else if (ct_value._typ == 12 /* u16 */) { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, u16_str((*ct_value._u16))); } else if (ct_value._typ == 13 /* u32 */) { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, u32_str((*ct_value._u32))); } else if (ct_value._typ == 14 /* u64 */) { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, string__plus(u64_str((*ct_value._u64)), _S("U"))); } else if (ct_value._typ == 16 /* f32 */) { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, f32_str((*ct_value._f32))); } else if (ct_value._typ == 17 /* f64 */) { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, f64_str((*ct_value._f64))); } else if (ct_value._typ == 22 /* rune */) { u32 rune_code = ((u32)((*ct_value._rune))); if (rune_code <= 127U) { if (rune_code == '"' || rune_code == '\\' || rune_code == '\'') { return false; } string escval = v__util__smart_quote(u8_ascii_str(((u8)(rune_code))), false); (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){v__util__no_dots(field_name)}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = mod,.def = str_intp(3, _MOV((StrIntpData[]){{_S("#define "), 0xfe10, {.d_s = cname}}, {_S(" '"), 0xfe10, {.d_s = escval}}, {_S("'"), 0, { .d_c = 0 }}})),.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = -1,.is_precomputed = 0,}); } else { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, u32_str(((u32)((*ct_value._rune))))); } } else if (ct_value._typ == 21 /* string */) { string escaped_val = v__util__smart_quote((*ct_value._string), false); string init = (typ == _const_v__ast__string_type ? (str_intp(2, _MOV((StrIntpData[]){{_S("_S(\""), 0xfe10, {.d_s = escaped_val}}, {_S("\")"), 0, { .d_c = 0 }}}))) : (str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = styp}}, {_S(")\""), 0xfe10, {.d_s = escaped_val}}, {_S("\""), 0, { .d_c = 0 }}})))); (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){v__util__no_dots(field_name)}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = mod,.def = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = cname}}, {_S("; // str inited later"), 0, { .d_c = 0 }}})),.init = str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = cname}}, {_S(" = "), 0xfe10, {.d_s = init}}, {_S(";"), 0, { .d_c = 0 }}})),.dep_names = __new_array(0, 0, sizeof(string)),.order = -1,.is_precomputed = 0,}); if (g->is_autofree) { strings__Builder_writeln(&(*(strings__Builder*)map_get(ADDR(map, g->cleanups), &(string[]){mod}, &(strings__Builder[]){ __new_array(0, 0, sizeof(u8)) })), str_intp(2, _MOV((StrIntpData[]){{_S("\tstring_free(&"), 0xfe10, {.d_s = cname}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else if (ct_value._typ == 2 /* voidptr */) { v__gen__c__Gen_const_decl_write_precomputed(g, mod, styp, cname, field_name, str_intp(2, _MOV((StrIntpData[]){{_S("(voidptr)(0x"), 0xfe11, {.d_p = (void*)((*ct_value._voidptr))}}, {_S(")"), 0, { .d_c = 0 }}}))); } else if (ct_value._typ == 354 /* v.ast.EmptyExpr */) { return false; } return true; } VV_LOC void v__gen__c__Gen_const_decl_write_precomputed(v__gen__c__Gen* g, string mod, string styp, string cname, string field_name, string ct_value) { if (g->pref->is_livemain || g->pref->is_liveshared) { (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){v__util__no_dots(field_name)}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = mod,.def = str_intp(3, _MOV((StrIntpData[]){{_S("#define "), 0xfe10, {.d_s = cname}}, {_S(" "), 0xfe10, {.d_s = ct_value}}, {_S(" // precomputed3, -live mode"), 0, { .d_c = 0 }}})),.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = -1,.is_precomputed = 0,}); return; } (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){v__util__no_dots(field_name)}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = mod,.def = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_S("const "), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = cname}}, {_S(" = "), 0xfe10, {.d_s = ct_value}}, {_S("; // precomputed2"), 0, { .d_c = 0 }}})),.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,}); } VV_LOC void v__gen__c__Gen_const_decl_simple_define(v__gen__c__Gen* g, string mod, string name, string val) { string x = v__util__no_dots(name); if (g->pref->translated && !g->is_builtin_mod && !v__util__module_is_builtin(string_all_before_last(name, _S(".")))) { if (string_starts_with(x, _S("main__"))) { x = string_substr(x, 6, 2147483647); } } else { x = str_intp(2, _MOV((StrIntpData[]){{_S("_const_"), 0xfe10, {.d_s = x}}, {_SLIT0, 0, { .d_c = 0 }}})); } if (g->pref->translated) { (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){v__util__no_dots(name)}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = mod,.def = str_intp(3, _MOV((StrIntpData[]){{_S("const int "), 0xfe10, {.d_s = x}}, {_S(" = "), 0xfe10, {.d_s = val}}, {_S(";"), 0, { .d_c = 0 }}})),.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = -1,.is_precomputed = 0,}); } else { (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){v__util__no_dots(name)}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = mod,.def = str_intp(3, _MOV((StrIntpData[]){{_S("#define "), 0xfe10, {.d_s = x}}, {_S(" "), 0xfe10, {.d_s = val}}, {_SLIT0, 0, { .d_c = 0 }}})),.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = -1,.is_precomputed = 0,}); } } VV_LOC string v__gen__c__Gen_c_const_name(v__gen__c__Gen* g, string name) { return (g->pref->translated && !g->is_builtin_mod ? (name) : (str_intp(2, _MOV((StrIntpData[]){{_S("_const_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})))); } VV_LOC void v__gen__c__Gen_const_decl_init_later(v__gen__c__Gen* g, string mod, string name, v__ast__Expr expr, v__ast__Type typ, bool surround_cbr) { if (string_starts_with(name, _S("C__"))) { return; } string styp = v__gen__c__Gen_styp(g, typ); string cname = v__gen__c__Gen_c_const_name(g, name); strings__Builder init = strings__new_builder(100); if (surround_cbr) { strings__Builder_writeln(&init, _S("{")); } if ((expr)._typ == 338 /* v.ast.ArrayInit */ && (*(v__ast__ArrayInit*)__as_cast((expr)._v__ast__ArrayInit,(expr)._typ, 338)).has_index) { strings__Builder_writeln(&init, v__gen__c__Gen_expr_string_surround(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tmemcpy(&"), 0xfe10, {.d_s = cname}}, {_S(", &"), 0, { .d_c = 0 }}})), expr, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}})))); } else if ((expr)._typ == 344 /* v.ast.CallExpr */ && v__ast__Table_final_sym(g->table, v__gen__c__Gen_unwrap_generic(g, (*(v__ast__CallExpr*)__as_cast((expr)._v__ast__CallExpr,(expr)._typ, 344)).return_type))->kind == v__ast__Kind__array_fixed) { strings__Builder_writeln(&init, v__gen__c__Gen_expr_string_surround(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tmemcpy(&"), 0xfe10, {.d_s = cname}}, {_S(", "), 0, { .d_c = 0 }}})), expr, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}})))); } else { strings__Builder_writeln(&init, v__gen__c__Gen_expr_string_surround(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = cname}}, {_S(" = "), 0, { .d_c = 0 }}})), expr, _S(";"))); } if (surround_cbr) { strings__Builder_writeln(&init, _S("}")); } string def = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = cname}}, {_SLIT0, 0, { .d_c = 0 }}})); if (g->pref->parallel_cc) { } v__ast__TypeSymbol* expr_sym = v__ast__Table_sym(g->table, typ); if (expr_sym->kind == v__ast__Kind__function) { v__ast__Fn func = (*(v__ast__FnType*)__as_cast((expr_sym->info)._v__ast__FnType,(expr_sym->info)._typ, 553)).func; Array_v__ast__Type _t1 = {0}; Array_v__ast__Param _t1_orig = func.params; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Param it = ((v__ast__Param*) _t1_orig.data)[_t3]; v__ast__Type _t2 = it.typ; array_push((array*)&_t1, &_t2); } def = v__gen__c__Gen_fn_var_signature(g, func.return_type,_t1, cname); } string init_str = string_trim_right(strings__Builder_str(&init), _S("\n")); (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){v__util__no_dots(name)}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = mod,.def = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = def}}, {_S("; // inited later"), 0, { .d_c = 0 }}})),.init = (string_count(init_str, _S("\n")) > 1 ? (str_intp(2, _MOV((StrIntpData[]){{_S("{\n"), 0xfe10, {.d_s = init_str}}, {_S("\n}"), 0, { .d_c = 0 }}}))) : (init_str)),.dep_names = v__ast__Table_dependent_names_in_expr(g->table, expr),.order = 0,.is_precomputed = 0,}); if (g->is_autofree) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); if (string_starts_with(styp, _S("Array_"))) { if (v__ast__TypeSymbol_has_method_with_generic_parent(sym, _S("free"))) { strings__Builder_writeln(&g->cleanup, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S("_free(&"), 0xfe10, {.d_s = cname}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->cleanup, str_intp(2, _MOV((StrIntpData[]){{_S("\tarray_free(&"), 0xfe10, {.d_s = cname}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else if (_SLIT_EQ(styp.str, styp.len, "string")) { strings__Builder_writeln(&g->cleanup, str_intp(2, _MOV((StrIntpData[]){{_S("\tstring_free(&"), 0xfe10, {.d_s = cname}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (sym->kind == v__ast__Kind__map) { strings__Builder_writeln(&g->cleanup, str_intp(2, _MOV((StrIntpData[]){{_S("\tmap_free(&"), 0xfe10, {.d_s = cname}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (_SLIT_EQ(styp.str, styp.len, "IError")) { strings__Builder_writeln(&g->cleanup, str_intp(2, _MOV((StrIntpData[]){{_S("\tIError_free(&"), 0xfe10, {.d_s = cname}}, {_S(");"), 0, { .d_c = 0 }}}))); } } } VV_LOC void v__gen__c__Gen_const_decl_init_later_msvc_string_fixed_array(v__gen__c__Gen* g, string mod, string name, v__ast__ArrayInit expr, v__ast__Type typ) { string styp = v__gen__c__Gen_styp(g, typ); string cname = v__gen__c__Gen_c_const_name(g, name); strings__Builder init = strings__new_builder(100); for (int i = 0; i < expr.exprs.len; ++i) { v__ast__Expr elem_expr = ((v__ast__Expr*)expr.exprs.data)[i]; if ((elem_expr)._typ == 338 /* v.ast.ArrayInit */ && (*(v__ast__ArrayInit*)__as_cast((elem_expr)._v__ast__ArrayInit,(elem_expr)._typ, 338)).is_fixed) { string elem_typ = v__gen__c__Gen_styp(g, (*elem_expr._v__ast__ArrayInit).typ); strings__Builder_writeln(&init, v__gen__c__Gen_expr_string_surround(g, str_intp(4, _MOV((StrIntpData[]){{_S("\tmemcpy("), 0xfe10, {.d_s = cname}}, {_S("["), 0xfe07, {.d_i32 = i}}, {_S("], ("), 0xfe10, {.d_s = elem_typ}}, {_S(")"), 0, { .d_c = 0 }}})), elem_expr, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = elem_typ}}, {_S("));"), 0, { .d_c = 0 }}})))); } else if ((elem_expr)._typ == 358 /* v.ast.Ident */) { v__ast__Type elem_typ = (*((*elem_expr._v__ast__Ident).obj.typ)); if (v__ast__Table_final_sym(g->table, elem_typ)->kind == v__ast__Kind__array_fixed) { string elem_styp = v__gen__c__Gen_styp(g, (*((*elem_expr._v__ast__Ident).obj.typ))); strings__Builder_writeln(&init, v__gen__c__Gen_expr_string_surround(g, str_intp(3, _MOV((StrIntpData[]){{_S("\tmemcpy("), 0xfe10, {.d_s = cname}}, {_S("["), 0xfe07, {.d_i32 = i}}, {_S("], "), 0, { .d_c = 0 }}})), elem_expr, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = elem_styp}}, {_S("));"), 0, { .d_c = 0 }}})))); } else { strings__Builder_writeln(&init, v__gen__c__Gen_expr_string_surround(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = cname}}, {_S("["), 0xfe07, {.d_i32 = i}}, {_S("] = "), 0, { .d_c = 0 }}})), elem_expr, _S(";"))); } } else { strings__Builder_writeln(&init, v__gen__c__Gen_expr_string_surround(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = cname}}, {_S("["), 0xfe07, {.d_i32 = i}}, {_S("] = "), 0, { .d_c = 0 }}})), elem_expr, _S(";"))); } } string def = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = cname}}, {_SLIT0, 0, { .d_c = 0 }}})); (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){v__util__no_dots(name)}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = mod,.def = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = def}}, {_S("; // inited later"), 0, { .d_c = 0 }}})),.init = string_trim_right(strings__Builder_str(&init), _S("\n")),.dep_names = v__ast__Table_dependent_names_in_expr(g->table, v__ast__ArrayInit_to_sumtype_v__ast__Expr(&expr)),.order = 0,.is_precomputed = 0,}); if (g->is_autofree) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); if (v__ast__TypeSymbol_has_method_with_generic_parent(sym, _S("free"))) { strings__Builder_writeln(&g->cleanup, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S("_free(&"), 0xfe10, {.d_s = cname}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->cleanup, str_intp(2, _MOV((StrIntpData[]){{_S("\tarray_free(&"), 0xfe10, {.d_s = cname}}, {_S(");"), 0, { .d_c = 0 }}}))); } } } VV_LOC void v__gen__c__Gen_global_decl(v__gen__c__Gen* g, v__ast__GlobalDecl node) { bool v__gen__c__Gen_global_decl_defer_0 = false; string visibility_kw = ((g->pref->use_cache || (g->pref->build_mode == v__pref__BuildMode__build_module && !string__eq(g->module_built, node.mod))) && !v__util__should_bundle_module(node.mod) ? (_S("extern ")) : (_S(""))); bool cinit = Array_v__ast__Attr_contains(node.attrs, _S("cinit")); g->inside_cinit = cinit; g->inside_global_decl = true; v__gen__c__Gen_global_decl_defer_0 = true; bool cextern = Array_v__ast__Attr_contains(node.attrs, _S("c_extern")); bool should_init = (!g->pref->use_cache && g->pref->build_mode != v__pref__BuildMode__build_module) || (g->pref->build_mode == v__pref__BuildMode__build_module && string__eq(g->module_built, node.mod)); string attributes = _S(""); if (Array_v__ast__Attr_contains(node.attrs, _S("weak"))) { attributes = string__plus(attributes, _S("VWEAK ")); } if (Array_v__ast__Attr_contains(node.attrs, _S("hidden"))) { attributes = string__plus(attributes, _S("VHIDDEN ")); } if (Array_v__ast__Attr_contains(node.attrs, _S("export"))) { attributes = string__plus(attributes, _S("VV_EXP ")); } _option_v__ast__Attr _t1; if (_t1 = Array_v__ast__Attr_find_first(node.attrs, _S("_linker_section")), _t1.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t1.data; attributes = string__plus(attributes, str_intp(2, _MOV((StrIntpData[]){{_S("__attribute__ ((section (\""), 0xfe10, {.d_s = attr.arg}}, {_S("\"))) "), 0, { .d_c = 0 }}}))); } for (int _t2 = 0; _t2 < node.fields.len; ++_t2) { v__ast__GlobalField field = ((v__ast__GlobalField*)node.fields.data)[_t2]; string name = v__gen__c__c_name(field.name); if (g->pref->skip_unused) { if (!_IN_MAP(ADDR(string, field.name), ADDR(map, g->table->used_features->used_globals))) { #if defined(CUSTOM_DEFINE_trace_skip_unused_globals) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">> skipping unused global name: "), 0xfe10, {.d_s = field.name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif continue; } } string styp = v__gen__c__Gen_styp(g, field.typ); v__ast__Expr anon_fn_expr = field.expr; if (field.has_expr && (anon_fn_expr)._typ == 336 /* v.ast.AnonFn */) { v__gen__c__Gen_gen_anon_fn_decl(g, &/*mut*/(*anon_fn_expr._v__ast__AnonFn)); string fn_type_name = v__gen__c__Gen_get_anon_fn_type_name(g, &/*mut*/(*anon_fn_expr._v__ast__AnonFn), field.name); (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){v__util__no_dots(fn_type_name)}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = node.mod,.def = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_type_name}}, {_S(" = "), 0xfe10, {.d_s = v__ast__Table_sym(g->table, field.typ)->name}}, {_S("; // global 1"), 0, { .d_c = 0 }}})),.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = -1,.is_precomputed = 0,}); continue; } strings__Builder def_builder = strings__new_builder(100); string init = _S(""); string __v_extern = (cextern ? (_S("extern ")) : (_S(""))); string modifier = (field.is_volatile ? (_S(" volatile ")) : (_S(""))); { strings__Builder_write_string(&def_builder, __v_extern); strings__Builder_write_string(&def_builder, visibility_kw); strings__Builder_write_string(&def_builder, modifier); strings__Builder_write_string(&def_builder, styp); strings__Builder_write_string(&def_builder, _S(" ")); strings__Builder_write_string(&def_builder, attributes); strings__Builder_write_string(&def_builder, field.name); } if (cextern) { strings__Builder_writeln(&def_builder, _S("; // global 2")); (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){name}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = node.mod,.def = strings__Builder_str(&def_builder),.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = -1,.is_precomputed = 0,}); continue; } if (field.has_expr || cinit) { bool is_simple_unsafe_expr = false; if ((field.expr)._typ == 388 /* v.ast.UnsafeExpr */) { if (((*field.expr._v__ast__UnsafeExpr).expr)._typ == 370 /* v.ast.Nil */) { is_simple_unsafe_expr = true; } if (v__ast__Expr_is_literal((*field.expr._v__ast__UnsafeExpr).expr)) { is_simple_unsafe_expr = true; } } if (g->pref->translated) { { strings__Builder_write_string(&def_builder, _S(" = ")); strings__Builder_write_string(&def_builder, v__gen__c__Gen_expr_string(g, field.expr)); } } else if ((v__ast__Expr_is_literal(field.expr) && should_init) || cinit || ((field.expr)._typ == 338 /* v.ast.ArrayInit */ && (*(v__ast__ArrayInit*)__as_cast((field.expr)._v__ast__ArrayInit,(field.expr)._typ, 338)).is_fixed) || (is_simple_unsafe_expr && should_init)) { { strings__Builder_write_string(&def_builder, _S(" = ")); strings__Builder_write_string(&def_builder, v__gen__c__Gen_expr_string(g, field.expr)); } } else { if (fast_string_eq(field.name, _S("g_main_argc")) || fast_string_eq(field.name, _S("g_main_argv"))) { init = str_intp(2, _MOV((StrIntpData[]){{_S("\t// skipping "), 0xfe10, {.d_s = field.name}}, {_S(", it was initialised in main"), 0, { .d_c = 0 }}})); } else { init = str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = field.name}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__Gen_expr_string(g, field.expr)}}, {_S("; // global 3"), 0, { .d_c = 0 }}})); } } } else if (!g->pref->translated) { array_clear(&g->type_default_vars); string default_initializer = v__gen__c__Gen_type_default(g, field.typ); if (_SLIT_EQ(default_initializer.str, default_initializer.len, "{0}") && should_init) { strings__Builder_write_string(&def_builder, _S(" = {0}")); } else if (_SLIT_EQ(default_initializer.str, default_initializer.len, "{E_STRUCT}") && should_init) { init = str_intp(5, _MOV((StrIntpData[]){{_S("\tmemcpy("), 0xfe10, {.d_s = field.name}}, {_S(", ("), 0xfe10, {.d_s = styp}}, {_S("){"), 0xfe10, {.d_s = default_initializer}}, {_S("}, sizeof("), 0xfe10, {.d_s = styp}}, {_S(")); // global 4"), 0, { .d_c = 0 }}})); } else { if (!(fast_string_eq(field.name, _S("as_cast_type_indexes")) || fast_string_eq(field.name, _S("g_memory_block")) || fast_string_eq(field.name, _S("global_allocator")))) { string decls = strings__Builder_str(&g->type_default_vars); if ((decls).len != 0) { init = str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = decls}}, {_SLIT0, 0, { .d_c = 0 }}})); } init = string__plus(init, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = field.name}}, {_S(" = *("), 0xfe10, {.d_s = styp}}, {_S("*)&(("), 0xfe10, {.d_s = styp}}, {_S("[]){"), 0xfe10, {.d_s = default_initializer}}, {_S("}[0]); // global 5"), 0, { .d_c = 0 }}}))); } } } strings__Builder_writeln(&def_builder, _S("; // global 6")); (*(v__gen__c__GlobalConstDef*)map_get_and_set((map*)&g->global_const_defs, &(string[]){name}, &(v__gen__c__GlobalConstDef[]){ (v__gen__c__GlobalConstDef){.mod = (string){.str=(byteptr)"", .is_lit=1},.def = (string){.str=(byteptr)"", .is_lit=1},.init = (string){.str=(byteptr)"", .is_lit=1},.dep_names = __new_array(0, 0, sizeof(string)),.order = 0,.is_precomputed = 0,} })) = ((v__gen__c__GlobalConstDef){.mod = node.mod,.def = strings__Builder_str(&def_builder),.init = init,.dep_names = v__ast__Table_dependent_names_in_expr(g->table, field.expr),.order = 0,.is_precomputed = 0,}); } // Defer begin if (v__gen__c__Gen_global_decl_defer_0) { g->inside_cinit = false; g->inside_global_decl = false; } // Defer end } VV_LOC void v__gen__c__Gen_sort_globals_consts(v__gen__c__Gen* g) { bool v__gen__c__Gen_sort_globals_consts_defer_0 = false; v__util__timing_start(_S("Gen.sort_globals_consts")); v__gen__c__Gen_sort_globals_consts_defer_0 = true; array_clear(&g->sorted_global_const_names); v__depgraph__DepGraph* dep_graph = v__depgraph__new_dep_graph(); Map_string_v__gen__c__GlobalConstDef _t1 = g->global_const_defs; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string var_name = *(string*)DenseArray_key(&_t1.key_values, _t2); var_name = string_clone(var_name); v__gen__c__GlobalConstDef var_info = (*(v__gen__c__GlobalConstDef*)DenseArray_value(&_t1.key_values, _t2)); v__depgraph__DepGraph_add_with_value(dep_graph, var_name, var_info.dep_names, var_info.order); } v__depgraph__DepGraph* dep_graph_sorted = v__depgraph__DepGraph_resolve(dep_graph); Array_int _t5 = new_array_from_c_array(2, 2, sizeof(int), _MOV((int[2]){-1, 0})); for (int _t6 = 0; _t6 < _t5.len; ++_t6) { int order = ((int*)_t5.data)[_t6]; for (int _t7 = 0; _t7 < dep_graph_sorted->nodes.len; ++_t7) { v__depgraph__DepGraphNode node = ((v__depgraph__DepGraphNode*)dep_graph_sorted->nodes.data)[_t7]; if (node.value == order) { array_push((array*)&g->sorted_global_const_names, _MOV((string[]){ string_clone(node.name) })); } } } // Defer begin if (v__gen__c__Gen_sort_globals_consts_defer_0) { v__util__timing_measure(_S("Gen.sort_globals_consts")); } // Defer end } VV_LOC void v__gen__c__Gen_write_coverage_point(v__gen__c__Gen* g, v__token__Pos pos) { if (!_IN_MAP(ADDR(u64, g->unique_file_path_hash), ADDR(map, g->coverage_files))) { string build_options = Array_string_join(g->pref->build_options, _S(" ")); string fhash = u64_hex_full(hash__sum64_string(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = build_options}}, {_S(":"), 0xfe08, {.d_u64 = g->unique_file_path_hash}}, {_SLIT0, 0, { .d_c = 0 }}})), 32U)); (*(v__gen__c__CoverageInfo**)map_get_and_set((map*)&g->coverage_files, &(u64[]){g->unique_file_path_hash}, &(v__gen__c__CoverageInfo*[]){ 0 })) = ((v__gen__c__CoverageInfo*)memdup(&(v__gen__c__CoverageInfo){.idx = 0,.points = __new_array_with_default(0, 0, sizeof(u64), 0),.file = g->file,.fhash = fhash,.build_options = build_options,}, sizeof(v__gen__c__CoverageInfo))); } if (g->fn_decl != ((void*)0)) { u64 curr_line = ((u64)(pos.line_nr)); v__gen__c__CoverageInfo* curr_cov = (*(v__gen__c__CoverageInfo**)map_get(ADDR(map, g->coverage_files), &(u64[]){g->unique_file_path_hash}, &(v__gen__c__CoverageInfo*[]){ 0 })); if (!(Array_u64_contains(curr_cov->points, curr_line))) { array_push((array*)&curr_cov->points, _MOV((u64[]){ curr_line })); } string stmt_str = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("_v_cov[_v_cov_file_offset_"), 0xfe08, {.d_u64 = g->unique_file_path_hash}}, {_S("+"), 0xfe07, {.d_i32 = (int)(curr_cov->points.len - 1)}}, {_S("]++;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); v__gen__c__Gen_write(g, stmt_str); } } VV_LOC void v__gen__c__Gen_write_coverage_stats(v__gen__c__Gen* g) { string build_options = Array_string_join(g->pref->build_options, _S(" ")); string coverage_dir = string_replace(os__real_path(g->pref->coverage_dir), _S("\\"), _S("/")); string coverage_meta_folder = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = coverage_dir}}, {_S("/meta"), 0, { .d_c = 0 }}})); if (!os__exists(coverage_meta_folder)) { _result_void _t1 = os__mkdir_all(coverage_meta_folder, ((os__MkdirParams){.mode = 0777,})); (void)_t1; ; } string counter_ulid = rand__ulid(); strings__Builder_writeln(&g->cov_declarations, _S("")); strings__Builder_writeln(&g->cov_declarations, _S("void vprint_coverage_stats() {")); strings__Builder_writeln(&g->cov_declarations, _S("\tchar cov_filename[2048];")); string covdir = v__gen__c__cesc(coverage_dir); strings__Builder_writeln(&g->cov_declarations, str_intp(2, _MOV((StrIntpData[]){{_S("\tchar *cov_dir = \""), 0xfe10, {.d_s = covdir}}, {_S("\";"), 0, { .d_c = 0 }}}))); Map_u64_v__gen__c__CoverageInfo_ptr _t2 = g->coverage_files; int _t4 = _t2.key_values.len; for (int _t3 = 0; _t3 < _t4; ++_t3 ) { int _t5 = _t2.key_values.len - _t4; _t4 = _t2.key_values.len; if (_t5 < 0) { _t3 = -1; continue; } if (!DenseArray_has_index(&_t2.key_values, _t3)) {continue;} v__gen__c__CoverageInfo** cov = &(*(v__gen__c__CoverageInfo**)DenseArray_value(&_t2.key_values, _t3)); string metadata_coverage_fpath = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = coverage_meta_folder}}, {_S("/"), 0xfe10, {.d_s = (*cov)->fhash}}, {_S(".json"), 0, { .d_c = 0 }}})); string filepath = string_replace(os__real_path((*cov)->file->path), _S("\\"), _S("/")); if (os__exists(metadata_coverage_fpath)) { continue; } _result_os__File _t6 = os__create(metadata_coverage_fpath); if (_t6.is_error) { IError err = _t6.err; continue; } os__File fmeta = (*(os__File*)_t6.data); _result_int _t7 = os__File_writeln(&fmeta, _S("{")); if (_t7.is_error) { IError err = _t7.err; continue; } ; string jfilepath = v__gen__c__jesc(filepath); string jfhash = v__gen__c__jesc((*cov)->fhash); string jversion = v__gen__c__jesc(v__util__version__full_v_version(true)); string jboptions = v__gen__c__jesc((*cov)->build_options); _result_int _t8 = os__File_writeln(&fmeta, str_intp(3, _MOV((StrIntpData[]){{_S(" \"file\": \""), 0xfe10, {.d_s = jfilepath}}, {_S("\", \"fhash\": \""), 0xfe10, {.d_s = jfhash}}, {_S("\","), 0, { .d_c = 0 }}}))); if (_t8.is_error) { IError err = _t8.err; continue; } ; _result_int _t9 = os__File_writeln(&fmeta, str_intp(2, _MOV((StrIntpData[]){{_S(" \"v_version\": \""), 0xfe10, {.d_s = jversion}}, {_S("\","), 0, { .d_c = 0 }}}))); if (_t9.is_error) { IError err = _t9.err; continue; } ; _result_int _t10 = os__File_writeln(&fmeta, str_intp(2, _MOV((StrIntpData[]){{_S(" \"build_options\": \""), 0xfe10, {.d_s = jboptions}}, {_S("\","), 0, { .d_c = 0 }}}))); if (_t10.is_error) { IError err = _t10.err; continue; } ; _result_int _t11 = os__File_writeln(&fmeta, str_intp(2, _MOV((StrIntpData[]){{_S(" \"npoints\": "), 0xfe07, {.d_i32 = (*cov)->points.len}}, {_S(","), 0, { .d_c = 0 }}}))); if (_t11.is_error) { IError err = _t11.err; continue; } ; _result_int _t12 = os__File_write_string(&fmeta, _S(" \"points\": [ ")); if (_t12.is_error) { IError err = _t12.err; continue; } ; for (int idx = 0; idx < (*cov)->points.len; ++idx) { u64 p = ((u64*)(*cov)->points.data)[idx]; _result_int _t13 = os__File_write_string(&fmeta, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe08, {.d_u64 = (u64)(p + 1U)}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (_t13.is_error) { IError err = _t13.err; continue; } ; if (idx < (int)((*cov)->points.len - 1)) { _result_int _t14 = os__File_write_string(&fmeta, _S(",")); if (_t14.is_error) { IError err = _t14.err; continue; } ; } } _result_int _t15 = os__File_writeln(&fmeta, _S(" ]")); if (_t15.is_error) { IError err = _t15.err; continue; } ; _result_int _t16 = os__File_writeln(&fmeta, _S("}")); if (_t16.is_error) { IError err = _t16.err; continue; } ; os__File_close(&fmeta); } strings__Builder_writeln(&g->cov_declarations, _S("\tlong int secs = 0;")); strings__Builder_writeln(&g->cov_declarations, _S("\tlong int nsecs = 0;")); strings__Builder_writeln(&g->cov_declarations, _S("\t#if defined(_WIN32)")); strings__Builder_writeln(&g->cov_declarations, _S("\tlong int ticks_passed = GetTickCount();")); strings__Builder_writeln(&g->cov_declarations, _S("\nsecs = ticks_passed / 1000;")); strings__Builder_writeln(&g->cov_declarations, _S("\nnsecs = (ticks_passed % 1000) * 1000000;")); strings__Builder_writeln(&g->cov_declarations, _S("\t#endif")); strings__Builder_writeln(&g->cov_declarations, _S("\t#if !defined(_WIN32)")); strings__Builder_writeln(&g->cov_declarations, _S("\tstruct timespec ts;")); strings__Builder_writeln(&g->cov_declarations, _S("\tclock_gettime(CLOCK_MONOTONIC, &ts);")); strings__Builder_writeln(&g->cov_declarations, _S("\tsecs = ts.tv_sec;")); strings__Builder_writeln(&g->cov_declarations, _S("\nsecs = ts.tv_nsec;")); strings__Builder_writeln(&g->cov_declarations, _S("\t#endif")); strings__Builder_writeln(&g->cov_declarations, str_intp(2, _MOV((StrIntpData[]){{_S("\tsnprintf(cov_filename, sizeof(cov_filename), \"%s/vcounters_"), 0xfe10, {.d_s = counter_ulid}}, {_S(".%07ld.%09ld.csv\", cov_dir, secs, nsecs);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->cov_declarations, _S("\tFILE *fp = fopen(cov_filename, \"wb+\");")); string cprefpath = v__gen__c__cesc(os__real_path(g->pref->path)); string cboptions = v__gen__c__cesc(build_options); strings__Builder_writeln(&g->cov_declarations, str_intp(2, _MOV((StrIntpData[]){{_S("\tfprintf(fp, \"# path: "), 0xfe10, {.d_s = cprefpath}}, {_S("\\n\");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->cov_declarations, str_intp(2, _MOV((StrIntpData[]){{_S("\tfprintf(fp, \"# build_options: "), 0xfe10, {.d_s = cboptions}}, {_S("\\n\");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->cov_declarations, _S("\tfprintf(fp, \"meta,point,hits\\n\");")); Map_u64_v__gen__c__CoverageInfo_ptr _t17 = g->coverage_files; int _t19 = _t17.key_values.len; for (int _t18 = 0; _t18 < _t19; ++_t18 ) { int _t20 = _t17.key_values.len - _t19; _t19 = _t17.key_values.len; if (_t20 < 0) { _t18 = -1; continue; } if (!DenseArray_has_index(&_t17.key_values, _t18)) {continue;} u64 k = *(u64*)DenseArray_key(&_t17.key_values, _t18); v__gen__c__CoverageInfo* cov = (*(v__gen__c__CoverageInfo**)DenseArray_value(&_t17.key_values, _t18)); int nr_points = cov->points.len; strings__Builder_writeln(&g->cov_declarations, _S("\t{")); strings__Builder_writeln(&g->cov_declarations, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tfor (int i = 0; i < "), 0xfe07, {.d_i32 = nr_points}}, {_S("; ++i) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->cov_declarations, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tif (_v_cov[_v_cov_file_offset_"), 0xfe08, {.d_u64 = k}}, {_S("+i]) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->cov_declarations, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t\t\tfprintf(fp, \"%s,%d,%ld\\n\", \""), 0xfe10, {.d_s = cov->fhash}}, {_S("\", i, _v_cov[_v_cov_file_offset_"), 0xfe08, {.d_u64 = k}}, {_S("+i]);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->cov_declarations, _S("\t\t\t}")); strings__Builder_writeln(&g->cov_declarations, _S("\t\t}")); strings__Builder_writeln(&g->cov_declarations, _S("\t}")); } strings__Builder_writeln(&g->cov_declarations, _S("\tfclose(fp);")); strings__Builder_writeln(&g->cov_declarations, _S("}")); } VV_LOC string v__gen__c__cesc(string s) { return v__gen__c__cescape_nonascii(v__gen__c__cestring(s)); } VV_LOC string v__gen__c__jesc(string s) { return v__gen__c__escape_quotes(s); } VV_LOC v__ast__CTempVar v__gen__c__Gen_new_ctemp_var(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_type) { return ((v__ast__CTempVar){.name = v__gen__c__Gen_new_tmp_var(g),.typ = expr_type,.is_ptr = v__ast__Type_is_ptr(expr_type),.orig = expr,.is_fixed_ret = 0,}); } VV_LOC v__ast__CTempVar v__gen__c__Gen_new_ctemp_var_then_gen(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expr_type) { v__ast__CTempVar x = v__gen__c__Gen_new_ctemp_var(g, expr, expr_type); v__gen__c__Gen_gen_ctemp_var(g, (voidptr)&x); return x; } VV_LOC void v__gen__c__Gen_gen_ctemp_var(v__gen__c__Gen* g, v__ast__CTempVar* tvar) { string styp = v__gen__c__Gen_styp(g, tvar->typ); v__ast__TypeSymbol* final_sym = v__ast__Table_final_sym(g->table, tvar->typ); if ((final_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { tvar->is_fixed_ret = (*final_sym->info._v__ast__ArrayFixed).is_fn_ret; v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = tvar->name}}, {_S(";"), 0, { .d_c = 0 }}}))); if (tvar->is_fixed_ret) { { v__gen__c__Gen_write(g, _S("memcpy(")); v__gen__c__Gen_write(g, tvar->name); v__gen__c__Gen_write(g, _S(".ret_arr, ")); } v__gen__c__Gen_expr(g, tvar->orig); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(" , sizeof("), 0xfe10, {.d_s = string_substr(styp, 3, 2147483647)}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { { v__gen__c__Gen_write(g, _S("memcpy(&")); v__gen__c__Gen_write(g, tvar->name); v__gen__c__Gen_write(g, _S(", ")); } v__gen__c__Gen_expr(g, tvar->orig); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(" , sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } } else { { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tvar->name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, tvar->orig); v__gen__c__Gen_writeln(g, _S(";")); } v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } VV_LOC void v__gen__c__Gen_dump_expr(v__gen__c__Gen* g, v__ast__DumpExpr node) { bool v__gen__c__Gen_dump_expr_defer_0 = false; string sexpr = v__gen__c__ctoslit(v__ast__Expr_str(&node.expr)); string fpath = v__gen__c__cestring(g->file->path); int line = (int)(node.pos.line_nr + 1); if ((Array_string_contains(g->pref->compile_defines, _S("nop_dump")))) { v__gen__c__Gen_expr(g, node.expr); return; } string name = node.cname; v__ast__Type expr_type = node.expr_type; if ((node.expr)._typ == 344 /* v.ast.CallExpr */) { g->inside_dump_fn = true; v__gen__c__Gen_dump_expr_defer_0 = true; } if (g->cur_fn != ((void*)0) && g->cur_fn->generic_names.len > 0) { if ((node.expr)._typ == 358 /* v.ast.Ident */) { if (((*node.expr._v__ast__Ident).info)._typ == 477 /* v.ast.IdentVar */ && (*node.expr._v__ast__Ident).language == v__ast__Language__v) { name = string_replace(v__gen__c__Gen_styp(g, v__gen__c__Gen_unwrap_generic(g, v__ast__Type_clear_flags((*(*node.expr._v__ast__Ident).info._v__ast__IdentVar).typ, new_array_from_c_array(2, 2, sizeof(v__ast__TypeFlag), _MOV((v__ast__TypeFlag[2]){v__ast__TypeFlag__shared_f, v__ast__TypeFlag__result}))))), _S("*"), _S("")); } } } if ((node.expr)._typ == 350 /* v.ast.ComptimeSelector */ && (*(v__ast__ComptimeSelector*)__as_cast((node.expr)._v__ast__ComptimeSelector,(node.expr)._typ, 350)).is_name) { if (((*node.expr._v__ast__ComptimeSelector).field_expr)._typ == 379 /* v.ast.SelectorExpr */ && ((*(v__ast__SelectorExpr*)__as_cast(((*node.expr._v__ast__ComptimeSelector).field_expr)._v__ast__SelectorExpr,((*node.expr._v__ast__ComptimeSelector).field_expr)._typ, 379)).expr)._typ == 358 /* v.ast.Ident */) { if (string__eq((*(*(*node.expr._v__ast__ComptimeSelector).field_expr._v__ast__SelectorExpr).expr._v__ast__Ident).name, g->comptime->comptime_for_field_var)) { multi_return_v__ast__StructField_string mr_1047 = v__type_resolver__TypeResolver_get_comptime_selector_var_type(&g->type_resolver, (*node.expr._v__ast__ComptimeSelector)); v__ast__StructField field = mr_1047.arg0; name = v__gen__c__Gen_styp(g, v__gen__c__Gen_unwrap_generic(g, v__ast__Type_clear_flags(field.typ, new_array_from_c_array(2, 2, sizeof(v__ast__TypeFlag), _MOV((v__ast__TypeFlag[2]){v__ast__TypeFlag__shared_f, v__ast__TypeFlag__result}))))); expr_type = field.typ; } } } else if ((node.expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node.expr)._v__ast__Ident,(node.expr)._typ, 358)).ct_expr) { expr_type = v__type_resolver__TypeResolver_get_type(&g->type_resolver, node.expr); name = string_replace(v__gen__c__Gen_styp(g, v__gen__c__Gen_unwrap_generic(g, v__ast__Type_clear_flags(expr_type, new_array_from_c_array(2, 2, sizeof(v__ast__TypeFlag), _MOV((v__ast__TypeFlag[2]){v__ast__TypeFlag__shared_f, v__ast__TypeFlag__result}))))), _S("*"), _S("")); } else if ((node.expr)._typ == 379 /* v.ast.SelectorExpr */ && ((*(v__ast__SelectorExpr*)__as_cast((node.expr)._v__ast__SelectorExpr,(node.expr)._typ, 379)).expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast(((*(v__ast__SelectorExpr*)__as_cast((node.expr)._v__ast__SelectorExpr,(node.expr)._typ, 379)).expr)._v__ast__Ident,((*(v__ast__SelectorExpr*)__as_cast((node.expr)._v__ast__SelectorExpr,(node.expr)._typ, 379)).expr)._typ, 358)).ct_expr) { expr_type = v__gen__c__Gen_comptime_selector_type(g, (*node.expr._v__ast__SelectorExpr)); name = string_replace(v__gen__c__Gen_styp(g, v__gen__c__Gen_unwrap_generic(g, v__ast__Type_clear_flags(expr_type, new_array_from_c_array(2, 2, sizeof(v__ast__TypeFlag), _MOV((v__ast__TypeFlag[2]){v__ast__TypeFlag__shared_f, v__ast__TypeFlag__result}))))), _S("*"), _S("")); } if (v__ast__Table_sym(g->table, node.expr_type)->language == v__ast__Language__c) { name = string_substr(name, 3, 2147483647); } string dump_fn_name = string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("_v_dump_expr_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})), ((v__ast__Type_is_ptr(expr_type) ? (string_repeat(_S("__ptr"), v__ast__Type_nr_muls(expr_type))) : (_S(""))))); { v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, dump_fn_name); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, v__gen__c__ctoslit(fpath)); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, line); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, sexpr); v__gen__c__Gen_write(g, _S(", ")); } if (v__ast__Type_has_flag(expr_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("&")); v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write(g, _S("->val")); } else if (v__ast__Type_has_flag(expr_type, v__ast__TypeFlag__result)) { bool old_inside_opt_or_res = g->inside_opt_or_res; g->inside_opt_or_res = true; { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S("*)")); } v__gen__c__Gen_expr(g, node.expr); v__gen__c__Gen_write(g, _S(".data)")); g->inside_opt_or_res = old_inside_opt_or_res; } else if ((node.expr)._typ == 338 /* v.ast.ArrayInit */) { if ((*node.expr._v__ast__ArrayInit).is_fixed) { string s = v__gen__c__Gen_styp(g, (*node.expr._v__ast__ArrayInit).typ); if (!(*node.expr._v__ast__ArrayInit).has_index) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, s); v__gen__c__Gen_write(g, _S(")")); } } } v__gen__c__Gen_expr(g, node.expr); } else { bool old_inside_opt_or_res = g->inside_opt_or_res; g->inside_opt_or_res = true; if (v__ast__Type_has_flag(expr_type, v__ast__TypeFlag__option_mut_param_t)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, node.expr); g->inside_opt_or_res = old_inside_opt_or_res; } v__gen__c__Gen_write(g, _S(")")); if ((g->inside_assign || g->expected_fixed_arr) && !v__ast__Type_has_option_or_result(expr_type) && v__ast__Table_final_sym(g->table, expr_type)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_write(g, _S(".ret_arr")); } // Defer begin if (v__gen__c__Gen_dump_expr_defer_0) { g->inside_dump_fn = false; } // Defer end } VV_LOC void v__gen__c__Gen_dump_expr_definitions(v__gen__c__Gen* g) { Map_string_bool dump_already_generated_fns = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_bool dump_typedefs = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; strings__Builder dump_fns = strings__new_builder(100); strings__Builder dump_fn_defs = strings__new_builder(100); Map_int_string _t1 = g->table->dumps; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} int dump_type = *(int*)DenseArray_key(&_t1.key_values, _t2); string cname = (*(string*)DenseArray_value(&_t1.key_values, _t2)); v__ast__TypeSymbol* dump_sym = v__ast__Table_sym(g->table, v__ast__idx_to_type(dump_type)); string name = cname; if (dump_sym->language == v__ast__Language__c) { name = string_substr(name, 3, 2147483647); } multi_return_bool_bool_int mr_3361 = v__ast__TypeSymbol_str_method_info(dump_sym); bool str_method_expects_ptr = mr_3361.arg1; v__ast__Type typ = v__ast__idx_to_type(dump_type); bool is_ptr = v__ast__Type_is_ptr(typ); multi_return_string_string mr_3463 = v__gen__c__deref_kind(str_method_expects_ptr, is_ptr, typ); string deref = mr_3463.arg0; string to_string_fn_name = v__gen__c__Gen_get_str_fn(g, v__ast__Type_clear_flags(typ, new_array_from_c_array(2, 2, sizeof(v__ast__TypeFlag), _MOV((v__ast__TypeFlag[2]){v__ast__TypeFlag__shared_f, v__ast__TypeFlag__result})))); bool is_option = v__ast__Type_has_option_or_result(typ); string ptr_asterisk = (is_ptr ? (string_repeat(_S("*"), v__ast__Type_nr_muls(typ))) : (_S(""))); string str_dumparg_type = _S(""); string str_dumparg_ret_type = _S(""); if (dump_sym->kind == v__ast__Kind__none) { str_dumparg_type = string__plus(_S("IError"), ptr_asterisk); } else if (dump_sym->kind == v__ast__Kind__function) { if (is_option) { ptr_asterisk = string_replace(ptr_asterisk, _S("*"), _S("_ptr")); } str_dumparg_type = string__plus(str_dumparg_type, string__plus(string_replace(v__gen__c__Gen_styp(g, typ), _S("*"), _S("")), ptr_asterisk)); } else { if (is_option) { str_dumparg_type = string__plus(str_dumparg_type, _S("_option_")); ptr_asterisk = string_replace(ptr_asterisk, _S("*"), _S("_ptr")); } str_dumparg_type = string__plus(str_dumparg_type, string__plus(v__gen__c__Gen_cc_type(g, typ, true), ptr_asterisk)); } bool is_fixed_arr_ret = false; if ((dump_sym->info)._typ == 553 /* v.ast.FnType */ && !is_option) { str_dumparg_type = str_intp(2, _MOV((StrIntpData[]){{_S("DumpFNType_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); int tdef_pos = g->out.len; v__gen__c__Gen_write_fn_ptr_decl(g, &(*dump_sym->info._v__ast__FnType), str_dumparg_type); string str_tdef = strings__Builder_after(&g->out, tdef_pos); v__gen__c__Gen_go_back(g, str_tdef.len); map_set(&dump_typedefs, &(string[]){str_intp(2, _MOV((StrIntpData[]){{_S("typedef "), 0xfe10, {.d_s = str_tdef}}, {_S(";"), 0, { .d_c = 0 }}}))}, &(bool[]) { true }); str_dumparg_ret_type = str_dumparg_type; } else if (!is_option && v__ast__TypeSymbol_is_array_fixed(dump_sym)) { if (dump_sym->kind == (v__ast__Kind__array_fixed)) { if ((*(v__ast__ArrayFixed*)__as_cast((dump_sym->info)._v__ast__ArrayFixed,(dump_sym->info)._typ, 549)).is_fn_ret) { str_dumparg_ret_type = str_dumparg_type; str_dumparg_type = string_trim_string_left(str_dumparg_type, _S("_v_")); } else { str_dumparg_ret_type = string__plus(_S("_v_"), str_dumparg_type); } } else if (dump_sym->kind == (v__ast__Kind__alias)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(g->table, (*(v__ast__Alias*)__as_cast((dump_sym->info)._v__ast__Alias,(dump_sym->info)._typ, 539)).parent_type); if (parent_sym->kind == v__ast__Kind__array_fixed) { str_dumparg_ret_type = string__plus(((*(v__ast__ArrayFixed*)__as_cast((parent_sym->info)._v__ast__ArrayFixed,(parent_sym->info)._typ, 549)).is_fn_ret ? (_S("")) : (_S("_v_"))), v__gen__c__Gen_cc_type(g, (*(v__ast__Alias*)__as_cast((dump_sym->info)._v__ast__Alias,(dump_sym->info)._typ, 539)).parent_type, true)); str_dumparg_type = string_trim_string_left(str_dumparg_ret_type, _S("_v_")); is_fixed_arr_ret = true; } } else { } is_fixed_arr_ret = true; } else { str_dumparg_ret_type = str_dumparg_type; } string dump_fn_name = string__plus(str_intp(2, _MOV((StrIntpData[]){{_S("_v_dump_expr_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})), ((is_ptr ? (string_repeat(_S("__ptr"), v__ast__Type_nr_muls(typ))) : (_S(""))))); if ((*(bool*)map_get(ADDR(map, dump_already_generated_fns), &(string[]){dump_fn_name}, &(bool[]){ 0 }))) { continue; } map_set(&dump_already_generated_fns, &(string[]){dump_fn_name}, &(bool[]) { true }); strings__Builder_writeln(&dump_fn_defs, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = str_dumparg_ret_type}}, {_S(" "), 0xfe10, {.d_s = dump_fn_name}}, {_S("(string fpath, int line, string sexpr, "), 0xfe10, {.d_s = str_dumparg_type}}, {_S(" dump_arg);"), 0, { .d_c = 0 }}}))); if (v__gen__c__Gen_writeln_fn_header(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = str_dumparg_ret_type}}, {_S(" "), 0xfe10, {.d_s = dump_fn_name}}, {_S("(string fpath, int line, string sexpr, "), 0xfe10, {.d_s = str_dumparg_type}}, {_S(" dump_arg)"), 0, { .d_c = 0 }}})), (voidptr)&dump_fns)) { continue; } v__util__Surrounder surrounder = v__util__new_surrounder(3); v__util__Surrounder_add(&surrounder, _S("\tstring sline = int_str(line);"), _S("\tstring_free(&sline);")); if (dump_sym->kind == v__ast__Kind__function && !is_option) { v__util__Surrounder_add(&surrounder, str_intp(2, _MOV((StrIntpData[]){{_S("\tstring value = "), 0xfe10, {.d_s = to_string_fn_name}}, {_S("();"), 0, { .d_c = 0 }}})), _S("\tstring_free(&value);")); } else if (dump_sym->kind == v__ast__Kind__none) { v__util__Surrounder_add(&surrounder, _S("\tstring value = _S(\"none\");"), _S("\tstring_free(&value);")); } else if (is_ptr) { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { v__util__Surrounder_add(&surrounder, str_intp(3, _MOV((StrIntpData[]){{_S("\tstring value = isnil(&dump_arg.data) ? _S(\"nil\") : "), 0xfe10, {.d_s = to_string_fn_name}}, {_S("("), 0xfe10, {.d_s = deref}}, {_S("dump_arg);"), 0, { .d_c = 0 }}})), _S("\tstring_free(&value);")); } else { string prefix = (v__ast__TypeSymbol_is_c_struct(dump_sym) ? (v__gen__c__c_struct_ptr(dump_sym, typ, str_method_expects_ptr)) : (deref)); v__util__Surrounder_add(&surrounder, str_intp(3, _MOV((StrIntpData[]){{_S("\tstring value = (dump_arg == NULL) ? _S(\"nil\") : "), 0xfe10, {.d_s = to_string_fn_name}}, {_S("("), 0xfe10, {.d_s = prefix}}, {_S("dump_arg);"), 0, { .d_c = 0 }}})), _S("\tstring_free(&value);")); } } else { string prefix = (v__ast__TypeSymbol_is_c_struct(dump_sym) ? (v__gen__c__c_struct_ptr(dump_sym, typ, str_method_expects_ptr)) : (deref)); v__util__Surrounder_add(&surrounder, str_intp(3, _MOV((StrIntpData[]){{_S("\tstring value = "), 0xfe10, {.d_s = to_string_fn_name}}, {_S("("), 0xfe10, {.d_s = prefix}}, {_S("dump_arg);"), 0, { .d_c = 0 }}})), _S("\tstring_free(&value);")); } v__util__Surrounder_add(&surrounder, _S("\n\011strings__Builder sb = strings__new_builder(64);\n"), _S("\n\011string res;\n\011res = strings__Builder_str(&sb);\n\011eprint(res);\n\011string_free(&res);\n\011strings__Builder_free(&sb);\n")); v__util__Surrounder_builder_write_befores(&surrounder, (voidptr)&dump_fns); strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_rune(&sb, '[');")); strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_string(&sb, fpath);")); strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_rune(&sb, ':');")); strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_string(&sb, sline);")); strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_rune(&sb, ']');")); strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_rune(&sb, ' ');")); strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_string(&sb, sexpr);")); strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_rune(&sb, ':');")); strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_rune(&sb, ' ');")); if (is_ptr) { for (int i = 0; i < v__ast__Type_nr_muls(typ); i++) { strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_rune(&sb, '&');")); } } strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_string(&sb, value);")); strings__Builder_writeln(&dump_fns, _S("\tstrings__Builder_write_rune(&sb, '\\n');")); v__util__Surrounder_builder_write_afters(&surrounder, (voidptr)&dump_fns); if (is_fixed_arr_ret) { string tmp_var = v__gen__c__Gen_new_tmp_var(g); string init_str = (v__ast__TypeSymbol_is_empty_struct_array(dump_sym) ? (_S("{E_STRUCT}")) : (_S("{0}"))); if (v__ast__Type_is_ptr(typ)) { strings__Builder_writeln(&dump_fns, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = str_dumparg_ret_type}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(" = HEAP("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(typ, 0))}}, {_S(", "), 0xfe10, {.d_s = init_str}}, {_S(");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&dump_fns, str_intp(3, _MOV((StrIntpData[]){{_S("\tmemcpy("), 0xfe10, {.d_s = tmp_var}}, {_S("->ret_arr, dump_arg, sizeof("), 0xfe10, {.d_s = str_dumparg_type}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&dump_fns, str_intp(4, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = str_dumparg_ret_type}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(" = "), 0xfe10, {.d_s = init_str}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&dump_fns, str_intp(3, _MOV((StrIntpData[]){{_S("\tmemcpy("), 0xfe10, {.d_s = tmp_var}}, {_S(".ret_arr, dump_arg, sizeof("), 0xfe10, {.d_s = str_dumparg_type}}, {_S("));"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&dump_fns, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&dump_fns, _S("\treturn dump_arg;")); } strings__Builder_writeln(&dump_fns, _S("}")); } int _t6 = dump_typedefs.key_values.len; for (int _t5 = 0; _t5 < _t6; ++_t5 ) { int _t7 = dump_typedefs.key_values.len - _t6; _t6 = dump_typedefs.key_values.len; if (_t7 < 0) { _t5 = -1; continue; } if (!DenseArray_has_index(&dump_typedefs.key_values, _t5)) {continue;} string tdef = *(string*)DenseArray_key(&dump_typedefs.key_values, _t5); tdef = string_clone(tdef); strings__Builder_writeln(&g->definitions, tdef); } if (dump_fn_defs.len > 0) { strings__Builder_writeln(&g->definitions, strings__Builder_str(&dump_fn_defs)); strings__Builder_writeln(&g->dump_funcs, strings__Builder_str(&dump_fns)); } } VV_LOC bool v__gen__c__Gen_writeln_fn_header(v__gen__c__Gen* g, string s, strings__Builder* sb) { if (g->pref->build_mode == v__pref__BuildMode__build_module) { strings__Builder_writeln(sb, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = s}}, {_S(";"), 0, { .d_c = 0 }}}))); return true; } strings__Builder_writeln(sb, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = s}}, {_S(" {"), 0, { .d_c = 0 }}}))); return false; } VV_LOC bool v__gen__c__Gen_should_really_embed_file(v__gen__c__Gen* g) { if ((Array_string_contains(g->pref->compile_defines, _S("embed_only_metadata")))) { return false; } return true; } VV_LOC void v__gen__c__Gen_handle_embedded_files_finish(v__gen__c__Gen* g) { if (g->embedded_files.len > 0) { if (v__gen__c__Gen_should_really_embed_file(g)) { v__gen__c__Gen_gen_embedded_data(g); } v__gen__c__Gen_gen_embedded_metadata(g); } } VV_LOC void v__gen__c__Gen_gen_embed_file_init(v__gen__c__Gen* g, v__ast__ComptimeCall* node) { #if defined(CUSTOM_DEFINE_trace_embed_file) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> gen_embed_file_init "), 0xfe10, {.d_s = node->embed_file.apath}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif if (v__gen__c__Gen_should_really_embed_file(g)) { _result_Array_u8 _t2 = os__read_bytes(node->embed_file.apath); if (_t2.is_error) { IError err = _t2.err; _v_panic(str_intp(2, _MOV((StrIntpData[]){{_S("unable to read file: \""), 0xfe10, {.d_s = node->embed_file.rpath}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } Array_u8 file_bytes = (*(Array_u8*)_t2.data); if (fast_string_eq(node->embed_file.compression_type, _S("none"))) { node->embed_file.bytes = file_bytes; } else { string cache_dir = os__join_path(os__vmodules_dir(), new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S(".cache"), _S("embed_file")}))); string cache_key = rand__ulid(); if (!os__exists(cache_dir)) { _result_void _t3 = os__mkdir_all(cache_dir, ((os__MkdirParams){.mode = 0777,})); if (_t3.is_error) { IError err = _t3.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; } string cache_path = os__join_path(cache_dir, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){cache_key}))); string vexe = v__pref__vexe_path(); string compress_cmd = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(vexe)}}, {_S(" compress "), 0xfe10, {.d_s = node->embed_file.compression_type}}, {_S(" "), 0xfe10, {.d_s = os__quoted_path(node->embed_file.apath)}}, {_S(" "), 0xfe10, {.d_s = os__quoted_path(cache_path)}}, {_SLIT0, 0, { .d_c = 0 }}})); #if defined(CUSTOM_DEFINE_trace_embed_file) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> gen_embed_file_init, compress_cmd: "), 0xfe10, {.d_s = compress_cmd}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif os__Result result = os__execute(compress_cmd); if (result.exit_code != 0) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("unable to compress file \""), 0xfe10, {.d_s = node->embed_file.rpath}}, {_S("\": "), 0xfe10, {.d_s = result.output}}, {_SLIT0, 0, { .d_c = 0 }}}))); node->embed_file.bytes = file_bytes; } else { _result_Array_u8 _t5 = os__read_bytes(cache_path); if (_t5.is_error) { IError err = _t5.err; eprintln(_S("unable to read compressed file")); { } *(Array_u8*) _t5.data = __new_array_with_default(0, 0, sizeof(u8), 0); } Array_u8 compressed_bytes = (*(Array_u8*)_t5.data); _result_void _t6 = os__rm(cache_path); (void)_t6; ; node->embed_file.is_compressed = compressed_bytes.len > 0 && compressed_bytes.len < file_bytes.len; node->embed_file.bytes = (node->embed_file.is_compressed ? (compressed_bytes) : (file_bytes)); } } if (node->embed_file.bytes.len > 5242880) { eprintln(_S("embedding of files >= ~5MB is currently not well supported")); } node->embed_file.len = file_bytes.len; } u64 ef_idx = v__ast__EmbeddedFile_hash(node->embed_file); { v__gen__c__Gen_write(g, _S("_v_embed_file_metadata( ")); v__gen__c__Gen_write_decimal(g, ef_idx); v__gen__c__Gen_write(g, _S("U )")); } array_push((array*)&g->file->embedded_files, _MOV((v__ast__EmbeddedFile[]){ node->embed_file })); #if defined(CUSTOM_DEFINE_trace_embed_file) { eprintln(str_intp(5, _MOV((StrIntpData[]){{_S("> gen_embed_file_init => _v_embed_file_metadata("), 0x32fe08, {.d_u64 = ef_idx}}, {_S(") | "), 0x64fe10, {.d_s = node->embed_file.apath}}, {_S(" | compression: "), 0xfe10, {.d_s = node->embed_file.compression_type}}, {_S(" | len: "), 0xfe07, {.d_i32 = node->embed_file.len}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif } VV_LOC void v__gen__c__Gen_gen_embedded_metadata(v__gen__c__Gen* g) { if (g->pref->parallel_cc) { strings__Builder_writeln(&g->extern_out, _S("extern v__embed_file__EmbedFileData _v_embed_file_metadata(u64 ef_hash);")); } strings__Builder_writeln(&g->embedded_data, _S("v__embed_file__EmbedFileData _v_embed_file_metadata(u64 ef_hash) {")); strings__Builder_writeln(&g->embedded_data, _S("\tv__embed_file__EmbedFileData res;")); strings__Builder_writeln(&g->embedded_data, _S("\tmemset(&res, 0, sizeof(res));")); strings__Builder_writeln(&g->embedded_data, _S("\tswitch(ef_hash) {")); for (int _t1 = 0; _t1 < g->embedded_files.len; ++_t1) { v__ast__EmbeddedFile emfile = ((v__ast__EmbeddedFile*)g->embedded_files.data)[_t1]; u64 ef_idx = v__ast__EmbeddedFile_hash(emfile); strings__Builder_writeln(&g->embedded_data, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tcase "), 0xfe08, {.d_u64 = ef_idx}}, {_S("U: {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->embedded_data, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tres.path = "), 0xfe10, {.d_s = v__gen__c__ctoslit(emfile.rpath)}}, {_S(";"), 0, { .d_c = 0 }}}))); if (v__gen__c__Gen_should_really_embed_file(g)) { strings__Builder_writeln(&g->embedded_data, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tres.apath = "), 0xfe10, {.d_s = v__gen__c__ctoslit(_S(""))}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->embedded_data, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tres.apath = "), 0xfe10, {.d_s = v__gen__c__ctoslit(emfile.apath)}}, {_S(";"), 0, { .d_c = 0 }}}))); } if (v__gen__c__Gen_should_really_embed_file(g)) { if (emfile.is_compressed) { strings__Builder_writeln(&g->embedded_data, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tres.compression_type = "), 0xfe10, {.d_s = v__gen__c__ctoslit(emfile.compression_type)}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->embedded_data, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t\tres.compressed = v__embed_file__find_index_entry_by_path((voidptr)_v_embed_file_index, "), 0xfe10, {.d_s = v__gen__c__ctoslit(emfile.rpath)}}, {_S(", "), 0xfe10, {.d_s = v__gen__c__ctoslit(emfile.compression_type)}}, {_S(")->data;"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->embedded_data, _S("\t\t\tres.uncompressed = NULL;")); } else { strings__Builder_writeln(&g->embedded_data, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t\tres.uncompressed = v__embed_file__find_index_entry_by_path((voidptr)_v_embed_file_index, "), 0xfe10, {.d_s = v__gen__c__ctoslit(emfile.rpath)}}, {_S(", "), 0xfe10, {.d_s = v__gen__c__ctoslit(emfile.compression_type)}}, {_S(")->data;"), 0, { .d_c = 0 }}}))); } } else { strings__Builder_writeln(&g->embedded_data, _S("\t\t\tres.uncompressed = NULL;")); } strings__Builder_writeln(&g->embedded_data, _S("\t\t\tres.free_compressed = 0;")); strings__Builder_writeln(&g->embedded_data, _S("\t\t\tres.free_uncompressed = 0;")); if (v__gen__c__Gen_should_really_embed_file(g)) { strings__Builder_writeln(&g->embedded_data, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tres.len = "), 0xfe07, {.d_i32 = emfile.len}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { u64 file_size = os__file_size(emfile.apath); if (file_size > 5242880U) { eprintln(_S("Warning: embedding of files >= ~5MB is currently not supported")); } strings__Builder_writeln(&g->embedded_data, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tres.len = "), 0xfe08, {.d_u64 = file_size}}, {_S(";"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->embedded_data, _S("\t\t\tbreak;")); strings__Builder_writeln(&g->embedded_data, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t} // case "), 0xfe08, {.d_u64 = ef_idx}}, {_SLIT0, 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->embedded_data, _S("\t\tdefault: _v_panic(_S(\"unknown embed file\"));")); strings__Builder_writeln(&g->embedded_data, _S("\t} // switch")); strings__Builder_writeln(&g->embedded_data, _S("\treturn res;")); strings__Builder_writeln(&g->embedded_data, _S("}")); } VV_LOC void v__gen__c__Gen_gen_embedded_data(v__gen__c__Gen* g) { for (int i = 0; i < g->embedded_files.len; ++i) { v__ast__EmbeddedFile emfile = ((v__ast__EmbeddedFile*)g->embedded_files.data)[i]; { strings__Builder_write_string(&g->embedded_data, _S("static const unsigned char _v_embed_blob_")); strings__Builder_write_decimal(&g->embedded_data, i); strings__Builder_write_string(&g->embedded_data, _S("[")); strings__Builder_write_decimal(&g->embedded_data, emfile.bytes.len); strings__Builder_write_string(&g->embedded_data, _S("] = {\n ")); } for (int j = 0; j < emfile.bytes.len; j++) { string b = u8_hex((*(u8*)array_get(emfile.bytes, j))); if (j < (int)(emfile.bytes.len - 1)) { { strings__Builder_write_string(&g->embedded_data, _S("0x")); strings__Builder_write_string(&g->embedded_data, b); strings__Builder_write_string(&g->embedded_data, _S(",")); } } else { { strings__Builder_write_string(&g->embedded_data, _S("0x")); strings__Builder_write_string(&g->embedded_data, b); } } if (0 == ((int)(((int)(j + 1)) % 16))) { strings__Builder_write_string(&g->embedded_data, _S("\n ")); } } strings__Builder_writeln(&g->embedded_data, _S("\n};")); } strings__Builder_writeln(&g->embedded_data, _S("")); strings__Builder_writeln(&g->embedded_data, _S("const v__embed_file__EmbedFileIndexEntry _v_embed_file_index[] = {")); for (int i = 0; i < g->embedded_files.len; ++i) { v__ast__EmbeddedFile emfile = ((v__ast__EmbeddedFile*)g->embedded_files.data)[i]; strings__Builder_writeln(&g->embedded_data, str_intp(7, _MOV((StrIntpData[]){{_S("\t{"), 0xfe07, {.d_i32 = i}}, {_S(", { .str=(byteptr)(\""), 0xfe10, {.d_s = v__gen__c__cestring(emfile.rpath)}}, {_S("\"), .len="), 0xfe07, {.d_i32 = emfile.rpath.len}}, {_S(", .is_lit=1 }, { .str=(byteptr)(\""), 0xfe10, {.d_s = v__gen__c__cestring(emfile.compression_type)}}, {_S("\"), .len="), 0xfe07, {.d_i32 = emfile.compression_type.len}}, {_S(", .is_lit=1 }, (byteptr)_v_embed_blob_"), 0xfe07, {.d_i32 = i}}, {_S("},"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->embedded_data, _S("\t{-1, { .str=(byteptr)(\"\"), .len=0, .is_lit=1 }, { .str=(byteptr)(\"\"), .len=0, .is_lit=1 }, NULL}")); strings__Builder_writeln(&g->embedded_data, _S("};")); } VV_LOC bool v__gen__c__Gen_is_used_by_main(v__gen__c__Gen* g, v__ast__FnDecl node) { bool v__gen__c__Gen_is_used_by_main_defer_0 = false; bool used_by_main; string fkey; #if defined(CUSTOM_DEFINE_trace_unused_by_main) { v__gen__c__Gen_is_used_by_main_defer_0 = true; } #endif if (node.is_c_extern) { bool _t2 = true; // Defer begin if (v__gen__c__Gen_is_used_by_main_defer_0) { #if defined(CUSTOM_DEFINE_trace_unused_by_main) used_by_main = _t2; if (!used_by_main) { fkey = v__ast__FnDecl_fkey(&node); println(str_intp(5, _MOV((StrIntpData[]){{_S("> trace_unused_by_main: mod: "), 0xfe10, {.d_s = node.mod}}, {_S(" | "), 0xfe10, {.d_s = node.name}}, {_S(" | fkey: "), 0xfe10, {.d_s = fkey}}, {_S(" | line_nr: "), 0xfe07, {.d_i32 = node.pos.line_nr}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif } // Defer end return _t2; } bool is_used_by_main = true; if (g->pref->skip_unused) { if (node.is_markused) { bool _t3 = true; // Defer begin if (v__gen__c__Gen_is_used_by_main_defer_0) { #if defined(CUSTOM_DEFINE_trace_unused_by_main) used_by_main = _t3; if (!used_by_main) { fkey = v__ast__FnDecl_fkey(&node); println(str_intp(5, _MOV((StrIntpData[]){{_S("> trace_unused_by_main: mod: "), 0xfe10, {.d_s = node.mod}}, {_S(" | "), 0xfe10, {.d_s = node.name}}, {_S(" | fkey: "), 0xfe10, {.d_s = fkey}}, {_S(" | line_nr: "), 0xfe07, {.d_i32 = node.pos.line_nr}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif } // Defer end return _t3; } fkey = v__ast__FnDecl_fkey(&node); is_used_by_main = (*(bool*)map_get(ADDR(map, g->table->used_features->used_fns), &(string[]){fkey}, &(bool[]){ 0 })); #if defined(CUSTOM_DEFINE_trace_skip_unused_fns) { println(str_intp(5, _MOV((StrIntpData[]){{_S("> is_used_by_main: "), 0xfe10, {.d_s = is_used_by_main ? _S("true") : _S("false")}}, {_S(" | node.name: "), 0xfe10, {.d_s = node.name}}, {_S(" | fkey: "), 0xfe10, {.d_s = fkey}}, {_S(" | node.is_method: "), 0xfe10, {.d_s = node.is_method ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif if (!is_used_by_main) { #if defined(CUSTOM_DEFINE_trace_skip_unused_fns_in_c_code) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("// trace_skip_unused_fns_in_c_code, "), 0xfe10, {.d_s = node.name}}, {_S(", fkey: "), 0xfe10, {.d_s = fkey}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif } } else { #if defined(CUSTOM_DEFINE_trace_skip_unused_fns_in_c_code) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("// trace_skip_unused_fns_in_c_code, "), 0xfe10, {.d_s = node.name}}, {_S(", fkey: "), 0xfe10, {.d_s = v__ast__FnDecl_fkey(&node)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif } bool _t7 = is_used_by_main; // Defer begin if (v__gen__c__Gen_is_used_by_main_defer_0) { #if defined(CUSTOM_DEFINE_trace_unused_by_main) used_by_main = _t7; if (!used_by_main) { fkey = v__ast__FnDecl_fkey(&node); println(str_intp(5, _MOV((StrIntpData[]){{_S("> trace_unused_by_main: mod: "), 0xfe10, {.d_s = node.mod}}, {_S(" | "), 0xfe10, {.d_s = node.name}}, {_S(" | fkey: "), 0xfe10, {.d_s = fkey}}, {_S(" | line_nr: "), 0xfe07, {.d_i32 = node.pos.line_nr}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif } // Defer end return _t7; } VV_LOC void v__gen__c__Gen_fn_decl(v__gen__c__Gen* g, v__ast__FnDecl node) { bool v__gen__c__Gen_fn_decl_defer_0 = false; bool prev_is_direct_array_access; bool v__gen__c__Gen_fn_decl_defer_1 = false; bool old_inside_c_extern; if (node.should_be_skipped) { return; } if (node.is_test) { array_push((array*)&g->test_function_names, _MOV((string[]){ string_clone(node.name) })); } if (node.ninstances == 0 && node.generic_names.len > 0) { #if defined(CUSTOM_DEFINE_trace_generics) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("skipping generic fn with no concrete instances: "), 0xfe10, {.d_s = node.mod}}, {_S(" "), 0xfe10, {.d_s = node.name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif return; } if (!v__gen__c__Gen_is_used_by_main(g, node)) { return; } if (g->is_builtin_mod && g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_leak && fast_string_eq(node.name, _S("malloc"))) { strings__Builder_write_string(&g->definitions, _S("#define _v_malloc GC_MALLOC\n")); return; } if (g->pref->parallel_cc) { if (node.is_anon) { } if (!node.is_anon) { array_push((array*)&g->out_fn_start_pos, _MOV((int[]){ g->out.len })); } } prev_is_direct_array_access = g->is_direct_array_access; g->is_direct_array_access = node.is_direct_arr || g->pref->no_bounds_checking; v__gen__c__Gen_fn_decl_defer_0 = true; old_inside_c_extern = g->inside_c_extern; v__gen__c__Gen_fn_decl_defer_1 = true; if (node.language == v__ast__Language__c && node.is_c_extern) { g->inside_c_extern = true; } v__gen__c__Gen_gen_attrs(g, node.attrs); bool skip = false; int pos = g->out.len; bool should_bundle_module = v__util__should_bundle_module(node.mod); if (g->pref->build_mode == v__pref__BuildMode__build_module) { string mod = (g->is_builtin_mod ? (_S("builtin")) : (string_all_before_last(node.name, _S(".")))); if (((!string__eq(mod, g->module_built) && !string__eq(node.mod, string_after(g->module_built, _S("/")))) || should_bundle_module) && node.generic_names.len == 0) { skip = true; } if (g->is_builtin_mod && fast_string_eq(g->module_built, _S("builtin")) && fast_string_eq(node.mod, _S("builtin"))) { skip = false; } if (!skip && g->pref->is_verbose) { println(str_intp(3, _MOV((StrIntpData[]){{_S("build module `"), 0xfe10, {.d_s = g->module_built}}, {_S("` fn `"), 0xfe10, {.d_s = node.name}}, {_S("`"), 0, { .d_c = 0 }}}))); } } if (g->pref->use_cache) { if (!fast_string_eq(node.mod, _S("main")) && !fast_string_eq(node.mod, _S("help")) && !should_bundle_module && !g->pref->is_test && node.generic_names.len == 0) { skip = true; } } v__ast__FnDecl* keep_fn_decl = g->fn_decl; { // Unsafe block g->fn_decl = &node; } if (node.is_main) { g->has_main = true; } bool is_backtrace = string_starts_with(node.name, _S("backtrace")) && (fast_string_eq(node.name, _S("backtrace_symbols")) || fast_string_eq(node.name, _S("backtrace")) || fast_string_eq(node.name, _S("backtrace_symbols_fd"))); if (is_backtrace) { v__gen__c__Gen_write(g, _S("\n#ifndef __cplusplus\n")); } v__gen__c__Gen_gen_fn_decl(g, (voidptr)&node, skip); if (is_backtrace) { v__gen__c__Gen_write(g, _S("\n#endif\n")); } g->fn_decl = keep_fn_decl; if (skip) { v__gen__c__Gen_go_back_to(g, pos); } if (!g->pref->skip_unused) { if (node.language != v__ast__Language__c) { v__gen__c__Gen_writeln(g, _S("")); } } // Defer begin if (v__gen__c__Gen_fn_decl_defer_1) { g->inside_c_extern = old_inside_c_extern; } // Defer end // Defer begin if (v__gen__c__Gen_fn_decl_defer_0) { g->is_direct_array_access = prev_is_direct_array_access; } // Defer end } VV_LOC void v__gen__c__Gen_gen_fn_decl(v__gen__c__Gen* g, v__ast__FnDecl* node, bool skip) { bool v__gen__c__Gen_gen_fn_decl_defer_0 = false; bool old_is_vlines_enabled; bool v__gen__c__Gen_gen_fn_decl_defer_1 = false; Array_string tmp_defer_vars; bool v__gen__c__Gen_gen_fn_decl_defer_2 = false; bool old_g_autofree; bool v__gen__c__Gen_gen_fn_decl_defer_3 = false; v__ast__FnDecl* cur_fn_save; bool v__gen__c__Gen_gen_fn_decl_defer_4 = false; string last_fn_c_name_save; bool v__gen__c__Gen_gen_fn_decl_defer_5 = false; int ctmp; bool v__gen__c__Gen_gen_fn_decl_defer_6 = false; int prev_indent; if (node->language == v__ast__Language__c) { if (!g->inside_c_extern) { return; } } old_is_vlines_enabled = g->is_vlines_enabled; g->is_vlines_enabled = true; v__gen__c__Gen_gen_fn_decl_defer_0 = true; tmp_defer_vars = g->defer_vars; if (!g->anon_fn) { g->defer_vars = __new_array_with_default(0, 0, sizeof(string), 0); } else { if (node->defer_stmts.len > 0) { g->defer_vars = __new_array_with_default(0, 0, sizeof(string), 0); v__gen__c__Gen_gen_fn_decl_defer_1 = true; } } g->returned_var_name = _S(""); old_g_autofree = g->is_autofree; if (node->is_manualfree) { g->is_autofree = false; } v__gen__c__Gen_gen_fn_decl_defer_2 = true; if (node->generic_names.len > 0 && g->cur_concrete_types.len == 0) { string nkey = v__ast__FnDecl_fkey(node); Array_Array_v__ast__Type generic_types_by_fn = (*(Array_Array_v__ast__Type*)map_get(ADDR(map, g->table->fn_generic_types), &(string[]){nkey}, &(Array_Array_v__ast__Type[]){ __new_array(0, 0, sizeof(Array_v__ast__Type)) })); #if defined(CUSTOM_DEFINE_trace_post_process_generic_fns) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S(">> gen_fn_decl, nkey: "), 0xfe10, {.d_s = nkey}}, {_S(" | generic_types_by_fn: "), 0xfe10, {.d_s = Array_Array_v__ast__Type_str(generic_types_by_fn)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif for (int _t2 = 0; _t2 < generic_types_by_fn.len; ++_t2) { Array_v__ast__Type concrete_types = ((Array_v__ast__Type*)generic_types_by_fn.data)[_t2]; if (g->pref->is_verbose) { Array_v__ast__TypeSymbol_ptr _t3 = {0}; Array_v__ast__Type _t3_orig = concrete_types; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__TypeSymbol*)); for (int _t5 = 0; _t5 < _t3_len; ++_t5) { v__ast__Type it = ((v__ast__Type*) _t3_orig.data)[_t5]; v__ast__TypeSymbol* _t4 = v__ast__Table_sym(g->table, it); array_push((array*)&_t3, &_t4); } Array_v__ast__TypeSymbol_ptr syms =_t3; Array_string _t6 = {0}; Array_v__ast__TypeSymbol_ptr _t6_orig = syms; int _t6_len = _t6_orig.len; _t6 = __new_array(0, _t6_len, sizeof(string)); for (int _t8 = 0; _t8 < _t6_len; ++_t8) { v__ast__TypeSymbol* it = ((v__ast__TypeSymbol**) _t6_orig.data)[_t8]; string _t7 = it->name; array_push((array*)&_t6, &_t7); } string the_type = Array_string_join(_t6, _S(", ")); println(str_intp(3, _MOV((StrIntpData[]){{_S("gen fn `"), 0xfe10, {.d_s = node->name}}, {_S("` for type `"), 0xfe10, {.d_s = the_type}}, {_S("`"), 0, { .d_c = 0 }}}))); } g->cur_concrete_types = concrete_types; v__gen__c__Gen_gen_fn_decl(g, node, skip); } g->cur_concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_2) { g->is_autofree = old_g_autofree; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_1) { g->defer_vars = tmp_defer_vars; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_0) { g->is_vlines_enabled = old_is_vlines_enabled; } // Defer end return; } cur_fn_save = g->cur_fn; v__gen__c__Gen_gen_fn_decl_defer_3 = true; { // Unsafe block g->cur_fn = node; } int fn_start_pos = g->out.len; bool is_closure = v__ast__Scope_has_inherited_vars(node->scope); string cur_closure_ctx = _S(""); if (is_closure) { cur_closure_ctx = v__gen__c__Gen_closure_ctx(g, *node); strings__Builder_write_string(&g->definitions, cur_closure_ctx); strings__Builder_writeln(&g->definitions, _S(";")); } v__gen__c__Gen_write_v_source_line_info_stmt(g, v__ast__FnDecl_to_sumtype_v__ast__Stmt(node)); string fn_attrs = v__gen__c__Gen_write_fn_attrs(g, node->attrs); bool is_livefn = Array_v__ast__Attr_contains(node->attrs, _S("live")); bool is_livemain = g->pref->is_livemain && is_livefn; bool is_liveshared = g->pref->is_liveshared && is_livefn; bool is_livemode = g->pref->is_livemain || g->pref->is_liveshared; bool is_live_wrap = is_livefn && is_livemode; if (is_livefn && !is_livemode) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("INFO: compile with `v -live "), 0xfe10, {.d_s = g->pref->path}}, {_S(" `, if you want to use the @[live] function "), 0xfe10, {.d_s = node->name}}, {_S(" ."), 0, { .d_c = 0 }}}))); } string name = v__gen__c__Gen_c_fn_name(g, node); string type_name = v__gen__c__Gen_ret_styp(g, v__gen__c__Gen_unwrap_generic(g, node->return_type)); if (is_livemode) { if (is_livefn) { array_push((array*)&g->hotcode_fn_names, _MOV((string[]){ string_clone(name) })); } array_push((array*)&g->hotcode_fpaths, _MOV((string[]){ string_clone(g->file->path) })); } string impl_fn_name = name; if (is_live_wrap) { impl_fn_name = str_intp(2, _MOV((StrIntpData[]){{_S("impl_live_"), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}})); } last_fn_c_name_save = g->last_fn_c_name; v__gen__c__Gen_gen_fn_decl_defer_4 = true; g->last_fn_c_name = impl_fn_name; if (!g->inside_c_extern && node->trace_fns.len > 0) { Map_string_v__ast__FnTrace _t11 = node->trace_fns; int _t13 = _t11.key_values.len; for (int _t12 = 0; _t12 < _t13; ++_t12 ) { int _t14 = _t11.key_values.len - _t13; _t13 = _t11.key_values.len; if (_t14 < 0) { _t12 = -1; continue; } if (!DenseArray_has_index(&_t11.key_values, _t12)) {continue;} string trace_fn = *(string*)DenseArray_key(&_t11.key_values, _t12); trace_fn = string_clone(trace_fn); v__ast__FnTrace call_fn = (*(v__ast__FnTrace*)DenseArray_value(&_t11.key_values, _t12)); if ((Array_string_contains(g->trace_fn_definitions, trace_fn))) { continue; } string trace_fn_ret_type = v__gen__c__Gen_styp(g, call_fn.return_type); { v__gen__c__Gen_write(g, _S("VV_LOC ")); v__gen__c__Gen_write(g, trace_fn_ret_type); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, v__gen__c__c_name(trace_fn)); v__gen__c__Gen_write(g, _S("(")); } { strings__Builder_write_string(&g->definitions, _S("VV_LOC ")); strings__Builder_write_string(&g->definitions, trace_fn_ret_type); strings__Builder_write_string(&g->definitions, _S(" ")); strings__Builder_write_string(&g->definitions, v__gen__c__c_name(trace_fn)); strings__Builder_write_string(&g->definitions, _S("(")); } if (call_fn.is_fn_var) { Array_v__ast__Type _t15 = {0}; Array_v__ast__Param _t15_orig = call_fn.func->params; int _t15_len = _t15_orig.len; _t15 = __new_array(0, _t15_len, sizeof(v__ast__Type)); for (int _t17 = 0; _t17 < _t15_len; ++_t17) { v__ast__Param it = ((v__ast__Param*) _t15_orig.data)[_t17]; v__ast__Type _t16 = it.typ; array_push((array*)&_t15, &_t16); } string sig = v__gen__c__Gen_fn_var_signature(g, call_fn.func->return_type,_t15, call_fn.name); v__gen__c__Gen_write(g, sig); strings__Builder_write_string(&g->definitions, sig); } else { v__gen__c__Gen_fn_decl_params(g, call_fn.func->params, ((void*)0), call_fn.func->is_variadic, call_fn.func->is_c_variadic); } v__gen__c__Gen_writeln(g, _S(") {")); strings__Builder_write_string(&g->definitions, _S(");\n")); Array_string _t18 = {0}; Array_v__ast__Param _t18_orig = call_fn.func->params; int _t18_len = _t18_orig.len; _t18 = __new_array(0, _t18_len, sizeof(string)); for (int _t20 = 0; _t20 < _t18_len; ++_t20) { v__ast__Param it = ((v__ast__Param*) _t18_orig.data)[_t20]; string _t19 = it.name; array_push((array*)&_t18, &_t19); } string orig_fn_args = Array_string_join(_t18, _S(", ")); bool add_trace_hook = g->pref->is_trace && !(fast_string_eq(call_fn.name, _S("v.debug.add_after_call")) || fast_string_eq(call_fn.name, _S("v.debug.add_before_call")) || fast_string_eq(call_fn.name, _S("v.debug.remove_after_call")) || fast_string_eq(call_fn.name, _S("v.debug.remove_before_call"))); if (g->pref->is_callstack) { if (g->cur_fn->is_method || g->cur_fn->is_static_type_method) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\tarray_push((array*)&g_callstack, _MOV((v__debug__FnTrace[]){ ((v__debug__FnTrace){.name = _S(\""), 0xfe10, {.d_s = v__ast__Table_type_to_str(g->table, g->cur_fn->receiver.typ)}}, {_S("."), 0xfe10, {.d_s = string_all_after_last(g->cur_fn->name, _S("__static__"))}}, {_S("\"),.file = _S(\""), 0xfe10, {.d_s = call_fn.file}}, {_S("\"),.line = "), 0xfe09, {.d_i64 = call_fn.line}}, {_S(",}) }));"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\tarray_push((array*)&g_callstack, _MOV((v__debug__FnTrace[]){ ((v__debug__FnTrace){.name = _S(\""), 0xfe10, {.d_s = g->cur_fn->name}}, {_S("\"),.file = _S(\""), 0xfe10, {.d_s = call_fn.file}}, {_S("\"),.line = "), 0xfe09, {.d_i64 = call_fn.line}}, {_S(",}) }));"), 0, { .d_c = 0 }}}))); } } if (call_fn.return_type == 0 || call_fn.return_type == _const_v__ast__void_type) { if (add_trace_hook) { v__gen__c__Gen_writeln(g, _S("\tif (!g_trace.in_hook) {")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tv__debug__before_call_hook(_S(\""), 0xfe10, {.d_s = call_fn.name}}, {_S("\"));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\t}")); } v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = v__gen__c__c_name(call_fn.name)}}, {_S("("), 0xfe10, {.d_s = orig_fn_args}}, {_S(");"), 0, { .d_c = 0 }}}))); if (add_trace_hook) { v__gen__c__Gen_writeln(g, _S("\tif (!g_trace.in_hook) {")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tv__debug__after_call_hook(_S(\""), 0xfe10, {.d_s = call_fn.name}}, {_S("\"));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\t}")); } if (g->pref->is_callstack) { v__gen__c__Gen_writeln(g, _S("\tarray_pop((array*)&g_callstack);")); } } else { if (add_trace_hook) { v__gen__c__Gen_writeln(g, _S("\tif (!g_trace.in_hook) {")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tv__debug__before_call_hook(_S(\""), 0xfe10, {.d_s = call_fn.name}}, {_S("\"));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\t}")); } v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, call_fn.return_type)}}, {_S(" ret = "), 0xfe10, {.d_s = v__gen__c__c_name(call_fn.name)}}, {_S("("), 0xfe10, {.d_s = orig_fn_args}}, {_S(");"), 0, { .d_c = 0 }}}))); if (g->pref->is_callstack) { v__gen__c__Gen_writeln(g, _S("\tarray_pop((array*)&g_callstack);")); } if (add_trace_hook) { v__gen__c__Gen_writeln(g, _S("\tif (!g_trace.in_hook) {")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tv__debug__after_call_hook(_S(\""), 0xfe10, {.d_s = call_fn.name}}, {_S("\"));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\t}")); } v__gen__c__Gen_writeln(g, _S("\treturn ret;")); } v__gen__c__Gen_writeln2(g, _S("}"), _S("")); array_push((array*)&g->trace_fn_definitions, _MOV((string[]){ string_clone(trace_fn) })); } } if (is_live_wrap) { if (is_livemain) { { strings__Builder_write_string(&g->definitions, type_name); strings__Builder_write_string(&g->definitions, _S(" (* ")); strings__Builder_write_string(&g->definitions, impl_fn_name); strings__Builder_write_string(&g->definitions, _S(")(")); } { v__gen__c__Gen_write(g, type_name); v__gen__c__Gen_write(g, _S(" no_impl_")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S("(")); } } if (is_liveshared) { if (g->pref->os == v__pref__OS__windows) { array_push((array*)&g->export_funcs, _MOV((string[]){ string_clone(impl_fn_name) })); { strings__Builder_write_string(&g->definitions, _S("VV_EXP ")); strings__Builder_write_string(&g->definitions, type_name); strings__Builder_write_string(&g->definitions, _S(" ")); strings__Builder_write_string(&g->definitions, impl_fn_name); strings__Builder_write_string(&g->definitions, _S("(")); } { v__gen__c__Gen_write(g, _S("VV_EXP ")); v__gen__c__Gen_write(g, type_name); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, impl_fn_name); v__gen__c__Gen_write(g, _S("(")); } } else { { strings__Builder_write_string(&g->definitions, type_name); strings__Builder_write_string(&g->definitions, _S(" ")); strings__Builder_write_string(&g->definitions, impl_fn_name); strings__Builder_write_string(&g->definitions, _S("(")); } { v__gen__c__Gen_write(g, type_name); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, impl_fn_name); v__gen__c__Gen_write(g, _S("(")); } } } } else if (g->inside_c_extern) { string c_extern_fn_header = str_intp(4, _MOV((StrIntpData[]){{_S("extern "), 0xfe10, {.d_s = type_name}}, {_S(" "), 0xfe10, {.d_s = fn_attrs}}, {_SLIT0, 0xfe10, {.d_s = string_all_after_first(name, _S("C__"))}}, {_S("("), 0, { .d_c = 0 }}})); strings__Builder_write_string(&g->definitions, c_extern_fn_header); } else { if (!(node->is_pub || g->pref->is_debug)) { if (g->pref->build_mode != v__pref__BuildMode__build_module && !g->pref->use_cache) { if (!(node->is_anon && g->pref->parallel_cc)) { v__gen__c__Gen_write(g, _S("VV_LOC ")); strings__Builder_write_string(&g->definitions, _S("VV_LOC ")); } } } string visibility_kw = (g->cur_concrete_types.len > 0 && (g->pref->build_mode == v__pref__BuildMode__build_module || g->pref->use_cache) ? (_S("static ")) : (_S(""))); string fn_header = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = visibility_kw}}, {_SLIT0, 0xfe10, {.d_s = type_name}}, {_S(" "), 0xfe10, {.d_s = fn_attrs}}, {_SLIT0, 0xfe10, {.d_s = name}}, {_S("("), 0, { .d_c = 0 }}})); strings__Builder_write_string(&g->definitions, fn_header); v__gen__c__Gen_write(g, fn_header); } int arg_start_pos = g->out.len; multi_return_Array_string_Array_string_Array_bool mr_12331 = v__gen__c__Gen_fn_decl_params(g, node->params, node->scope, node->is_variadic, node->is_c_variadic); Array_string fargs = mr_12331.arg0; Array_string fargtypes = mr_12331.arg1; Array_bool heap_promoted = mr_12331.arg2; if (is_closure) { g->nr_closures++; } string arg_str = strings__Builder_after(&g->out, arg_start_pos); if (node->no_body || ((g->pref->use_cache && g->pref->build_mode != v__pref__BuildMode__build_module) && node->is_builtin && !g->pref->is_test) || skip) { strings__Builder_writeln(&g->definitions, _S(");")); if (!g->inside_c_extern) { v__gen__c__Gen_writeln(g, _S(");")); } // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_4) { g->last_fn_c_name = last_fn_c_name_save; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_3) { g->cur_fn = cur_fn_save; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_2) { g->is_autofree = old_g_autofree; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_1) { g->defer_vars = tmp_defer_vars; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_0) { g->is_vlines_enabled = old_is_vlines_enabled; } // Defer end return; } if (node->params.len == 0) { strings__Builder_write_string(&g->definitions, _S("void")); } _option_v__ast__Attr _t23; if (_t23 = Array_v__ast__Attr_find_first(node->attrs, _S("_linker_section")), _t23.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t23.data; strings__Builder_writeln(&g->definitions, str_intp(2, _MOV((StrIntpData[]){{_S(") __attribute__ ((section (\""), 0xfe10, {.d_s = attr.arg}}, {_S("\")));"), 0, { .d_c = 0 }}}))); } else { IError err = _t23.err; strings__Builder_writeln(&g->definitions, _S(");")); } v__gen__c__Gen_writeln(g, _S(") {")); if (is_closure) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = cur_closure_ctx}}, {_S("* "), 0xfe10, {.d_s = _const_v__gen__c__closure_ctx}}, {_S(" = g_closure.closure_get_data();"), 0, { .d_c = 0 }}}))); } for (int i = 0; i < heap_promoted.len; ++i) { bool is_promoted = ((bool*)heap_promoted.data)[i]; if (is_promoted) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*(string*)array_get(fargtypes, i))}}, {_S("* "), 0xfe10, {.d_s = (*(string*)array_get(fargs, i))}}, {_S(" = HEAP("), 0xfe10, {.d_s = (*(string*)array_get(fargtypes, i))}}, {_S(", _v_toheap_"), 0xfe10, {.d_s = (*(string*)array_get(fargs, i))}}, {_S(");"), 0, { .d_c = 0 }}}))); } } g->indent++; for (int _t24 = 0; _t24 < node->defer_stmts.len; ++_t24) { v__ast__DeferStmt defer_stmt = ((v__ast__DeferStmt*)node->defer_stmts.data)[_t24]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("bool "), 0xfe10, {.d_s = v__gen__c__Gen_defer_flag_var(g, (voidptr)&defer_stmt)}}, {_S(" = false;"), 0, { .d_c = 0 }}}))); for (int _t25 = 0; _t25 < defer_stmt.defer_vars.len; ++_t25) { v__ast__Ident var = ((v__ast__Ident*)defer_stmt.defer_vars.data)[_t25]; if ((Array_string_contains(fargs, var.name)) || var.kind == v__ast__IdentKind__constant) { continue; } if (var.kind == v__ast__IdentKind__variable) { if (!(Array_string_contains(g->defer_vars, var.name))) { array_push((array*)&g->defer_vars, _MOV((string[]){ string_clone(var.name) })); string deref = _S(""); _option_v__ast__Var_ptr _t27; if (_t27 = v__ast__Scope_find_var(var.scope, var.name), _t27.state == 0) { v__ast__Var* v = *(v__ast__Var**)_t27.data; if (v->is_auto_heap) { deref = _S("*"); } } v__ast__Var info = *(v__ast__Var*)__as_cast((var.obj)._v__ast__Var,(var.obj)._typ, 422); if (v__ast__Table_sym(g->table, info.typ)->kind != v__ast__Kind__function) { if (info.is_static) { v__gen__c__Gen_write(g, _S("static ")); } if (info.is_volatile) { v__gen__c__Gen_write(g, _S("volatile ")); } v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, info.typ)}}, {_SLIT0, 0xfe10, {.d_s = deref}}, {_S(" "), 0xfe10, {.d_s = v__gen__c__c_name(var.name)}}, {_S(";"), 0, { .d_c = 0 }}}))); } } } } } g->indent--; if (is_live_wrap) { Array_string fn_args_list = __new_array_with_default(0, 0, sizeof(string), 0); for (int ia = 0; ia < fargs.len; ++ia) { string fa = ((string*)fargs.data)[ia]; array_push((array*)&fn_args_list, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = (*(string*)array_get(fargtypes, ia))}}, {_S(" "), 0xfe10, {.d_s = fa}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } string live_fncall = string__plus(string__plus(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = impl_fn_name}}, {_S("("), 0, { .d_c = 0 }}})), Array_string_join(fargs, _S(", "))), _S(");")); string live_fnreturn = _S(""); if (_SLIT_NE(type_name.str, type_name.len, "void")) { live_fncall = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_name}}, {_S(" res = "), 0xfe10, {.d_s = live_fncall}}, {_SLIT0, 0, { .d_c = 0 }}})); live_fnreturn = _S("return res;"); } strings__Builder_writeln(&g->definitions, string__plus(string__plus(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_name}}, {_S(" "), 0xfe10, {.d_s = name}}, {_S("("), 0, { .d_c = 0 }}})), Array_string_join(fn_args_list, _S(", "))), _S(");"))); strings__Builder_writeln(&g->hotcode_definitions, string__plus(string__plus(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_name}}, {_S(" "), 0xfe10, {.d_s = name}}, {_S("("), 0, { .d_c = 0 }}})), Array_string_join(fn_args_list, _S(", "))), _S("){"))); strings__Builder_writeln(&g->hotcode_definitions, _S(" pthread_mutex_lock(&live_fn_mutex);")); strings__Builder_writeln(&g->hotcode_definitions, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = live_fncall}}, {_SLIT0, 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->hotcode_definitions, _S(" pthread_mutex_unlock(&live_fn_mutex);")); strings__Builder_writeln(&g->hotcode_definitions, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = live_fnreturn}}, {_SLIT0, 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->hotcode_definitions, _S("}")); } if (g->pref->is_prof && g->pref->build_mode != v__pref__BuildMode__build_module) { v__gen__c__Gen_profile_fn(g, *node); } Array_v__ast__DeferStmt prev_defer_stmts = g->defer_stmts; g->defer_stmts = __new_array_with_default(0, 0, sizeof(v__ast__DeferStmt), 0); ctmp = g->tmp_count; g->tmp_count = 0; v__gen__c__Gen_gen_fn_decl_defer_5 = true; int prev_inside_ternary = g->inside_ternary; g->inside_ternary = 0; prev_indent = g->indent; g->indent = 0; v__gen__c__Gen_gen_fn_decl_defer_6 = true; v__gen__c__Gen_stmts(g, node->stmts); g->inside_ternary = prev_inside_ternary; if (node->is_noreturn) { v__gen__c__Gen_writeln(g, _S("\twhile(1);")); } if (!node->has_return) { v__gen__c__Gen_write_defer_stmts_when_needed(g); } if (node->is_anon) { g->defer_stmts = prev_defer_stmts; } else { g->defer_stmts = __new_array_with_default(0, 0, sizeof(v__ast__DeferStmt), 0); } bool _t30 = (node->return_type != _const_v__ast__void_type && node->stmts.len > 0); bool _t29 = ( _t30 && ((*(v__ast__Stmt*)array_last(node->stmts)))._typ != 412 /* v.ast.Return */); if ( _t29 && !Array_v__ast__Attr_contains(node->attrs, _S("_naked"))) { string default_expr = v__gen__c__Gen_type_default(g, node->return_type); if (_SLIT_EQ(default_expr.str, default_expr.len, "{0}")) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\treturn ("), 0xfe10, {.d_s = type_name}}, {_S(")"), 0xfe10, {.d_s = default_expr}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = default_expr}}, {_S(";"), 0, { .d_c = 0 }}}))); } } v__gen__c__Gen_writeln(g, _S("}")); if (g->pref->printfn_list.len > 0 && (Array_string_contains(g->pref->printfn_list, g->last_fn_c_name))) { println(strings__Builder_after(&g->out, fn_start_pos)); } for (int _t31 = 0; _t31 < node->attrs.len; ++_t31) { v__ast__Attr attr = ((v__ast__Attr*)node->attrs.data)[_t31]; if (fast_string_eq(attr.name, _S("export"))) { bool _t33 = false; Array_v__ast__Attr _t33_orig = node->attrs; int _t33_len = _t33_orig.len; for (int _t34 = 0; _t34 < _t33_len; ++_t34) { v__ast__Attr it = ((v__ast__Attr*) _t33_orig.data)[_t34]; if (fast_string_eq(it.name, _S("weak"))) { _t33 = true; break; } } string _t32; /* if prepend */ if (_t33) { _t32 = _S("VWEAK "); } else { _t32 = _S(""); } string weak = _t32; v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("// export alias: "), 0xfe10, {.d_s = attr.arg}}, {_S(" -> "), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))); array_push((array*)&g->export_funcs, _MOV((string[]){ string_clone(attr.arg) })); string export_alias = str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = weak}}, {_SLIT0, 0xfe10, {.d_s = type_name}}, {_S(" "), 0xfe10, {.d_s = fn_attrs}}, {_SLIT0, 0xfe10, {.d_s = attr.arg}}, {_S("("), 0xfe10, {.d_s = arg_str}}, {_S(")"), 0, { .d_c = 0 }}})); strings__Builder_writeln(&g->definitions, str_intp(3, _MOV((StrIntpData[]){{_S("VV_EXP "), 0xfe10, {.d_s = export_alias}}, {_S("; // exported fn "), 0xfe10, {.d_s = node->name}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = export_alias}}, {_S(" {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_S("\treturn "), 0xfe10, {.d_s = name}}, {_S("("), 0, { .d_c = 0 }}})), Array_string_join(fargs, _S(", "))); v__gen__c__Gen_writeln2(g, _S(");"), _S("}")); } } // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_6) { g->indent = prev_indent; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_5) { g->tmp_count = ctmp; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_4) { g->last_fn_c_name = last_fn_c_name_save; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_3) { g->cur_fn = cur_fn_save; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_2) { g->is_autofree = old_g_autofree; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_1) { g->defer_vars = tmp_defer_vars; } // Defer end // Defer begin if (v__gen__c__Gen_gen_fn_decl_defer_0) { g->is_vlines_enabled = old_is_vlines_enabled; } // Defer end } VV_LOC string v__gen__c__Gen_c_fn_name(v__gen__c__Gen* g, v__ast__FnDecl* node) { string name = node->name; if (_SLIT_EQ(name.str, name.len, "+") || _SLIT_EQ(name.str, name.len, "-") || _SLIT_EQ(name.str, name.len, "*") || _SLIT_EQ(name.str, name.len, "/") || _SLIT_EQ(name.str, name.len, "%") || _SLIT_EQ(name.str, name.len, "<") || _SLIT_EQ(name.str, name.len, "==")) { name = v__util__replace_op(name); } if (node->is_method) { v__ast__Type unwrapped_rec_typ = v__gen__c__Gen_unwrap_generic(g, node->receiver.typ); name = string__plus(string__plus(v__gen__c__Gen_cc_type(g, unwrapped_rec_typ, false), _S("_")), name); if (v__ast__Table_sym(g->table, unwrapped_rec_typ)->kind == v__ast__Kind__placeholder) { name = string_replace_each(name, _const_v__gen__c__c_fn_name_escape_seq); } } if (node->is_anon && (g->comptime->comptime_for_method_var).len != 0 && v__ast__Scope_is_inherited_var(node->scope, _S("method"))) { name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = name}}, {_S("_"), 0xfe07, {.d_i32 = g->comptime->comptime_loop_id}}, {_SLIT0, 0, { .d_c = 0 }}})); } if (node->language == v__ast__Language__c) { name = v__util__no_dots(name); } else { name = v__gen__c__c_fn_name(name); } if (node->generic_names.len > 0) { name = v__gen__c__Gen_generic_fn_name(g, g->cur_concrete_types, name); name = string_replace_each(name, _const_v__gen__c__c_fn_name_escape_seq); } if (g->pref->translated || g->file->is_translated || node->is_file_translated) { _option_v__ast__Attr _t1; if (_t1 = Array_v__ast__Attr_find_first(node->attrs, _S("c")), _t1.state == 0) { v__ast__Attr cattr = *(v__ast__Attr*)_t1.data; name = cattr.arg; } } return name; } VV_LOC string v__gen__c__Gen_gen_closure_fn_name(v__gen__c__Gen* g, v__ast__AnonFn node) { string fn_name = node.decl.name; if (node.decl.generic_names.len > 0) { fn_name = v__gen__c__Gen_generic_fn_name(g, g->cur_concrete_types, fn_name); } bool _t1 = (node.inherited_vars.len > 0 && (g->comptime->comptime_for_method_var).len != 0); bool _t2 = false; if (_t1) { Array_v__ast__Param _t2_orig = node.inherited_vars; int _t2_len = _t2_orig.len; for (int _t3 = 0; _t3 < _t2_len; ++_t3) { v__ast__Param it = ((v__ast__Param*) _t2_orig.data)[_t3]; if (fast_string_eq(it.name, _S("method"))) { _t2 = true; break; } } } if ( _t1 &&_t2) { fn_name = string__plus(fn_name, str_intp(2, _MOV((StrIntpData[]){{_S("_"), 0xfe07, {.d_i32 = g->comptime->comptime_loop_id}}, {_SLIT0, 0, { .d_c = 0 }}}))); } return fn_name; } VV_LOC string v__gen__c__Gen_closure_ctx(v__gen__c__Gen* g, v__ast__FnDecl node) { string fn_name = node.name; if (node.generic_names.len > 0) { fn_name = v__gen__c__Gen_generic_fn_name(g, g->cur_concrete_types, fn_name); } return str_intp(2, _MOV((StrIntpData[]){{_S("struct _V_"), 0xfe10, {.d_s = fn_name}}, {_S("_Ctx"), 0, { .d_c = 0 }}})); } VV_LOC void v__gen__c__Gen_gen_anon_fn(v__gen__c__Gen* g, v__ast__AnonFn* node) { bool v__gen__c__Gen_gen_anon_fn_defer_0 = false; bool is_amp; is_amp = g->is_amp; g->is_amp = false; v__gen__c__Gen_gen_anon_fn_defer_0 = true; v__gen__c__Gen_gen_anon_fn_decl(g, node); string fn_name = v__gen__c__Gen_gen_closure_fn_name(g, *node); if (!v__ast__Scope_has_inherited_vars(node->decl.scope)) { v__gen__c__Gen_write(g, fn_name); // Defer begin if (v__gen__c__Gen_gen_anon_fn_defer_0) { g->is_amp = is_amp; } // Defer end return; } string ctx_struct = v__gen__c__Gen_closure_ctx(g, node->decl); { v__gen__c__Gen_write(g, _S("builtin__closure__closure_create(")); v__gen__c__Gen_write(g, fn_name); v__gen__c__Gen_write(g, _S(", (")); v__gen__c__Gen_write(g, ctx_struct); v__gen__c__Gen_write(g, _S("*) memdup_uncollectable(&(")); v__gen__c__Gen_write(g, ctx_struct); v__gen__c__Gen_write(g, _S("){")); } g->indent++; for (int _t1 = 0; _t1 < node->inherited_vars.len; ++_t1) { v__ast__Param var = ((v__ast__Param*)node->inherited_vars.data)[_t1]; bool has_inherited = false; bool is_ptr = false; string var_name = v__gen__c__c_name(var.name); _option_v__ast__Var_ptr _t2; if (_t2 = v__ast__Scope_find_var(node->decl.scope, var.name), _t2.state == 0) { v__ast__Var* obj = *(v__ast__Var**)_t2.data; is_ptr = v__ast__Type_is_ptr(obj->typ); if (obj->has_inherited) { has_inherited = true; v__ast__TypeSymbol* var_sym = v__ast__Table_sym(g->table, var.typ); if ((var_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { { v__gen__c__Gen_write(g, _S(".")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(" = {")); } for (int i = 0; i < (*var_sym->info._v__ast__ArrayFixed).size; ++i) { { v__gen__c__Gen_write(g, _const_v__gen__c__closure_ctx); v__gen__c__Gen_write(g, _S("->")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_write_decimal(g, i); v__gen__c__Gen_write(g, _S("],")); } } v__gen__c__Gen_writeln(g, _S("},")); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = var_name}}, {_S(" = "), 0xfe10, {.d_s = _const_v__gen__c__closure_ctx}}, {_S("->"), 0xfe10, {.d_s = var_name}}, {_S(","), 0, { .d_c = 0 }}}))); } } } if (!has_inherited) { v__ast__TypeSymbol* var_sym = v__ast__Table_sym(g->table, var.typ); if ((var_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { { v__gen__c__Gen_write(g, _S(".")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(" = {")); } for (int i = 0; i < (*var_sym->info._v__ast__ArrayFixed).size; ++i) { { v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_write_decimal(g, i); v__gen__c__Gen_write(g, _S("],")); } } v__gen__c__Gen_writeln(g, _S("},")); } else if (g->is_autofree && !var.is_mut && (var_sym->info)._typ == 513 /* v.ast.Array */) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = var_name}}, {_S(" = array_clone(&"), 0xfe10, {.d_s = var_name}}, {_S("),"), 0, { .d_c = 0 }}}))); } else if (g->is_autofree && !var.is_mut && var_sym->kind == v__ast__Kind__string) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = var_name}}, {_S(" = string_clone("), 0xfe10, {.d_s = var_name}}, {_S("),"), 0, { .d_c = 0 }}}))); } else { bool is_auto_heap = false; string field_name = _S(""); _option_v__ast__ScopeObject _t3; if (_t3 = v__ast__Scope_find(node->decl.scope->parent, var.name), _t3.state == 0) { v__ast__ScopeObject obj = *(v__ast__ScopeObject*)_t3.data; if ((obj)._typ == 422 /* v.ast.Var */) { is_auto_heap = !(*obj._v__ast__Var).is_stack_obj && (*obj._v__ast__Var).is_auto_heap; if ((*obj._v__ast__Var).smartcasts.len > 0) { if (v__ast__Table_type_kind(g->table, (*obj._v__ast__Var).typ) == v__ast__Kind__sum_type) { v__ast__TypeSymbol* cast_sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_last((*obj._v__ast__Var).smartcasts))); field_name = string__plus(field_name, str_intp(2, _MOV((StrIntpData[]){{_S("._"), 0xfe10, {.d_s = cast_sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } } } if ((is_auto_heap && !is_ptr) || (field_name).len != 0) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = var_name}}, {_S(" = *"), 0xfe10, {.d_s = var_name}}, {_SLIT0, 0xfe10, {.d_s = field_name}}, {_S(","), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = var_name}}, {_S(" = "), 0xfe10, {.d_s = var_name}}, {_S(","), 0, { .d_c = 0 }}}))); } } } } g->indent--; { v__gen__c__Gen_write(g, _S("}, sizeof(")); v__gen__c__Gen_write(g, ctx_struct); v__gen__c__Gen_write(g, _S(")))")); } g->empty_line = false; // Defer begin if (v__gen__c__Gen_gen_anon_fn_defer_0) { g->is_amp = is_amp; } // Defer end } VV_LOC void v__gen__c__Gen_gen_anon_fn_decl(v__gen__c__Gen* g, v__ast__AnonFn* node) { string fn_name = v__gen__c__Gen_gen_closure_fn_name(g, *node); if ((*(bool*)map_get(ADDR(map, node->has_gen), &(string[]){fn_name}, &(bool[]){ 0 }))) { return; } map_set(&node->has_gen, &(string[]){fn_name}, &(bool[]) { true }); strings__Builder builder = strings__new_builder(256); if (node->inherited_vars.len > 0) { string ctx_struct = v__gen__c__Gen_closure_ctx(g, node->decl); if (!(Array_string_contains(g->closure_structs, ctx_struct))) { array_push((array*)&g->closure_structs, _MOV((string[]){ string_clone(ctx_struct) })); strings__Builder_writeln(&g->definitions, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ctx_struct}}, {_S(" {"), 0, { .d_c = 0 }}}))); for (int _t2 = 0; _t2 < node->inherited_vars.len; ++_t2) { v__ast__Param var = ((v__ast__Param*)node->inherited_vars.data)[_t2]; v__ast__TypeSymbol* var_sym = v__ast__Table_sym(g->table, var.typ); if ((var_sym->info)._typ == 553 /* v.ast.FnType */) { Array_v__ast__Type _t3 = {0}; Array_v__ast__Param _t3_orig = (*var_sym->info._v__ast__FnType).func.params; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__Type)); for (int _t5 = 0; _t5 < _t3_len; ++_t5) { v__ast__Param it = ((v__ast__Param*) _t3_orig.data)[_t5]; v__ast__Type _t4 = it.typ; array_push((array*)&_t3, &_t4); } string sig = v__gen__c__Gen_fn_var_signature(g, (*var_sym->info._v__ast__FnType).func.return_type,_t3, v__gen__c__c_name(var.name)); strings__Builder_writeln(&g->definitions, string__plus(string__plus(_S("\t"), sig), _S(";"))); } else { string styp = v__gen__c__Gen_styp(g, var.typ); strings__Builder_writeln(&g->definitions, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = v__gen__c__c_name(var.name)}}, {_S(";"), 0, { .d_c = 0 }}}))); } } strings__Builder_writeln(&g->definitions, _S("};\n")); } } int pos = g->out.len; bool was_anon_fn = g->anon_fn; g->anon_fn = true; v__gen__c__Gen_fn_decl(g, node->decl); g->anon_fn = was_anon_fn; strings__Builder_write_string(&builder, strings__Builder_cut_to(&g->out, pos)); string out = strings__Builder_str(&builder); array_push((array*)&g->anon_fn_definitions, _MOV((string[]){ string_clone(out) })); if (g->pref->parallel_cc) { strings__Builder_writeln(&g->extern_out, str_intp(2, _MOV((StrIntpData[]){{_S("extern "), 0xfe10, {.d_s = string_all_before(out, _S(" {"))}}, {_S(";"), 0, { .d_c = 0 }}}))); } } VV_LOC string v__gen__c__Gen_defer_flag_var(v__gen__c__Gen* g, v__ast__DeferStmt* stmt) { return str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->last_fn_c_name}}, {_S("_defer_"), 0xfe07, {.d_i32 = stmt->idx_in_fn}}, {_SLIT0, 0, { .d_c = 0 }}})); } VV_LOC void v__gen__c__Gen_write_defer_stmts_when_needed(v__gen__c__Gen* g) { v__gen__c__Gen_unlock_locks(g); if (g->defer_stmts.len > 0) { v__gen__c__Gen_write_defer_stmts(g); } if (g->defer_profile_code.len > 0) { v__gen__c__Gen_writeln2(g, _S(""), _S("\t// defer_profile_code")); v__gen__c__Gen_writeln2(g, g->defer_profile_code, _S("")); } } VV_LOC multi_return_Array_string_Array_string_Array_bool v__gen__c__Gen_fn_decl_params(v__gen__c__Gen* g, Array_v__ast__Param params, v__ast__Scope* scope, bool is_variadic, bool is_c_variadic) { Array_string fparams = __new_array_with_default(0, 0, sizeof(string), 0); Array_string fparamtypes = __new_array_with_default(0, 0, sizeof(string), 0); Array_bool heap_promoted = __new_array_with_default(0, 0, sizeof(bool), 0); if (params.len == 0) { if (!g->inside_c_extern) { v__gen__c__Gen_write(g, _S("void")); } } for (int i = 0; i < params.len; ++i) { v__ast__Param param = ((v__ast__Param*)params.data)[i]; string caname = (fast_string_eq(param.name, _S("_")) ? (str_intp(2, _MOV((StrIntpData[]){{_S("_d"), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (v__gen__c__c_name(param.name))); v__ast__Type typ = v__gen__c__Gen_unwrap_generic(g, param.typ); if (g->pref->translated && g->file->is_translated && v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__variadic)) { typ = v__ast__Type_set_flag(v__ast__TypeSymbol_array_info(v__ast__Table_sym(g->table, typ)).elem_type, v__ast__TypeFlag__variadic); } v__ast__TypeSymbol* param_type_sym = v__ast__Table_sym(g->table, typ); string param_type_name = v__gen__c__Gen_styp(g, typ); if (v__ast__Type_has_flag(param.typ, v__ast__TypeFlag__generic)) { param_type_name = string_replace_each(param_type_name, _const_v__gen__c__c_fn_name_escape_seq); } if (param_type_sym->kind == v__ast__Kind__function && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { v__ast__FnType info = *(v__ast__FnType*)__as_cast((param_type_sym->info)._v__ast__FnType,(param_type_sym->info)._typ, 553); v__ast__Fn func = info.func; if (!g->inside_c_extern) { { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, func.return_type)); v__gen__c__Gen_write(g, _S(" (*")); v__gen__c__Gen_write(g, caname); v__gen__c__Gen_write(g, _S(")(")); } } { strings__Builder_write_string(&g->definitions, v__gen__c__Gen_styp(g, func.return_type)); strings__Builder_write_string(&g->definitions, _S(" (*")); strings__Builder_write_string(&g->definitions, caname); strings__Builder_write_string(&g->definitions, _S(")(")); } v__gen__c__Gen_fn_decl_params(g, func.params, ((void*)0), func.is_variadic, func.is_c_variadic); if (!g->inside_c_extern) { v__gen__c__Gen_write(g, _S(")")); } strings__Builder_write_string(&g->definitions, _S(")")); array_push((array*)&fparams, _MOV((string[]){ string_clone(caname) })); array_push((array*)&fparamtypes, _MOV((string[]){ string_clone(param_type_name) })); array_push((array*)&heap_promoted, _MOV((bool[]){ false })); } else { bool heap_prom = false; if (scope != ((void*)0)) { if (!fast_string_eq(param.name, _S("_"))) { _option_v__ast__Var_ptr _t4; if (_t4 = v__ast__Scope_find_var(scope, param.name), _t4.state == 0) { v__ast__Var* v = *(v__ast__Var**)_t4.data; if (!v->is_stack_obj && v->is_auto_heap) { heap_prom = true; } } } } string var_name_prefix = (heap_prom ? (_S("_v_toheap_")) : (_S(""))); string const_prefix = (v__ast__Type_is_any_kind_of_pointer(param.typ) && !param.is_mut && string_starts_with(param.name, _S("const_")) ? (_S("const ")) : (_S(""))); string s = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = const_prefix}}, {_SLIT0, 0xfe10, {.d_s = param_type_name}}, {_S(" "), 0xfe10, {.d_s = var_name_prefix}}, {_SLIT0, 0xfe10, {.d_s = caname}}, {_SLIT0, 0, { .d_c = 0 }}})); if (!g->inside_c_extern) { v__gen__c__Gen_write(g, s); } strings__Builder_write_string(&g->definitions, s); array_push((array*)&fparams, _MOV((string[]){ string_clone(caname) })); array_push((array*)&fparamtypes, _MOV((string[]){ string_clone(param_type_name) })); array_push((array*)&heap_promoted, _MOV((bool[]){ heap_prom })); } if (i < (int)(params.len - 1)) { if (!g->inside_c_extern) { v__gen__c__Gen_write(g, _S(", ")); } strings__Builder_write_string(&g->definitions, _S(", ")); } } if ((g->pref->translated && is_variadic) || is_c_variadic) { if (!g->inside_c_extern) { v__gen__c__Gen_write(g, _S(", ... ")); } strings__Builder_write_string(&g->definitions, _S(", ... ")); } return (multi_return_Array_string_Array_string_Array_bool){.arg0=fparams, .arg1=fparamtypes, .arg2=heap_promoted}; } VV_LOC string v__gen__c__Gen_get_anon_fn_type_name(v__gen__c__Gen* g, v__ast__AnonFn* node, string var_name) { strings__Builder builder = strings__new_builder(64); string return_styp = v__gen__c__Gen_styp(g, node->decl.return_type); { strings__Builder_write_string(&builder, return_styp); strings__Builder_write_string(&builder, _S(" (*")); strings__Builder_write_string(&builder, var_name); strings__Builder_write_string(&builder, _S(") (")); } if (node->decl.params.len == 0) { strings__Builder_write_string(&builder, _S("void)")); } else { for (int i = 0; i < node->decl.params.len; ++i) { v__ast__Param param = ((v__ast__Param*)node->decl.params.data)[i]; string param_styp = v__gen__c__Gen_styp(g, param.typ); { strings__Builder_write_string(&builder, param_styp); strings__Builder_write_string(&builder, _S(" ")); strings__Builder_write_string(&builder, param.name); } if (i != (int)(node->decl.params.len - 1)) { strings__Builder_write_string(&builder, _S(", ")); } } strings__Builder_write_string(&builder, _S(")")); } return strings__Builder_str(&builder); } VV_LOC void v__gen__c__Gen_call_expr(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_call_expr_defer_0 = false; bool old_inside_call; if (node.should_be_skipped) { return; } string tmp_anon_fn_var = _S(""); if ((node.left)._typ == 336 /* v.ast.AnonFn */) { if ((*node.left._v__ast__AnonFn).inherited_vars.len > 0) { tmp_anon_fn_var = v__gen__c__Gen_new_tmp_var(g); Array_v__ast__Type _t1 = {0}; Array_v__ast__Param _t1_orig = (*node.left._v__ast__AnonFn).decl.params; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Param it = ((v__ast__Param*) _t1_orig.data)[_t3]; v__ast__Type _t2 = it.typ; array_push((array*)&_t1, &_t2); } string fn_type = v__gen__c__Gen_fn_var_signature(g, (*node.left._v__ast__AnonFn).decl.return_type,_t1, tmp_anon_fn_var); string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; { v__gen__c__Gen_write(g, fn_type); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); v__gen__c__Gen_write(g, line); if (node.or_block.kind == v__ast__OrKind__absent) { if (!string__eq(strings__Builder_last_n(&g->out, 1), _S("\n"))) { v__gen__c__Gen_writeln(g, _S("")); } v__gen__c__Gen_write(g, tmp_anon_fn_var); } } else if (node.or_block.kind == v__ast__OrKind__absent) { v__gen__c__Gen_expr(g, node.left); } } else if (!g->inside_curry_call && (node.left)._typ == 361 /* v.ast.IndexExpr */ && (node.name).len == 0) { if (node.or_block.kind == v__ast__OrKind__absent) { bool old_is_fn_index_call = g->is_fn_index_call; g->is_fn_index_call = true; v__gen__c__Gen_expr(g, node.left); g->is_fn_index_call = old_is_fn_index_call; } else { string line = v__gen__c__Gen_go_before_last_stmt(g); g->empty_line = true; v__ast__Type left_typ = v__ast__Table_value_type(g->table, (*node.left._v__ast__IndexExpr).left_type); string tmp_res = v__gen__c__Gen_new_tmp_var(g); v__ast__FnType fn_sym = ({ v__ast__TypeInfo _t4 = v__ast__Table_sym(g->table, left_typ)->info; *(v__ast__FnType*)__as_cast(_t4._v__ast__FnType,_t4._typ, 553); }); Array_v__ast__Type _t5 = {0}; Array_v__ast__Param _t5_orig = fn_sym.func.params; int _t5_len = _t5_orig.len; _t5 = __new_array(0, _t5_len, sizeof(v__ast__Type)); for (int _t7 = 0; _t7 < _t5_len; ++_t7) { v__ast__Param it = ((v__ast__Param*) _t5_orig.data)[_t7]; v__ast__Type _t6 = it.typ; array_push((array*)&_t5, &_t6); } string fn_type = v__gen__c__Gen_fn_var_signature(g, fn_sym.func.return_type,_t5, tmp_res); bool old_is_fn_index_call = g->is_fn_index_call; g->is_fn_index_call = true; { v__gen__c__Gen_write(g, fn_type); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, node.left); g->is_fn_index_call = old_is_fn_index_call; v__gen__c__Gen_writeln(g, _S(";")); string tmp_res2 = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, node.return_type)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_res2); v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_write(g, tmp_res); } array_push((array*)&g->last_tmp_call_var, _MOV((string[]){ string_clone(tmp_res2) })); bool old_inside_curry_call = g->inside_curry_call; g->inside_curry_call = true; v__gen__c__Gen_expr(g, v__ast__CallExpr_to_sumtype_v__ast__Expr(&node)); g->inside_curry_call = old_inside_curry_call; v__gen__c__Gen_write2(g, line, str_intp(3, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, node.return_type)}}, {_S("*)"), 0xfe10, {.d_s = tmp_res2}}, {_S(".data"), 0, { .d_c = 0 }}}))); return; } } else if (!g->inside_curry_call && (node.left)._typ == 344 /* v.ast.CallExpr */ && (node.name).len == 0) { if (node.or_block.kind == v__ast__OrKind__absent) { v__gen__c__Gen_expr(g, node.left); } else { v__ast__Type ret_typ = node.return_type; string line = v__gen__c__Gen_go_before_last_stmt(g); g->empty_line = true; string tmp_res = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, ret_typ)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_res); v__gen__c__Gen_write(g, _S(" = ")); } array_push((array*)&g->last_tmp_call_var, _MOV((string[]){ string_clone(tmp_res) })); v__gen__c__Gen_expr(g, node.left); bool old_inside_curry_call = g->inside_curry_call; g->inside_curry_call = true; v__gen__c__Gen_expr(g, v__ast__CallExpr_to_sumtype_v__ast__Expr(&node)); g->inside_curry_call = old_inside_curry_call; v__gen__c__Gen_write2(g, line, str_intp(3, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, ret_typ)}}, {_S("*)"), 0xfe10, {.d_s = tmp_res}}, {_S(".data"), 0, { .d_c = 0 }}}))); return; } } old_inside_call = g->inside_call; g->inside_call = true; v__gen__c__Gen_call_expr_defer_0 = true; bool gen_keep_alive = node.is_keep_alive && node.return_type != _const_v__ast__void_type && (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full_opt || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt); bool gen_or = node.or_block.kind != v__ast__OrKind__absent; bool is_gen_or_and_assign_rhs = gen_or && !g->discard_or_result; string _t10; /* if prepend */ if (!g->inside_curry_call && (is_gen_or_and_assign_rhs || gen_keep_alive)) { string line = v__gen__c__Gen_go_before_last_stmt(g); strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); _t10 = line; } else { _t10 = _S(""); } string cur_line = _t10; string _t11; /* if prepend */ if (gen_or || gen_keep_alive) { string _t12; /* if prepend */ if (g->inside_curry_call && g->last_tmp_call_var.len > 0) { _t12 = (*(string*)array_pop(&g->last_tmp_call_var)); } else if (!g->inside_or_block) { string new_tmp = v__gen__c__Gen_new_tmp_var(g); array_push((array*)&g->last_tmp_call_var, _MOV((string[]){ string_clone(new_tmp) })); _t12 = new_tmp; } else { _t12 = v__gen__c__Gen_new_tmp_var(g); } _t11 = _t12; } else { _t11 = _S(""); } string tmp_opt = _t11; if (gen_or || gen_keep_alive) { v__ast__Type ret_typ = node.return_type; if (v__ast__Table_sym(g->table, ret_typ)->kind == v__ast__Kind__alias) { v__ast__Type unaliased_type = v__ast__Table_unaliased_type(g->table, ret_typ); if (v__ast__Type_has_option_or_result(unaliased_type)) { ret_typ = unaliased_type; } } else if (node.return_type_generic != 0 && node.raw_concrete_types.len == 0) { v__ast__Type unwrapped_ret_typ = v__gen__c__Gen_unwrap_generic(g, node.return_type_generic); if (!v__ast__Type_has_flag(unwrapped_ret_typ, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* ret_sym = v__ast__Table_sym(g->table, unwrapped_ret_typ); if ((ret_sym->info)._typ == 513 /* v.ast.Array */ && v__ast__Table_sym(g->table, node.return_type_generic)->kind == v__ast__Kind__array) { if (string_count(v__ast__Table_type_to_str(g->table, node.return_type_generic), _S("[]")) < string_count(v__ast__Table_type_to_str(g->table, unwrapped_ret_typ), _S("[]"))) { ret_typ = v__ast__Type_derive(v__gen__c__Gen_unwrap_generic(g, (*ret_sym->info._v__ast__Array).elem_type), unwrapped_ret_typ); } } } else { v__ast__Type r_typ = v__gen__c__Gen_resolve_return_type(g, node); if (r_typ != _const_v__ast__void_type && !v__ast__Type_has_flag(r_typ, v__ast__TypeFlag__generic)) { if (v__ast__Type_has_flag(node.return_type, v__ast__TypeFlag__result)) { ret_typ = v__ast__Type_set_flag(r_typ, v__ast__TypeFlag__result); } else { ret_typ = v__ast__Type_set_flag(r_typ, v__ast__TypeFlag__option); } } } } string styp = v__gen__c__Gen_styp(g, ret_typ); if (gen_or && !is_gen_or_and_assign_rhs) { cur_line = v__gen__c__Gen_go_before_last_stmt(g); } if (gen_or && g->infix_left_var_name.len > 0) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = tmp_opt}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = g->infix_left_var_name}}, {_S(") {"), 0, { .d_c = 0 }}}))); g->indent++; { v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(" = ")); } } else if (!g->inside_curry_call) { if (g->assign_ct_type != 0 && (node.or_block.kind == v__ast__OrKind__propagate_option || node.or_block.kind == v__ast__OrKind__propagate_result)) { styp = v__gen__c__Gen_styp(g, v__ast__Type_derive(g->assign_ct_type, ret_typ)); } { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(" = ")); } if ((node.left)._typ == 336 /* v.ast.AnonFn */) { if ((*node.left._v__ast__AnonFn).inherited_vars.len > 0) { v__gen__c__Gen_write(g, tmp_anon_fn_var); } else { v__gen__c__Gen_expr(g, node.left); } } } } if (node.is_method && !node.is_field) { if (g->pref->experimental && node.args.len > 0 && fast_string_eq(node.name, _S("writeln")) && ((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ == 383 /* v.ast.StringInterLiteral */ && fast_string_eq(v__ast__Table_sym(g->table, node.receiver_type)->name, _S("strings.Builder"))) { v__gen__c__Gen_string_inter_literal_sb_optimized(g, node); } else { v__gen__c__Gen_method_call(g, node); } } else { v__gen__c__Gen_fn_call(g, node); } if (gen_or) { v__gen__c__Gen_or_block(g, tmp_opt, node.or_block, node.return_type); v__ast__Type unwrapped_typ = v__ast__Type_clear_option_and_result(node.return_type); if (v__ast__Table_sym(g->table, unwrapped_typ)->kind == v__ast__Kind__alias) { v__ast__Type unaliased_type = v__ast__Table_unaliased_type(g->table, unwrapped_typ); if (v__ast__Type_has_option_or_result(unaliased_type)) { unwrapped_typ = v__ast__Type_clear_option_and_result(unaliased_type); } } string unwrapped_styp = v__gen__c__Gen_styp(g, unwrapped_typ); if (g->infix_left_var_name.len > 0) { g->indent--; v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } if (unwrapped_typ == _const_v__ast__void_type) { { v__gen__c__Gen_write(g, _S("\n ")); v__gen__c__Gen_write(g, cur_line); } } else if (!g->inside_curry_call) { if (!g->inside_const_opt_or_res) { if (g->assign_ct_type != 0 && (node.or_block.kind == v__ast__OrKind__propagate_option || node.or_block.kind == v__ast__OrKind__propagate_result)) { unwrapped_styp = v__gen__c__Gen_styp(g, v__ast__Type_clear_option_and_result(v__ast__Type_derive(g->assign_ct_type, node.return_type))); } if (v__ast__Table_sym(g->table, node.return_type)->kind == v__ast__Kind__array_fixed && string_starts_with(unwrapped_styp, _S("_v_"))) { unwrapped_styp = string_substr(unwrapped_styp, 3, 2147483647); } if (node.is_return_used) { { v__gen__c__Gen_write(g, _S("\n ")); v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, unwrapped_styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(".data)")); } } else { { v__gen__c__Gen_write(g, _S("\n ")); v__gen__c__Gen_write(g, cur_line); } } } else { if (!g->inside_or_block && g->last_tmp_call_var.len > 0 && !string_contains(cur_line, _S(" = "))) { { v__gen__c__Gen_write(g, _S("\n\t*(")); v__gen__c__Gen_write(g, unwrapped_styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, (*(string*)array_pop(&g->last_tmp_call_var))); v__gen__c__Gen_write(g, _S(".data = ")); v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, unwrapped_styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(".data)")); } } else { { v__gen__c__Gen_write(g, _S("\n ")); v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, unwrapped_styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(".data)")); } } } } } else if (gen_keep_alive) { if (node.return_type == _const_v__ast__void_type) { { v__gen__c__Gen_write(g, _S("\n ")); v__gen__c__Gen_write(g, cur_line); } } else { { v__gen__c__Gen_write(g, _S("\n ")); v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_opt); } } } if (node.is_noreturn) { if (g->inside_ternary == 0) { v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write(g, _S("VUNREACHABLE()")); } else { #if defined(_MSC_VER) { } #else { v__gen__c__Gen_write(g, _S(", ({VUNREACHABLE();})")); } #endif } } // Defer begin if (v__gen__c__Gen_call_expr_defer_0) { g->inside_call = old_inside_call; } // Defer end } VV_LOC void v__gen__c__Gen_conversion_function_call(v__gen__c__Gen* g, string prefix, string postfix, v__ast__CallExpr node) { { v__gen__c__Gen_write(g, prefix); v__gen__c__Gen_write(g, _S("( (")); } v__gen__c__Gen_expr(g, node.left); string dot = (v__ast__Type_is_ptr(node.left_type) ? (_S("->")) : (_S("."))); { v__gen__c__Gen_write(g, _S(")")); v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_typ )")); v__gen__c__Gen_write(g, postfix); } } inline VV_LOC void v__gen__c__Gen_gen_arg_from_type(v__gen__c__Gen* g, v__ast__Type node_type, v__ast__Expr node) { if (v__ast__Type_has_flag(node_type, v__ast__TypeFlag__shared_f)) { if (v__ast__Type_is_ptr(node_type)) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, node); v__gen__c__Gen_write(g, _S("->val")); } else { if (v__ast__Type_is_ptr(node_type)) { v__gen__c__Gen_expr(g, node); } else if (!v__ast__Expr_is_lvalue(node) || ((node)._typ == 358 /* v.ast.Ident */ && v__ast__Table_is_interface_smartcast(g->table, (*(v__ast__Ident*)__as_cast((node)._v__ast__Ident,(node)._typ, 358)).obj))) { { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, node_type)); v__gen__c__Gen_write(g, _S(", ")); } v__gen__c__Gen_expr(g, node); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_write(g, _S("&")); v__gen__c__Gen_expr(g, node); } } } VV_LOC bool v__gen__c__Gen_gen_map_method_call(v__gen__c__Gen* g, v__ast__CallExpr node, v__ast__Type left_type, v__ast__TypeSymbol left_sym) { if (_SLIT_EQ(node.name.str, node.name.len, "reserve")) { v__gen__c__Gen_write(g, _S("map_reserve(")); v__gen__c__Gen_gen_arg_from_type(g, left_type, node.left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 0)).expr); v__gen__c__Gen_write(g, _S(")")); } else if (_SLIT_EQ(node.name.str, node.name.len, "delete")) { v__ast__Map left_info = *(v__ast__Map*)__as_cast((left_sym.info)._v__ast__Map,(left_sym.info)._typ, 514); string elem_type_str = v__gen__c__Gen_styp(g, left_info.key_type); v__gen__c__Gen_write(g, _S("map_delete(")); v__gen__c__Gen_gen_arg_from_type(g, left_type, node.left); { v__gen__c__Gen_write(g, _S(", &(")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("[]){")); } v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 0)).expr); v__gen__c__Gen_write(g, _S("})")); } else if (_SLIT_EQ(node.name.str, node.name.len, "free") || _SLIT_EQ(node.name.str, node.name.len, "clear") || _SLIT_EQ(node.name.str, node.name.len, "keys") || _SLIT_EQ(node.name.str, node.name.len, "values")) { { v__gen__c__Gen_write(g, _S("map_")); v__gen__c__Gen_write(g, node.name); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_gen_arg_from_type(g, left_type, node.left); v__gen__c__Gen_write(g, _S(")")); } else { return false; } return true; } VV_LOC bool v__gen__c__Gen_gen_array_method_call(v__gen__c__Gen* g, v__ast__CallExpr node, v__ast__Type left_type, v__ast__TypeSymbol left_sym) { if (_SLIT_EQ(node.name.str, node.name.len, "filter")) { v__gen__c__Gen_gen_array_filter(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "sort")) { v__gen__c__Gen_gen_array_sort(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "sorted")) { v__gen__c__Gen_gen_array_sorted(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "insert")) { v__gen__c__Gen_gen_array_insert(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "map")) { v__gen__c__Gen_gen_array_map(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "prepend")) { v__gen__c__Gen_gen_array_prepend(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "contains")) { v__gen__c__Gen_gen_array_contains(g, left_type, node.left, (*(v__ast__CallArg*)array_get(node.args, 0)).typ, (*(v__ast__CallArg*)array_get(node.args, 0)).expr); } else if (_SLIT_EQ(node.name.str, node.name.len, "index")) { v__gen__c__Gen_gen_array_index(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "wait")) { v__gen__c__Gen_gen_array_wait(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "any")) { v__gen__c__Gen_gen_array_any(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "count")) { v__gen__c__Gen_gen_array_count(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "all")) { v__gen__c__Gen_gen_array_all(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "delete") || _SLIT_EQ(node.name.str, node.name.len, "drop") || _SLIT_EQ(node.name.str, node.name.len, "delete_last") || _SLIT_EQ(node.name.str, node.name.len, "delete_many")) { { v__gen__c__Gen_write(g, _S("array_")); v__gen__c__Gen_write(g, node.name); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_gen_arg_from_type(g, left_type, node.left); if (!fast_string_eq(node.name, _S("delete_last"))) { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 0)).expr); if (fast_string_eq(node.name, _S("delete_many"))) { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 1)).expr); } } v__gen__c__Gen_write(g, _S(")")); } else if (_SLIT_EQ(node.name.str, node.name.len, "grow_cap") || _SLIT_EQ(node.name.str, node.name.len, "grow_len")) { { v__gen__c__Gen_write(g, _S("array_")); v__gen__c__Gen_write(g, node.name); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_gen_arg_from_type(g, left_type, node.left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 0)).expr); v__gen__c__Gen_write(g, _S(")")); } else if (_SLIT_EQ(node.name.str, node.name.len, "first") || _SLIT_EQ(node.name.str, node.name.len, "last") || _SLIT_EQ(node.name.str, node.name.len, "pop")) { string noscan = _S(""); v__ast__Array array_info = *(v__ast__Array*)__as_cast((left_sym.info)._v__ast__Array,(left_sym.info)._typ, 513); if (fast_string_eq(node.name, _S("pop"))) { noscan = v__gen__c__Gen_check_noscan(g, array_info.elem_type); } string return_type_str = v__gen__c__Gen_styp(g, node.return_type); { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, return_type_str); v__gen__c__Gen_write(g, _S("*)array_")); v__gen__c__Gen_write(g, node.name); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); } if (fast_string_eq(node.name, _S("pop"))) { v__gen__c__Gen_gen_arg_from_type(g, left_type, node.left); } else { if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write2(g, _S("("), string_repeat(_S("*"), v__ast__Type_nr_muls(node.left_type))); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_expr(g, node.left); } if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S(".val")); } } v__gen__c__Gen_write(g, _S("))")); } else if (_SLIT_EQ(node.name.str, node.name.len, "clone") || _SLIT_EQ(node.name.str, node.name.len, "repeat")) { v__ast__Array array_info = *(v__ast__Array*)__as_cast((left_sym.info)._v__ast__Array,(left_sym.info)._typ, 513); int array_depth = v__gen__c__Gen_get_array_depth(g, array_info.elem_type); string to_depth = (array_depth >= 0 ? (_S("_to_depth")) : (_S(""))); bool is_range_slice = false; if ((node.left)._typ == 361 /* v.ast.IndexExpr */ && ((*(v__ast__IndexExpr*)__as_cast((node.left)._v__ast__IndexExpr,(node.left)._typ, 361)).index)._typ == 377 /* v.ast.RangeExpr */ && fast_string_eq(node.name, _S("clone"))) { is_range_slice = true; } string to_static = (is_range_slice ? (_S("_static")) : (_S(""))); { v__gen__c__Gen_write(g, _S("array_")); v__gen__c__Gen_write(g, node.name); v__gen__c__Gen_write(g, to_static); v__gen__c__Gen_write(g, to_depth); v__gen__c__Gen_write(g, _S("(")); } if (fast_string_eq(node.name, _S("clone"))) { if (is_range_slice) { if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(node.left_type))); } v__gen__c__Gen_expr(g, node.left); } else { v__gen__c__Gen_gen_arg_from_type(g, left_type, node.left); } } else { if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(node.left_type))); } v__gen__c__Gen_expr(g, node.left); } if (fast_string_eq(node.name, _S("repeat"))) { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 0)).expr); } if (array_depth >= 0) { { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, array_depth); } } v__gen__c__Gen_write(g, _S(")")); } else { return false; } return true; } VV_LOC bool v__gen__c__Gen_gen_fixed_array_method_call(v__gen__c__Gen* g, v__ast__CallExpr node, v__ast__Type left_type) { if (_SLIT_EQ(node.name.str, node.name.len, "index")) { v__gen__c__Gen_gen_array_index(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "contains")) { v__gen__c__Gen_gen_array_contains(g, left_type, node.left, (*(v__ast__CallArg*)array_get(node.args, 0)).typ, (*(v__ast__CallArg*)array_get(node.args, 0)).expr); } else if (_SLIT_EQ(node.name.str, node.name.len, "any")) { v__gen__c__Gen_gen_array_any(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "count")) { v__gen__c__Gen_gen_array_count(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "all")) { v__gen__c__Gen_gen_array_all(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "map")) { v__gen__c__Gen_gen_array_map(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "sort")) { v__gen__c__Gen_gen_array_sort(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "sorted")) { v__gen__c__Gen_gen_array_sorted(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "sort_with_compare")) { v__gen__c__Gen_gen_fixed_array_sort_with_compare(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "sorted_with_compare")) { v__gen__c__Gen_gen_fixed_array_sorted_with_compare(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "reverse")) { v__gen__c__Gen_gen_fixed_array_reverse(g, node); } else if (_SLIT_EQ(node.name.str, node.name.len, "reverse_in_place")) { v__gen__c__Gen_gen_fixed_array_reverse_in_place(g, node); } else { return false; } return true; } VV_LOC bool v__gen__c__Gen_gen_to_str_method_call(v__gen__c__Gen* g, v__ast__CallExpr node) { v__ast__Type rec_type = node.receiver_type; if (v__ast__Type_has_flag(rec_type, v__ast__TypeFlag__shared_f)) { rec_type = v__ast__Type_set_nr_muls(v__ast__Type_clear_flag(rec_type, v__ast__TypeFlag__shared_f), 0); } v__ast__Expr left_node = node.left; if ((left_node)._typ == 350 /* v.ast.ComptimeSelector */) { if (((*left_node._v__ast__ComptimeSelector).typ_key).len != 0) { rec_type = v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, (*left_node._v__ast__ComptimeSelector).typ_key, rec_type); v__gen__c__Gen_gen_expr_to_string(g, left_node, rec_type); return true; } } else if ((left_node)._typ == 375 /* v.ast.PostfixExpr */) { rec_type = v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, (*left_node._v__ast__PostfixExpr).expr, rec_type); if ((*left_node._v__ast__PostfixExpr).op == v__token__Kind__question) { rec_type = v__ast__Type_clear_flag(rec_type, v__ast__TypeFlag__option); } v__gen__c__Gen_gen_expr_to_string(g, left_node, rec_type); return true; } else if ((left_node)._typ == 349 /* v.ast.ComptimeCall */) { if ((*left_node._v__ast__ComptimeCall).kind == v__ast__ComptimeCallKind__method) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, (*left_node._v__ast__ComptimeCall).left_type)); _option_v__ast__Fn _t3; if (_t3 = v__ast__TypeSymbol_find_method(sym, g->comptime->comptime_for_method->name), _t3.state == 0) { v__ast__Fn m = *(v__ast__Fn*)_t3.data; rec_type = m.return_type; v__gen__c__Gen_gen_expr_to_string(g, left_node, rec_type); return true; } } } else if ((left_node)._typ == 358 /* v.ast.Ident */) { if (((*left_node._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { if ((*(*left_node._v__ast__Ident).obj._v__ast__Var).ct_type_var != v__ast__ComptimeVarKind__no_comptime) { rec_type = v__type_resolver__TypeResolver_get_type(&g->type_resolver, left_node); v__gen__c__Gen_gen_expr_to_string(g, left_node, rec_type); return true; } else if ((*(*left_node._v__ast__Ident).obj._v__ast__Var).smartcasts.len > 0) { rec_type = v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Type*)array_last((*(*left_node._v__ast__Ident).obj._v__ast__Var).smartcasts))); v__ast__TypeSymbol* cast_sym = v__ast__Table_sym(g->table, rec_type); if ((cast_sym->info)._typ == 537 /* v.ast.Aggregate */) { rec_type = (*(v__ast__Type*)array_get((*cast_sym->info._v__ast__Aggregate).types, g->aggregate_type_idx)); } v__gen__c__Gen_gen_expr_to_string(g, left_node, rec_type); return true; } else if ((*left_node._v__ast__Ident).or_expr.kind == v__ast__OrKind__propagate_option) { v__gen__c__Gen_gen_expr_to_string(g, left_node, v__gen__c__Gen_unwrap_generic(g, node.left_type)); return true; } } } else if ((left_node)._typ == 371 /* v.ast.None */) { v__gen__c__Gen_gen_expr_to_string(g, left_node, _const_v__ast__none_type); return true; } else if (v__ast__Type_has_flag(node.left_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_gen_expr_to_string(g, left_node, v__gen__c__Gen_unwrap_generic(g, node.left_type)); return true; } v__gen__c__Gen_get_str_fn(g, rec_type); return false; } VV_LOC v__ast__Type v__gen__c__Gen_resolve_return_type(v__gen__c__Gen* g, v__ast__CallExpr node) { if (node.is_method) { _result_v__ast__Fn _t1; if (_t1 = v__ast__Table_find_method(g->table, v__ast__Table_sym(g->table, node.left_type), node.name), !_t1.is_error) { v__ast__Fn func = *(v__ast__Fn*)_t1.data; if (func.generic_names.len > 0) { Array_v__ast__Type _t2 = {0}; Array_v__ast__Type _t2_orig = node.concrete_types; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(v__ast__Type)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Type it = ((v__ast__Type*) _t2_orig.data)[_t4]; v__ast__Type _t3 = v__gen__c__Gen_unwrap_generic(g, it); array_push((array*)&_t2, &_t3); } Array_v__ast__Type concrete_types =_t2; int rec_len = 0; if (v__ast__Type_has_flag(node.left_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* rec_sym = v__ast__Table_final_sym(g->table, v__gen__c__Gen_unwrap_generic(g, node.left_type)); if (rec_sym->info._typ == 518 /* v.ast.Struct */) { rec_len += (*rec_sym->info._v__ast__Struct).generic_types.len; } else if (rec_sym->info._typ == 542 /* v.ast.Interface */) { rec_len += (*rec_sym->info._v__ast__Interface).generic_types.len; } else if (rec_sym->info._typ == 544 /* v.ast.SumType */) { rec_len += (*rec_sym->info._v__ast__SumType).generic_types.len; } else { } } v__ast__CallExpr call_ = node; Map_int_v__ast__Type comptime_args = v__type_resolver__TypeResolver_resolve_args(&g->type_resolver, g->cur_fn, (voidptr)&func, (voidptr)&call_, concrete_types); if (concrete_types.len > 0) { int _t6 = comptime_args.key_values.len; for (int _t5 = 0; _t5 < _t6; ++_t5 ) { int _t7 = comptime_args.key_values.len - _t6; _t6 = comptime_args.key_values.len; if (_t7 < 0) { _t5 = -1; continue; } if (!DenseArray_has_index(&comptime_args.key_values, _t5)) {continue;} int k = *(int*)DenseArray_key(&comptime_args.key_values, _t5); v__ast__Type v = (*(v__ast__Type*)DenseArray_value(&comptime_args.key_values, _t5)); if (((int)(rec_len + k)) < concrete_types.len) { if (!v__ast__Type_has_flag((*(v__ast__Type*)array_get(node.concrete_types, k)), v__ast__TypeFlag__generic)) { array_set(&concrete_types, (int)(rec_len + k), &(v__ast__Type[]) { v__gen__c__Gen_unwrap_generic(g, v) }); } } } } _option_v__ast__Type _t8; if (_t8 = v__ast__Table_convert_generic_type(g->table, node.return_type_generic, func.generic_names, concrete_types), _t8.state == 0) { v__ast__Type gen_type = *(v__ast__Type*)_t8.data; if (!v__ast__Type_has_flag(gen_type, v__ast__TypeFlag__generic)) { return (node.or_block.kind == v__ast__OrKind__absent ? (gen_type) : (v__ast__Type_clear_option_and_result(gen_type))); } } } } } else if (node.is_static_method) { if (g->cur_fn != ((void*)0)) { multi_return_v__ast__Type_string mr_42335 = v__ast__Table_convert_generic_static_type_name(g->table, node.name, g->cur_fn->generic_names, g->cur_concrete_types); string name = mr_42335.arg1; _option_v__ast__Fn _t10; if (_t10 = v__ast__Table_find_fn(g->table, name), _t10.state == 0) { v__ast__Fn func = *(v__ast__Fn*)_t10.data; return (node.or_block.kind == v__ast__OrKind__absent ? (func.return_type) : (v__ast__Type_clear_option_and_result(func.return_type))); } } return (node.or_block.kind == v__ast__OrKind__absent ? (node.return_type) : (v__ast__Type_clear_option_and_result(node.return_type))); } else { _option_v__ast__Fn _t13; if (_t13 = v__ast__Table_find_fn(g->table, node.name), _t13.state == 0) { v__ast__Fn func = *(v__ast__Fn*)_t13.data; if (func.generic_names.len > 0) { Array_v__ast__Type _t14 = {0}; Array_v__ast__Type _t14_orig = node.concrete_types; int _t14_len = _t14_orig.len; _t14 = __new_array(0, _t14_len, sizeof(v__ast__Type)); for (int _t16 = 0; _t16 < _t14_len; ++_t16) { v__ast__Type it = ((v__ast__Type*) _t14_orig.data)[_t16]; v__ast__Type _t15 = v__gen__c__Gen_unwrap_generic(g, it); array_push((array*)&_t14, &_t15); } Array_v__ast__Type concrete_types =_t14; v__ast__CallExpr call_ = node; Map_int_v__ast__Type comptime_args = v__type_resolver__TypeResolver_resolve_args(&g->type_resolver, g->cur_fn, (voidptr)&func, (voidptr)&call_, concrete_types); if (concrete_types.len > 0) { int _t18 = comptime_args.key_values.len; for (int _t17 = 0; _t17 < _t18; ++_t17 ) { int _t19 = comptime_args.key_values.len - _t18; _t18 = comptime_args.key_values.len; if (_t19 < 0) { _t17 = -1; continue; } if (!DenseArray_has_index(&comptime_args.key_values, _t17)) {continue;} int k = *(int*)DenseArray_key(&comptime_args.key_values, _t17); v__ast__Type v = (*(v__ast__Type*)DenseArray_value(&comptime_args.key_values, _t17)); if (k < concrete_types.len) { if (!v__ast__Type_has_flag((*(v__ast__Type*)array_get(node.concrete_types, k)), v__ast__TypeFlag__generic)) { array_set(&concrete_types, k, &(v__ast__Type[]) { v__gen__c__Gen_unwrap_generic(g, v) }); } } } } _option_v__ast__Type _t20; if (_t20 = v__ast__Table_convert_generic_type(g->table, node.return_type_generic, func.generic_names, concrete_types), _t20.state == 0) { v__ast__Type gen_type = *(v__ast__Type*)_t20.data; if (!v__ast__Type_has_flag(gen_type, v__ast__TypeFlag__generic)) { return (node.or_block.kind == v__ast__OrKind__absent ? (gen_type) : (v__ast__Type_clear_option_and_result(gen_type))); } } } } } return _const_v__ast__void_type; } VV_LOC string v__gen__c__Gen_resolve_receiver_name(v__gen__c__Gen* g, v__ast__CallExpr node, v__ast__Type unwrapped_rec_type, v__ast__TypeSymbol final_left_sym, v__ast__TypeSymbol left_sym, v__ast__TypeSymbol typ_sym) { string receiver_type_name = v__util__no_dots(v__gen__c__Gen_cc_type(g, unwrapped_rec_type, false)); if (final_left_sym.kind == v__ast__Kind__map && (fast_string_eq(node.name, _S("clone")) || fast_string_eq(node.name, _S("move")))) { receiver_type_name = _S("map"); } if (final_left_sym.kind == v__ast__Kind__array && !(left_sym.kind == v__ast__Kind__alias && v__ast__TypeSymbol_has_method(&left_sym, node.name)) && (fast_string_eq(node.name, _S("clear")) || fast_string_eq(node.name, _S("repeat")) || fast_string_eq(node.name, _S("sort_with_compare")) || fast_string_eq(node.name, _S("sorted_with_compare")) || fast_string_eq(node.name, _S("push_many")) || fast_string_eq(node.name, _S("trim")) || fast_string_eq(node.name, _S("first")) || fast_string_eq(node.name, _S("last")) || fast_string_eq(node.name, _S("pop")) || fast_string_eq(node.name, _S("clone")) || fast_string_eq(node.name, _S("reverse")) || fast_string_eq(node.name, _S("slice")) || fast_string_eq(node.name, _S("pointers")))) { if (!((left_sym.info)._typ == 539 /* v.ast.Alias */ && v__ast__TypeSymbol_has_method(&typ_sym, node.name))) { receiver_type_name = _S("array"); } } return receiver_type_name; } VV_LOC multi_return_v__ast__Type_ref_v__ast__TypeSymbol v__gen__c__Gen_unwrap_receiver_type(v__gen__c__Gen* g, v__ast__CallExpr node) { v__ast__Type left_type = v__gen__c__Gen_unwrap_generic(g, node.left_type); v__ast__Type unwrapped_rec_type = node.receiver_type; if (g->cur_fn != ((void*)0) && g->cur_fn->generic_names.len > 0) { unwrapped_rec_type = v__gen__c__Gen_unwrap_generic(g, node.receiver_type); unwrapped_rec_type = v__type_resolver__TypeResolver_unwrap_generic_expr(&g->type_resolver, node.left, unwrapped_rec_type); } else { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, node.receiver_type); if (sym->info._typ == 518 /* v.ast.Struct */) { Array_string _t1 = {0}; Array_v__ast__Type _t1_orig = (*sym->info._v__ast__Struct).generic_types; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Type it = ((v__ast__Type*) _t1_orig.data)[_t3]; string _t2 = v__ast__Table_sym(g->table, it)->name; array_push((array*)&_t1, &_t2); } Array_string generic_names =_t1; v__ast__Table* muttable = ((v__ast__Table*)(g->table)); _option_v__ast__Type _t4; if (_t4 = v__ast__Table_convert_generic_type(muttable, node.receiver_type, generic_names, (*sym->info._v__ast__Struct).concrete_types), _t4.state == 0) { v__ast__Type utyp = *(v__ast__Type*)_t4.data; unwrapped_rec_type = utyp; } } else if (sym->info._typ == 542 /* v.ast.Interface */) { Array_string _t5 = {0}; Array_v__ast__Type _t5_orig = (*sym->info._v__ast__Interface).generic_types; int _t5_len = _t5_orig.len; _t5 = __new_array(0, _t5_len, sizeof(string)); for (int _t7 = 0; _t7 < _t5_len; ++_t7) { v__ast__Type it = ((v__ast__Type*) _t5_orig.data)[_t7]; string _t6 = v__ast__Table_sym(g->table, it)->name; array_push((array*)&_t5, &_t6); } Array_string generic_names =_t5; v__ast__Table* muttable = ((v__ast__Table*)(g->table)); _option_v__ast__Type _t8; if (_t8 = v__ast__Table_convert_generic_type(muttable, node.receiver_type, generic_names, (*sym->info._v__ast__Interface).concrete_types), _t8.state == 0) { v__ast__Type utyp = *(v__ast__Type*)_t8.data; unwrapped_rec_type = utyp; } } else if (sym->info._typ == 544 /* v.ast.SumType */) { Array_string _t9 = {0}; Array_v__ast__Type _t9_orig = (*sym->info._v__ast__SumType).generic_types; int _t9_len = _t9_orig.len; _t9 = __new_array(0, _t9_len, sizeof(string)); for (int _t11 = 0; _t11 < _t9_len; ++_t11) { v__ast__Type it = ((v__ast__Type*) _t9_orig.data)[_t11]; string _t10 = v__ast__Table_sym(g->table, it)->name; array_push((array*)&_t9, &_t10); } Array_string generic_names =_t9; v__ast__Table* muttable = ((v__ast__Table*)(g->table)); _option_v__ast__Type _t12; if (_t12 = v__ast__Table_convert_generic_type(muttable, node.receiver_type, generic_names, (*sym->info._v__ast__SumType).concrete_types), _t12.state == 0) { v__ast__Type utyp = *(v__ast__Type*)_t12.data; unwrapped_rec_type = utyp; } } else { } } if (node.from_embed_types.len == 0 && (node.left)._typ == 358 /* v.ast.Ident */) { if (((*node.left._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { if ((*(*node.left._v__ast__Ident).obj._v__ast__Var).smartcasts.len > 0) { if ((*(*node.left._v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__smartcast) { unwrapped_rec_type = v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, node.left)); } else { unwrapped_rec_type = v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Type*)array_last((*(*node.left._v__ast__Ident).obj._v__ast__Var).smartcasts))); v__ast__TypeSymbol* cast_sym = v__ast__Table_sym(g->table, unwrapped_rec_type); if ((cast_sym->info)._typ == 537 /* v.ast.Aggregate */) { unwrapped_rec_type = (*(v__ast__Type*)array_get((*cast_sym->info._v__ast__Aggregate).types, g->aggregate_type_idx)); } } } } } v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(g->table, unwrapped_rec_type); if (!v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option) && (typ_sym->info)._typ == 539 /* v.ast.Alias */ && !fast_string_eq(node.name, _S("str")) && !v__ast__TypeSymbol_has_method(typ_sym, node.name)) { unwrapped_rec_type = (*typ_sym->info._v__ast__Alias).parent_type; typ_sym = v__ast__Table_sym(g->table, unwrapped_rec_type); } else if ((typ_sym->info)._typ == 513 /* v.ast.Array */ && !v__ast__TypeSymbol_has_method(typ_sym, node.name) && !fast_string_eq(node.name, _S("str"))) { v__ast__Type typ = v__ast__Table_unaliased_type(g->table, (*typ_sym->info._v__ast__Array).elem_type); int typ_idx = v__ast__Table_find_type_idx(g->table, v__ast__Table_array_name(g->table, typ)); if (typ_idx > 0) { unwrapped_rec_type = v__ast__idx_to_type(typ_idx); typ_sym = v__ast__Table_sym(g->table, unwrapped_rec_type); } } if (node.from_embed_types.len > 0 && !v__ast__TypeSymbol_has_method(typ_sym, node.name)) { unwrapped_rec_type = (*(v__ast__Type*)array_last(node.from_embed_types)); typ_sym = v__ast__Table_sym(g->table, unwrapped_rec_type); } return (multi_return_v__ast__Type_ref_v__ast__TypeSymbol){.arg0=unwrapped_rec_type, .arg1=typ_sym}; } VV_LOC void v__gen__c__Gen_method_call(v__gen__c__Gen* g, v__ast__CallExpr node) { if (node.left_type == 0) { v__gen__c__Gen_checker_bug(g, _S("CallExpr.left_type is 0 in method_call"), node.pos); } if (node.receiver_type == 0) { v__gen__c__Gen_checker_bug(g, _S("CallExpr.receiver_type is 0 in method_call"), node.pos); } v__ast__Type left_type = v__gen__c__Gen_unwrap_generic(g, node.left_type); multi_return_v__ast__Type_ref_v__ast__TypeSymbol mr_47144 = v__gen__c__Gen_unwrap_receiver_type(g, node); v__ast__Type unwrapped_rec_type = mr_47144.arg0; v__ast__TypeSymbol* typ_sym = mr_47144.arg1; string rec_cc_type = v__gen__c__Gen_cc_type(g, unwrapped_rec_type, false); string receiver_type_name = v__util__no_dots(rec_cc_type); if ((typ_sym->info)._typ == 542 /* v.ast.Interface */ && v__ast__Interface_defines_method((*(v__ast__Interface*)__as_cast((typ_sym->info)._v__ast__Interface,(typ_sym->info)._typ, 542)), node.name)) { #if defined(CUSTOM_DEFINE_debug_interface_method_call) { eprintln(str_intp(4, _MOV((StrIntpData[]){{_S(">>> interface typ_sym.name: "), 0xfe10, {.d_s = typ_sym->name}}, {_S(" | receiver_type_name: "), 0xfe10, {.d_s = receiver_type_name}}, {_S(" | pos: "), 0xfe10, {.d_s = v__token__Pos_str(node.pos)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif string left_cc_type = v__gen__c__Gen_cc_type(g, v__ast__Table_unaliased_type(g->table, left_type), false); string left_type_name = v__util__no_dots(left_cc_type); { v__gen__c__Gen_write(g, v__gen__c__c_name(left_type_name)); v__gen__c__Gen_write(g, _S("_name_table[")); } if (v__ast__Expr_is_auto_deref_var(node.left) && v__ast__Type_nr_muls(left_type) > 1) { v__gen__c__Gen_write2(g, _S("("), string_repeat(_S("*"), (int)(v__ast__Type_nr_muls(left_type) - 1))); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_expr(g, node.left); } string dot = v__gen__c__Gen_dot_or_ptr(g, left_type); string mname = v__gen__c__c_fn_name(node.name); { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_typ]._method_")); v__gen__c__Gen_write(g, mname); v__gen__c__Gen_write(g, _S("(")); } if (v__ast__Expr_is_auto_deref_var(node.left) && v__ast__Type_nr_muls(left_type) > 1) { v__gen__c__Gen_write2(g, _S("("), string_repeat(_S("*"), (int)(v__ast__Type_nr_muls(left_type) - 1))); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_expr(g, node.left); } { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_object")); } bool _t2 = (node.expected_arg_types.len > 0); bool is_variadic = _t2 && v__ast__Type_has_flag((*(v__ast__Type*)array_last(node.expected_arg_types)), v__ast__TypeFlag__variadic); if (node.args.len > 0 || is_variadic) { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_call_args(g, node); } v__gen__c__Gen_write(g, _S(")")); if (!v__ast__Type_has_option_or_result(node.return_type)) { if (v__ast__Table_final_sym(g->table, node.return_type)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_write(g, _S(".ret_arr")); } } return; } else if ((typ_sym->info)._typ == 551 /* v.ast.Thread */) { string waiter_fn_name = v__gen__c__Gen_gen_gohandle_name(g, (*typ_sym->info._v__ast__Thread).return_type); v__gen__c__Gen_create_waiter_handler(g, node.return_type, v__gen__c__Gen_styp(g, (*typ_sym->info._v__ast__Thread).return_type), waiter_fn_name); } v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, left_type); v__ast__TypeSymbol* final_left_sym = v__ast__Table_final_sym(g->table, left_type); if (final_left_sym->kind == v__ast__Kind__array && !(left_sym->kind == v__ast__Kind__alias && v__ast__TypeSymbol_has_method(left_sym, node.name))) { if (v__gen__c__Gen_gen_array_method_call(g, node, left_type, *final_left_sym)) { return; } } if (final_left_sym->kind == v__ast__Kind__array_fixed && !(left_sym->kind == v__ast__Kind__alias && v__ast__TypeSymbol_has_method(left_sym, node.name))) { if (v__gen__c__Gen_gen_fixed_array_method_call(g, node, left_type)) { return; } } if (final_left_sym->kind == v__ast__Kind__map && !(left_sym->kind == v__ast__Kind__alias && v__ast__TypeSymbol_has_method(left_sym, node.name))) { if (v__gen__c__Gen_gen_map_method_call(g, node, left_type, *final_left_sym)) { return; } } if (left_sym->kind == v__ast__Kind__array_fixed && fast_string_eq(node.name, _S("wait"))) { v__gen__c__Gen_gen_fixed_array_wait(g, node); return; } if (left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface) { string prefix_name = (left_sym->kind == v__ast__Kind__sum_type ? (_S("sumtype")) : (_S("interface"))); if (_SLIT_EQ(node.name.str, node.name.len, "type_name")) { if (left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface) { v__gen__c__Gen_conversion_function_call(g, str_intp(3, _MOV((StrIntpData[]){{_S("charptr_vstring_literal(v_typeof_"), 0xfe10, {.d_s = prefix_name}}, {_S("_"), 0xfe10, {.d_s = typ_sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}})), _S(")"), node); return; } } else if (_SLIT_EQ(node.name.str, node.name.len, "type_idx")) { if (left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface) { v__gen__c__Gen_conversion_function_call(g, str_intp(3, _MOV((StrIntpData[]){{_S("v_typeof_"), 0xfe10, {.d_s = prefix_name}}, {_S("_idx_"), 0xfe10, {.d_s = typ_sym->cname}}, {_SLIT0, 0, { .d_c = 0 }}})), _S(""), node); return; } } else { } } bool is_free_method = false; if (fast_string_eq(node.name, _S("str"))) { if (v__gen__c__Gen_gen_to_str_method_call(g, node)) { return; } } else if (fast_string_eq(node.name, _S("free"))) { v__gen__c__Gen_register_free_method(g, node.receiver_type); is_free_method = true; } int cast_n = 0; bool old_inside_smartcast = g->inside_smartcast; receiver_type_name = v__gen__c__Gen_resolve_receiver_name(g, node, unwrapped_rec_type, *final_left_sym, *left_sym, *typ_sym); string name = _S(""); if (is_free_method) { string free_method_name = v__gen__c__Gen_get_free_method(g, unwrapped_rec_type); name = free_method_name; } else { name = v__util__no_dots(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = receiver_type_name}}, {_S("_"), 0xfe10, {.d_s = node.name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (left_sym->kind == v__ast__Kind__chan && (fast_string_eq(node.name, _S("close")) || fast_string_eq(node.name, _S("try_pop")) || fast_string_eq(node.name, _S("try_push")))) { name = str_intp(2, _MOV((StrIntpData[]){{_S("sync__Channel_"), 0xfe10, {.d_s = node.name}}, {_SLIT0, 0, { .d_c = 0 }}})); } bool is_range_slice = false; if (v__ast__Type_is_ptr(node.receiver_type) && !v__ast__Type_is_ptr(left_type)) { if ((node.left)._typ == 361 /* v.ast.IndexExpr */) { v__ast__Expr idx = (*node.left._v__ast__IndexExpr).index; if ((idx)._typ == 377 /* v.ast.RangeExpr */) { is_range_slice = true; } } } if (node.concrete_types.len > 0) { int rec_len = 0; if (v__ast__Type_has_flag(node.left_type, v__ast__TypeFlag__generic)) { v__ast__TypeSymbol* rec_sym = v__ast__Table_final_sym(g->table, v__gen__c__Gen_unwrap_generic(g, node.left_type)); if (rec_sym->info._typ == 518 /* v.ast.Struct */) { rec_len += (*rec_sym->info._v__ast__Struct).generic_types.len; } else if (rec_sym->info._typ == 542 /* v.ast.Interface */) { rec_len += (*rec_sym->info._v__ast__Interface).generic_types.len; } else if (rec_sym->info._typ == 544 /* v.ast.SumType */) { rec_len += (*rec_sym->info._v__ast__SumType).generic_types.len; } else { } } Array_v__ast__Type _t3 = {0}; Array_v__ast__Type _t3_orig = node.concrete_types; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__Type)); for (int _t5 = 0; _t5 < _t3_len; ++_t5) { v__ast__Type it = ((v__ast__Type*) _t3_orig.data)[_t5]; v__ast__Type _t4 = v__gen__c__Gen_unwrap_generic(g, it); array_push((array*)&_t3, &_t4); } Array_v__ast__Type concrete_types =_t3; _result_v__ast__Fn _t6; if (_t6 = v__ast__Table_find_method(g->table, v__ast__Table_sym(g->table, node.left_type), node.name), !_t6.is_error) { v__ast__Fn m = *(v__ast__Fn*)_t6.data; v__ast__CallExpr node_ = node; Map_int_v__ast__Type comptime_args = v__type_resolver__TypeResolver_resolve_args(&g->type_resolver, g->cur_fn, (voidptr)&m, (voidptr)&node_, concrete_types); int _t8 = comptime_args.key_values.len; for (int _t7 = 0; _t7 < _t8; ++_t7 ) { int _t9 = comptime_args.key_values.len - _t8; _t8 = comptime_args.key_values.len; if (_t9 < 0) { _t7 = -1; continue; } if (!DenseArray_has_index(&comptime_args.key_values, _t7)) {continue;} int k = *(int*)DenseArray_key(&comptime_args.key_values, _t7); v__ast__Type v = (*(v__ast__Type*)DenseArray_value(&comptime_args.key_values, _t7)); if (((int)(rec_len + k)) < concrete_types.len) { if (!v__ast__Type_has_flag((*(v__ast__Type*)array_get(node.concrete_types, k)), v__ast__TypeFlag__generic)) { array_set(&concrete_types, (int)(rec_len + k), &(v__ast__Type[]) { v__gen__c__Gen_unwrap_generic(g, v) }); } } } name = v__gen__c__Gen_generic_fn_name(g, concrete_types, name); } else { IError err = _t6.err; name = v__gen__c__Gen_generic_fn_name(g, concrete_types, name); } } if (!v__ast__Type_is_ptr(node.receiver_type) && v__ast__Type_is_ptr(left_type) && fast_string_eq(node.name, _S("str"))) { if (v__ast__Type_is_int_valptr(left_type)) { v__gen__c__Gen_write(g, _S("ptr_str(")); } else { v__gen__c__Gen_gen_expr_to_string(g, node.left, left_type); return; } } else if (v__ast__Type_is_ptr(node.receiver_type) && v__ast__Type_is_ptr(left_type) && fast_string_eq(node.name, _S("str")) && !v__ast__TypeSymbol_has_method(left_sym, _S("str"))) { v__gen__c__Gen_gen_expr_to_string(g, node.left, left_type); return; } else { if (g->cur_fn != ((void*)0) && g->cur_fn->trace_fns.len > 0) { v__gen__c__Gen_gen_trace_call(g, node, name); v__gen__c__Gen_write(g, _S("(")); } else { { v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S("(")); } } } bool is_interface = left_sym->kind == v__ast__Kind__interface && v__ast__Table_sym(g->table, node.receiver_type)->kind == v__ast__Kind__interface; if (v__ast__Type_is_ptr(node.receiver_type) && (!v__ast__Type_is_ptr(left_type) || node.from_embed_types.len != 0 || (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__shared_f) && !fast_string_eq(node.name, _S("str"))))) { if (!is_range_slice) { if (!v__ast__Expr_is_lvalue(node.left)) { if (v__ast__Expr_is_as_cast(node.left)) { g->inside_smartcast = true; if ((node.left)._typ == 379 /* v.ast.SelectorExpr */ && !v__ast__Type_is_ptr(left_type)) { v__gen__c__Gen_write(g, _S("&")); } } else { { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, rec_cc_type); v__gen__c__Gen_write(g, _S(", ")); } cast_n++; } } else if ((node.left)._typ == 358 /* v.ast.Ident */ && v__ast__Table_is_interface_smartcast(g->table, (*(v__ast__Ident*)__as_cast((node.left)._v__ast__Ident,(node.left)._typ, 358)).obj)) { { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, rec_cc_type); v__gen__c__Gen_write(g, _S(", ")); } cast_n++; } else if (!(v__ast__Type_has_flag(left_type, v__ast__TypeFlag__shared_f) && string__eq(v__gen__c__Gen_styp(g, left_type), v__gen__c__Gen_styp(g, node.receiver_type)))) { v__gen__c__Gen_write(g, _S("&")); } } else { if (!v__ast__Type_is_ptr(left_type)) { { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, rec_cc_type); v__gen__c__Gen_write(g, _S(", ")); } cast_n++; } } } else if (!v__ast__Type_is_ptr(node.receiver_type) && v__ast__Type_is_ptr(left_type) && !fast_string_eq(node.name, _S("str")) && node.from_embed_types.len == 0) { if (!v__ast__Type_has_flag(left_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(left_type))); } } else if (!is_range_slice && node.from_embed_types.len == 0 && !fast_string_eq(node.name, _S("str"))) { int diff = (int)(v__ast__Type_nr_muls(left_type) - v__ast__Type_nr_muls(node.receiver_type)); if (diff > 0) { v__gen__c__Gen_write(g, string_repeat(_S("*"), diff)); } } if (g->is_autofree && node.free_receiver && !g->inside_lambda && !g->is_builtin_mod) { string fn_name = string_replace(node.name, _S("."), _S("_")); string arg_name = str_intp(3, _MOV((StrIntpData[]){{_S("_arg_expr_"), 0xfe10, {.d_s = fn_name}}, {_S("_0_"), 0xfe07, {.d_i32 = node.pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}})); v__gen__c__Gen_write(g, string__plus(_S("/*af receiver arg*/"), arg_name)); } else { if ((node.left)._typ == 368 /* v.ast.MapInit */) { v__gen__c__Gen_write(g, _S("(map[]){")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S("}[0]")); } else if (!is_interface && node.from_embed_types.len > 0) { int n_ptr = (int)(v__ast__Type_nr_muls(node.left_type) - 1); if (n_ptr > 0) { v__gen__c__Gen_write2(g, _S("("), string_repeat(_S("*"), n_ptr)); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_expr(g, node.left); } } else if (is_interface && node.from_embed_types.len > 0) { if (string__eq(strings__Builder_last_n(&g->out, 1), _S("&"))) { v__gen__c__Gen_go_back(g, 1); } if (v__ast__Type_is_ptr(node.receiver_type) && v__ast__Type_is_ptr(left_type)) { v__gen__c__Gen_write2(g, _S("("), v__ast__Table_sym(g->table, (*(v__ast__Type*)array_last(node.from_embed_types)))->cname); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_expr(g, node.left); } else if (v__ast__Type_is_ptr(node.receiver_type) && !v__ast__Type_is_ptr(left_type)) { v__gen__c__Gen_write2(g, _S("("), v__ast__Table_sym(g->table, (*(v__ast__Type*)array_last(node.from_embed_types)))->cname); v__gen__c__Gen_write(g, _S("*)&")); v__gen__c__Gen_expr(g, node.left); } else if (!v__ast__Type_is_ptr(node.receiver_type) && v__ast__Type_is_ptr(left_type)) { v__gen__c__Gen_write2(g, _S("*(("), v__ast__Table_sym(g->table, (*(v__ast__Type*)array_last(node.from_embed_types)))->cname); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_write2(g, _S("*(("), v__ast__Table_sym(g->table, (*(v__ast__Type*)array_last(node.from_embed_types)))->cname); v__gen__c__Gen_write(g, _S("*)&")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } } else { if (is_free_method && !v__ast__Type_is_ptr(node.receiver_type)) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, node.left); } if (!is_interface || node.from_embed_types.len == 0) { Array_v__ast__Type node_embed_types = array_clone_to_depth(&node.from_embed_types, 0); if ((node.left)._typ == 358 /* v.ast.Ident */ && v__type_resolver__ResolverInfo_get_ct_type_var(g->comptime, v__ast__Ident_to_sumtype_v__ast__Expr((v__ast__Ident*)__as_cast((node.left)._v__ast__Ident,(node.left)._typ, 358))) == v__ast__ComptimeVarKind__generic_var) { _result_multi_return_v__ast__Fn_Array_v__ast__Type _t10 = v__ast__Table_find_method_from_embeds(g->table, final_left_sym, node.name); if (_t10.is_error) { IError err = _t10.err; *(multi_return_v__ast__Fn_Array_v__ast__Type*) _t10.data = (multi_return_v__ast__Fn_Array_v__ast__Type){.arg0=((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } multi_return_v__ast__Fn_Array_v__ast__Type mr_55781 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t10.data); Array_v__ast__Type embed_types = mr_55781.arg1; if (embed_types.len > 0) { node_embed_types = array_clone_to_depth(&embed_types, 0); } } for (int i = 0; i < node_embed_types.len; ++i) { v__ast__Type embed = ((v__ast__Type*)node_embed_types.data)[i]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(g->table, embed); string embed_name = v__ast__TypeSymbol_embed_name(embed_sym); bool is_left_ptr = (i == 0 ? (v__ast__Type_is_ptr(left_type)) : (v__ast__Type_is_ptr((*(v__ast__Type*)array_get(node_embed_types, (int)(i - 1)))))); if (is_left_ptr) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } v__gen__c__Gen_write(g, embed_name); } } if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__shared_f) && !string__eq(v__gen__c__Gen_styp(g, left_type), v__gen__c__Gen_styp(g, node.receiver_type))) { v__gen__c__Gen_write(g, _S("->val")); } } if (cast_n > 0) { v__gen__c__Gen_write(g, string_repeat(_S(")"), cast_n)); } bool _t11 = (node.expected_arg_types.len > 0); bool is_variadic = _t11 && v__ast__Type_has_flag((*(v__ast__Type*)array_last(node.expected_arg_types)), v__ast__TypeFlag__variadic); if (node.args.len > 0 || is_variadic) { v__gen__c__Gen_write(g, _S(", ")); } g->inside_smartcast = old_inside_smartcast; v__gen__c__Gen_call_args(g, node); v__gen__c__Gen_write(g, _S(")")); if (node.return_type != 0 && !v__ast__Type_has_option_or_result(node.return_type) && v__ast__Table_final_sym(g->table, node.return_type)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_write(g, _S(".ret_arr")); } } VV_LOC void v__gen__c__Gen_fn_call(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_fn_call_defer_0 = false; bool v__gen__c__Gen_fn_call_defer_1 = false; bool is_interface_call = false; bool is_selector_call = false; if (node.is_method && node.left_type != 0) { v__ast__Type fn_typ = _const_v__ast__no_type; v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, node.left_type); if (node.is_field) { _result_v__ast__StructField _t1; if (_t1 = v__ast__Table_find_field_with_embeds(g->table, left_sym, node.name), !_t1.is_error) { v__ast__StructField field = *(v__ast__StructField*)_t1.data; fn_typ = field.typ; } if (node.is_unwrapped_fn_selector) { fn_typ = v__ast__Type_clear_option_and_result(fn_typ); } } if (left_sym->kind == v__ast__Kind__interface || v__ast__Type_is_ptr(fn_typ)) { is_interface_call = true; v__gen__c__Gen_write(g, _S("(*")); } if (node.is_unwrapped_fn_selector) { v__ast__TypeSymbol* callback_sym = v__ast__Table_final_sym(g->table, fn_typ); if ((callback_sym->info)._typ == 553 /* v.ast.FnType */) { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, fn_typ)); v__gen__c__Gen_write(g, _S("*)")); } } } v__gen__c__Gen_expr(g, node.left); if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } for (int _t2 = 0; _t2 < node.from_embed_types.len; ++_t2) { v__ast__Type embed = ((v__ast__Type*)node.from_embed_types.data)[_t2]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(g->table, embed); string embed_name = v__ast__TypeSymbol_embed_name(embed_sym); v__gen__c__Gen_write(g, embed_name); if (v__ast__Type_is_ptr(embed)) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } } is_selector_call = true; } string node_name = node.name; string name = node.name; if (node.is_static_method) { if (g->cur_fn != ((void*)0)) { multi_return_v__ast__Type_string mr_58347 = v__ast__Table_convert_generic_static_type_name(g->table, node.name, g->cur_fn->generic_names, g->cur_concrete_types); name = mr_58347.arg1; if (node.concrete_types.len > 0) { node_name = name; } } } bool is_print = (_SLIT_EQ(name.str, name.len, "print") || _SLIT_EQ(name.str, name.len, "println") || _SLIT_EQ(name.str, name.len, "eprint") || _SLIT_EQ(name.str, name.len, "eprintln") || _SLIT_EQ(name.str, name.len, "panic")); string print_method = name; bool is_json_encode = _SLIT_EQ(name.str, name.len, "json.encode"); bool is_json_encode_pretty = _SLIT_EQ(name.str, name.len, "json.encode_pretty"); bool is_json_decode = _SLIT_EQ(name.str, name.len, "json.decode"); bool is_json_fn = is_json_encode || is_json_encode_pretty || is_json_decode; bool is_va_arg = _SLIT_EQ(name.str, name.len, "C.va_arg"); string json_type_str = _S(""); string json_obj = _S(""); if (is_json_fn) { g->is_json_fn = true; json_obj = v__gen__c__Gen_new_tmp_var(g); string tmp2 = _S(""); string cur_line = v__gen__c__Gen_go_before_last_stmt(g); if (is_json_encode || is_json_encode_pretty) { v__gen__c__Gen_gen_json_for_type(g, (*(v__ast__CallArg*)array_get(node.args, 0)).typ); json_type_str = v__gen__c__Gen_styp(g, (*(v__ast__CallArg*)array_get(node.args, 0)).typ); string encode_name = v__gen__c__js_enc_name(json_type_str); g->empty_line = true; v__gen__c__Gen_writeln(g, _S("// json.encode")); { v__gen__c__Gen_write(g, _S("cJSON* ")); v__gen__c__Gen_write(g, json_obj); v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_write(g, encode_name); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_call_args(g, node); v__gen__c__Gen_writeln(g, _S(");")); tmp2 = (g->is_autofree ? (str_intp(3, _MOV((StrIntpData[]){{_S("_arg_expr_"), 0xfe10, {.d_s = string_replace(node.name, _S("."), _S("_"))}}, {_S("_"), 0xfe07, {.d_i32 = node.pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (v__gen__c__Gen_new_tmp_var(g))); if (is_json_encode) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("string "), 0xfe10, {.d_s = tmp2}}, {_S(" = json__json_print("), 0xfe10, {.d_s = json_obj}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("string "), 0xfe10, {.d_s = tmp2}}, {_S(" = json__json_print_pretty("), 0xfe10, {.d_s = json_obj}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else { v__ast__TypeNode ast_type = *(v__ast__TypeNode*)__as_cast(((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._v__ast__TypeNode,((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ, 386); string typ = v__gen__c__c_name(v__gen__c__Gen_styp(g, ast_type.typ)); string fn_name = string__plus(string__plus(v__gen__c__c_fn_name(name), _S("_")), typ); v__gen__c__Gen_gen_json_for_type(g, ast_type.typ); g->empty_line = true; v__gen__c__Gen_writeln(g, _S("// json.decode")); { v__gen__c__Gen_write(g, _S("cJSON* ")); v__gen__c__Gen_write(g, json_obj); v__gen__c__Gen_write(g, _S(" = json__json_parse(")); } g->is_js_call = true; v__gen__c__Gen_call_args(g, node); v__gen__c__Gen_writeln(g, _S(");")); tmp2 = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = typ}}, {_S(" "), 0xfe10, {.d_s = tmp2}}, {_S(" = "), 0xfe10, {.d_s = fn_name}}, {_S("("), 0xfe10, {.d_s = json_obj}}, {_S(");"), 0, { .d_c = 0 }}}))); } if (!g->is_autofree) { { v__gen__c__Gen_write(g, _S("cJSON_Delete(")); v__gen__c__Gen_write(g, json_obj); v__gen__c__Gen_write(g, _S("); // del")); } } { v__gen__c__Gen_write(g, _S("\n")); v__gen__c__Gen_write(g, cur_line); } name = _S(""); json_obj = tmp2; } else if (is_va_arg) { v__ast__TypeNode ast_type = *(v__ast__TypeNode*)__as_cast(((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._v__ast__TypeNode,((*(v__ast__CallArg*)array_get(node.args, 0)).expr)._typ, 386); string typ = v__gen__c__Gen_styp(g, ast_type.typ); v__gen__c__Gen_write(g, _S("va_arg(")); v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(node.args, 1)).expr); { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, typ); v__gen__c__Gen_write(g, _S(")")); } return; } if (_SLIT_EQ(name.str, name.len, "__addr")) { name = _S("&"); } if (node.language == v__ast__Language__c) { name = v__util__no_dots(string_substr(name, 2, 2147483647)); } else { name = (is_selector_call ? (v__gen__c__c_name(name)) : (v__gen__c__c_fn_name(name))); } if (g->pref->translated || g->file->is_translated || node.is_file_translated) { _option_v__ast__Fn _t3; if (_t3 = v__ast__Table_find_fn(g->table, node.name), _t3.state == 0) { v__ast__Fn f = *(v__ast__Fn*)_t3.data; _option_v__ast__Attr _t4; if (_t4 = Array_v__ast__Attr_find_first(f.attrs, _S("c")), _t4.state == 0) { v__ast__Attr cattr = *(v__ast__Attr*)_t4.data; name = cattr.arg; } } } if (!is_selector_call) { _option_v__ast__Fn _t5; if (_t5 = v__ast__Table_find_fn(g->table, node_name), _t5.state == 0) { v__ast__Fn func = *(v__ast__Fn*)_t5.data; Array_v__ast__Type _t6 = {0}; Array_v__ast__Type _t6_orig = node.concrete_types; int _t6_len = _t6_orig.len; _t6 = __new_array(0, _t6_len, sizeof(v__ast__Type)); for (int _t8 = 0; _t8 < _t6_len; ++_t8) { v__ast__Type it = ((v__ast__Type*) _t6_orig.data)[_t8]; v__ast__Type _t7 = v__gen__c__Gen_unwrap_generic(g, it); array_push((array*)&_t6, &_t7); } Array_v__ast__Type concrete_types =_t6; v__ast__CallExpr node_ = node; Map_int_v__ast__Type comptime_args = v__type_resolver__TypeResolver_resolve_args(&g->type_resolver, g->cur_fn, (voidptr)&func, (voidptr)&node_, concrete_types); if (concrete_types.len > 0) { int _t10 = comptime_args.key_values.len; for (int _t9 = 0; _t9 < _t10; ++_t9 ) { int _t11 = comptime_args.key_values.len - _t10; _t10 = comptime_args.key_values.len; if (_t11 < 0) { _t9 = -1; continue; } if (!DenseArray_has_index(&comptime_args.key_values, _t9)) {continue;} int k = *(int*)DenseArray_key(&comptime_args.key_values, _t9); v__ast__Type v = (*(v__ast__Type*)DenseArray_value(&comptime_args.key_values, _t9)); if (k < concrete_types.len) { if (!v__ast__Type_has_flag((*(v__ast__Type*)array_get(node.concrete_types, k)), v__ast__TypeFlag__generic)) { array_set(&concrete_types, k, &(v__ast__Type[]) { v__gen__c__Gen_unwrap_generic(g, v) }); } } } name = v__gen__c__Gen_generic_fn_name(g, concrete_types, name); name = string_replace_each(name, _const_v__gen__c__c_fn_name_escape_seq); } } } if (node.is_fn_a_const) { name = v__gen__c__Gen_c_const_name(g, string_replace(node.const_name, _S("."), _S("__"))); } bool print_auto_str = false; if (is_print && ((*(v__ast__CallArg*)array_get(node.args, 0)).typ != _const_v__ast__string_type || g->comptime->comptime_for_method != ((void*)0) || (*(v__ast__CallArg*)array_get(node.args, 0)).ct_expr)) { g->inside_interface_deref = true; v__gen__c__Gen_fn_call_defer_0 = true; v__ast__Type typ = v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, (*(v__ast__CallArg*)array_get(node.args, 0)).expr, (*(v__ast__CallArg*)array_get(node.args, 0)).typ); if (typ == 0) { v__gen__c__Gen_checker_bug(g, _S("print arg.typ is 0"), node.pos); } if (typ != _const_v__ast__string_type || g->comptime->comptime_for_method != ((void*)0)) { v__ast__Expr expr = (*(v__ast__CallArg*)array_get(node.args, 0)).expr; v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(g->table, typ); if (typ_sym->kind == v__ast__Kind__interface && v__ast__Interface_defines_method((*(v__ast__Interface*)__as_cast((typ_sym->info)._v__ast__Interface,(typ_sym->info)._typ, 542)), _S("str"))) { { v__gen__c__Gen_write(g, v__gen__c__c_fn_name(print_method)); v__gen__c__Gen_write(g, _S("(")); } string rec_type_name = v__util__no_dots(v__gen__c__Gen_cc_type(g, typ, false)); { v__gen__c__Gen_write(g, v__gen__c__c_name(rec_type_name)); v__gen__c__Gen_write(g, _S("_name_table[")); } v__gen__c__Gen_expr(g, expr); string dot = (v__ast__Type_is_ptr(typ) ? (_S("->")) : (_S("."))); { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_typ]._method_str(")); } v__gen__c__Gen_expr(g, expr); { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_object")); } v__gen__c__Gen_writeln(g, _S("));")); // Defer begin if (v__gen__c__Gen_fn_call_defer_0) { g->inside_interface_deref = false; } // Defer end return; } if (g->is_autofree && !v__ast__Type_has_option_or_result(typ)) { string tmp = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, _S("string ")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_gen_expr_to_string(g, expr, typ); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("; "), 0xfe10, {.d_s = v__gen__c__c_fn_name(print_method)}}, {_S("("), 0xfe10, {.d_s = tmp}}, {_S("); string_free(&"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { { v__gen__c__Gen_write(g, v__gen__c__c_fn_name(print_method)); v__gen__c__Gen_write(g, _S("(")); } if ((expr)._typ == 350 /* v.ast.ComptimeSelector */) { if (((*expr._v__ast__ComptimeSelector).typ_key).len != 0) { typ = v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, (*expr._v__ast__ComptimeSelector).typ_key, typ); } } else if ((expr)._typ == 349 /* v.ast.ComptimeCall */) { if ((*expr._v__ast__ComptimeCall).kind == v__ast__ComptimeCallKind__method) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, (*expr._v__ast__ComptimeCall).left_type)); _option_v__ast__Fn _t12; if (_t12 = v__ast__TypeSymbol_find_method(sym, g->comptime->comptime_for_method->name), _t12.state == 0) { v__ast__Fn m = *(v__ast__Fn*)_t12.data; typ = m.return_type; } } } else if ((expr)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).obj)._typ == 422 /* v.ast.Var */) { typ = (*(*expr._v__ast__Ident).obj._v__ast__Var).typ; if ((*(*expr._v__ast__Ident).obj._v__ast__Var).smartcasts.len > 0) { typ = v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Type*)array_last((*(*expr._v__ast__Ident).obj._v__ast__Var).smartcasts))); v__ast__TypeSymbol* cast_sym = v__ast__Table_sym(g->table, typ); if ((cast_sym->info)._typ == 537 /* v.ast.Aggregate */) { typ = (*(v__ast__Type*)array_get((*cast_sym->info._v__ast__Aggregate).types, g->aggregate_type_idx)); } else if ((*(*expr._v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__smartcast) { typ = v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, expr)); } } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option) && (*expr._v__ast__Ident).or_expr.kind != v__ast__OrKind__absent) { typ = v__ast__Type_clear_flag(typ, v__ast__TypeFlag__option); } } v__gen__c__Gen_gen_expr_to_string(g, expr, typ); v__gen__c__Gen_write(g, _S(")")); } print_auto_str = true; } } if (!print_auto_str) { if (is_print) { g->inside_interface_deref = true; v__gen__c__Gen_fn_call_defer_1 = true; } if (g->pref->is_debug && fast_string_eq(node.name, _S("panic"))) { multi_return_int_string_string_string mr_64701 = v__gen__c__Gen_panic_debug_info(g, node.pos); int paline = mr_64701.arg0; string pafile = mr_64701.arg1; string pamod = mr_64701.arg2; string pafn = mr_64701.arg3; { v__gen__c__Gen_write(g, _S("panic_debug(")); v__gen__c__Gen_write_decimal(g, paline); v__gen__c__Gen_write(g, _S(", tos3(\"")); v__gen__c__Gen_write(g, pafile); v__gen__c__Gen_write(g, _S("\"), tos3(\"")); v__gen__c__Gen_write(g, pamod); v__gen__c__Gen_write(g, _S("\"), tos3(\"")); v__gen__c__Gen_write(g, pafn); v__gen__c__Gen_write(g, _S("\"), ")); } v__gen__c__Gen_call_args(g, node); v__gen__c__Gen_write(g, _S(")")); } else if (string_ends_with(node.name, _S("__static__from_string")) && !v__ast__Table_known_fn(g->table, node.name)) { multi_return_string_int mr_64976 = v__gen__c__Gen_get_enum_type_idx_from_fn_name(g, node.name); string mod_enum_name = mr_64976.arg0; int idx = mr_64976.arg1; string fn_mod = string_all_before_last(mod_enum_name, _S(".")); string full_fn_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_mod}}, {_S("."), 0xfe10, {.d_s = node.name}}, {_SLIT0, 0, { .d_c = 0 }}})); string fn_name = v__util__no_dots(full_fn_name); sync__RwMutex_lock(&g->str_fn_names->mtx); /*lock*/ { if (!(Array_string_contains(g->str_fn_names->val, fn_name))) { v__gen__c__Gen_gen_enum_static_from_string(g, fn_name, mod_enum_name, idx); array_push((array*)&g->str_fn_names->val, _MOV((string[]){ string_clone(fn_name) })); } } sync__RwMutex_unlock(&g->str_fn_names->mtx);; { v__gen__c__Gen_write(g, fn_name); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_call_args(g, node); v__gen__c__Gen_write(g, _S(")")); } else { bool is_fn_var = false; _option_v__ast__Var_ptr _t14; if (_t14 = v__ast__Scope_find_var(node.scope, node.name), _t14.state == 0) { v__ast__Var* obj = *(v__ast__Var**)_t14.data; bool is_cast_needed = true; if (node.is_method && node.left_type != 0) { v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, node.left_type); if (left_sym->kind == v__ast__Kind__struct && string__eq(node.name, obj->name)) { is_cast_needed = false; } } if (obj->smartcasts.len > 0 && is_cast_needed) { for (int _t15 = 0; _t15 < obj->smartcasts.len; ++_t15) { v__ast__Type typ = ((v__ast__Type*)obj->smartcasts.data)[_t15]; v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, typ)); if (v__ast__Type_has_flag(obj->orig_type, v__ast__TypeFlag__option) && sym->kind == v__ast__Kind__function) { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, sym->cname); v__gen__c__Gen_write(g, _S("*)(")); } } else { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, sym->cname); v__gen__c__Gen_write(g, _S(")(")); } } } for (int i = 0; i < obj->smartcasts.len; ++i) { v__ast__Type typ = ((v__ast__Type*)obj->smartcasts.data)[i]; v__ast__TypeSymbol* cast_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, typ)); bool is_ptr = false; if (i == 0) { if (obj->is_inherited) { v__gen__c__Gen_write(g, string__plus(_S("_V_closure_ctx->"), v__gen__c__c_name(node.name))); } else { v__gen__c__Gen_write(g, node.name); } if (v__ast__Type_is_ptr(obj->orig_type)) { is_ptr = true; } } string dot = (is_ptr ? (_S("->")) : (_S("."))); if ((cast_sym->info)._typ == 537 /* v.ast.Aggregate */) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get((*cast_sym->info._v__ast__Aggregate).types, g->aggregate_type_idx))); { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, sym->cname); } } else if (cast_sym->kind == v__ast__Kind__function && v__ast__Type_has_flag(obj->orig_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_write(g, _S(".data")); } else { { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, cast_sym->cname); } } v__gen__c__Gen_write(g, _S("))")); } is_fn_var = true; } else if (obj->is_inherited) { v__gen__c__Gen_write(g, string__plus(_S("_V_closure_ctx->"), v__gen__c__c_name(node.name))); is_fn_var = true; } } if (!is_fn_var) { if (g->cur_fn != ((void*)0) && g->cur_fn->trace_fns.len > 0) { v__gen__c__Gen_gen_trace_call(g, node, name); if (node.is_fn_var) { // Defer begin if (v__gen__c__Gen_fn_call_defer_1) { g->inside_interface_deref = false; } // Defer end // Defer begin if (v__gen__c__Gen_fn_call_defer_0) { g->inside_interface_deref = false; } // Defer end return; } } else { v__gen__c__Gen_write(g, v__gen__c__Gen_get_ternary_name(g, name)); } } if (node.is_unwrapped_fn_selector) { v__gen__c__Gen_write(g, _S(".data)")); } if (is_interface_call) { v__gen__c__Gen_write(g, _S(")")); } int tmp_cnt_save = -1; if (_SLIT_NE(name.str, name.len, "&")) { v__gen__c__Gen_write(g, _S("(")); } if (is_json_fn) { v__gen__c__Gen_write(g, json_obj); } else { if (node.is_keep_alive && (g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_full_opt || g->pref->gc_mode == v__pref__GarbageCollectionMode__boehm_incr_opt)) { string cur_line = v__gen__c__Gen_go_before_last_stmt(g); tmp_cnt_save = v__gen__c__Gen_keep_alive_call_pregen(g, node); v__gen__c__Gen_write(g, cur_line); for (int i = 0; i < node.args.len; ++i) { if (i > 0) { v__gen__c__Gen_write(g, _S(", ")); } { v__gen__c__Gen_write(g, _S("__tmp_arg_")); v__gen__c__Gen_write_decimal(g, (int)(tmp_cnt_save + i)); } } } else { v__gen__c__Gen_call_args(g, node); } } if (_SLIT_NE(name.str, name.len, "&")) { v__gen__c__Gen_write(g, _S(")")); } if (node.return_type != 0 && !v__ast__Type_has_option_or_result(node.return_type) && v__ast__Table_final_sym(g->table, node.return_type)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_write(g, _S(".ret_arr")); } if (tmp_cnt_save >= 0) { v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_keep_alive_call_postgen(g, node, tmp_cnt_save); } } } g->is_json_fn = false; // Defer begin if (v__gen__c__Gen_fn_call_defer_1) { g->inside_interface_deref = false; } // Defer end // Defer begin if (v__gen__c__Gen_fn_call_defer_0) { g->inside_interface_deref = false; } // Defer end } VV_LOC void v__gen__c__Gen_gen_trace_call(v__gen__c__Gen* g, v__ast__CallExpr node, string name) { multi_return_string_string mr_68594 = v__ast__Table_get_trace_fn_name(g->table, *g->cur_fn, node); string hash_fn = mr_68594.arg0; v__ast__FnTrace* _t2 = (v__ast__FnTrace*)(map_get_check(ADDR(map, g->cur_fn->trace_fns), &(string[]){hash_fn})); _option_v__ast__FnTrace _t1 = {0}; if (_t2) { *((v__ast__FnTrace*)&_t1.data) = *((v__ast__FnTrace*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { v__ast__FnTrace _dummy_1 = (*(v__ast__FnTrace*)_t1.data); v__gen__c__Gen_write(g, v__gen__c__c_name(hash_fn)); if (node.is_fn_var) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, node.name); v__gen__c__Gen_write(g, _S(")")); } } } else { IError err = _t1.err; v__gen__c__Gen_write(g, v__gen__c__Gen_get_ternary_name(g, name)); } } VV_LOC void v__gen__c__Gen_autofree_call_pregen(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_autofree_call_pregen_defer_0 = false; string t; bool free_tmp_arg_vars = g->is_autofree && !g->is_builtin_mod && node.args.len > 0 && !v__ast__Type_has_option_or_result((*(v__ast__CallArg*)array_get(node.args, 0)).typ); if (!free_tmp_arg_vars) { return; } if (g->is_js_call) { return; } if (g->inside_const) { return; } free_tmp_arg_vars = false; g->tmp_count_af++; v__ast__Scope* scope = v__ast__Scope_innermost(g->file->scope, node.pos.pos); Array_v__ast__CallArg args = new_array_from_c_array(1, 1, sizeof(v__ast__CallArg), _MOV((v__ast__CallArg[1]){((v__ast__CallArg){.is_mut = 0,.share = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.expr = node.left,.typ = node.receiver_type,.is_tmp_autofree = node.free_receiver,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.should_be_ptr = 0,.ct_expr = 0,})})); _PUSH_MANY(&args, (node.args), _t1, Array_v__ast__CallArg); for (int i = 0; i < args.len; ++i) { v__ast__CallArg arg = ((v__ast__CallArg*)args.data)[i]; if (!arg.is_tmp_autofree) { if ((arg.expr)._typ == 344 /* v.ast.CallExpr */ && (fast_string_eq((*(v__ast__CallExpr*)__as_cast((arg.expr)._v__ast__CallExpr,(arg.expr)._typ, 344)).name, _S("json.encode")) || fast_string_eq((*(v__ast__CallExpr*)__as_cast((arg.expr)._v__ast__CallExpr,(arg.expr)._typ, 344)).name, _S("json.encode_pretty")))) { t = str_intp(3, _MOV((StrIntpData[]){{_S("_arg_expr_"), 0xfe10, {.d_s = string_replace((*arg.expr._v__ast__CallExpr).name, _S("."), _S("_"))}}, {_S("_"), 0xfe07, {.d_i32 = (*arg.expr._v__ast__CallExpr).pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}})); v__gen__c__Gen_autofree_call_pregen_defer_0 = true; } continue; } if ((arg.expr)._typ == 344 /* v.ast.CallExpr */) { v__gen__c__Gen_autofree_call_pregen(g, (*arg.expr._v__ast__CallExpr)); } free_tmp_arg_vars = true; string fn_name = string_replace(node.name, _S("."), _S("_")); t = str_intp(4, _MOV((StrIntpData[]){{_S("_arg_expr_"), 0xfe10, {.d_s = fn_name}}, {_S("_"), 0xfe07, {.d_i32 = i}}, {_S("_"), 0xfe07, {.d_i32 = node.pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}})); bool used = false; string s = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = t}}, {_S(" = "), 0, { .d_c = 0 }}})); if (used) { _option_v__ast__Var_ptr _t2; if (_t2 = v__ast__Scope_find_var(scope, t), _t2.state == 0) { v__ast__Var* x = *(v__ast__Var**)_t2.data; x->is_used = false; } s = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = t}}, {_S(" = "), 0, { .d_c = 0 }}})); } else { v__ast__Scope_register(scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.name = t,.share = 0,.is_mut = 0,.is_static = 0,.is_volatile = 0,.is_autofree_tmp = true,.is_inherited = 0,.has_inherited = 0,.is_arg = 0,.is_auto_deref = 0,.is_unwrapped = 0,.is_index_var = 0,.expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.typ = _const_v__ast__string_type,.orig_type = 0,.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.pos = node.pos,.is_used = 0,.is_changed = 0,.ct_type_var = 0,.ct_type_unwrapped = 0,.is_or = 0,.is_tmp = 0,.is_auto_heap = 0,.is_stack_obj = 0,}))))); s = str_intp(2, _MOV((StrIntpData[]){{_S("string "), 0xfe10, {.d_s = t}}, {_S(" = "), 0, { .d_c = 0 }}})); } s = string__plus(s, v__gen__c__Gen_expr_string(g, arg.expr)); s = string__plus(s, _S(";// new af2 pre")); array_push((array*)&g->strs_to_free0, _MOV((string[]){ string_clone(s) })); } // Defer begin if (v__gen__c__Gen_autofree_call_pregen_defer_0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(";\n\tstring_free(&"), 0xfe10, {.d_s = t}}, {_S(");"), 0, { .d_c = 0 }}}))); } // Defer end } VV_LOC void v__gen__c__Gen_call_args(v__gen__c__Gen* g, v__ast__CallExpr node) { bool v__gen__c__Gen_call_args_defer_0 = false; g->expected_fixed_arr = true; v__gen__c__Gen_call_args_defer_0 = true; Array_v__ast__CallArg _t1; /* if prepend */ if (g->is_js_call) { if (node.args.len < 1) { v__gen__c__Gen_error(g, _S("node should have at least 1 arg"), node.pos); VUNREACHABLE(); } g->is_js_call = false; _t1 = array_slice(node.args, 1, 2147483647); } else { _t1 = node.args; } Array_v__ast__CallArg args = _t1; Array_v__ast__Type _t2 = {0}; Array_v__ast__Type _t2_orig = node.expected_arg_types; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(v__ast__Type)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Type it = ((v__ast__Type*) _t2_orig.data)[_t4]; v__ast__Type _t3 = v__gen__c__Gen_unwrap_generic(g, it); array_push((array*)&_t2, &_t3); } Array_v__ast__Type expected_types =_t2; bool _t5 = (node.concrete_types.len > 0); bool _t6 = true; if (_t5) { Array_v__ast__Type _t6_orig = node.concrete_types; int _t6_len = _t6_orig.len; for (int _t7 = 0; _t7 < _t6_len; ++_t7) { v__ast__Type it = ((v__ast__Type*) _t6_orig.data)[_t7]; if (!(!v__ast__Type_has_flag(it, v__ast__TypeFlag__generic))) { _t6 = false; break; } } } if ( _t5 &&_t6) { if (node.is_method) { _result_v__ast__Fn _t8; if (_t8 = v__ast__Table_find_method(g->table, v__ast__Table_sym(g->table, node.left_type), node.name), !_t8.is_error) { v__ast__Fn func = *(v__ast__Fn*)_t8.data; if (func.generic_names.len > 0) { for (int i = 0; i < expected_types.len; ++i) { v__ast__Table* muttable = ((v__ast__Table*)(g->table)); _option_v__ast__Type _t9; if (_t9 = v__ast__Table_convert_generic_type(muttable, (*(v__ast__Type*)array_get(node.expected_arg_types, i)), func.generic_names, node.concrete_types), _t9.state == 0) { v__ast__Type utyp = *(v__ast__Type*)_t9.data; array_set(&expected_types, i, &(v__ast__Type[]) { utyp }); } } } } } else { _option_v__ast__Fn _t10; if (_t10 = v__ast__Table_find_fn(g->table, node.name), _t10.state == 0) { v__ast__Fn func = *(v__ast__Fn*)_t10.data; if (func.generic_names.len > 0) { for (int i = 0; i < expected_types.len; ++i) { v__ast__Table* muttable = ((v__ast__Table*)(g->table)); _option_v__ast__Type _t11; if (_t11 = v__ast__Table_convert_generic_type(muttable, (*(v__ast__Type*)array_get(node.expected_arg_types, i)), func.generic_names, node.concrete_types), _t11.state == 0) { v__ast__Type utyp = *(v__ast__Type*)_t11.data; array_set(&expected_types, i, &(v__ast__Type[]) { utyp }); } } } } } } bool _t12 = (expected_types.len > 0); bool is_variadic = _t12 && v__ast__Type_has_flag((*(v__ast__Type*)array_last(expected_types)), v__ast__TypeFlag__variadic) && node.language == v__ast__Language__v; bool already_decomposed = false; for (int i = 0; i < args.len; ++i) { v__ast__CallArg arg = ((v__ast__CallArg*)args.data)[i]; if (is_variadic && i == (int)(expected_types.len - 1)) { break; } bool is_smartcast = false; if ((arg.expr)._typ == 358 /* v.ast.Ident */) { if (((*arg.expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { if (i < node.expected_arg_types.len && v__ast__Type_has_flag((*(v__ast__Type*)array_get(node.expected_arg_types, i)), v__ast__TypeFlag__generic) && !((*(*arg.expr._v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__generic_param || (*(*arg.expr._v__ast__Ident).obj._v__ast__Var).ct_type_var == v__ast__ComptimeVarKind__no_comptime)) { bool exp_option = v__ast__Type_has_flag((*(v__ast__Type*)array_get(node.expected_arg_types, i)), v__ast__TypeFlag__option); array_set(&expected_types, i, &(v__ast__Type[]) { v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, arg.expr)) }); if (!exp_option) { array_set(&expected_types, i, &(v__ast__Type[]) { v__ast__Type_clear_flag((*(v__ast__Type*)array_get(expected_types, i)), v__ast__TypeFlag__option) }); } } else if ((*(*arg.expr._v__ast__Ident).obj._v__ast__Var).smartcasts.len > 0) { v__ast__TypeSymbol* exp_sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get(expected_types, i))); v__ast__TypeSymbol* orig_sym = v__ast__Table_sym(g->table, (*(*arg.expr._v__ast__Ident).obj._v__ast__Var).orig_type); if (orig_sym->kind != v__ast__Kind__interface && (exp_sym->kind != v__ast__Kind__sum_type && (*(v__ast__Type*)array_get(expected_types, i)) != (*(*arg.expr._v__ast__Ident).obj._v__ast__Var).orig_type)) { array_set(&expected_types, i, &(v__ast__Type[]) { v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Type*)array_last((*(*arg.expr._v__ast__Ident).obj._v__ast__Var).smartcasts))) }); v__ast__TypeSymbol* cast_sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get(expected_types, i))); if ((cast_sym->info)._typ == 537 /* v.ast.Aggregate */) { array_set(&expected_types, i, &(v__ast__Type[]) { (*(v__ast__Type*)array_get((*cast_sym->info._v__ast__Aggregate).types, g->aggregate_type_idx)) }); } is_smartcast = true; } } } } else if ((arg.expr)._typ == 337 /* v.ast.ArrayDecompose */) { int d_count = 0; for (int d_i = i; d_i < expected_types.len; ++d_i) { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, (*(v__ast__Type*)array_get(expected_types, d_i)))); v__gen__c__Gen_write(g, _S("*)array_get(")); } v__gen__c__Gen_expr(g, arg.expr); { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, d_count); v__gen__c__Gen_write(g, _S(")")); } if (d_i < (int)(expected_types.len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } d_count++; } already_decomposed = true; continue; } else if ((arg.expr)._typ == 350 /* v.ast.ComptimeSelector */ && i < node.expected_arg_types.len && v__ast__Type_has_flag((*(v__ast__Type*)array_get(node.expected_arg_types, i)), v__ast__TypeFlag__generic)) { bool exp_option = v__ast__Type_has_flag((*(v__ast__Type*)array_get(node.expected_arg_types, i)), v__ast__TypeFlag__option); array_set(&expected_types, i, &(v__ast__Type[]) { v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, arg.expr)) }); if (!exp_option) { array_set(&expected_types, i, &(v__ast__Type[]) { v__ast__Type_clear_flag((*(v__ast__Type*)array_get(expected_types, i)), v__ast__TypeFlag__option) }); } } else if ((arg.expr)._typ == 344 /* v.ast.CallExpr */) { if ((*arg.expr._v__ast__CallExpr).nr_ret_values > 1) { string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; v__ast__Type ret_type = (*arg.expr._v__ast__CallExpr).return_type; string tmp_var = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, ret_type)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, arg.expr); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write(g, line); for (int n = 0; n < (*arg.expr._v__ast__CallExpr).nr_ret_values; ++n) { if (n != (int)((*arg.expr._v__ast__CallExpr).nr_ret_values - 1) || i != (int)(args.len - 1)) { { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(".arg")); v__gen__c__Gen_write_decimal(g, n); v__gen__c__Gen_write(g, _S(", ")); } } else { { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(".arg")); v__gen__c__Gen_write_decimal(g, n); } } } continue; } } bool use_tmp_var_autofree = g->is_autofree && arg.typ == _const_v__ast__string_type && arg.is_tmp_autofree && !g->inside_const && !g->is_builtin_mod; if (i < expected_types.len) { if (use_tmp_var_autofree) { if (arg.is_tmp_autofree) { string fn_name = string_replace(node.name, _S("."), _S("_")); string name = str_intp(4, _MOV((StrIntpData[]){{_S("_arg_expr_"), 0xfe10, {.d_s = fn_name}}, {_S("_"), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S("_"), 0xfe07, {.d_i32 = node.pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}})); v__gen__c__Gen_write(g, string__plus(_S("/*autofree arg*/"), name)); } } else { v__gen__c__Gen_ref_or_deref_arg(g, arg, (*(v__ast__Type*)array_get(expected_types, i)), node.language, is_smartcast); } } else { if (use_tmp_var_autofree) { int n = (fast_string_eq(node.name, _S("json.decode")) ? ((int)(i + 2)) : ((int)(i + 1))); string fn_name = string_replace(node.name, _S("."), _S("_")); string name = str_intp(4, _MOV((StrIntpData[]){{_S("_arg_expr_"), 0xfe10, {.d_s = fn_name}}, {_S("_"), 0xfe07, {.d_i32 = n}}, {_S("_"), 0xfe07, {.d_i32 = node.pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}})); v__gen__c__Gen_write(g, string__plus(_S("/*af arg2*/"), name)); } else { v__gen__c__Gen_expr(g, arg.expr); } } if (i < (int)(args.len - 1) || is_variadic) { v__gen__c__Gen_write(g, _S(", ")); } } int arg_nr = (int)(expected_types.len - 1); if (is_variadic) { v__ast__Type varg_type = (*(v__ast__Type*)array_last(expected_types)); int variadic_count = (int)(args.len - arg_nr); v__ast__TypeSymbol* arr_sym = v__ast__Table_sym(g->table, varg_type); v__ast__Array arr_info = *(v__ast__Array*)__as_cast((arr_sym->info)._v__ast__Array,(arr_sym->info)._typ, 513); if (v__ast__Type_has_flag(varg_type, v__ast__TypeFlag__generic)) { if (node.is_method) { v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, node.left_type); _option_v__ast__Fn _t13; if (_t13 = v__ast__TypeSymbol_find_method_with_generic_parent(left_sym, node.name), _t13.state == 0) { v__ast__Fn fn_def = *(v__ast__Fn*)_t13.data; v__ast__Table* muttable = ((v__ast__Table*)(g->table)); _option_v__ast__Type _t14; if (_t14 = v__ast__Table_convert_generic_type(muttable, arr_info.elem_type, fn_def.generic_names, node.concrete_types), _t14.state == 0) { v__ast__Type utyp = *(v__ast__Type*)_t14.data; arr_info.elem_type = utyp; } } else { IError err = _t13.err; v__gen__c__Gen_error(g, str_intp(2, _MOV((StrIntpData[]){{_S("unable to find method "), 0xfe10, {.d_s = node.name}}, {_SLIT0, 0, { .d_c = 0 }}})), node.pos); VUNREACHABLE(); } } else { _option_v__ast__Fn _t15; if (_t15 = v__ast__Table_find_fn(g->table, node.name), _t15.state == 0) { v__ast__Fn fn_def = *(v__ast__Fn*)_t15.data; v__ast__Table* muttable = ((v__ast__Table*)(g->table)); _option_v__ast__Type _t16; if (_t16 = v__ast__Table_convert_generic_type(muttable, arr_info.elem_type, fn_def.generic_names, node.concrete_types), _t16.state == 0) { v__ast__Type utyp = *(v__ast__Type*)_t16.data; arr_info.elem_type = utyp; } } else { IError err = _t15.err; v__gen__c__Gen_error(g, str_intp(2, _MOV((StrIntpData[]){{_S("unable to find function "), 0xfe10, {.d_s = node.name}}, {_SLIT0, 0, { .d_c = 0 }}})), node.pos); VUNREACHABLE(); } } } string elem_type = v__gen__c__Gen_styp(g, arr_info.elem_type); bool _t17 = (g->pref->translated || g->file->is_translated) && args.len == 1; bool _t18; if (!(_t17)) { bool _t19 = (args.len > 0); _t18 = _t19 && ((*(v__ast__CallArg*)array_last(args)).expr)._typ == 337 /* v.ast.ArrayDecompose */; } if (_t17) { v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(args, 0)).expr); } else if (_t18) { if (!already_decomposed) { v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_last(args)).expr); } } else { if (variadic_count > 0) { if (g->pref->translated || g->file->is_translated) { for (int j = arg_nr; j < args.len; ++j) { v__gen__c__Gen_expr(g, (*(v__ast__CallArg*)array_get(args, j)).expr); if (j < (int)(args.len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } } } else { if (args.len == 1 && ((v__ast__Type_has_flag((*(v__ast__CallArg*)array_get(args, arg_nr)).typ, v__ast__TypeFlag__variadic) && (*(v__ast__CallArg*)array_get(args, arg_nr)).typ == varg_type) || (v__ast__Type_has_flag(varg_type, v__ast__TypeFlag__variadic) && (*(v__ast__CallArg*)array_get(args, arg_nr)).typ == v__ast__Type_clear_flag(varg_type, v__ast__TypeFlag__variadic)))) { v__gen__c__Gen_ref_or_deref_arg(g, (*(v__ast__CallArg*)array_get(args, arg_nr)), arr_info.elem_type, node.language, false); } else { string noscan = v__gen__c__Gen_check_noscan(g, arr_info.elem_type); { v__gen__c__Gen_write(g, _S("new_array_from_c_array")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write_decimal(g, variadic_count); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, variadic_count); v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, elem_type); v__gen__c__Gen_write(g, _S("), _MOV((")); v__gen__c__Gen_write(g, elem_type); v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_write_decimal(g, variadic_count); v__gen__c__Gen_write(g, _S("]){")); } for (int j = arg_nr; j < args.len; ++j) { v__gen__c__Gen_ref_or_deref_arg(g, (*(v__ast__CallArg*)array_get(args, j)), arr_info.elem_type, node.language, false); if (j < (int)(args.len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } } v__gen__c__Gen_write(g, _S("}))")); } } } else { { v__gen__c__Gen_write(g, _S("__new_array(0, 0, sizeof(")); v__gen__c__Gen_write(g, elem_type); v__gen__c__Gen_write(g, _S("))")); } } } } // Defer begin if (v__gen__c__Gen_call_args_defer_0) { g->expected_fixed_arr = false; } // Defer end } VV_LOC int v__gen__c__Gen_keep_alive_call_pregen(v__gen__c__Gen* g, v__ast__CallExpr node) { g->empty_line = true; v__gen__c__Gen_writeln(g, _S("// keep_alive_call_pregen()")); int tmp_cnt_save = (int)(g->tmp_count + 1); g->tmp_count += node.args.len; for (int i = 0; i < node.args.len; ++i) { v__ast__CallArg arg = ((v__ast__CallArg*)node.args.data)[i]; v__ast__Type expected_type = (*(v__ast__Type*)array_get(node.expected_arg_types, i)); v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(g->table, expected_type); string typ = v__gen__c__Gen_styp(g, expected_type); if (typ_sym->kind != v__ast__Kind__array_fixed) { { v__gen__c__Gen_write(g, typ); v__gen__c__Gen_write(g, _S(" __tmp_arg_")); v__gen__c__Gen_write_decimal(g, (int)(tmp_cnt_save + i)); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_ref_or_deref_arg(g, arg, expected_type, node.language, false); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = typ}}, {_S(" __tmp_arg_"), 0xfe07, {.d_i32 = (int)(tmp_cnt_save + i)}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("memcpy(&__tmp_arg_")); v__gen__c__Gen_write_decimal(g, (int)(tmp_cnt_save + i)); v__gen__c__Gen_write(g, _S(", ")); } v__gen__c__Gen_ref_or_deref_arg(g, arg, expected_type, node.language, false); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, _S(";")); } g->empty_line = false; return tmp_cnt_save; } VV_LOC void v__gen__c__Gen_keep_alive_call_postgen(v__gen__c__Gen* g, v__ast__CallExpr node, int tmp_cnt_save) { v__gen__c__Gen_writeln(g, _S("// keep_alive_call_postgen()")); for (int i = 0; i < node.expected_arg_types.len; ++i) { v__ast__Type expected_type = ((v__ast__Type*)node.expected_arg_types.data)[i]; if (v__ast__Type_is_any_kind_of_pointer(expected_type)) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("GC_reachable_here(__tmp_arg_"), 0xfe07, {.d_i32 = (int)(tmp_cnt_save + i)}}, {_S(");"), 0, { .d_c = 0 }}}))); } } } inline VV_LOC void v__gen__c__Gen_ref_or_deref_arg(v__gen__c__Gen* g, v__ast__CallArg arg, v__ast__Type expected_type, v__ast__Language lang, bool is_smartcast) { bool v__gen__c__Gen_ref_or_deref_arg_defer_0 = false; bool old_expected_arg_mut; v__ast__Type arg_typ = (arg.ct_expr ? (v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type(&g->type_resolver, arg.expr))) : (v__gen__c__Gen_unwrap_generic(g, arg.typ))); v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(g->table, arg_typ); bool exp_is_ptr = v__ast__Type_is_any_kind_of_pointer(expected_type); bool arg_is_ptr = v__ast__Type_is_any_kind_of_pointer(arg_typ); if (expected_type == 0) { v__gen__c__Gen_checker_bug(g, _S("ref_or_deref_arg expected_type is 0"), arg.pos); } old_expected_arg_mut = g->expected_arg_mut; g->expected_arg_mut = arg.is_mut; v__gen__c__Gen_ref_or_deref_arg_defer_0 = true; v__ast__TypeSymbol* exp_sym = v__ast__Table_sym(g->table, expected_type); bool needs_closing = false; bool old_inside_smartcast = g->inside_smartcast; if (arg.is_mut && !exp_is_ptr) { v__gen__c__Gen_write(g, _S("&/*mut*/")); } else if (arg.is_mut && v__ast__Type_is_ptr(arg_typ) && v__ast__Type_is_ptr(expected_type) && v__ast__Table_sym(g->table, arg_typ)->kind == v__ast__Kind__struct && expected_type == v__ast__Type_ref(arg_typ)) { if ((arg.expr)._typ == 376 /* v.ast.PrefixExpr */ && (*(v__ast__PrefixExpr*)__as_cast((arg.expr)._v__ast__PrefixExpr,(arg.expr)._typ, 376)).op == v__token__Kind__amp) { g->arg_no_auto_deref = true; v__gen__c__Gen_expr(g, arg.expr); g->arg_no_auto_deref = false; } else { v__gen__c__Gen_write(g, _S("&/*mut*/")); v__gen__c__Gen_expr(g, arg.expr); } // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } else if (exp_is_ptr && !arg_is_ptr && !(arg_sym->kind == v__ast__Kind__alias && v__ast__Type_is_pointer(v__ast__Table_unaliased_type(g->table, arg_typ)) && v__ast__Type_is_pointer(expected_type))) { if (arg.is_mut) { if (exp_sym->kind == v__ast__Kind__array) { if (((arg.expr)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((arg.expr)._v__ast__Ident,(arg.expr)._typ, 358)).kind == v__ast__IdentKind__global || (*(v__ast__Ident*)__as_cast((arg.expr)._v__ast__Ident,(arg.expr)._typ, 358)).kind == v__ast__IdentKind__variable)) || (arg.expr)._typ == 379 /* v.ast.SelectorExpr */) { v__gen__c__Gen_write(g, _S("&")); if (v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__option_mut_param_t)) { v__gen__c__Gen_expr_with_opt(g, arg.expr, arg_typ, expected_type); } else { v__gen__c__Gen_expr(g, arg.expr); } } else { v__gen__c__Gen_write(g, _S("&(array[]){")); v__gen__c__Gen_expr(g, arg.expr); v__gen__c__Gen_write(g, _S("}[0]")); } // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } else if (arg_sym->kind == v__ast__Kind__sum_type && exp_sym->kind == v__ast__Kind__sum_type && ((arg.expr)._typ == 358 /* v.ast.Ident */ || (arg.expr)._typ == 379 /* v.ast.SelectorExpr */)) { v__gen__c__Gen_write(g, _S("&")); v__gen__c__Gen_expr(g, arg.expr); // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } else if (arg_sym->kind == v__ast__Kind__interface && exp_sym->kind == v__ast__Kind__interface && ((arg.expr)._typ == 358 /* v.ast.Ident */ || (arg.expr)._typ == 379 /* v.ast.SelectorExpr */)) { v__gen__c__Gen_write(g, _S("&")); v__gen__c__Gen_expr(g, arg.expr); // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } } if (!g->is_json_fn) { if (arg_typ == 0) { v__gen__c__Gen_checker_bug(g, _S("ref_or_deref_arg arg.typ is 0"), arg.pos); } v__ast__TypeSymbol* arg_typ_sym = v__ast__Table_sym(g->table, arg_typ); v__ast__Type expected_deref_type = (v__ast__Type_is_ptr(expected_type) ? (v__ast__Type_deref(expected_type)) : (expected_type)); v__ast__TypeSymbol* deref_sym = v__ast__Table_sym(g->table, expected_deref_type); if (arg_typ_sym->kind != v__ast__Kind__function && !(deref_sym->kind == v__ast__Kind__sum_type || deref_sym->kind == v__ast__Kind__interface) && lang != v__ast__Language__c) { if (v__ast__Expr_is_lvalue(arg.expr)) { if (v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__option)) { if (v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__option_mut_param_t)) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, expected_type)); v__gen__c__Gen_write(g, _S(")&")); } } v__gen__c__Gen_expr_with_opt(g, arg.expr, arg_typ, expected_type); // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } else if ((arg.expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((arg.expr)._v__ast__Ident,(arg.expr)._typ, 358)).language == v__ast__Language__c) { v__gen__c__Gen_write(g, _S("(voidptr)")); } else if (!(!arg.is_mut && arg_sym->kind == v__ast__Kind__alias && v__ast__Type_is_any_kind_of_pointer(v__ast__Table_unaliased_type(g->table, arg_typ)))) { v__gen__c__Gen_write(g, _S("(voidptr)&")); } } else { v__ast__Type atype = expected_deref_type; if (v__ast__Type_has_flag(atype, v__ast__TypeFlag__generic)) { atype = v__gen__c__Gen_unwrap_generic(g, atype); } if (v__ast__Type_has_flag(atype, v__ast__TypeFlag__generic) || (arg.expr)._typ == 385 /* v.ast.StructInit */) { v__gen__c__Gen_write(g, _S("(voidptr)&")); } else if ((arg.expr)._typ == 371 /* v.ast.None */) { v__gen__c__Gen_expr_with_opt(g, arg.expr, arg_typ, expected_type); // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } else if (v__ast__Expr_is_literal(arg.expr)) { { v__gen__c__Gen_write(g, _S("(voidptr)ADDR(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, arg_typ)); v__gen__c__Gen_write(g, _S(", ")); } v__gen__c__Gen_expr(g, arg.expr); v__gen__c__Gen_write(g, _S(")")); // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } else { if (arg_typ_sym->kind == v__ast__Kind__sum_type || arg_typ_sym->kind == v__ast__Kind__interface) { atype = arg_typ; } if (v__ast__Expr_is_as_cast(arg.expr)) { g->inside_smartcast = true; } else { { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, atype)); v__gen__c__Gen_write(g, _S(", ")); } needs_closing = true; } } } } else if (arg_sym->kind == v__ast__Kind__sum_type && exp_sym->kind == v__ast__Kind__sum_type) { if ((arg.expr)._typ == 379 /* v.ast.SelectorExpr */) { v__gen__c__Gen_write(g, _S("&")); v__gen__c__Gen_expr(g, arg.expr); // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } else if ((arg.expr)._typ == 345 /* v.ast.CastExpr */) { { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, expected_deref_type)); v__gen__c__Gen_write(g, _S(", ")); } v__gen__c__Gen_expr_with_cast(g, arg.expr, arg_typ, expected_type); v__gen__c__Gen_write(g, _S(")")); // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } } else if (arg_sym->kind == v__ast__Kind__interface && exp_sym->kind == v__ast__Kind__interface) { if (exp_is_ptr && !arg_is_ptr) { v__gen__c__Gen_write(g, _S("&")); } } } } else if (v__ast__Type_has_flag(arg_typ, v__ast__TypeFlag__shared_f) && !v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__shared_f)) { if (v__ast__Type_is_ptr(expected_type)) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, arg.expr); v__gen__c__Gen_write(g, _S("->val")); // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } else if (v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__option)) { if (v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__option_mut_param_t) && v__ast__Type_nr_muls(arg_typ) <= v__ast__Type_nr_muls(expected_type) && !((arg.expr)._typ == 358 /* v.ast.Ident */ && (((*(v__ast__Ident*)__as_cast((arg.expr)._v__ast__Ident,(arg.expr)._typ, 358)).obj)._typ == 422 /* v.ast.Var */ && (*(v__ast__Var*)__as_cast(((*(v__ast__Ident*)__as_cast((arg.expr)._v__ast__Ident,(arg.expr)._typ, 358)).obj)._v__ast__Var,((*(v__ast__Ident*)__as_cast((arg.expr)._v__ast__Ident,(arg.expr)._typ, 358)).obj)._typ, 422)).is_inherited))) { v__gen__c__Gen_write(g, _S("&")); } if (((arg_sym->info)._typ == 539 /* v.ast.Alias */ || (exp_sym->info)._typ == 539 /* v.ast.Alias */) && expected_type != arg_typ) { v__gen__c__Gen_expr_opt_with_alias(g, arg.expr, arg_typ, expected_type); } else { if ((arg.expr)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((arg.expr)._v__ast__Ident,(arg.expr)._typ, 358)).obj)._typ == 422 /* v.ast.Var */) { if ((*(*arg.expr._v__ast__Ident).obj._v__ast__Var).smartcasts.len > 0) { arg_typ = (*(v__ast__Type*)array_last((*(*arg.expr._v__ast__Ident).obj._v__ast__Var).smartcasts)); } } v__gen__c__Gen_expr_with_opt(g, arg.expr, arg_typ, expected_type); } // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } else if ((arg.expr)._typ == 338 /* v.ast.ArrayInit */) { if ((*arg.expr._v__ast__ArrayInit).is_fixed) { if (!(*arg.expr._v__ast__ArrayInit).has_index) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, (*arg.expr._v__ast__ArrayInit).typ)); v__gen__c__Gen_write(g, _S(")")); } } } } else if ((arg.expr)._typ == 350 /* v.ast.ComptimeSelector */ && v__ast__Type_has_flag(arg_typ, v__ast__TypeFlag__option) && !v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__option)) { string styp = v__gen__c__Gen_base_type(g, arg_typ); { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)")); } v__gen__c__Gen_expr_with_cast(g, arg.expr, arg_typ, expected_type); v__gen__c__Gen_write(g, _S(".data")); // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end return; } else if ((arg.expr)._typ == 358 /* v.ast.Ident */ && (arg_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((arg_sym->info)._v__ast__Struct,(arg_sym->info)._typ, 518)).is_anon && !v__ast__Type_has_flag(expected_type, v__ast__TypeFlag__generic)) { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, v__gen__c__Gen_cc_type(g, expected_type, false)); v__gen__c__Gen_write(g, _S("*)&")); } } g->arg_no_auto_deref = is_smartcast && !arg_is_ptr && !exp_is_ptr && arg.should_be_ptr; v__gen__c__Gen_expr_with_cast(g, arg.expr, arg_typ, expected_type); g->arg_no_auto_deref = false; g->inside_smartcast = old_inside_smartcast; if (needs_closing) { v__gen__c__Gen_write(g, _S(")")); } // Defer begin if (v__gen__c__Gen_ref_or_deref_arg_defer_0) { g->expected_arg_mut = old_expected_arg_mut; } // Defer end } VV_LOC bool v__gen__c__Gen_is_gui_app(v__gen__c__Gen* g) { if (g->pref->subsystem == (v__pref__Subsystem__windows)) { return true; } else if (g->pref->subsystem == (v__pref__Subsystem__console)) { return false; } else if (g->pref->subsystem == (v__pref__Subsystem__auto)) { } if (g->pref->os == v__pref__OS__windows) { if (g->force_main_console) { return false; } for (int _t4 = 0; _t4 < g->table->cflags.len; ++_t4) { v__cflag__CFlag cf = ((v__cflag__CFlag*)g->table->cflags.data)[_t4]; if (string__eq(string_to_lower_ascii(cf.value), _S("gdi32"))) { return true; } } } return false; } VV_LOC string v__gen__c__Gen_write_fn_attrs(v__gen__c__Gen* g, Array_v__ast__Attr attrs) { string fn_attrs = _S(""); for (int _t1 = 0; _t1 < attrs.len; ++_t1) { v__ast__Attr attr = ((v__ast__Attr*)attrs.data)[_t1]; if (_SLIT_EQ(attr.name.str, attr.name.len, "inline")) { v__gen__c__Gen_write(g, _S("inline ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "noinline")) { v__gen__c__Gen_write(g, _S("__NOINLINE ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "weak")) { bool _t2 = false; Array_v__ast__Attr _t2_orig = attrs; int _t2_len = _t2_orig.len; for (int _t3 = 0; _t3 < _t2_len; ++_t3) { v__ast__Attr it = ((v__ast__Attr*) _t2_orig.data)[_t3]; if (fast_string_eq(it.name, _S("export"))) { _t2 = true; break; } } if (_t2) { continue; } v__gen__c__Gen_write(g, _S("VWEAK ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "noreturn")) { v__gen__c__Gen_write(g, _S("VNORETURN ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "irq_handler")) { v__gen__c__Gen_write(g, _S("__IRQHANDLER ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "_cold")) { v__gen__c__Gen_write(g, _S("__attribute__((cold)) ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "_constructor")) { v__gen__c__Gen_write(g, _S("__attribute__((constructor)) ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "_destructor")) { v__gen__c__Gen_write(g, _S("__attribute__((destructor)) ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "_flatten")) { v__gen__c__Gen_write(g, _S("__attribute__((flatten)) ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "_hot")) { v__gen__c__Gen_write(g, _S("__attribute__((hot)) ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "_malloc")) { v__gen__c__Gen_write(g, _S("__attribute__((malloc)) ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "_pure")) { v__gen__c__Gen_write(g, _S("__attribute__((const)) ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "_naked")) { v__gen__c__Gen_write(g, _S("__attribute__((naked)) ")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "windows_stdcall")) { fn_attrs = string__plus(fn_attrs, v__gen__c__call_convention_attribute(_S("stdcall"), g->is_cc_msvc)); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "_fastcall")) { fn_attrs = string__plus(fn_attrs, v__gen__c__call_convention_attribute(_S("fastcall"), g->is_cc_msvc)); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "callconv")) { fn_attrs = string__plus(fn_attrs, v__gen__c__call_convention_attribute(attr.arg, g->is_cc_msvc)); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "console")) { g->force_main_console = true; } else { } } return fn_attrs; } VV_LOC string v__gen__c__call_convention_attribute(string cconvention, bool is_cc_msvc) { return (is_cc_msvc ? (str_intp(2, _MOV((StrIntpData[]){{_S("__"), 0xfe10, {.d_s = cconvention}}, {_S(" "), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("__attribute__(("), 0xfe10, {.d_s = cconvention}}, {_S(")) "), 0, { .d_c = 0 }}})))); } VV_LOC void v__gen__c__Gen_for_c_stmt(v__gen__c__Gen* g, v__ast__ForCStmt node) { g->loop_depth++; if (node.is_multi) { g->is_vlines_enabled = false; g->inside_for_c_stmt = true; if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.label}}, {_S(":"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, _S("{")); g->indent++; if (node.has_init) { v__gen__c__Gen_stmt(g, node.init); if ((node.init)._typ == 401 /* v.ast.ExprStmt */) { v__gen__c__Gen_write(g, _S("; ")); } } v__gen__c__Gen_writeln(g, _S("bool _is_first = true;")); v__gen__c__Gen_writeln(g, _S("while (true) {")); v__gen__c__Gen_writeln(g, _S("\tif (_is_first) {")); v__gen__c__Gen_writeln(g, _S("\t\t_is_first = false;")); v__gen__c__Gen_writeln(g, _S("\t} else {")); if (node.has_inc) { g->indent++; v__gen__c__Gen_stmt(g, node.inc); v__gen__c__Gen_writeln(g, _S(";")); g->indent--; } v__gen__c__Gen_writeln(g, _S("}")); if (node.has_cond) { v__gen__c__Gen_write(g, _S("if (!(")); v__gen__c__Gen_expr(g, node.cond); v__gen__c__Gen_writeln(g, _S(")) break;")); } g->is_vlines_enabled = true; g->inside_for_c_stmt = false; v__gen__c__Gen_stmts(g, node.stmts); if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.label}}, {_S("__continue: {}"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, _S("}")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.label}}, {_S("__break: {}"), 0, { .d_c = 0 }}}))); } } else { g->is_vlines_enabled = false; g->inside_for_c_stmt = true; if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.label}}, {_S(":"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); g->skip_stmt_pos = true; v__gen__c__Gen_write(g, _S("for (")); if (!node.has_init) { v__gen__c__Gen_write(g, _S("; ")); } else { v__gen__c__Gen_stmt(g, node.init); if ((node.init)._typ == 401 /* v.ast.ExprStmt */) { v__gen__c__Gen_write(g, _S("; ")); } if (string__eq(strings__Builder_last_n(&g->out, 1), _S("\n"))) { v__gen__c__Gen_go_back(g, 1); g->empty_line = false; v__gen__c__Gen_write(g, _S(" ")); } } if (node.has_cond) { v__gen__c__Gen_expr(g, node.cond); } v__gen__c__Gen_write(g, _S("; ")); if (node.has_inc) { bool processed = false; if ((node.inc)._typ == 401 /* v.ast.ExprStmt */ && ((*(v__ast__ExprStmt*)__as_cast((node.inc)._v__ast__ExprStmt,(node.inc)._typ, 401)).expr)._typ == 352 /* v.ast.ConcatExpr */) { for (int inc_expr_idx = 0; inc_expr_idx < (*(*node.inc._v__ast__ExprStmt).expr._v__ast__ConcatExpr).vals.len; ++inc_expr_idx) { v__ast__Expr inc_expr = ((v__ast__Expr*)(*(*node.inc._v__ast__ExprStmt).expr._v__ast__ConcatExpr).vals.data)[inc_expr_idx]; v__gen__c__Gen_expr(g, inc_expr); if (inc_expr_idx < (int)((*(*node.inc._v__ast__ExprStmt).expr._v__ast__ConcatExpr).vals.len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } } processed = true; } if (!processed) { v__gen__c__Gen_stmt(g, node.inc); } } v__gen__c__Gen_writeln(g, _S(") {")); g->skip_stmt_pos = false; g->is_vlines_enabled = true; g->inside_for_c_stmt = false; v__gen__c__Gen_stmts(g, node.stmts); if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.label}}, {_S("__continue: {}"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, _S("}")); if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.label}}, {_S("__break: {}"), 0, { .d_c = 0 }}}))); } } g->loop_depth--; } VV_LOC void v__gen__c__Gen_for_stmt(v__gen__c__Gen* g, v__ast__ForStmt node) { g->loop_depth++; g->is_vlines_enabled = false; if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.label}}, {_S(":"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, _S("for (;;) {")); if (!node.is_inf) { g->indent++; v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); v__gen__c__Gen_write(g, _S("if (!(")); v__gen__c__Gen_expr(g, node.cond); v__gen__c__Gen_writeln(g, _S(")) break;")); g->indent--; } g->is_vlines_enabled = true; v__gen__c__Gen_stmts(g, node.stmts); if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.label}}, {_S("__continue: {}"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, _S("}")); if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.label}}, {_S("__break: {}"), 0, { .d_c = 0 }}}))); } g->loop_depth--; } VV_LOC void v__gen__c__Gen_for_in_stmt(v__gen__c__Gen* g, v__ast__ForInStmt node_) { bool v__gen__c__Gen_for_in_stmt_defer_0 = false; v__ast__ForInStmt node; bool v__gen__c__Gen_for_in_stmt_defer_1 = false; node = node_; bool is_comptime = false; if (((node.cond)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node.cond)._v__ast__Ident,(node.cond)._typ, 358)).ct_expr) || (node.cond)._typ == 350 /* v.ast.ComptimeSelector */) { v__ast__Type unwrapped_typ = v__gen__c__Gen_unwrap_generic(g, node.cond_type); v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type(&g->type_resolver, node.cond); if (ctyp != _const_v__ast__void_type) { unwrapped_typ = v__gen__c__Gen_unwrap_generic(g, ctyp); is_comptime = true; } v__ast__TypeSymbol* unwrapped_sym = v__ast__Table_sym(g->table, unwrapped_typ); node.cond_type = unwrapped_typ; node.val_type = v__ast__Table_value_type(g->table, unwrapped_typ); if (node.val_is_mut) { node.val_type = v__ast__Type_ref(node.val_type); } v__ast__Scope_update_var_type(node.scope, node.val_var, node.val_type); node.kind = unwrapped_sym->kind; if (is_comptime) { v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, node.val_var, node.val_type); v__ast__Scope_update_ct_var_kind(node.scope, node.val_var, v__ast__ComptimeVarKind__value_var); v__gen__c__Gen_for_in_stmt_defer_0 = true; } if (node.key_var.len > 0) { v__ast__Type key_type = ((unwrapped_sym->kind == (v__ast__Kind__map))? (v__ast__TypeSymbol_map_info(unwrapped_sym).key_type) : (_const_v__ast__int_type)); node.key_type = key_type; v__ast__Scope_update_var_type(node.scope, node.key_var, key_type); if (is_comptime) { v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, node.key_var, node.key_type); v__ast__Scope_update_ct_var_kind(node.scope, node.key_var, v__ast__ComptimeVarKind__key_var); v__gen__c__Gen_for_in_stmt_defer_1 = true; } } } if (node.kind == v__ast__Kind__any && !is_comptime) { v__ast__Type unwrapped_typ = v__gen__c__Gen_unwrap_generic(g, node.cond_type); v__ast__TypeSymbol* unwrapped_sym = v__ast__Table_sym(g->table, unwrapped_typ); node.kind = unwrapped_sym->kind; node.cond_type = unwrapped_typ; if (node.key_var.len > 0) { v__ast__Type key_type = ((unwrapped_sym->kind == (v__ast__Kind__map))? (v__ast__TypeSymbol_map_info(unwrapped_sym).key_type) : (_const_v__ast__int_type)); node.key_type = key_type; v__ast__Scope_update_var_type(node.scope, node.key_var, key_type); } node.val_type = v__ast__Table_value_type(g->table, unwrapped_typ); v__ast__Scope_update_var_type(node.scope, node.val_var, node.val_type); } g->loop_depth++; if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.label}}, {_S(": {}"), 0, { .d_c = 0 }}}))); } if (node.is_range) { string i = (fast_string_eq(node.val_var, _S("_")) ? (v__gen__c__Gen_new_tmp_var(g)) : (v__gen__c__c_name(node.val_var))); v__ast__Type val_typ = v__ast__mktyp(node.val_type); { v__gen__c__Gen_write(g, _S("for (")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, val_typ)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, i); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, node.cond); { v__gen__c__Gen_write(g, _S("; ")); v__gen__c__Gen_write(g, i); v__gen__c__Gen_write(g, _S(" < ")); } v__gen__c__Gen_expr(g, node.high); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("; ++"), 0xfe10, {.d_s = i}}, {_S(") {"), 0, { .d_c = 0 }}}))); } else if (node.kind == v__ast__Kind__array) { string styp = v__gen__c__Gen_styp(g, node.val_type); v__ast__TypeSymbol* val_sym = v__ast__Table_sym(g->table, node.val_type); string op_field = v__gen__c__Gen_dot_or_ptr(g, node.cond_type); string cond_var = _S(""); bool cond_is_option = v__ast__Type_has_flag(node.cond_type, v__ast__TypeFlag__option); if (((node.cond)._typ == 358 /* v.ast.Ident */ && !cond_is_option) || ((node.cond)._typ == 379 /* v.ast.SelectorExpr */ && (*(v__ast__SelectorExpr*)__as_cast((node.cond)._v__ast__SelectorExpr,(node.cond)._typ, 379)).or_block.kind == v__ast__OrKind__absent)) { cond_var = v__gen__c__Gen_expr_string(g, node.cond); } else { cond_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_write2(g, v__gen__c__Gen_styp(g, node.cond_type), str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = cond_var}}, {_S(" = "), 0, { .d_c = 0 }}}))); bool old_inside_opt_or_res = g->inside_opt_or_res; if (cond_is_option) { g->inside_opt_or_res = true; } v__gen__c__Gen_expr(g, node.cond); g->inside_opt_or_res = old_inside_opt_or_res; v__gen__c__Gen_writeln(g, _S(";")); } string i = ((fast_string_eq(node.key_var, _S("")) || fast_string_eq(node.key_var, _S("_"))) ? (v__gen__c__Gen_new_tmp_var(g)) : (node.key_var)); g->empty_line = true; string opt_expr = str_intp(4, _MOV((StrIntpData[]){{_S("(*("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(node.cond_type, v__ast__TypeFlag__option))}}, {_S("*)"), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = op_field}}, {_S("data)"), 0, { .d_c = 0 }}})); string cond_expr = (cond_is_option ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = opt_expr}}, {_SLIT0, 0xfe10, {.d_s = op_field}}, {_S("len"), 0, { .d_c = 0 }}}))) : (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = op_field}}, {_S("len"), 0, { .d_c = 0 }}})))); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = i}}, {_S(" = 0; "), 0xfe10, {.d_s = i}}, {_S(" < "), 0xfe10, {.d_s = cond_expr}}, {_S("; ++"), 0xfe10, {.d_s = i}}, {_S(") {"), 0, { .d_c = 0 }}}))); if (!fast_string_eq(node.val_var, _S("_"))) { if ((val_sym->info)._typ == 553 /* v.ast.FnType */) { v__gen__c__Gen_write(g, _S("\t")); string tcc_bug = v__gen__c__c_name(node.val_var); v__gen__c__Gen_write_fn_ptr_decl(g, &(*val_sym->info._v__ast__FnType), tcc_bug); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" = ((voidptr*)"), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = op_field}}, {_S("data)["), 0xfe10, {.d_s = i}}, {_S("];"), 0, { .d_c = 0 }}}))); } else if (!v__ast__Type_has_flag(node.val_type, v__ast__TypeFlag__option) && val_sym->kind == v__ast__Kind__array_fixed && !node.val_is_mut) { string right = str_intp(5, _MOV((StrIntpData[]){{_S("(("), 0xfe10, {.d_s = styp}}, {_S("*)"), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = op_field}}, {_S("data)["), 0xfe10, {.d_s = i}}, {_S("]"), 0, { .d_c = 0 }}})); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = v__gen__c__c_name(node.val_var)}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\tmemcpy(*("), 0xfe10, {.d_s = styp}}, {_S("*)"), 0xfe10, {.d_s = v__gen__c__c_name(node.val_var)}}, {_S(", (byte*)"), 0xfe10, {.d_s = right}}, {_S(", sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { bool needs_memcpy = !v__ast__Type_is_ptr(node.val_type) && !v__ast__Type_has_flag(node.val_type, v__ast__TypeFlag__option) && v__ast__Table_final_sym(g->table, node.val_type)->kind == v__ast__Kind__array_fixed; string right = (cond_is_option ? (str_intp(5, _MOV((StrIntpData[]){{_S("(("), 0xfe10, {.d_s = styp}}, {_S("*)"), 0xfe10, {.d_s = opt_expr}}, {_SLIT0, 0xfe10, {.d_s = op_field}}, {_S("data)["), 0xfe10, {.d_s = i}}, {_S("]"), 0, { .d_c = 0 }}}))) : node.val_is_mut || node.val_is_ref ? (str_intp(5, _MOV((StrIntpData[]){{_S("(("), 0xfe10, {.d_s = styp}}, {_S(")"), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = op_field}}, {_S("data) + "), 0xfe10, {.d_s = i}}, {_SLIT0, 0, { .d_c = 0 }}}))) : val_sym->kind == v__ast__Kind__array_fixed ? (str_intp(5, _MOV((StrIntpData[]){{_S("(("), 0xfe10, {.d_s = styp}}, {_S("*)"), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = op_field}}, {_S("data)["), 0xfe10, {.d_s = i}}, {_S("]"), 0, { .d_c = 0 }}}))) : (str_intp(5, _MOV((StrIntpData[]){{_S("(("), 0xfe10, {.d_s = styp}}, {_S("*)"), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = op_field}}, {_S("data)["), 0xfe10, {.d_s = i}}, {_S("]"), 0, { .d_c = 0 }}})))); if (!needs_memcpy) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = v__gen__c__c_name(node.val_var)}}, {_S(" = "), 0xfe10, {.d_s = right}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = v__gen__c__c_name(node.val_var)}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\tmemcpy("), 0xfe10, {.d_s = v__gen__c__c_name(node.val_var)}}, {_S(", "), 0xfe10, {.d_s = right}}, {_S(", sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } } } } else if (node.kind == v__ast__Kind__array_fixed) { string cond_var = _S(""); bool cond_type_is_ptr = v__ast__Type_is_ptr(node.cond_type); bool cond_is_literal = (node.cond)._typ == 338 /* v.ast.ArrayInit */; if (cond_is_literal) { cond_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_write2(g, v__gen__c__Gen_styp(g, node.cond_type), str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = cond_var}}, {_S(" = "), 0, { .d_c = 0 }}}))); v__gen__c__Gen_expr(g, node.cond); v__gen__c__Gen_writeln(g, _S(";")); } else if (cond_type_is_ptr) { cond_var = v__gen__c__Gen_new_tmp_var(g); string cond_var_type = string_trim(v__gen__c__Gen_styp(g, node.cond_type), _S("*")); if (!v__ast__Expr_is_lvalue(node.cond)) { { v__gen__c__Gen_write(g, cond_var_type); v__gen__c__Gen_write(g, _S(" *")); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" = ((")); v__gen__c__Gen_write(g, cond_var_type); v__gen__c__Gen_write(g, _S(")")); } } else { { v__gen__c__Gen_write(g, cond_var_type); v__gen__c__Gen_write(g, _S(" *")); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" = (")); } } v__gen__c__Gen_expr(g, node.cond); v__gen__c__Gen_writeln(g, _S(");")); } else { cond_var = v__gen__c__Gen_expr_string(g, node.cond); } string idx = ((fast_string_eq(node.key_var, _S("")) || fast_string_eq(node.key_var, _S("_"))) ? (v__gen__c__Gen_new_tmp_var(g)) : (node.key_var)); v__ast__TypeSymbol* cond_sym = v__ast__Table_final_sym(g->table, node.cond_type); v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((cond_sym->info)._v__ast__ArrayFixed,(cond_sym->info)._typ, 549); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = idx}}, {_S(" = 0; "), 0xfe10, {.d_s = idx}}, {_S(" != "), 0xfe07, {.d_i32 = info.size}}, {_S("; ++"), 0xfe10, {.d_s = idx}}, {_S(") {"), 0, { .d_c = 0 }}}))); if (!fast_string_eq(node.val_var, _S("_"))) { v__ast__TypeSymbol* val_sym = v__ast__Table_sym(g->table, node.val_type); bool is_fixed_array = val_sym->kind == v__ast__Kind__array_fixed && !node.val_is_mut && !v__ast__Type_has_flag(node.val_type, v__ast__TypeFlag__option); if ((val_sym->info)._typ == 553 /* v.ast.FnType */) { v__gen__c__Gen_write(g, _S("\t")); string tcc_bug = v__gen__c__c_name(node.val_var); v__gen__c__Gen_write_fn_ptr_decl(g, &(*val_sym->info._v__ast__FnType), tcc_bug); } else if (is_fixed_array) { string styp = v__gen__c__Gen_styp(g, node.val_type); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = v__gen__c__c_name(node.val_var)}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("\tmemcpy(*("), 0xfe10, {.d_s = styp}}, {_S("*)"), 0xfe10, {.d_s = v__gen__c__c_name(node.val_var)}}, {_S(", (byte*)"), 0xfe10, {.d_s = cond_var}}, {_S("["), 0xfe10, {.d_s = idx}}, {_S("], sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { string styp = v__gen__c__Gen_styp(g, node.val_type); { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, v__gen__c__c_name(node.val_var)); } } if (!is_fixed_array) { string addr = (node.val_is_mut ? (_S("&")) : (_S(""))); if (cond_type_is_ptr) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" = "), 0xfe10, {.d_s = addr}}, {_S("(*"), 0xfe10, {.d_s = cond_var}}, {_S(")["), 0xfe10, {.d_s = idx}}, {_S("];"), 0, { .d_c = 0 }}}))); } else if (cond_is_literal) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(" = "), 0xfe10, {.d_s = addr}}, {_SLIT0, 0xfe10, {.d_s = cond_var}}, {_S("["), 0xfe10, {.d_s = idx}}, {_S("];"), 0, { .d_c = 0 }}}))); } else { { v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_write(g, addr); } v__gen__c__Gen_expr(g, node.cond); if (info.is_fn_ret) { v__gen__c__Gen_write(g, _S(".ret_arr")); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("["), 0xfe10, {.d_s = idx}}, {_S("];"), 0, { .d_c = 0 }}}))); } } } } else if (node.kind == v__ast__Kind__map) { string cond_var = _S(""); if ((node.cond)._typ == 358 /* v.ast.Ident */) { cond_var = v__gen__c__Gen_expr_string(g, node.cond); } else { cond_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_write2(g, v__gen__c__Gen_styp(g, node.cond_type), str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = cond_var}}, {_S(" = "), 0, { .d_c = 0 }}}))); v__gen__c__Gen_expr(g, node.cond); v__gen__c__Gen_writeln(g, _S(";")); } string dot_or_ptr = v__gen__c__Gen_dot_or_ptr(g, node.cond_type); string idx = v__gen__c__Gen_new_tmp_var(g); string map_len = v__gen__c__Gen_new_tmp_var(g); g->empty_line = true; v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("int "), 0xfe10, {.d_s = map_len}}, {_S(" = "), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("key_values.len;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = idx}}, {_S(" = 0; "), 0xfe10, {.d_s = idx}}, {_S(" < "), 0xfe10, {.d_s = map_len}}, {_S("; ++"), 0xfe10, {.d_s = idx}}, {_S(" ) {"), 0, { .d_c = 0 }}}))); g->indent++; string diff = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("int "), 0xfe10, {.d_s = diff}}, {_S(" = "), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("key_values.len - "), 0xfe10, {.d_s = map_len}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = map_len}}, {_S(" = "), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("key_values.len;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = diff}}, {_S(" < 0) {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = idx}}, {_S(" = -1;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\tcontinue;")); v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("if (!DenseArray_has_index(&"), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("key_values, "), 0xfe10, {.d_s = idx}}, {_S(")) {continue;}"), 0, { .d_c = 0 }}}))); if (!fast_string_eq(node.key_var, _S("_"))) { string key_styp = v__gen__c__Gen_styp(g, node.key_type); string key = v__gen__c__c_name(node.key_var); v__gen__c__Gen_writeln(g, str_intp(7, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = key_styp}}, {_S(" "), 0xfe10, {.d_s = key}}, {_S(" = *("), 0xfe10, {.d_s = key_styp}}, {_S("*)DenseArray_key(&"), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("key_values, "), 0xfe10, {.d_s = idx}}, {_S(");"), 0, { .d_c = 0 }}}))); if (node.key_type == _const_v__ast__string_type) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = key}}, {_S(" = string_clone("), 0xfe10, {.d_s = key}}, {_S(");"), 0, { .d_c = 0 }}}))); } } if (!fast_string_eq(node.val_var, _S("_"))) { v__ast__TypeSymbol* val_sym = v__ast__Table_sym(g->table, node.val_type); if ((val_sym->info)._typ == 553 /* v.ast.FnType */) { string tcc_bug = v__gen__c__c_name(node.val_var); v__gen__c__Gen_write_fn_ptr_decl(g, &(*val_sym->info._v__ast__FnType), tcc_bug); v__gen__c__Gen_write(g, _S(" = (*(voidptr*)")); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("DenseArray_value(&"), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("key_values, "), 0xfe10, {.d_s = idx}}, {_S("));"), 0, { .d_c = 0 }}}))); } else if (val_sym->kind == v__ast__Kind__array_fixed && !node.val_is_mut) { string val_styp = v__gen__c__Gen_styp(g, node.val_type); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = val_styp}}, {_S(" "), 0xfe10, {.d_s = v__gen__c__c_name(node.val_var)}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(7, _MOV((StrIntpData[]){{_S("memcpy(*("), 0xfe10, {.d_s = val_styp}}, {_S("*)"), 0xfe10, {.d_s = v__gen__c__c_name(node.val_var)}}, {_S(", (byte*)DenseArray_value(&"), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("key_values, "), 0xfe10, {.d_s = idx}}, {_S("), sizeof("), 0xfe10, {.d_s = val_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { string val_styp = v__gen__c__Gen_styp(g, node.val_type); if (v__ast__Type_is_ptr(node.val_type)) { if (node.val_is_mut || node.val_is_ref) { { v__gen__c__Gen_write(g, val_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, v__gen__c__c_name(node.val_var)); v__gen__c__Gen_write(g, _S(" = &(*(")); v__gen__c__Gen_write(g, val_styp); v__gen__c__Gen_write(g, _S(")")); } } else { { v__gen__c__Gen_write(g, val_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, v__gen__c__c_name(node.val_var)); v__gen__c__Gen_write(g, _S(" = (*(")); v__gen__c__Gen_write(g, val_styp); v__gen__c__Gen_write(g, _S("*)")); } } } else { { v__gen__c__Gen_write(g, val_styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, v__gen__c__c_name(node.val_var)); v__gen__c__Gen_write(g, _S(" = (*(")); v__gen__c__Gen_write(g, val_styp); v__gen__c__Gen_write(g, _S("*)")); } } v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("DenseArray_value(&"), 0xfe10, {.d_s = cond_var}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("key_values, "), 0xfe10, {.d_s = idx}}, {_S("));"), 0, { .d_c = 0 }}}))); } } g->indent--; } else if (node.kind == v__ast__Kind__string) { v__ast__Expr cond = (((node.cond)._typ == 384 /* v.ast.StringLiteral */ || (node.cond)._typ == 383 /* v.ast.StringInterLiteral */) ? (v__ast__CTempVar_to_sumtype_v__ast__Expr(ADDR(v__ast__CTempVar, (v__gen__c__Gen_new_ctemp_var_then_gen(g, node.cond, _const_v__ast__string_type))))) : (node.cond)); string field_accessor = (v__ast__Type_is_ptr(node.cond_type) ? (_S("->")) : (_S("."))); string i = ((fast_string_eq(node.key_var, _S("")) || fast_string_eq(node.key_var, _S("_"))) ? (v__gen__c__Gen_new_tmp_var(g)) : (node.key_var)); { v__gen__c__Gen_write(g, _S("for (int ")); v__gen__c__Gen_write(g, i); v__gen__c__Gen_write(g, _S(" = 0; ")); v__gen__c__Gen_write(g, i); v__gen__c__Gen_write(g, _S(" < ")); } v__gen__c__Gen_expr(g, cond); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = field_accessor}}, {_S("len; ++"), 0xfe10, {.d_s = i}}, {_S(") {"), 0, { .d_c = 0 }}}))); if (!fast_string_eq(node.val_var, _S("_"))) { { v__gen__c__Gen_write(g, _S("\tu8 ")); v__gen__c__Gen_write(g, v__gen__c__c_name(node.val_var)); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, cond); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = field_accessor}}, {_S("str["), 0xfe10, {.d_s = i}}, {_S("];"), 0, { .d_c = 0 }}}))); } } else if (node.kind == v__ast__Kind__struct || node.kind == v__ast__Kind__interface) { v__ast__TypeSymbol* cond_type_sym = v__ast__Table_sym(g->table, node.cond_type); v__ast__Fn next_fn = ((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); if (cond_type_sym->kind == v__ast__Kind__alias) { _option_v__ast__Fn _t1 = v__ast__TypeSymbol_find_method_with_generic_parent(cond_type_sym, _S("next")); if (_t1.state != 0) { IError err = _t1.err; _option_v__ast__Fn _t2 = v__ast__TypeSymbol_find_method_with_generic_parent(v__ast__Table_final_sym(g->table, node.cond_type), _S("next")); if (_t2.state != 0) { IError err = _t2.err; v__gen__c__verror(_S("`next` method not found")); VUNREACHABLE(); // Defer begin if (v__gen__c__Gen_for_in_stmt_defer_1) { map_delete(&g->type_resolver.type_map, &(string[]){node.key_var}); } // Defer end // Defer begin if (v__gen__c__Gen_for_in_stmt_defer_0) { map_delete(&g->type_resolver.type_map, &(string[]){node.val_var}); } // Defer end return; } *(v__ast__Fn*) _t1.data = (*(v__ast__Fn*)_t2.data); } next_fn = (*(v__ast__Fn*)_t1.data); } else { _option_v__ast__Fn _t3 = v__ast__TypeSymbol_find_method_with_generic_parent(cond_type_sym, _S("next")); if (_t3.state != 0) { IError err = _t3.err; v__gen__c__verror(_S("`next` method not found")); VUNREACHABLE(); // Defer begin if (v__gen__c__Gen_for_in_stmt_defer_1) { map_delete(&g->type_resolver.type_map, &(string[]){node.key_var}); } // Defer end // Defer begin if (v__gen__c__Gen_for_in_stmt_defer_0) { map_delete(&g->type_resolver.type_map, &(string[]){node.val_var}); } // Defer end return; } next_fn = (*(v__ast__Fn*)_t3.data); } v__ast__Type ret_typ = next_fn.return_type; string t_expr = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, node.cond_type)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, t_expr); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, node.cond); v__gen__c__Gen_writeln(g, _S(";")); if (fast_string_eq(node.key_var, _S("")) || fast_string_eq(node.key_var, _S("_"))) { v__gen__c__Gen_writeln(g, _S("while (1) {")); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("for (size_t "), 0xfe10, {.d_s = node.key_var}}, {_S(" = 0;; ++"), 0xfe10, {.d_s = node.key_var}}, {_S(") {"), 0, { .d_c = 0 }}}))); } string t_var = v__gen__c__Gen_new_tmp_var(g); v__ast__Type receiver_typ = v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Param*)array_get(next_fn.params, 0)).typ); string receiver_styp = v__gen__c__Gen_cc_type(g, receiver_typ, false); string fn_name = string__plus(string_replace_each(receiver_styp, new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S("*"), _S(""), _S("."), _S("__")}))), _S("_next")); v__ast__TypeSymbol* receiver_sym = v__ast__Table_sym(g->table, receiver_typ); if ((receiver_sym->info)._typ == 518 /* v.ast.Struct */) { if ((*receiver_sym->info._v__ast__Struct).concrete_types.len > 0) { fn_name = v__gen__c__Gen_generic_fn_name(g, (*receiver_sym->info._v__ast__Struct).concrete_types, fn_name); } } else if ((receiver_sym->info)._typ == 542 /* v.ast.Interface */) { string left_cc_type = v__gen__c__Gen_cc_type(g, v__ast__Table_unaliased_type(g->table, node.cond_type), false); string left_type_name = v__util__no_dots(left_cc_type); fn_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(left_type_name)}}, {_S("_name_table["), 0xfe10, {.d_s = t_expr}}, {_S("._typ]._method_next"), 0, { .d_c = 0 }}})); } { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, ret_typ)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, t_var); v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_write(g, fn_name); v__gen__c__Gen_write(g, _S("(")); } if (!v__ast__Type_is_ptr(node.cond_type) && v__ast__Type_is_ptr(receiver_typ)) { v__gen__c__Gen_write(g, _S("&")); } if (node.kind == v__ast__Kind__interface) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = t_expr}}, {_S("._object);"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = t_expr}}, {_S(");"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = t_var}}, {_S(".state != 0) break;"), 0, { .d_c = 0 }}}))); string val = ((fast_string_eq(node.val_var, _S("")) || fast_string_eq(node.val_var, _S("_"))) ? (v__gen__c__Gen_new_tmp_var(g)) : (node.val_var)); string val_styp = v__gen__c__Gen_styp(g, v__ast__Type_clear_option_and_result(ret_typ)); bool ret_is_fixed_array = v__ast__TypeSymbol_is_array_fixed(v__ast__Table_sym(g->table, ret_typ)); if (node.val_is_mut) { if (v__ast__Type_has_flag(ret_typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = val_styp}}, {_S("* "), 0xfe10, {.d_s = val}}, {_S(" = ("), 0xfe10, {.d_s = val_styp}}, {_S("*)"), 0xfe10, {.d_s = t_var}}, {_S(".data;"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = val_styp}}, {_S(" "), 0xfe10, {.d_s = val}}, {_S(" = ("), 0xfe10, {.d_s = val_styp}}, {_S(")"), 0xfe10, {.d_s = t_var}}, {_S(".data;"), 0, { .d_c = 0 }}}))); } } else { if (ret_is_fixed_array) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = val_styp}}, {_S(" "), 0xfe10, {.d_s = val}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("\tmemcpy(")); v__gen__c__Gen_write(g, val); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, t_var); v__gen__c__Gen_write(g, _S(".data, sizeof(")); v__gen__c__Gen_write(g, val_styp); v__gen__c__Gen_write(g, _S("));")); } } else { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = val_styp}}, {_S(" "), 0xfe10, {.d_s = val}}, {_S(" = *("), 0xfe10, {.d_s = val_styp}}, {_S("*)"), 0xfe10, {.d_s = t_var}}, {_S(".data;"), 0, { .d_c = 0 }}}))); } } } else if (node.kind == v__ast__Kind__aggregate) { v__ast__Type for_type = (*(v__ast__Type*)array_get((({ v__ast__TypeInfo _t4 = v__ast__Table_sym(g->table, node.cond_type)->info; *(v__ast__Aggregate*)__as_cast(_t4._v__ast__Aggregate,_t4._typ, 537); })).types, g->aggregate_type_idx)); v__ast__Type val_type = v__ast__Table_value_type(g->table, for_type); v__ast__Scope_update_var_type(node.scope, node.val_var, val_type); v__gen__c__Gen_for_in_stmt(g, ((v__ast__ForInStmt){ .key_var = (string){.str=(byteptr)"", .is_lit=1}, .val_var = node.val_var, .is_range = 0, .pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .kv_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .vv_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .comments = __new_array(0, 0, sizeof(v__ast__Comment)), .val_is_mut = node.val_is_mut, .val_is_ref = node.val_is_ref, .cond = node.cond, .key_type = 0, .val_type = val_type, .cond_type = for_type, .high = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335}, .high_type = 0, .kind = v__ast__Table_sym(g->table, for_type)->kind, .label = (string){.str=(byteptr)"", .is_lit=1}, .scope = ((void*)0), .stmts = node.stmts, })); g->loop_depth--; // Defer begin if (v__gen__c__Gen_for_in_stmt_defer_1) { map_delete(&g->type_resolver.type_map, &(string[]){node.key_var}); } // Defer end // Defer begin if (v__gen__c__Gen_for_in_stmt_defer_0) { map_delete(&g->type_resolver.type_map, &(string[]){node.val_var}); } // Defer end return; } else { string typ_str = v__ast__Table_type_to_str(g->table, node.cond_type); v__gen__c__Gen_error(g, str_intp(3, _MOV((StrIntpData[]){{_S("for in: unhandled symbol `"), 0xfe10, {.d_s = v__ast__Expr_str(&node.cond)}}, {_S("` of type `"), 0xfe10, {.d_s = typ_str}}, {_S("`"), 0, { .d_c = 0 }}})), node.pos); VUNREACHABLE(); } v__gen__c__Gen_stmts(g, node.stmts); if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.label}}, {_S("__continue: {}"), 0, { .d_c = 0 }}}))); } if (node.kind == v__ast__Kind__map) { } v__gen__c__Gen_writeln(g, _S("}")); if (node.label.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = node.label}}, {_S("__break: {}"), 0, { .d_c = 0 }}}))); } g->loop_depth--; // Defer begin if (v__gen__c__Gen_for_in_stmt_defer_1) { map_delete(&g->type_resolver.type_map, &(string[]){node.key_var}); } // Defer end // Defer begin if (v__gen__c__Gen_for_in_stmt_defer_0) { map_delete(&g->type_resolver.type_map, &(string[]){node.val_var}); } // Defer end } VV_LOC bool v__gen__c__Gen_need_tmp_var_in_if(v__gen__c__Gen* g, v__ast__IfExpr node) { if (node.is_expr && (g->inside_ternary == 0 || g->is_assign_lhs)) { if (g->is_autofree || v__ast__Type_has_option_or_result(node.typ) || node.is_comptime || g->is_assign_lhs) { return true; } for (int _t2 = 0; _t2 < node.branches.len; ++_t2) { v__ast__IfBranch branch = ((v__ast__IfBranch*)node.branches.data)[_t2]; if (branch.stmts.len > 1) { return true; } if (v__gen__c__Gen_need_tmp_var_in_expr(g, branch.cond)) { return true; } if (branch.stmts.len == 1) { if (((*(v__ast__Stmt*)array_get(branch.stmts, 0)))._typ == 401 /* v.ast.ExprStmt */) { v__ast__ExprStmt stmt = *(v__ast__ExprStmt*)__as_cast(((*(v__ast__Stmt*)array_get(branch.stmts, 0)))._v__ast__ExprStmt,((*(v__ast__Stmt*)array_get(branch.stmts, 0)))._typ, 401); if ((stmt.expr)._typ == 338 /* v.ast.ArrayInit */ && (*(v__ast__ArrayInit*)__as_cast((stmt.expr)._v__ast__ArrayInit,(stmt.expr)._typ, 338)).is_fixed) { return true; } if (v__gen__c__Gen_need_tmp_var_in_expr(g, stmt.expr)) { return true; } } else if (((*(v__ast__Stmt*)array_get(branch.stmts, 0)))._typ == 412 /* v.ast.Return */) { return true; } else if (((*(v__ast__Stmt*)array_get(branch.stmts, 0)))._typ == 394 /* v.ast.BranchStmt */) { return true; } } } } return false; } VV_LOC bool v__gen__c__Gen_need_tmp_var_in_expr(v__gen__c__Gen* g, v__ast__Expr expr) { if (v__gen__c__is_noreturn_callexpr(expr)) { return true; } if (expr._typ == 338 /* v.ast.ArrayInit */) { if (v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__ArrayInit).len_expr)) { return true; } if (v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__ArrayInit).cap_expr)) { return true; } if (v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__ArrayInit).init_expr)) { return true; } for (int _t5 = 0; _t5 < (*expr._v__ast__ArrayInit).exprs.len; ++_t5) { v__ast__Expr elem_expr = ((v__ast__Expr*)(*expr._v__ast__ArrayInit).exprs.data)[_t5]; if (v__gen__c__Gen_need_tmp_var_in_expr(g, elem_expr)) { return true; } } } else if (expr._typ == 344 /* v.ast.CallExpr */) { if ((*expr._v__ast__CallExpr).is_method) { v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, (*expr._v__ast__CallExpr).receiver_type); if (left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed || left_sym->kind == v__ast__Kind__map) { return true; } } if ((*expr._v__ast__CallExpr).or_block.kind != v__ast__OrKind__absent) { return true; } if (v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__CallExpr).left)) { return true; } for (int _t10 = 0; _t10 < (*expr._v__ast__CallExpr).args.len; ++_t10) { v__ast__CallArg arg = ((v__ast__CallArg*)(*expr._v__ast__CallExpr).args.data)[_t10]; if (v__gen__c__Gen_need_tmp_var_in_expr(g, arg.expr)) { return true; } } bool _t13 = false; Array_v__ast__Type _t13_orig = (*expr._v__ast__CallExpr).expected_arg_types; int _t13_len = _t13_orig.len; for (int _t14 = 0; _t14 < _t13_len; ++_t14) { v__ast__Type it = ((v__ast__Type*) _t13_orig.data)[_t14]; if (v__ast__Type_has_flag(it, v__ast__TypeFlag__option)) { _t13 = true; break; } } return _t13; } else if (expr._typ == 345 /* v.ast.CastExpr */) { return v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__CastExpr).expr); } else if (expr._typ == 352 /* v.ast.ConcatExpr */) { for (int _t16 = 0; _t16 < (*expr._v__ast__ConcatExpr).vals.len; ++_t16) { v__ast__Expr val = ((v__ast__Expr*)(*expr._v__ast__ConcatExpr).vals.data)[_t16]; if ((val)._typ == 344 /* v.ast.CallExpr */) { if (v__ast__Type_has_option_or_result((*val._v__ast__CallExpr).return_type)) { return true; } } } } else if (expr._typ == 358 /* v.ast.Ident */) { return (*expr._v__ast__Ident).or_expr.kind != v__ast__OrKind__absent; } else if (expr._typ == 359 /* v.ast.IfExpr */) { if (v__gen__c__Gen_need_tmp_var_in_if(g, (*expr._v__ast__IfExpr))) { return true; } } else if (expr._typ == 360 /* v.ast.IfGuardExpr */) { return true; } else if (expr._typ == 361 /* v.ast.IndexExpr */) { if ((*expr._v__ast__IndexExpr).or_expr.kind != v__ast__OrKind__absent) { return true; } if (v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__IndexExpr).index)) { return true; } } else if (expr._typ == 362 /* v.ast.InfixExpr */) { if (v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__InfixExpr).left)) { return true; } if (v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__InfixExpr).right)) { return true; } } else if (expr._typ == 368 /* v.ast.MapInit */) { for (int _t25 = 0; _t25 < (*expr._v__ast__MapInit).keys.len; ++_t25) { v__ast__Expr key = ((v__ast__Expr*)(*expr._v__ast__MapInit).keys.data)[_t25]; if (v__gen__c__Gen_need_tmp_var_in_expr(g, key)) { return true; } } for (int _t27 = 0; _t27 < (*expr._v__ast__MapInit).vals.len; ++_t27) { v__ast__Expr val = ((v__ast__Expr*)(*expr._v__ast__MapInit).vals.data)[_t27]; if (v__gen__c__Gen_need_tmp_var_in_expr(g, val)) { return true; } } } else if (expr._typ == 369 /* v.ast.MatchExpr */) { return true; } else if (expr._typ == 374 /* v.ast.ParExpr */) { return v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__ParExpr).expr); } else if (expr._typ == 376 /* v.ast.PrefixExpr */) { return v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__PrefixExpr).right); } else if (expr._typ == 379 /* v.ast.SelectorExpr */) { if (v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__SelectorExpr).expr)) { return true; } return (*expr._v__ast__SelectorExpr).or_block.kind != v__ast__OrKind__absent; } else if (expr._typ == 383 /* v.ast.StringInterLiteral */) { for (int _t34 = 0; _t34 < (*expr._v__ast__StringInterLiteral).exprs.len; ++_t34) { v__ast__Expr e = ((v__ast__Expr*)(*expr._v__ast__StringInterLiteral).exprs.data)[_t34]; if (v__gen__c__Gen_need_tmp_var_in_expr(g, e)) { return true; } } } else if (expr._typ == 385 /* v.ast.StructInit */) { if (v__gen__c__Gen_need_tmp_var_in_expr(g, (*expr._v__ast__StructInit).update_expr)) { return true; } for (int _t37 = 0; _t37 < (*expr._v__ast__StructInit).init_fields.len; ++_t37) { v__ast__StructInitField init_field = ((v__ast__StructInitField*)(*expr._v__ast__StructInit).init_fields.data)[_t37]; if (v__gen__c__Gen_need_tmp_var_in_expr(g, init_field.expr)) { return true; } } v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, (*expr._v__ast__StructInit).typ); return (sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518)).has_option; } else { } return false; } VV_LOC bool v__gen__c__Gen_needs_conds_order(v__gen__c__Gen* g, v__ast__IfExpr node) { if (node.branches.len > 1) { for (int _t1 = 0; _t1 < node.branches.len; ++_t1) { v__ast__IfBranch branch = ((v__ast__IfBranch*)node.branches.data)[_t1]; if (v__gen__c__Gen_need_tmp_var_in_expr(g, branch.cond)) { return true; } } } return false; } VV_LOC void v__gen__c__Gen_if_expr(v__gen__c__Gen* g, v__ast__IfExpr node) { bool v__gen__c__Gen_if_expr_defer_0 = false; v__ast__Type tmp_if_option_type; bool v__gen__c__Gen_if_expr_defer_1 = false; bool raw_state; bool v__gen__c__Gen_if_expr_defer_2 = false; bool v__gen__c__Gen_if_expr_defer_3 = false; bool needs_tmp_var = g->inside_if_option || v__gen__c__Gen_need_tmp_var_in_if(g, node); bool needs_conds_order = v__gen__c__Gen_needs_conds_order(g, node); string tmp = (g->inside_if_option || (node.typ != _const_v__ast__void_type && needs_tmp_var) ? (v__gen__c__Gen_new_tmp_var(g)) : (_S(""))); string cur_line = _S(""); raw_state = false; tmp_if_option_type = g->last_if_option_type; if (needs_tmp_var) { string styp = v__gen__c__Gen_styp(g, node.typ); if (g->inside_if_option || v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__option)) { raw_state = g->inside_if_option; if (node.typ != _const_v__ast__void_type) { g->last_if_option_type = node.typ; v__gen__c__Gen_if_expr_defer_0 = true; } v__gen__c__Gen_if_expr_defer_1 = true; g->inside_if_option = true; styp = string_replace(styp, _S("*"), _S("_ptr")); } else if (v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__result)) { raw_state = g->inside_if_result; v__gen__c__Gen_if_expr_defer_2 = true; g->inside_if_result = true; styp = string_replace(styp, _S("*"), _S("_ptr")); } else { g->last_if_option_type = node.typ; v__gen__c__Gen_if_expr_defer_3 = true; } cur_line = v__gen__c__Gen_go_before_last_stmt(g); g->empty_line = true; if ((tmp).len != 0) { if (node.typ == _const_v__ast__void_type && g->last_if_option_type != 0) { v__gen__c__Gen_write2(g, v__gen__c__Gen_styp(g, g->last_if_option_type), _S(" ")); } else { { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); } } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp}}, {_S("; /* if prepend */"), 0, { .d_c = 0 }}}))); } if (g->infix_left_var_name.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = g->infix_left_var_name}}, {_S(") {"), 0, { .d_c = 0 }}}))); g->indent++; } } else if (node.is_expr || g->inside_ternary != 0) { g->inside_ternary++; v__gen__c__Gen_write(g, _S("(")); for (int i = 0; i < node.branches.len; ++i) { v__ast__IfBranch branch = ((v__ast__IfBranch*)node.branches.data)[i]; if (i > 0) { v__gen__c__Gen_write(g, _S(" : ")); } if (i < (int)(node.branches.len - 1) || !node.has_else) { v__gen__c__Gen_expr(g, branch.cond); v__gen__c__Gen_write(g, _S(" ? ")); } v__ast__Type prev_expected_cast_type = g->expected_cast_type; if (node.is_expr && (v__ast__Table_sym(g->table, node.typ)->kind == v__ast__Kind__sum_type || v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__shared_f))) { g->expected_cast_type = node.typ; } v__gen__c__Gen_stmts(g, branch.stmts); g->expected_cast_type = prev_expected_cast_type; } if (node.branches.len == 1 && !node.is_expr) { v__gen__c__Gen_write(g, _S(": 0")); } v__gen__c__Gen_write(g, _S(")")); v__gen__c__Gen_decrement_inside_ternary(g); // Defer begin if (v__gen__c__Gen_if_expr_defer_3) { g->last_if_option_type = tmp_if_option_type; } // Defer end // Defer begin if (v__gen__c__Gen_if_expr_defer_2) { g->inside_if_result = raw_state; } // Defer end // Defer begin if (v__gen__c__Gen_if_expr_defer_1) { g->inside_if_option = raw_state; } // Defer end // Defer begin if (v__gen__c__Gen_if_expr_defer_0) { g->last_if_option_type = tmp_if_option_type; } // Defer end return; } bool is_guard = false; int guard_idx = 0; Array_string guard_vars = __new_array_with_default(0, 0, sizeof(string), 0); for (int i = 0; i < node.branches.len; ++i) { v__ast__IfBranch branch = ((v__ast__IfBranch*)node.branches.data)[i]; v__ast__Expr cond = branch.cond; if ((cond)._typ == 360 /* v.ast.IfGuardExpr */) { if (!is_guard) { is_guard = true; guard_vars = __new_array_with_default(node.branches.len, 0, sizeof(string), &(string[]){_S("")}); } guard_idx = i; if (!(((*cond._v__ast__IfGuardExpr).expr)._typ == 361 /* v.ast.IndexExpr */ || ((*cond._v__ast__IfGuardExpr).expr)._typ == 376 /* v.ast.PrefixExpr */)) { string var_name = v__gen__c__Gen_new_tmp_var(g); array_set(&guard_vars, i, &(string[]) { var_name }); v__ast__Type cond_expr_type = (((*cond._v__ast__IfGuardExpr).expr)._typ == 344 /* v.ast.CallExpr */ && (*(v__ast__CallExpr*)__as_cast(((*cond._v__ast__IfGuardExpr).expr)._v__ast__CallExpr,((*cond._v__ast__IfGuardExpr).expr)._typ, 344)).is_static_method && v__ast__Type_has_flag((*(v__ast__CallExpr*)__as_cast(((*cond._v__ast__IfGuardExpr).expr)._v__ast__CallExpr,((*cond._v__ast__IfGuardExpr).expr)._typ, 344)).left_type, v__ast__TypeFlag__generic) ? (v__gen__c__Gen_resolve_return_type(g, (*(*cond._v__ast__IfGuardExpr).expr._v__ast__CallExpr))) : ((*cond._v__ast__IfGuardExpr).expr_type)); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, v__gen__c__Gen_unwrap_generic(g, cond_expr_type))}}, {_S(" "), 0xfe10, {.d_s = var_name}}, {_S(";"), 0, { .d_c = 0 }}}))); } else if (((*cond._v__ast__IfGuardExpr).expr)._typ == 361 /* v.ast.IndexExpr */) { v__ast__Type value_type = v__ast__Table_value_type(g->table, v__gen__c__Gen_unwrap_generic(g, (*(*cond._v__ast__IfGuardExpr).expr._v__ast__IndexExpr).left_type)); if (v__ast__Type_has_flag(value_type, v__ast__TypeFlag__option)) { string var_name = v__gen__c__Gen_new_tmp_var(g); array_set(&guard_vars, i, &(string[]) { var_name }); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, value_type)}}, {_S(" "), 0xfe10, {.d_s = var_name}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { array_set(&guard_vars, i, &(string[]) { _S("") }); } } else { array_set(&guard_vars, i, &(string[]) { _S("") }); } } } Array_string branch_cond_var_names = __new_array_with_default(0, 0, sizeof(string), 0); for (int i = 0; i < node.branches.len; ++i) { v__ast__IfBranch branch = ((v__ast__IfBranch*)node.branches.data)[i]; if (i > 0) { v__gen__c__Gen_write(g, _S("} else ")); } if (i == (int)(node.branches.len - 1) && node.has_else) { v__gen__c__Gen_writeln(g, _S("{")); if (is_guard && guard_idx == (int)(i - 1)) { string cvar_name = (*(string*)array_get(guard_vars, guard_idx)); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tIError err = "), 0xfe10, {.d_s = cvar_name}}, {_S(".err;"), 0, { .d_c = 0 }}}))); } } else if ((branch.cond)._typ == 360 /* v.ast.IfGuardExpr */) { string var_name = (*(string*)array_get(guard_vars, i)); bool short_opt = false; g->left_is_opt = true; if ((var_name).len == 0) { short_opt = true; var_name = v__gen__c__Gen_new_tmp_var(g); array_set(&guard_vars, i, &(string[]) { var_name }); g->tmp_count--; if (v__ast__Type_has_flag((*branch.cond._v__ast__IfGuardExpr).expr_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = var_name}}, {_S(".state == 0) {"), 0, { .d_c = 0 }}}))); } else if (v__ast__Type_has_flag((*branch.cond._v__ast__IfGuardExpr).expr_type, v__ast__TypeFlag__result)) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if (!"), 0xfe10, {.d_s = var_name}}, {_S(".is_error) {"), 0, { .d_c = 0 }}}))); } } else { { v__gen__c__Gen_write(g, _S("if (")); v__gen__c__Gen_write(g, var_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, (*branch.cond._v__ast__IfGuardExpr).expr); if (v__ast__Type_has_flag((*branch.cond._v__ast__IfGuardExpr).expr_type, v__ast__TypeFlag__option)) { string dot_or_ptr = (!v__ast__Type_has_flag((*branch.cond._v__ast__IfGuardExpr).expr_type, v__ast__TypeFlag__option_mut_param_t) ? (_S(".")) : (_S("-> "))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(", "), 0xfe10, {.d_s = var_name}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("state == 0) {"), 0, { .d_c = 0 }}}))); } else if (v__ast__Type_has_flag((*branch.cond._v__ast__IfGuardExpr).expr_type, v__ast__TypeFlag__result)) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", !"), 0xfe10, {.d_s = var_name}}, {_S(".is_error) {"), 0, { .d_c = 0 }}}))); } } if (short_opt || (*branch.cond._v__ast__IfGuardExpr).vars.len > 1 || !fast_string_eq((*(v__ast__IfGuardVar*)array_get((*branch.cond._v__ast__IfGuardExpr).vars, 0)).name, _S("_"))) { string base_type = v__gen__c__Gen_base_type(g, (*branch.cond._v__ast__IfGuardExpr).expr_type); if (short_opt) { string cond_var_name = (fast_string_eq((*(v__ast__IfGuardVar*)array_get((*branch.cond._v__ast__IfGuardExpr).vars, 0)).name, _S("_")) ? (str_intp(2, _MOV((StrIntpData[]){{_S("_dummy_"), 0xfe07, {.d_i32 = (int)(g->tmp_count + 1)}}, {_SLIT0, 0, { .d_c = 0 }}}))) : ((*(v__ast__IfGuardVar*)array_get((*branch.cond._v__ast__IfGuardExpr).vars, 0)).name)); if (v__ast__Table_sym(g->table, (*branch.cond._v__ast__IfGuardExpr).expr_type)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = base_type}}, {_S(" "), 0xfe10, {.d_s = cond_var_name}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); { v__gen__c__Gen_write(g, _S("\tmemcpy((")); v__gen__c__Gen_write(g, base_type); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, cond_var_name); v__gen__c__Gen_write(g, _S(", &")); } v__gen__c__Gen_expr(g, (*branch.cond._v__ast__IfGuardExpr).expr); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", sizeof("), 0xfe10, {.d_s = base_type}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, base_type); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, cond_var_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, (*branch.cond._v__ast__IfGuardExpr).expr); v__gen__c__Gen_writeln(g, _S(";")); } } else { bool is_auto_heap = false; if (branch.stmts.len > 0) { v__ast__Scope* scope = v__ast__Scope_innermost(g->file->scope, v__ast__Node_pos(v__ast__Stmt_to_sumtype_v__ast__Node(ADDR(v__ast__Stmt, ((*(v__ast__Stmt*)array_last(branch.stmts)))))).pos); _option_v__ast__Var_ptr _t1; if (_t1 = v__ast__Scope_find_var(scope, (*(v__ast__IfGuardVar*)array_get((*branch.cond._v__ast__IfGuardExpr).vars, 0)).name), _t1.state == 0) { v__ast__Var* v = *(v__ast__Var**)_t1.data; is_auto_heap = v->is_auto_heap; } } if ((*branch.cond._v__ast__IfGuardExpr).vars.len == 1) { string left_var_name = v__gen__c__c_name((*(v__ast__IfGuardVar*)array_get((*branch.cond._v__ast__IfGuardExpr).vars, 0)).name); if (is_auto_heap) { v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = base_type}}, {_S("* "), 0xfe10, {.d_s = left_var_name}}, {_S(" = HEAP("), 0xfe10, {.d_s = base_type}}, {_S(", *("), 0xfe10, {.d_s = base_type}}, {_S("*)"), 0xfe10, {.d_s = var_name}}, {_S(".data);"), 0, { .d_c = 0 }}}))); } else if (string_starts_with(base_type, _S("Array_fixed"))) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = base_type}}, {_S(" "), 0xfe10, {.d_s = left_var_name}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("memcpy("), 0xfe10, {.d_s = left_var_name}}, {_S(", ("), 0xfe10, {.d_s = base_type}}, {_S("*)"), 0xfe10, {.d_s = var_name}}, {_S(".data, sizeof("), 0xfe10, {.d_s = base_type}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { string dot_or_ptr = (!v__ast__Type_has_flag((*branch.cond._v__ast__IfGuardExpr).expr_type, v__ast__TypeFlag__option_mut_param_t) ? (_S(".")) : (_S("-> "))); v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = base_type}}, {_S(" "), 0xfe10, {.d_s = left_var_name}}, {_S(" = *("), 0xfe10, {.d_s = base_type}}, {_S("*)"), 0xfe10, {.d_s = var_name}}, {_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("data;"), 0, { .d_c = 0 }}}))); } } else if ((*branch.cond._v__ast__IfGuardExpr).vars.len > 1) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, (*branch.cond._v__ast__IfGuardExpr).expr_type); if ((sym->info)._typ == 552 /* v.ast.MultiReturn */) { if ((*sym->info._v__ast__MultiReturn).types.len == (*branch.cond._v__ast__IfGuardExpr).vars.len) { for (int vi = 0; vi < (*branch.cond._v__ast__IfGuardExpr).vars.len; ++vi) { v__ast__IfGuardVar var = ((v__ast__IfGuardVar*)(*branch.cond._v__ast__IfGuardExpr).vars.data)[vi]; if (fast_string_eq(var.name, _S("_"))) { continue; } string var_typ = v__gen__c__Gen_styp(g, (*(v__ast__Type*)array_get((*sym->info._v__ast__MultiReturn).types, vi))); string left_var_name = v__gen__c__c_name(var.name); if (is_auto_heap) { v__gen__c__Gen_writeln(g, str_intp(7, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = var_typ}}, {_S("* "), 0xfe10, {.d_s = left_var_name}}, {_S(" = (HEAP("), 0xfe10, {.d_s = base_type}}, {_S(", *("), 0xfe10, {.d_s = base_type}}, {_S("*)"), 0xfe10, {.d_s = var_name}}, {_S(".data).arg"), 0xfe07, {.d_i32 = vi}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = var_typ}}, {_S(" "), 0xfe10, {.d_s = left_var_name}}, {_S(" = (*("), 0xfe10, {.d_s = base_type}}, {_S("*)"), 0xfe10, {.d_s = var_name}}, {_S(".data).arg"), 0xfe07, {.d_i32 = vi}}, {_S(";"), 0, { .d_c = 0 }}}))); } } } } } } } } else { if (i == 0 && node.branches.len > 1 && !needs_tmp_var && needs_conds_order) { string cond_var_name = v__gen__c__Gen_new_tmp_var(g); string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; { v__gen__c__Gen_write(g, _S("bool ")); v__gen__c__Gen_write(g, cond_var_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, branch.cond); v__gen__c__Gen_writeln(g, _S(";")); array_push((array*)&branch_cond_var_names, _MOV((string[]){ string_clone(cond_var_name) })); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); v__gen__c__Gen_writeln2(g, line, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = cond_var_name}}, {_S(") {"), 0, { .d_c = 0 }}}))); } else if (i > 0 && branch_cond_var_names.len > 0 && !needs_tmp_var && needs_conds_order) { string cond_var_name = v__gen__c__Gen_new_tmp_var(g); string line = v__gen__c__Gen_go_before_last_stmt(g); g->empty_line = true; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("bool "), 0xfe10, {.d_s = cond_var_name}}, {_S(";"), 0, { .d_c = 0 }}}))); string branch_cond = Array_string_join(branch_cond_var_names, _S(" || ")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if (!("), 0xfe10, {.d_s = branch_cond}}, {_S(")) {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); g->indent++; { v__gen__c__Gen_write(g, cond_var_name); v__gen__c__Gen_write(g, _S(" = ")); } bool prev_is_autofree = g->is_autofree; g->is_autofree = false; v__gen__c__Gen_expr(g, branch.cond); g->is_autofree = prev_is_autofree; v__gen__c__Gen_writeln(g, _S(";")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); array_push((array*)&branch_cond_var_names, _MOV((string[]){ string_clone(cond_var_name) })); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); v__gen__c__Gen_write(g, line); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = cond_var_name}}, {_S(") {"), 0, { .d_c = 0 }}}))); } else { bool no_needs_par = false; if ((branch.cond)._typ == 362 /* v.ast.InfixExpr */) { if ((*branch.cond._v__ast__InfixExpr).op == v__token__Kind__key_in && ((*branch.cond._v__ast__InfixExpr).left)._typ != 362 /* v.ast.InfixExpr */ && ((*branch.cond._v__ast__InfixExpr).right)._typ == 338 /* v.ast.ArrayInit */) { no_needs_par = true; } } bool inside_interface_deref_old = g->inside_interface_deref; if (!g->inside_interface_deref && (branch.cond)._typ == 358 /* v.ast.Ident */ && v__ast__Table_is_interface_var(g->table, (*(v__ast__Ident*)__as_cast((branch.cond)._v__ast__Ident,(branch.cond)._typ, 358)).obj)) { g->inside_interface_deref = true; } if (no_needs_par) { v__gen__c__Gen_write(g, _S("if ")); } else { v__gen__c__Gen_write(g, _S("if (")); } v__gen__c__Gen_expr(g, branch.cond); if (no_needs_par) { v__gen__c__Gen_writeln(g, _S(" {")); } else { v__gen__c__Gen_writeln(g, _S(") {")); } g->inside_interface_deref = inside_interface_deref_old; } } if (needs_tmp_var) { v__ast__Type prev_expected_cast_type = g->expected_cast_type; if (node.is_expr && (v__ast__Table_sym(g->table, node.typ)->kind == v__ast__Kind__sum_type || v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__shared_f))) { g->expected_cast_type = node.typ; } v__gen__c__Gen_stmts_with_tmp_var(g, branch.stmts, tmp); g->expected_cast_type = prev_expected_cast_type; } else { int stmt_pos = v__gen__c__Gen_nth_stmt_pos(g, 0); v__gen__c__Gen_stmts(g, branch.stmts); array_push((array*)&g->stmt_path_pos, _MOV((int[]){ stmt_pos })); } } if (node.branches.len > 0) { v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } if (needs_tmp_var) { if (g->infix_left_var_name.len > 0) { g->indent--; v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } g->empty_line = false; { v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, tmp); } } // Defer begin if (v__gen__c__Gen_if_expr_defer_3) { g->last_if_option_type = tmp_if_option_type; } // Defer end // Defer begin if (v__gen__c__Gen_if_expr_defer_2) { g->inside_if_result = raw_state; } // Defer end // Defer begin if (v__gen__c__Gen_if_expr_defer_1) { g->inside_if_option = raw_state; } // Defer end // Defer begin if (v__gen__c__Gen_if_expr_defer_0) { g->last_if_option_type = tmp_if_option_type; } // Defer end } VV_LOC void v__gen__c__Gen_index_expr(v__gen__c__Gen* g, v__ast__IndexExpr node) { if ((node.index)._typ == 377 /* v.ast.RangeExpr */) { v__gen__c__Gen_index_range_expr(g, node, (*node.index._v__ast__RangeExpr)); } else { v__ast__Type left_type = v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, node.left, node.left_type)); v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, left_type); bool _t1 = sym->kind == v__ast__Kind__array; bool _t2; if (!(_t1)) { _t2 = sym->kind == v__ast__Kind__array_fixed; } bool _t3; if (!(_t1 || _t2)) { _t3 = sym->kind == v__ast__Kind__map; } bool _t4; if (!(_t1 || _t2 || _t3)) { _t4 = sym->kind == v__ast__Kind__string && !v__ast__Type_is_ptr(node.left_type); } bool _t5; if (!(_t1 || _t2 || _t3 || _t4)) { bool _t6 = ((sym->info)._typ == 537 /* v.ast.Aggregate */); bool _t7 = true; if (_t6) { Array_v__ast__Type _t7_orig = (*(v__ast__Aggregate*)__as_cast((sym->info)._v__ast__Aggregate,(sym->info)._typ, 537)).types; int _t7_len = _t7_orig.len; for (int _t8 = 0; _t8 < _t7_len; ++_t8) { v__ast__Type it = ((v__ast__Type*) _t7_orig.data)[_t8]; if (!((Array_v__ast__Kind_contains(new_array_from_c_array(4, 4, sizeof(v__ast__Kind), _MOV((v__ast__Kind[4]){v__ast__Kind__array, v__ast__Kind__array_fixed, v__ast__Kind__string, v__ast__Kind__map})), v__ast__Table_type_kind(g->table, it))))) { _t7 = false; break; } } } _t5 = _t6 &&_t7; } if (_t1) { v__gen__c__Gen_index_of_array(g, node, *sym); } else if (_t2) { v__gen__c__Gen_index_of_fixed_array(g, node, *sym); } else if (_t3) { v__gen__c__Gen_index_of_map(g, node, *sym); } else if (_t4) { bool gen_or = node.or_expr.kind != v__ast__OrKind__absent || node.is_option; if (gen_or) { string tmp_opt = v__gen__c__Gen_new_tmp_var(g); string cur_line = v__gen__c__Gen_go_before_last_stmt(g); strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); string opt_elem_type = v__gen__c__Gen_styp(g, v__ast__Type_set_flag(_const_v__ast__u8_type, v__ast__TypeFlag__option)); { v__gen__c__Gen_write(g, opt_elem_type); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(" = string_at_with_check(")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, node.index); v__gen__c__Gen_writeln(g, _S(");")); if (!node.is_option) { v__gen__c__Gen_or_block(g, tmp_opt, node.or_expr, _const_v__ast__u8_type); } { v__gen__c__Gen_write(g, _S("\n")); v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S("*(byte*)&")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(".data")); } } else { bool is_direct_array_access = g->is_direct_array_access || node.is_direct; if (is_direct_array_access) { v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(".str[ ")); v__gen__c__Gen_expr(g, node.index); v__gen__c__Gen_write(g, _S("]")); } else { v__gen__c__Gen_write(g, _S("string_at(")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, node.index); v__gen__c__Gen_write(g, _S(")")); } } } else if (_t5) { v__ast__Type unwrapped_got_type = (*(v__ast__Type*)array_get((*sym->info._v__ast__Aggregate).types, g->aggregate_type_idx)); v__gen__c__Gen_index_expr(g, ((v__ast__IndexExpr){.pos = (node).pos,.index = (node).index,.or_expr = (node).or_expr,.left = (node).left,.left_type = unwrapped_got_type,.is_setter = (node).is_setter,.is_map = (node).is_map,.is_array = (node).is_array,.is_farray = (node).is_farray,.is_option = (node).is_option,.is_direct = (node).is_direct,.is_gated = (node).is_gated,.typ = (node).typ,})); } else { v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S("[")); v__gen__c__Gen_expr(g, node.index); v__gen__c__Gen_write(g, _S("]")); } } } VV_LOC void v__gen__c__Gen_index_range_expr(v__gen__c__Gen* g, v__ast__IndexExpr node, v__ast__RangeExpr range) { v__ast__Type unwrapped_left_type = v__gen__c__Gen_unwrap_generic(g, node.left_type); v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, unwrapped_left_type); string tmp_opt = _S(""); string cur_line = _S(""); bool gen_or = node.or_expr.kind != v__ast__OrKind__absent || node.is_option; bool left_is_shared = v__ast__Type_has_flag(unwrapped_left_type, v__ast__TypeFlag__shared_f); if (sym->kind == v__ast__Kind__string) { if (node.is_gated) { v__gen__c__Gen_write(g, _S("string_substr_ni(")); } else { if (gen_or) { tmp_opt = v__gen__c__Gen_new_tmp_var(g); cur_line = v__gen__c__Gen_go_before_last_stmt(g); strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); string opt_elem_type = v__gen__c__Gen_styp(g, v__ast__Type_set_flag(_const_v__ast__string_type, v__ast__TypeFlag__result)); { v__gen__c__Gen_write(g, opt_elem_type); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(" = string_substr_with_check(")); } } else { v__gen__c__Gen_write(g, _S("string_substr(")); } } if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, node.left); } else if (sym->kind == v__ast__Kind__array) { if (node.is_gated) { v__gen__c__Gen_write(g, _S("array_slice_ni(")); } else { v__gen__c__Gen_write(g, _S("array_slice(")); } if (left_is_shared) { v__gen__c__Gen_write(g, _S("(")); } if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, node.left); if (left_is_shared) { v__gen__c__Gen_write(g, _S(").val")); } } else if ((sym->info)._typ == 549 /* v.ast.ArrayFixed */) { string noscan = v__gen__c__Gen_check_noscan(g, (*sym->info._v__ast__ArrayFixed).elem_type); if (node.is_gated) { v__gen__c__Gen_write(g, _S("array_slice_ni(")); } else { v__gen__c__Gen_write(g, _S("array_slice(")); } { v__gen__c__Gen_write(g, _S("new_array_from_c_array")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); } string ctype = v__gen__c__Gen_styp(g, (*sym->info._v__ast__ArrayFixed).elem_type); { v__gen__c__Gen_write_decimal(g, (*sym->info._v__ast__ArrayFixed).size); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, (*sym->info._v__ast__ArrayFixed).size); v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, ctype); v__gen__c__Gen_write(g, _S("), ")); } if (left_is_shared) { v__gen__c__Gen_write(g, _S("(")); } if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, _S("*")); } if ((node.left)._typ == 338 /* v.ast.ArrayInit */) { string var = v__gen__c__Gen_new_tmp_var(g); string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); string styp = v__gen__c__Gen_styp(g, node.left_type); g->empty_line = true; { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write2(g, line, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = var}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_expr(g, node.left); } if (left_is_shared) { v__gen__c__Gen_write(g, _S(").val")); } v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_expr(g, node.left); } v__gen__c__Gen_write(g, _S(", ")); if (range.has_low) { v__gen__c__Gen_expr(g, range.low); } else { v__gen__c__Gen_write(g, _S("0")); } v__gen__c__Gen_write(g, _S(", ")); if (range.has_high) { v__gen__c__Gen_expr(g, range.high); } else if ((sym->info)._typ == 549 /* v.ast.ArrayFixed */) { { v__gen__c__Gen_write_decimal(g, (*sym->info._v__ast__ArrayFixed).size); } } else { v__gen__c__Gen_write(g, _S("2147483647")); } v__gen__c__Gen_write(g, _S(")")); if (gen_or) { if (!node.is_option) { v__gen__c__Gen_or_block(g, tmp_opt, node.or_expr, v__ast__Type_set_flag(_const_v__ast__string_type, v__ast__TypeFlag__result)); } { v__gen__c__Gen_write(g, _S("\n")); v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S("*(string*)&")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(".data")); } } } VV_LOC void v__gen__c__Gen_index_of_array(v__gen__c__Gen* g, v__ast__IndexExpr node, v__ast__TypeSymbol sym) { bool gen_or = node.or_expr.kind != v__ast__OrKind__absent || node.is_option; bool left_is_ptr = v__ast__Type_is_ptr(node.left_type); v__ast__Array info = *(v__ast__Array*)__as_cast((sym.info)._v__ast__Array,(sym.info)._typ, 513); v__ast__Type elem_type = info.elem_type; v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, elem_type); string elem_type_str = (elem_sym->kind == v__ast__Kind__function ? (_S("voidptr")) : (v__gen__c__Gen_styp(g, info.elem_type))); bool left_is_shared = v__ast__Type_has_flag(node.left_type, v__ast__TypeFlag__shared_f); if (g->is_assign_lhs && node.is_setter) { bool is_direct_array_access = g->is_direct_array_access || node.is_direct; bool is_op_assign = g->assign_op != v__token__Kind__assign && info.elem_type != _const_v__ast__string_type; if (is_direct_array_access) { { v__gen__c__Gen_write(g, _S("((")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("*)")); } } else if (is_op_assign) { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("*)array_get(")); } if (left_is_ptr && !left_is_shared) { v__gen__c__Gen_write(g, _S("*")); } } else { array_push((array*)&g->cur_indexexpr, _MOV((int[]){ node.pos.pos })); g->is_arraymap_set = true; v__gen__c__Gen_write(g, _S("array_set(")); if (!left_is_ptr || left_is_shared) { v__gen__c__Gen_write(g, _S("&")); } } if ((node.left)._typ == 361 /* v.ast.IndexExpr */) { g->inside_array_index = true; v__gen__c__Gen_expr(g, node.left); g->inside_array_index = false; } else { v__gen__c__Gen_expr(g, node.left); } if (left_is_shared) { if ((node.index)._typ != 377 /* v.ast.RangeExpr */ && left_is_ptr) { v__gen__c__Gen_write(g, _S("->val")); } else { v__gen__c__Gen_write(g, _S(".val")); } } if (is_direct_array_access) { if (left_is_ptr && !left_is_shared) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } v__gen__c__Gen_write(g, _S("data)[")); v__gen__c__Gen_expr(g, node.index); v__gen__c__Gen_write(g, _S("]")); } else { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, node.index); if (!is_op_assign) { bool need_wrapper = true; if (elem_sym->kind != v__ast__Kind__array_fixed) { if (need_wrapper) { { v__gen__c__Gen_write(g, _S(", &(")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("[]) { ")); } } else { v__gen__c__Gen_write(g, _S(", &")); } } } else { v__gen__c__Gen_write(g, _S("))")); } } } else { bool is_direct_array_access = g->is_direct_array_access || node.is_direct; bool is_fn_index_call = g->is_fn_index_call && (elem_sym->info)._typ == 553 /* v.ast.FnType */; bool needs_clone = info.elem_type == 21 && g->is_autofree && !(g->inside_return && g->fn_decl != ((void*)0) && v__ast__Type_has_flag(g->fn_decl->return_type, v__ast__TypeFlag__option)) && !g->is_assign_lhs; bool is_gen_or_and_assign_rhs = gen_or && !g->discard_or_result; string _t2; /* if prepend */ if (is_gen_or_and_assign_rhs) { string line = v__gen__c__Gen_go_before_last_stmt(g); strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); _t2 = line; } else { _t2 = _S(""); } string cur_line = _t2; string tmp_opt = (gen_or ? (v__gen__c__Gen_new_tmp_var(g)) : (_S(""))); string tmp_opt_ptr = (gen_or ? (v__gen__c__Gen_new_tmp_var(g)) : (_S(""))); if (gen_or) { { v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("* ")); v__gen__c__Gen_write(g, tmp_opt_ptr); v__gen__c__Gen_write(g, _S(" = (")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("*)(array_get_with_check(")); } if (left_is_ptr && !left_is_shared) { v__gen__c__Gen_write(g, _S("*")); } } else { if (needs_clone) { v__gen__c__Gen_write(g, _S("string_clone(")); } if (is_fn_index_call) { if ((elem_sym->info)._typ == 553 /* v.ast.FnType */) { v__gen__c__Gen_write(g, _S("((")); v__gen__c__Gen_write_fn_ptr_decl(g, &(*elem_sym->info._v__ast__FnType), _S("")); if (is_direct_array_access) { { v__gen__c__Gen_write(g, _S(")((")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("*)")); } } else { { v__gen__c__Gen_write(g, _S(")(*(")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("*)array_get(")); } } } if (left_is_ptr && !left_is_shared) { v__gen__c__Gen_write(g, _S("*")); } } else if (is_direct_array_access) { { v__gen__c__Gen_write(g, _S("((")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("*)")); } } else { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("*)array_get(")); } if (left_is_ptr && !left_is_shared) { v__gen__c__Gen_write(g, _S("*")); } } } v__gen__c__Gen_expr(g, node.left); if (left_is_shared) { if (left_is_ptr) { v__gen__c__Gen_write(g, _S("->val")); } else { v__gen__c__Gen_write(g, _S(".val")); } } if (is_direct_array_access && !gen_or) { if (left_is_ptr && !left_is_shared) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } v__gen__c__Gen_write(g, _S("data)[")); v__gen__c__Gen_expr(g, node.index); v__gen__c__Gen_write(g, _S("]")); if (is_fn_index_call) { v__gen__c__Gen_write(g, _S(")")); } } else { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, node.index); if (is_fn_index_call) { v__gen__c__Gen_write(g, _S(")))")); } else { v__gen__c__Gen_write(g, _S("))")); } } if (!gen_or && needs_clone) { v__gen__c__Gen_write(g, _S(")")); } if (gen_or) { v__gen__c__Gen_writeln(g, _S(";")); string opt_elem_type = v__gen__c__Gen_styp(g, v__ast__Type_set_flag(elem_type, v__ast__TypeFlag__option)); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = opt_elem_type}}, {_S(" "), 0xfe10, {.d_s = tmp_opt}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = tmp_opt_ptr}}, {_S(") {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\t*(("), 0xfe10, {.d_s = elem_type_str}}, {_S("*)&"), 0xfe10, {.d_s = tmp_opt}}, {_S(".data) = *(("), 0xfe10, {.d_s = elem_type_str}}, {_S("*)"), 0xfe10, {.d_s = tmp_opt_ptr}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("} else {")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = tmp_opt}}, {_S(".state = 2; "), 0xfe10, {.d_s = tmp_opt}}, {_S(".err = _v_error(_S(\"array index out of range\"));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("}")); if (!node.is_option) { v__gen__c__Gen_or_block(g, tmp_opt, node.or_expr, elem_type); } if (!g->is_amp) { if (g->inside_opt_or_res && v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__option) && g->inside_assign) { { v__gen__c__Gen_write(g, _S("\n")); v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("*)&")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(")")); } } else { { v__gen__c__Gen_write(g, _S("\n")); v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(".data)")); } } } else { { v__gen__c__Gen_write(g, _S("\n")); v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S("*")); v__gen__c__Gen_write(g, tmp_opt_ptr); } } } } } VV_LOC void v__gen__c__Gen_index_of_fixed_array(v__gen__c__Gen* g, v__ast__IndexExpr node, v__ast__TypeSymbol sym) { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((sym.info)._v__ast__ArrayFixed,(sym.info)._typ, 549); v__ast__Type elem_type = info.elem_type; v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, elem_type); bool is_fn_index_call = g->is_fn_index_call && (elem_sym->info)._typ == 553 /* v.ast.FnType */; if ((node.left)._typ == 338 /* v.ast.ArrayInit */) { v__gen__c__PastTmpVar past = v__gen__c__Gen_past_tmp_var_new(g); string styp = v__gen__c__Gen_styp(g, node.left_type); { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, past.tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_past_tmp_var_done(g, (voidptr)&past); } else if ((node.left)._typ == 361 /* v.ast.IndexExpr */ && (*(v__ast__IndexExpr*)__as_cast((node.left)._v__ast__IndexExpr,(node.left)._typ, 361)).is_setter) { string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; string tmp_var = v__gen__c__Gen_new_tmp_var(g); string styp = v__gen__c__Gen_styp(g, node.left_type); { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("* ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = &")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write(g, line); v__gen__c__Gen_write(g, _S("(*")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(")")); } else { if (is_fn_index_call) { v__gen__c__Gen_write(g, _S("(*")); } if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, _S("(*")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_expr(g, node.left); } if (v__ast__Type_has_flag(node.left_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S(".val")); } } v__gen__c__Gen_write(g, _S("[")); if (g->is_direct_array_access || g->pref->translated || (node.index)._typ == 363 /* v.ast.IntegerLiteral */) { v__gen__c__Gen_expr(g, node.index); } else { v__gen__c__Gen_write(g, _S("v_fixed_index(")); v__gen__c__Gen_expr(g, node.index); { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, info.size); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_write(g, _S("]")); if (is_fn_index_call) { v__gen__c__Gen_write(g, _S(")")); } } VV_LOC void v__gen__c__Gen_index_of_map(v__gen__c__Gen* g, v__ast__IndexExpr node, v__ast__TypeSymbol sym) { bool gen_or = node.or_expr.kind != v__ast__OrKind__absent || node.is_option; bool left_is_ptr = v__ast__Type_is_ptr(node.left_type); v__ast__Map info = *(v__ast__Map*)__as_cast((sym.info)._v__ast__Map,(sym.info)._typ, 514); string key_type_str = v__gen__c__Gen_styp(g, info.key_type); v__ast__Type val_type = info.value_type; v__ast__TypeSymbol* val_sym = v__ast__Table_sym(g->table, val_type); bool left_is_shared = v__ast__Type_has_flag(node.left_type, v__ast__TypeFlag__shared_f); string val_type_str = (val_sym->kind == v__ast__Kind__function ? (_S("voidptr")) : ((g->inside_return ? (v__gen__c__Gen_styp(g, val_type)) : (v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(val_type, v__ast__TypeFlag__result)))))); bool get_and_set_types = (val_sym->kind == v__ast__Kind__struct || val_sym->kind == v__ast__Kind__map || val_sym->kind == v__ast__Kind__array || val_sym->kind == v__ast__Kind__array_fixed); if (g->is_assign_lhs && !g->is_arraymap_set && !get_and_set_types) { if (g->assign_op == v__token__Kind__assign || info.value_type == _const_v__ast__string_type) { array_push((array*)&g->cur_indexexpr, _MOV((int[]){ node.pos.pos })); g->is_arraymap_set = true; v__gen__c__Gen_write(g, _S("map_set(")); } else { if (node.is_setter) { { v__gen__c__Gen_write(g, _S("(*((")); v__gen__c__Gen_write(g, val_type_str); v__gen__c__Gen_write(g, _S("*)map_get_and_set((map*)")); } } else { { v__gen__c__Gen_write(g, _S("(*((")); v__gen__c__Gen_write(g, val_type_str); v__gen__c__Gen_write(g, _S("*)map_get((map*)")); } } } if (!left_is_ptr || left_is_shared) { v__gen__c__Gen_write(g, _S("&")); } if ((node.left)._typ == 361 /* v.ast.IndexExpr */) { g->inside_map_index = true; v__gen__c__Gen_expr(g, node.left); g->inside_map_index = false; } else { v__gen__c__Gen_expr(g, node.left); } if (left_is_shared) { v__gen__c__Gen_write(g, _S("->val")); } { v__gen__c__Gen_write(g, _S(", &(")); v__gen__c__Gen_write(g, key_type_str); v__gen__c__Gen_write(g, _S("[]){")); } bool old_is_arraymap_set = g->is_arraymap_set; bool old_is_assign_lhs = g->is_assign_lhs; g->is_arraymap_set = false; g->is_assign_lhs = false; v__gen__c__Gen_expr(g, node.index); g->is_arraymap_set = old_is_arraymap_set; g->is_assign_lhs = old_is_assign_lhs; v__gen__c__Gen_write(g, _S("}")); g->arraymap_set_pos = g->out.len; { v__gen__c__Gen_write(g, _S(", &(")); v__gen__c__Gen_write(g, val_type_str); v__gen__c__Gen_write(g, _S("[]) { ")); } if (g->assign_op != v__token__Kind__assign && info.value_type != _const_v__ast__string_type) { string zero = v__gen__c__Gen_type_default(g, info.value_type); { v__gen__c__Gen_write(g, zero); v__gen__c__Gen_write(g, _S(" })))")); } } } else if (!gen_or && (g->inside_map_postfix || g->inside_map_infix || g->inside_map_index || g->inside_array_index || (g->is_assign_lhs && !g->is_arraymap_set && get_and_set_types))) { string zero = v__gen__c__Gen_type_default(g, info.value_type); if (node.is_setter) { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, val_type_str); v__gen__c__Gen_write(g, _S("*)map_get_and_set((map*)")); } } else { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, val_type_str); v__gen__c__Gen_write(g, _S("*)map_get((map*)")); } } if (!left_is_ptr || left_is_shared) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, node.left); if (left_is_shared) { v__gen__c__Gen_write(g, _S("->val")); } { v__gen__c__Gen_write(g, _S(", &(")); v__gen__c__Gen_write(g, key_type_str); v__gen__c__Gen_write(g, _S("[]){")); } bool old_is_assign_lhs = g->is_assign_lhs; g->is_assign_lhs = false; v__gen__c__Gen_expr(g, node.index); g->is_assign_lhs = old_is_assign_lhs; { v__gen__c__Gen_write(g, _S("}, &(")); v__gen__c__Gen_write(g, val_type_str); v__gen__c__Gen_write(g, _S("[]){ ")); v__gen__c__Gen_write(g, zero); v__gen__c__Gen_write(g, _S(" }))")); } } else { string zero = v__gen__c__Gen_type_default(g, info.value_type); bool is_gen_or_and_assign_rhs = gen_or && !g->discard_or_result; string _t2; /* if prepend */ if (is_gen_or_and_assign_rhs) { string line = v__gen__c__Gen_go_before_last_stmt(g); strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); _t2 = line; } else { _t2 = _S(""); } string cur_line = _t2; string tmp_opt = (gen_or ? (v__gen__c__Gen_new_tmp_var(g)) : (_S(""))); string tmp_opt_ptr = (gen_or ? (v__gen__c__Gen_new_tmp_var(g)) : (_S(""))); bool is_fn_last_index_call = false; if (gen_or) { { v__gen__c__Gen_write(g, val_type_str); v__gen__c__Gen_write(g, _S("* ")); v__gen__c__Gen_write(g, tmp_opt_ptr); v__gen__c__Gen_write(g, _S(" = (")); v__gen__c__Gen_write(g, val_type_str); v__gen__c__Gen_write(g, _S("*)(map_get_check(")); } } else { if (g->is_fn_index_call) { if ((val_sym->info)._typ == 553 /* v.ast.FnType */) { v__gen__c__Gen_write(g, _S("((")); v__gen__c__Gen_write_fn_ptr_decl(g, &(*val_sym->info._v__ast__FnType), _S("")); v__gen__c__Gen_write(g, _S(")(*(voidptr*)map_get(")); is_fn_last_index_call = true; g->is_fn_index_call = false; } } else { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, val_type_str); v__gen__c__Gen_write(g, _S("*)map_get(")); } } } if (!left_is_ptr || left_is_shared) { v__gen__c__Gen_write(g, _S("ADDR(map, ")); v__gen__c__Gen_expr(g, node.left); } else { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_expr(g, node.left); } if (left_is_shared) { if (left_is_ptr) { v__gen__c__Gen_write(g, _S("->val")); } else { v__gen__c__Gen_write(g, _S(".val")); } } { v__gen__c__Gen_write(g, _S("), &(")); v__gen__c__Gen_write(g, key_type_str); v__gen__c__Gen_write(g, _S("[]){")); } v__gen__c__Gen_expr(g, node.index); v__gen__c__Gen_write(g, _S("}")); if (gen_or) { v__gen__c__Gen_write(g, _S("))")); } else if (is_fn_last_index_call) { { v__gen__c__Gen_write(g, _S(", &(voidptr[]){ ")); v__gen__c__Gen_write(g, zero); v__gen__c__Gen_write(g, _S(" })))")); } } else { { v__gen__c__Gen_write(g, _S(", &(")); v__gen__c__Gen_write(g, val_type_str); v__gen__c__Gen_write(g, _S("[]){ ")); v__gen__c__Gen_write(g, zero); v__gen__c__Gen_write(g, _S(" }))")); } } if (gen_or) { v__gen__c__Gen_writeln(g, _S(";")); string opt_val_type = v__gen__c__Gen_styp(g, v__ast__Type_set_flag(val_type, v__ast__TypeFlag__option)); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = opt_val_type}}, {_S(" "), 0xfe10, {.d_s = tmp_opt}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = tmp_opt_ptr}}, {_S(") {"), 0, { .d_c = 0 }}}))); if (val_sym->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("\tmemcpy(("), 0xfe10, {.d_s = val_type_str}}, {_S("*)"), 0xfe10, {.d_s = tmp_opt}}, {_S(".data, ("), 0xfe10, {.d_s = val_type_str}}, {_S("*)"), 0xfe10, {.d_s = tmp_opt_ptr}}, {_S(", sizeof("), 0xfe10, {.d_s = val_type_str}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\t*(("), 0xfe10, {.d_s = val_type_str}}, {_S("*)&"), 0xfe10, {.d_s = tmp_opt}}, {_S(".data) = *(("), 0xfe10, {.d_s = val_type_str}}, {_S("*)"), 0xfe10, {.d_s = tmp_opt_ptr}}, {_S(");"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, _S("} else {")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = tmp_opt}}, {_S(".state = 2; "), 0xfe10, {.d_s = tmp_opt}}, {_S(".err = _v_error(_S(\"map key does not exist\"));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("}")); if (!node.is_option) { v__gen__c__Gen_or_block(g, tmp_opt, node.or_expr, val_type); } { v__gen__c__Gen_write(g, _S("\n")); v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, val_type_str); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(".data)")); } } } } VV_LOC void v__gen__c__Gen_infix_expr(v__gen__c__Gen* g, v__ast__InfixExpr node) { bool v__gen__c__Gen_infix_expr_defer_0 = false; g->expected_fixed_arr = true; v__gen__c__Gen_infix_expr_defer_0 = true; if ((node.auto_locked).len != 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("sync__RwMutex_lock(&"), 0xfe10, {.d_s = node.auto_locked}}, {_S("->mtx);"), 0, { .d_c = 0 }}}))); } switch (node.op) { case v__token__Kind__arrow: { v__gen__c__Gen_infix_expr_arrow_op(g, node); break; } case v__token__Kind__eq: case v__token__Kind__ne: { v__gen__c__Gen_infix_expr_eq_op(g, node); break; } case v__token__Kind__gt: case v__token__Kind__ge: case v__token__Kind__lt: case v__token__Kind__le: { v__gen__c__Gen_infix_expr_cmp_op(g, node); break; } case v__token__Kind__key_in: case v__token__Kind__not_in: { v__gen__c__Gen_infix_expr_in_op(g, node); break; } case v__token__Kind__key_is: case v__token__Kind__not_is: { v__gen__c__Gen_infix_expr_is_op(g, node); break; } case v__token__Kind__plus: case v__token__Kind__minus: case v__token__Kind__mul: case v__token__Kind__div: case v__token__Kind__mod: { v__gen__c__Gen_infix_expr_arithmetic_op(g, node); break; } case v__token__Kind__left_shift: { v__gen__c__Gen_infix_expr_left_shift_op(g, node); break; } case v__token__Kind__right_shift: { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_gen_plain_infix_expr(g, node); v__gen__c__Gen_write(g, _S(")")); break; } case v__token__Kind__and: case v__token__Kind__logical_or: { v__gen__c__Gen_infix_expr_and_or_op(g, node); break; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__xor: case v__token__Kind__pipe: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__amp: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__unsigned_right_shift: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_interface: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_like: case v__token__Kind__key_ilike: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { bool need_par = (node.op == v__token__Kind__amp || node.op == v__token__Kind__pipe || node.op == v__token__Kind__xor); if (need_par) { v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_gen_plain_infix_expr(g, node); if (need_par) { v__gen__c__Gen_write(g, _S(")")); } break; } } } if ((node.auto_locked).len != 0) { v__gen__c__Gen_writeln(g, _S(";")); { v__gen__c__Gen_write(g, _S("sync__RwMutex_unlock(&")); v__gen__c__Gen_write(g, node.auto_locked); v__gen__c__Gen_write(g, _S("->mtx)")); } } // Defer begin if (v__gen__c__Gen_infix_expr_defer_0) { g->expected_fixed_arr = false; } // Defer end } VV_LOC void v__gen__c__Gen_infix_expr_arrow_op(v__gen__c__Gen* g, v__ast__InfixExpr node) { v__gen__c__Type left = v__gen__c__Gen_unwrap(g, node.left_type); string styp = left.sym->cname; v__ast__Type elem_type = (*(v__ast__Chan*)__as_cast((left.sym->info)._v__ast__Chan,(left.sym->info)._typ, 550)).elem_type; bool gen_or = node.or_block.kind != v__ast__OrKind__absent; string tmp_opt = (gen_or ? (v__gen__c__Gen_new_tmp_var(g)) : (_S(""))); if (gen_or) { string elem_styp = v__gen__c__Gen_styp(g, elem_type); v__gen__c__Gen_register_chan_push_option_fn(g, elem_styp, styp); { v__gen__c__Gen_write(g, _const_v__gen__c__option_name); v__gen__c__Gen_write(g, _S("_void ")); v__gen__c__Gen_write(g, tmp_opt); v__gen__c__Gen_write(g, _S(" = __Option_")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("_pushval(")); } } else { { v__gen__c__Gen_write(g, _S("__")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("_pushval(")); } } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); if (v__ast__Table_sym(g->table, elem_type)->kind == v__ast__Kind__sum_type || v__ast__Table_sym(g->table, elem_type)->kind == v__ast__Kind__interface) { v__gen__c__Gen_expr_with_cast(g, node.right, node.right_type, elem_type); } else { v__gen__c__Gen_expr(g, node.right); } v__gen__c__Gen_write(g, _S(")")); if (gen_or) { v__gen__c__Gen_or_block(g, tmp_opt, node.or_block, _const_v__ast__void_type); } } VV_LOC void v__gen__c__Gen_infix_expr_eq_op(v__gen__c__Gen* g, v__ast__InfixExpr node) { v__ast__Type left_type = v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, node.left, node.left_type); v__ast__Type right_type = v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, node.right, node.right_type); v__gen__c__Type left = v__gen__c__Gen_unwrap(g, left_type); v__gen__c__Type right = v__gen__c__Gen_unwrap(g, right_type); bool has_defined_eq_operator = false; bool eq_operator_expects_ptr = false; _result_v__ast__Fn _t1; if (_t1 = v__ast__Table_find_method(g->table, left.sym, _S("==")), !_t1.is_error) { v__ast__Fn m = *(v__ast__Fn*)_t1.data; has_defined_eq_operator = true; eq_operator_expects_ptr = v__ast__Type_is_ptr(m.receiver_type); } bool has_alias_eq_op_overload = (left.sym->info)._typ == 539 /* v.ast.Alias */ && v__ast__TypeSymbol_has_method(left.sym, _S("==")); if (g->pref->translated && !g->is_builtin_mod) { v__gen__c__Gen_gen_plain_infix_expr(g, node); return; } bool left_is_option = v__ast__Type_has_flag(left_type, v__ast__TypeFlag__option); bool right_is_option = v__ast__Type_has_flag(right_type, v__ast__TypeFlag__option); bool is_none_check = left_is_option && (node.right)._typ == 371 /* v.ast.None */; if (is_none_check) { v__gen__c__Gen_gen_is_none_check(g, node); } else if ((v__ast__Type_is_ptr(left.typ) && v__ast__Type_is_int(right.typ)) || (v__ast__Type_is_ptr(right.typ) && v__ast__Type_is_int(left.typ)) || (v__ast__Type_is_ptr(left.typ) && right.typ == _const_v__ast__nil_type)) { v__gen__c__Gen_gen_plain_infix_expr(g, node); } else if ((v__ast__Type_idx(left.typ) == 21 || (!has_defined_eq_operator && v__ast__Type_idx(left.unaliased) == 21)) && (node.right)._typ == 384 /* v.ast.StringLiteral */ && (((*(v__ast__StringLiteral*)__as_cast((node.right)._v__ast__StringLiteral,(node.right)._typ, 384)).val).len == 0 || ((node.left)._typ == 379 /* v.ast.SelectorExpr */ || ((node.left)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node.left)._v__ast__Ident,(node.left)._typ, 358)).or_expr.kind == v__ast__OrKind__absent)))) { if (((*node.right._v__ast__StringLiteral).val).len == 0) { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); string arrow = (v__ast__Type_is_ptr(left.typ) ? (_S("->")) : (_S("."))); v__gen__c__Gen_write(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arrow}}, {_S("len "), 0xfe10, {.d_s = v__token__Kind_str(node.op)}}, {_S(" 0"), 0, { .d_c = 0 }}}))); } else if ((node.left)._typ == 358 /* v.ast.Ident */) { string slit = v__gen__c__cescape_nonascii(v__util__smart_quote((*node.right._v__ast__StringLiteral).val, (*node.right._v__ast__StringLiteral).is_raw)); string var = v__gen__c__Gen_expr_string(g, node.left); string arrow = (v__ast__Type_is_ptr(left.typ) ? (_S("->")) : (_S("."))); if (node.op == v__token__Kind__eq) { { v__gen__c__Gen_write(g, _S("_SLIT_EQ(")); v__gen__c__Gen_write(g, var); v__gen__c__Gen_write(g, arrow); v__gen__c__Gen_write(g, _S("str, ")); v__gen__c__Gen_write(g, var); v__gen__c__Gen_write(g, arrow); v__gen__c__Gen_write(g, _S("len, \"")); v__gen__c__Gen_write(g, slit); v__gen__c__Gen_write(g, _S("\")")); } } else { { v__gen__c__Gen_write(g, _S("_SLIT_NE(")); v__gen__c__Gen_write(g, var); v__gen__c__Gen_write(g, arrow); v__gen__c__Gen_write(g, _S("str, ")); v__gen__c__Gen_write(g, var); v__gen__c__Gen_write(g, arrow); v__gen__c__Gen_write(g, _S("len, \"")); v__gen__c__Gen_write(g, slit); v__gen__c__Gen_write(g, _S("\")")); } } } else { if (node.op == v__token__Kind__ne) { v__gen__c__Gen_write(g, _S("!fast_string_eq(")); } else { v__gen__c__Gen_write(g, _S("fast_string_eq(")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _S(")")); } } else if (has_defined_eq_operator) { if (node.op == v__token__Kind__ne) { v__gen__c__Gen_write(g, _S("!")); } if (has_alias_eq_op_overload) { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(left.typ, 0))); } else { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(left.unaliased, 0))); } v__gen__c__Gen_write2(g, _S("__eq("), string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); if (eq_operator_expects_ptr) { v__gen__c__Gen_write(g, _S("&")); } if ((node.left)._typ == 338 /* v.ast.ArrayInit */ && v__ast__Table_sym(g->table, node.left_type)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*node.left._v__ast__ArrayInit), node.left_type); } else { v__gen__c__Gen_expr(g, node.left); } v__gen__c__Gen_write2(g, _S(", "), string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); if (eq_operator_expects_ptr) { v__gen__c__Gen_write(g, _S("&")); } if ((node.right)._typ == 338 /* v.ast.ArrayInit */ && v__ast__Table_sym(g->table, node.right_type)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*node.right._v__ast__ArrayInit), node.right_type); } else { v__gen__c__Gen_expr(g, node.right); } v__gen__c__Gen_write(g, _S(")")); } else if (v__ast__Type_idx(left.unaliased) == v__ast__Type_idx(right.unaliased) && (left.sym->kind == v__ast__Kind__array || left.sym->kind == v__ast__Kind__array_fixed || left.sym->kind == v__ast__Kind__alias || left.sym->kind == v__ast__Kind__map || left.sym->kind == v__ast__Kind__struct || left.sym->kind == v__ast__Kind__sum_type || left.sym->kind == v__ast__Kind__interface)) { if (g->pref->translated && !g->is_builtin_mod) { v__gen__c__Gen_gen_plain_infix_expr(g, node); return; } v__ast__Kind kind = (left.sym->kind == v__ast__Kind__alias && right.sym->kind != v__ast__Kind__alias ? (left.unaliased_sym->kind) : (left.sym->kind)); switch (kind) { case v__ast__Kind__alias: { if (v__ast__TypeSymbol_is_int(left.unaliased_sym)) { if (v__ast__Type_is_ptr(left.typ) && v__ast__Expr_is_auto_deref_var(node.left) && !v__ast__Type_is_pointer(right.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = v__token__Kind_str(node.op)}}, {_S(" "), 0, { .d_c = 0 }}}))); if (v__ast__Type_is_ptr(right.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); } v__gen__c__Gen_expr(g, node.right); map_set(&g->no_eq_method_types, &(v__ast__Type[]){left.typ}, &(bool[]) { true }); } else { string ptr_typ = v__gen__c__Gen_equality_fn(g, left.typ); if (node.op == v__token__Kind__ne) { v__gen__c__Gen_write(g, _S("!")); } { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_alias_eq(")); } if (v__ast__Type_is_ptr(left.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); } if ((node.left)._typ == 385 /* v.ast.StructInit */ && v__ast__TypeSymbol_is_primitive_fixed_array(left.unaliased_sym)) { string s = v__gen__c__Gen_styp(g, left.unaliased); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, s); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); if ((node.right)._typ == 385 /* v.ast.StructInit */ && v__ast__TypeSymbol_is_primitive_fixed_array(right.unaliased_sym)) { string s = v__gen__c__Gen_styp(g, right.unaliased); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, s); v__gen__c__Gen_write(g, _S(")")); } } if (v__ast__Type_is_ptr(right.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); } v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _S(")")); } break; } case v__ast__Kind__array: { string ptr_typ = v__gen__c__Gen_equality_fn(g, v__ast__Type_clear_flag(left.unaliased, v__ast__TypeFlag__shared_f)); if (node.op == v__token__Kind__ne) { v__gen__c__Gen_write(g, _S("!")); } { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_arr_eq(")); } if (v__ast__Type_is_ptr(left.typ) && !v__ast__Type_has_flag(left.typ, v__ast__TypeFlag__shared_f)) { if ((node.left)._typ != 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); } } v__gen__c__Gen_expr(g, node.left); if (v__ast__Type_has_flag(left.typ, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("->val")); } v__gen__c__Gen_write(g, _S(", ")); if (v__ast__Type_is_ptr(right.typ) && !v__ast__Type_has_flag(right.typ, v__ast__TypeFlag__shared_f)) { if ((node.right)._typ != 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); } } v__gen__c__Gen_expr(g, node.right); if (v__ast__Type_has_flag(right.typ, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("->val")); } v__gen__c__Gen_write(g, _S(")")); break; } case v__ast__Kind__array_fixed: { string ptr_typ = v__gen__c__Gen_equality_fn(g, left.unaliased); if (node.op == v__token__Kind__ne) { v__gen__c__Gen_write(g, _S("!")); } { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_arr_eq(")); } if (v__ast__Type_is_ptr(left.typ)) { v__gen__c__Gen_write(g, _S("*")); } if ((node.left)._typ == 338 /* v.ast.ArrayInit */) { if (!(*node.left._v__ast__ArrayInit).has_index) { string s = v__gen__c__Gen_styp(g, left.unaliased); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, s); v__gen__c__Gen_write(g, _S(")")); } } } else if ((node.left)._typ == 385 /* v.ast.StructInit */ && v__ast__TypeSymbol_is_primitive_fixed_array(left.unaliased_sym)) { string s = v__gen__c__Gen_styp(g, left.unaliased); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, s); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); if ((node.right)._typ == 338 /* v.ast.ArrayInit */) { if (!(*node.right._v__ast__ArrayInit).has_index) { string s = v__gen__c__Gen_styp(g, right.unaliased); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, s); v__gen__c__Gen_write(g, _S(")")); } } } else if ((node.right)._typ == 385 /* v.ast.StructInit */ && v__ast__TypeSymbol_is_primitive_fixed_array(right.unaliased_sym)) { string s = v__gen__c__Gen_styp(g, right.unaliased); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, s); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _S(")")); break; } case v__ast__Kind__map: { string ptr_typ = v__gen__c__Gen_equality_fn(g, left.unaliased); if (node.op == v__token__Kind__ne) { v__gen__c__Gen_write(g, _S("!")); } { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_map_eq(")); } if (v__ast__Type_is_ptr(left.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); if (v__ast__Type_is_ptr(right.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); } v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _S(")")); break; } case v__ast__Kind__struct: { string ptr_typ = v__gen__c__Gen_equality_fn(g, left.unaliased); if (node.op == v__token__Kind__ne) { v__gen__c__Gen_write(g, _S("!")); } { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_struct_eq(")); } if (v__ast__Type_is_ptr(left.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); if (v__ast__Type_is_ptr(right.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); } v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _S(")")); break; } case v__ast__Kind__sum_type: { string ptr_typ = v__gen__c__Gen_equality_fn(g, left.unaliased); if (node.op == v__token__Kind__ne) { v__gen__c__Gen_write(g, _S("!")); } { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_sumtype_eq(")); } if (v__ast__Type_is_ptr(left.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); if (v__ast__Type_is_ptr(right.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); } v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _S(")")); break; } case v__ast__Kind__interface: { string ptr_typ = v__gen__c__Gen_equality_fn(g, left.unaliased); if (node.op == v__token__Kind__ne) { v__gen__c__Gen_write(g, _S("!")); } { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_interface_eq(")); } if (v__ast__Type_is_ptr(left.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); if (v__ast__Type_is_ptr(right.typ)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); } v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _S(")")); break; } case v__ast__Kind__placeholder: case v__ast__Kind__void: case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__i32: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__isize: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__usize: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__bool: case v__ast__Kind__none: case v__ast__Kind__string: case v__ast__Kind__chan: case v__ast__Kind__any: case v__ast__Kind__generic_inst: case v__ast__Kind__multi_return: case v__ast__Kind__enum: case v__ast__Kind__function: case v__ast__Kind__float_literal: case v__ast__Kind__int_literal: case v__ast__Kind__aggregate: case v__ast__Kind__thread: default: { { v__gen__c__Gen_gen_plain_infix_expr(g, node); break; } } } } else if ((Array_int_contains(new_array_from_c_array(2, 2, sizeof(int), _MOV((int[2]){_const_v__ast__u32_type_idx, _const_v__ast__u64_type_idx})), v__ast__Type_idx(left.unaliased))) && v__ast__Type_is_signed(right.unaliased)) { v__gen__c__Gen_gen_safe_integer_infix_expr(g, ((v__gen__c__GenSafeIntegerCfg){.op = node.op,.reverse = 0,.unsigned_type = left.unaliased,.unsigned_expr = node.left,.signed_type = right.unaliased,.signed_expr = node.right,})); } else if ((Array_int_contains(new_array_from_c_array(2, 2, sizeof(int), _MOV((int[2]){_const_v__ast__u32_type_idx, _const_v__ast__u64_type_idx})), v__ast__Type_idx(right.unaliased))) && v__ast__Type_is_signed(left.unaliased)) { v__gen__c__Gen_gen_safe_integer_infix_expr(g, ((v__gen__c__GenSafeIntegerCfg){ .op = node.op, .reverse = true, .unsigned_type = right.unaliased, .unsigned_expr = node.right, .signed_type = left.unaliased, .signed_expr = node.left, })); } else if (left_is_option && right_is_option) { bool old_inside_opt_or_res = g->inside_opt_or_res; g->inside_opt_or_res = true; if (node.op == v__token__Kind__eq) { v__gen__c__Gen_write(g, _S("!")); } v__gen__c__Gen_write(g, _S("memcmp(")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(".data, ")); v__gen__c__Gen_expr(g, node.right); { v__gen__c__Gen_write(g, _S(".data, sizeof(")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, left_type)); v__gen__c__Gen_write(g, _S("))")); } g->inside_opt_or_res = old_inside_opt_or_res; } else { v__gen__c__Gen_gen_plain_infix_expr(g, node); } } VV_LOC void v__gen__c__Gen_infix_expr_cmp_op(v__gen__c__Gen* g, v__ast__InfixExpr node) { v__gen__c__Type left = v__gen__c__Gen_unwrap(g, node.left_type); v__gen__c__Type right = v__gen__c__Gen_unwrap(g, node.right_type); bool has_operator_overloading = false; bool operator_expects_ptr = false; _result_v__ast__Fn _t1; if (_t1 = v__ast__Table_find_method(g->table, left.sym, _S("<")), !_t1.is_error) { v__ast__Fn m = *(v__ast__Fn*)_t1.data; has_operator_overloading = true; operator_expects_ptr = v__ast__Type_is_ptr(m.receiver_type); } if (g->pref->translated && !g->is_builtin_mod) { v__gen__c__Gen_gen_plain_infix_expr(g, node); return; } if (left.sym->kind == v__ast__Kind__struct && (*(v__ast__Struct*)__as_cast((left.sym->info)._v__ast__Struct,(left.sym->info)._typ, 518)).generic_types.len > 0) { if (node.op == v__token__Kind__le || node.op == v__token__Kind__ge) { v__gen__c__Gen_write(g, _S("!")); } Array_v__ast__Type concrete_types = (*(v__ast__Struct*)__as_cast((left.sym->info)._v__ast__Struct,(left.sym->info)._typ, 518)).concrete_types; string method_name = string__plus(left.sym->cname, _S("__lt")); method_name = v__gen__c__Gen_generic_fn_name(g, concrete_types, method_name); v__gen__c__Gen_write(g, method_name); if (node.op == v__token__Kind__lt || node.op == v__token__Kind__ge) { v__gen__c__Gen_write2(g, _S("("), string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); if (operator_expects_ptr) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write2(g, _S(", "), string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); if (operator_expects_ptr) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_write2(g, _S("("), string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); if (operator_expects_ptr) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write2(g, _S(", "), string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); if (operator_expects_ptr) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } } else if (left.unaliased_sym->kind == right.unaliased_sym->kind && has_operator_overloading) { if (node.op == v__token__Kind__le || node.op == v__token__Kind__ge) { v__gen__c__Gen_write(g, _S("!")); } v__gen__c__Gen_write2(g, v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(left.typ, 0)), _S("__lt")); if (node.op == v__token__Kind__lt || node.op == v__token__Kind__ge) { v__gen__c__Gen_write2(g, _S("("), string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); if (operator_expects_ptr) { v__gen__c__Gen_write(g, _S("&")); } if ((node.left)._typ == 338 /* v.ast.ArrayInit */ && v__ast__Table_sym(g->table, node.left_type)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*node.left._v__ast__ArrayInit), node.left_type); } else { v__gen__c__Gen_expr(g, node.left); } v__gen__c__Gen_write2(g, _S(", "), string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); if (operator_expects_ptr) { v__gen__c__Gen_write(g, _S("&")); } if ((node.right)._typ == 338 /* v.ast.ArrayInit */ && v__ast__Table_sym(g->table, node.right_type)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_fixed_array_init_with_cast(g, (*node.right._v__ast__ArrayInit), node.right_type); } else { v__gen__c__Gen_expr(g, node.right); } v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_write2(g, _S("("), string_repeat(_S("*"), v__ast__Type_nr_muls(right.typ))); if (operator_expects_ptr) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write2(g, _S(", "), string_repeat(_S("*"), v__ast__Type_nr_muls(left.typ))); if (operator_expects_ptr) { v__gen__c__Gen_write(g, _S("&")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } } else if ((Array_int_contains(new_array_from_c_array(2, 2, sizeof(int), _MOV((int[2]){_const_v__ast__u32_type_idx, _const_v__ast__u64_type_idx})), v__ast__Type_idx(left.unaliased))) && v__ast__Type_is_signed(right.unaliased)) { v__gen__c__Gen_gen_safe_integer_infix_expr(g, ((v__gen__c__GenSafeIntegerCfg){.op = node.op,.reverse = 0,.unsigned_type = left.unaliased,.unsigned_expr = node.left,.signed_type = right.unaliased,.signed_expr = node.right,})); } else if ((Array_int_contains(new_array_from_c_array(2, 2, sizeof(int), _MOV((int[2]){_const_v__ast__u32_type_idx, _const_v__ast__u64_type_idx})), v__ast__Type_idx(right.unaliased))) && v__ast__Type_is_signed(left.unaliased)) { v__gen__c__Gen_gen_safe_integer_infix_expr(g, ((v__gen__c__GenSafeIntegerCfg){ .op = node.op, .reverse = true, .unsigned_type = right.unaliased, .unsigned_expr = node.right, .signed_type = left.unaliased, .signed_expr = node.left, })); } else { v__gen__c__Gen_gen_plain_infix_expr(g, node); } } VV_LOC void v__gen__c__Gen_infix_expr_in_sumtype_interface_array(v__gen__c__Gen* g, Array_v__ast__InfixExpr infix_exprs) { for (int i = 0; i < infix_exprs.len; ++i) { v__gen__c__Gen_infix_expr_is_op(g, (*(v__ast__InfixExpr*)array_get(infix_exprs, i))); if (i != (int)(infix_exprs.len - 1)) { v__gen__c__Gen_write(g, _S(" || ")); } } } VV_LOC void v__gen__c__Gen_infix_expr_in_op(v__gen__c__Gen* g, v__ast__InfixExpr node) { v__gen__c__Type left = v__gen__c__Gen_unwrap(g, node.left_type); v__gen__c__Type right = v__gen__c__Gen_unwrap(g, node.right_type); if (node.op == v__token__Kind__not_in) { v__gen__c__Gen_write(g, _S("!")); } if (right.unaliased_sym->kind == v__ast__Kind__array) { if (left.sym->kind == v__ast__Kind__sum_type || left.sym->kind == v__ast__Kind__interface) { if ((node.right)._typ == 338 /* v.ast.ArrayInit */) { if ((*node.right._v__ast__ArrayInit).exprs.len > 0 && !(v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get((*node.right._v__ast__ArrayInit).expr_types, 0)))->kind == v__ast__Kind__sum_type || v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get((*node.right._v__ast__ArrayInit).expr_types, 0)))->kind == v__ast__Kind__interface)) { Array_v__ast__InfixExpr infix_exprs = __new_array_with_default(0, 0, sizeof(v__ast__InfixExpr), 0); for (int i = 0; i < (*node.right._v__ast__ArrayInit).exprs.len; ++i) { array_push((array*)&infix_exprs, _MOV((v__ast__InfixExpr[]){ ((v__ast__InfixExpr){.op = v__token__Kind__key_is,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_stmt = 0,.left = node.left,.right = (*(v__ast__Expr*)array_get((*node.right._v__ast__ArrayInit).exprs, i)),.left_type = node.left_type,.right_type = (*(v__ast__Type*)array_get((*node.right._v__ast__ArrayInit).expr_types, i)),.promoted_type = _const_v__ast__void_type,.auto_locked = (string){.str=(byteptr)"", .is_lit=1},.or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.ct_left_value_evaled = 0,.ct_left_value = _const_v__ast__empty_comptime_const_value,.left_ct_expr = 0,.ct_right_value_evaled = 0,.ct_right_value = _const_v__ast__empty_comptime_const_value,.right_ct_expr = 0,.before_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.after_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}) })); } v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_infix_expr_in_sumtype_interface_array(g, infix_exprs); v__gen__c__Gen_write(g, _S(")")); return; } } } if ((node.right)._typ == 338 /* v.ast.ArrayInit */) { v__ast__Type elem_type = (*node.right._v__ast__ArrayInit).elem_type; v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, elem_type); if ((*node.right._v__ast__ArrayInit).exprs.len > 0 && ((node.left)._typ == 358 /* v.ast.Ident */ || (node.left)._typ == 361 /* v.ast.IndexExpr */ || (node.left)._typ == 379 /* v.ast.SelectorExpr */)) { v__gen__c__Gen_write(g, _S("(")); if (elem_sym->kind == v__ast__Kind__sum_type && left.sym->kind != v__ast__Kind__sum_type) { if ((Array_v__ast__Type_contains(v__ast__TypeSymbol_sumtype_info(elem_sym).variants, node.left_type))) { v__ast__CastExpr new_node_left = ((v__ast__CastExpr){.arg = _const_v__ast__empty_expr,.typ = elem_type,.expr = node.left,.typname = (string){.str=(byteptr)"", .is_lit=1},.expr_type = node.left_type,.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); v__gen__c__Gen_infix_expr_in_optimization(g, v__ast__CastExpr_to_sumtype_v__ast__Expr(&new_node_left), node.left_type, (*node.right._v__ast__ArrayInit)); } } else { v__gen__c__Gen_infix_expr_in_optimization(g, node.left, node.left_type, (*node.right._v__ast__ArrayInit)); } v__gen__c__Gen_write(g, _S(")")); return; } } if ((right.sym->info)._typ == 513 /* v.ast.Array */) { v__ast__Type elem_type = (*right.sym->info._v__ast__Array).elem_type; v__gen__c__Type elem_type_ = v__gen__c__Gen_unwrap(g, elem_type); if (elem_type_.sym->kind == v__ast__Kind__sum_type) { if ((Array_v__ast__Type_contains(v__ast__TypeSymbol_sumtype_info(elem_type_.sym).variants, v__ast__mktyp(node.left_type)))) { v__ast__CastExpr new_node_left = ((v__ast__CastExpr){.arg = _const_v__ast__empty_expr,.typ = elem_type,.expr = node.left,.typname = (string){.str=(byteptr)"", .is_lit=1},.expr_type = v__ast__mktyp(node.left_type),.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_gen_array_contains(g, node.right_type, node.right, elem_type, v__ast__CastExpr_to_sumtype_v__ast__Expr(&new_node_left)); v__gen__c__Gen_write(g, _S(")")); return; } } else if (elem_type_.sym->kind == v__ast__Kind__interface) { v__ast__CastExpr new_node_left = ((v__ast__CastExpr){.arg = _const_v__ast__empty_expr,.typ = elem_type,.expr = node.left,.typname = (string){.str=(byteptr)"", .is_lit=1},.expr_type = v__ast__mktyp(node.left_type),.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_gen_array_contains(g, node.right_type, node.right, elem_type, v__ast__CastExpr_to_sumtype_v__ast__Expr(&new_node_left)); v__gen__c__Gen_write(g, _S(")")); return; } } v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_gen_array_contains(g, node.right_type, node.right, node.left_type, node.left); v__gen__c__Gen_write(g, _S(")")); } else if (right.unaliased_sym->kind == v__ast__Kind__map) { v__gen__c__Gen_write(g, _S("_IN_MAP(")); if (!v__ast__Type_is_ptr(left.typ)) { string styp = v__gen__c__Gen_styp(g, node.left_type); { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(", ")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_expr(g, node.left); } v__gen__c__Gen_write(g, _S(", ")); if (!v__ast__Type_is_ptr(right.typ) || v__ast__Type_has_flag(right.typ, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("ADDR(map, ")); v__gen__c__Gen_expr(g, node.right); if (v__ast__Type_has_flag(right.typ, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("->val")); } v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_expr(g, node.right); } v__gen__c__Gen_write(g, _S(")")); } else if (right.unaliased_sym->kind == v__ast__Kind__array_fixed) { if (left.sym->kind == v__ast__Kind__sum_type || left.sym->kind == v__ast__Kind__interface) { if ((node.right)._typ == 338 /* v.ast.ArrayInit */) { if ((*node.right._v__ast__ArrayInit).exprs.len > 0) { Array_v__ast__InfixExpr infix_exprs = __new_array_with_default(0, 0, sizeof(v__ast__InfixExpr), 0); for (int i = 0; i < (*node.right._v__ast__ArrayInit).exprs.len; ++i) { array_push((array*)&infix_exprs, _MOV((v__ast__InfixExpr[]){ ((v__ast__InfixExpr){.op = v__token__Kind__key_is,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_stmt = 0,.left = node.left,.right = (*(v__ast__Expr*)array_get((*node.right._v__ast__ArrayInit).exprs, i)),.left_type = node.left_type,.right_type = (*(v__ast__Type*)array_get((*node.right._v__ast__ArrayInit).expr_types, i)),.promoted_type = _const_v__ast__void_type,.auto_locked = (string){.str=(byteptr)"", .is_lit=1},.or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}),.ct_left_value_evaled = 0,.ct_left_value = _const_v__ast__empty_comptime_const_value,.left_ct_expr = 0,.ct_right_value_evaled = 0,.ct_right_value = _const_v__ast__empty_comptime_const_value,.right_ct_expr = 0,.before_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.after_op_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}) })); } v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_infix_expr_in_sumtype_interface_array(g, infix_exprs); v__gen__c__Gen_write(g, _S(")")); return; } } } if ((node.right)._typ == 338 /* v.ast.ArrayInit */) { if ((*node.right._v__ast__ArrayInit).exprs.len > 0) { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_infix_expr_in_optimization(g, node.left, node.left_type, (*node.right._v__ast__ArrayInit)); v__gen__c__Gen_write(g, _S(")")); return; } } if ((right.sym->info)._typ == 549 /* v.ast.ArrayFixed */) { v__ast__Type elem_type = (*right.sym->info._v__ast__ArrayFixed).elem_type; v__gen__c__Type elem_type_ = v__gen__c__Gen_unwrap(g, elem_type); if (elem_type_.sym->kind == v__ast__Kind__sum_type) { if ((Array_v__ast__Type_contains(v__ast__TypeSymbol_sumtype_info(elem_type_.sym).variants, v__ast__mktyp(node.left_type)))) { v__ast__CastExpr new_node_left = ((v__ast__CastExpr){.arg = _const_v__ast__empty_expr,.typ = elem_type,.expr = node.left,.typname = (string){.str=(byteptr)"", .is_lit=1},.expr_type = v__ast__mktyp(node.left_type),.has_arg = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}); v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_gen_array_contains(g, node.right_type, node.right, elem_type, v__ast__CastExpr_to_sumtype_v__ast__Expr(&new_node_left)); v__gen__c__Gen_write(g, _S(")")); return; } } } v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_gen_array_contains(g, node.right_type, node.right, node.left_type, node.left); v__gen__c__Gen_write(g, _S(")")); } else if (right.unaliased_sym->kind == v__ast__Kind__string && (node.right)._typ != 377 /* v.ast.RangeExpr */) { v__gen__c__Gen_write2(g, _S("("), _S("string_contains(")); v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S("))")); } else if ((node.right)._typ == 377 /* v.ast.RangeExpr */) { if ((node.left)._typ == 344 /* v.ast.CallExpr */) { string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; string tmp_var = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, (*node.left._v__ast__CallExpr).return_type)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write(g, line); v__gen__c__Gen_write(g, _S("(")); { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" >= ")); } v__gen__c__Gen_expr(g, (*node.right._v__ast__RangeExpr).low); v__gen__c__Gen_write(g, _S(" && ")); { v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" < ")); } v__gen__c__Gen_expr(g, (*node.right._v__ast__RangeExpr).high); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(" >= ")); v__gen__c__Gen_expr(g, (*node.right._v__ast__RangeExpr).low); v__gen__c__Gen_write(g, _S(" && ")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(" < ")); v__gen__c__Gen_expr(g, (*node.right._v__ast__RangeExpr).high); v__gen__c__Gen_write(g, _S(")")); } } } VV_LOC void v__gen__c__Gen_infix_expr_in_optimization(v__gen__c__Gen* g, v__ast__Expr left, v__ast__Type left_type, v__ast__ArrayInit right) { string tmp_var = ((left)._typ == 344 /* v.ast.CallExpr */ ? (v__gen__c__Gen_new_tmp_var(g)) : (_S(""))); v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, right.elem_type); int left_parent_idx = v__ast__Table_sym(g->table, left_type)->parent_idx; for (int i = 0; i < right.exprs.len; ++i) { v__ast__Expr array_expr = ((v__ast__Expr*)right.exprs.data)[i]; if (elem_sym->kind == (v__ast__Kind__string) || elem_sym->kind == (v__ast__Kind__alias) || elem_sym->kind == (v__ast__Kind__sum_type) || elem_sym->kind == (v__ast__Kind__map) || elem_sym->kind == (v__ast__Kind__interface) || elem_sym->kind == (v__ast__Kind__array) || elem_sym->kind == (v__ast__Kind__struct)) { if (elem_sym->kind == v__ast__Kind__string) { bool is_auto_deref_var = v__ast__Expr_is_auto_deref_var(left); if ((left)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((left)._v__ast__Ident,(left)._typ, 358)).or_expr.kind == v__ast__OrKind__absent && (array_expr)._typ == 384 /* v.ast.StringLiteral */) { string var = v__gen__c__Gen_expr_string(g, left); string slit = v__gen__c__cescape_nonascii(v__util__smart_quote((*array_expr._v__ast__StringLiteral).val, (*array_expr._v__ast__StringLiteral).is_raw)); if (is_auto_deref_var || (((*left._v__ast__Ident).info)._typ == 477 /* v.ast.IdentVar */ && (v__ast__Table_sym(g->table, (*((*left._v__ast__Ident).obj.typ)))->kind == v__ast__Kind__interface || v__ast__Table_sym(g->table, (*((*left._v__ast__Ident).obj.typ)))->kind == v__ast__Kind__sum_type))) { { v__gen__c__Gen_write(g, _S("_SLIT_EQ(")); v__gen__c__Gen_write(g, var); v__gen__c__Gen_write(g, _S("->str, ")); v__gen__c__Gen_write(g, var); v__gen__c__Gen_write(g, _S("->len, \"")); v__gen__c__Gen_write(g, slit); v__gen__c__Gen_write(g, _S("\")")); } } else { { v__gen__c__Gen_write(g, _S("_SLIT_EQ(")); v__gen__c__Gen_write(g, var); v__gen__c__Gen_write(g, _S(".str, ")); v__gen__c__Gen_write(g, var); v__gen__c__Gen_write(g, _S(".len, \"")); v__gen__c__Gen_write(g, slit); v__gen__c__Gen_write(g, _S("\")")); } } if (i < (int)(right.exprs.len - 1)) { v__gen__c__Gen_write(g, _S(" || ")); } continue; } else if ((array_expr)._typ == 384 /* v.ast.StringLiteral */) { v__gen__c__Gen_write(g, _S("fast_string_eq(")); } else { v__gen__c__Gen_write(g, _S("string__eq(")); } if (is_auto_deref_var || ((left)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast((left)._v__ast__Ident,(left)._typ, 358)).info)._typ == 477 /* v.ast.IdentVar */ && (v__ast__Table_sym(g->table, (*((*(v__ast__Ident*)__as_cast((left)._v__ast__Ident,(left)._typ, 358)).obj.typ)))->kind == v__ast__Kind__interface || v__ast__Table_sym(g->table, (*((*(v__ast__Ident*)__as_cast((left)._v__ast__Ident,(left)._typ, 358)).obj.typ)))->kind == v__ast__Kind__sum_type))) { v__gen__c__Gen_write(g, _S("*")); } } else { string ptr_typ = v__gen__c__Gen_equality_fn(g, right.elem_type); if (elem_sym->kind == v__ast__Kind__alias) { if (v__ast__TypeSymbol_is_int(elem_sym)) { v__gen__c__Gen_expr(g, left); v__gen__c__Gen_write(g, _S(" == ")); if (left_parent_idx != 0 && !(((array_expr)._typ == 379 /* v.ast.SelectorExpr */ && (*(v__ast__SelectorExpr*)__as_cast((array_expr)._v__ast__SelectorExpr,(array_expr)._typ, 379)).typ == left_type) || ((array_expr)._typ == 358 /* v.ast.Ident */ && (*((*(v__ast__Ident*)__as_cast((array_expr)._v__ast__Ident,(array_expr)._typ, 358)).obj.typ)) == left_type))) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, left_parent_idx)); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_expr(g, array_expr); if (i < (int)(right.exprs.len - 1)) { v__gen__c__Gen_write(g, _S(" || ")); } continue; } else { { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_alias_eq(")); } } } else if (elem_sym->kind == v__ast__Kind__sum_type) { { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_sumtype_eq(")); } } else if (elem_sym->kind == v__ast__Kind__map) { { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_map_eq(")); } } else if (elem_sym->kind == v__ast__Kind__interface) { { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_interface_eq(")); } } else if (elem_sym->kind == v__ast__Kind__array) { { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_arr_eq(")); } } else if (elem_sym->kind == v__ast__Kind__struct) { { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_struct_eq(")); } } } if ((left)._typ == 344 /* v.ast.CallExpr */) { if (i == 0) { string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, (*left._v__ast__CallExpr).return_type)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, left); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write2(g, line, tmp_var); } else { v__gen__c__Gen_write(g, tmp_var); } } else { v__gen__c__Gen_expr(g, left); } v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, array_expr); v__gen__c__Gen_write(g, _S(")")); } else { if ((left)._typ == 344 /* v.ast.CallExpr */) { if (i == 0) { string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, (*left._v__ast__CallExpr).return_type)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, left); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write2(g, line, tmp_var); } else { v__gen__c__Gen_write(g, tmp_var); } } else { v__gen__c__Gen_expr(g, left); } v__gen__c__Gen_write(g, _S(" == ")); if (elem_sym->kind == v__ast__Kind__array_fixed) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, right.elem_type)); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_expr(g, array_expr); } if (i < (int)(right.exprs.len - 1)) { v__gen__c__Gen_write(g, _S(" || ")); } } } VV_LOC void v__gen__c__Gen_infix_expr_is_op(v__gen__c__Gen* g, v__ast__InfixExpr node) { v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, node.left, node.left_type))); bool is_aggregate = (node.left)._typ == 358 /* v.ast.Ident */ && v__type_resolver__ResolverInfo_get_ct_type_var(g->comptime, v__ast__Ident_to_sumtype_v__ast__Expr((v__ast__Ident*)__as_cast((node.left)._v__ast__Ident,(node.left)._typ, 358))) == v__ast__ComptimeVarKind__aggregate; v__ast__TypeSymbol* right_sym = v__ast__Table_sym(g->table, node.right_type); if (left_sym->kind == v__ast__Kind__interface && right_sym->kind == v__ast__Kind__interface) { v__gen__c__Gen_gen_interface_is_op(g, node); return; } string cmp_op = (node.op == v__token__Kind__key_is ? (_S("==")) : (_S("!="))); v__gen__c__Gen_write(g, _S("(")); if (v__ast__Type_nr_muls(node.left_type) > 1) { v__gen__c__Gen_write(g, string_repeat(_S("*"), (int)(v__ast__Type_nr_muls(node.left_type) - 1))); } if (is_aggregate) { v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__ast__Expr_str(&node.left)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_expr(g, node.left); } v__gen__c__Gen_write(g, _S(")")); if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } if (left_sym->kind == v__ast__Kind__interface) { { v__gen__c__Gen_write(g, _S("_typ ")); v__gen__c__Gen_write(g, cmp_op); v__gen__c__Gen_write(g, _S(" ")); } v__ast__Type sub_type = ((node.right._typ == 386 /* v.ast.TypeNode */)? (v__gen__c__Gen_unwrap_generic(g, (*node.right._v__ast__TypeNode).typ)) : (node.right._typ == 371 /* v.ast.None */)? (v__ast__idx_to_type((*(int*)map_get(ADDR(map, g->table->type_idxs), &(string[]){_S("None__")}, &(int[]){ 0 })))) : (_const_v__ast__no_type)); v__ast__TypeSymbol* sub_sym = v__ast__Table_sym(g->table, sub_type); { v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, left_sym->cname); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, sub_sym->cname); v__gen__c__Gen_write(g, _S("_index")); } return; } else if (left_sym->kind == v__ast__Kind__sum_type || is_aggregate) { { v__gen__c__Gen_write(g, _S("_typ ")); v__gen__c__Gen_write(g, cmp_op); v__gen__c__Gen_write(g, _S(" ")); } } if ((node.right)._typ == 371 /* v.ast.None */) { { v__gen__c__Gen_write_decimal(g, v__ast__Type_idx(_const_v__ast__none_type)); } } else if ((node.right)._typ == 358 /* v.ast.Ident */ && string__eq((*(v__ast__Ident*)__as_cast((node.right)._v__ast__Ident,(node.right)._typ, 358)).name, g->comptime->comptime_for_variant_var)) { v__ast__Type variant_idx = v__type_resolver__TypeResolver_get_ct_type_or_default(&g->type_resolver, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->comptime->comptime_for_variant_var}}, {_S(".typ"), 0, { .d_c = 0 }}})), _const_v__ast__void_type); { v__gen__c__Gen_write_decimal(g, ((int)(variant_idx))); } } else { v__gen__c__Gen_expr(g, node.right); } } VV_LOC void v__gen__c__Gen_gen_interface_is_op(v__gen__c__Gen* g, v__ast__InfixExpr node) { v__ast__TypeSymbol* left_sym = v__ast__Table_sym(g->table, node.left_type); v__ast__TypeSymbol* right_sym = v__ast__Table_sym(g->table, node.right_type); v__ast__Interface info = *(v__ast__Interface*)__as_cast((left_sym->info)._v__ast__Interface,(left_sym->info)._typ, 542); sync__RwMutex_lock(&info.conversions->mtx); /*lock*/ { Array_v__ast__Type* _t2 = (Array_v__ast__Type*)(map_get_check(ADDR(map, info.conversions->val), &(int[]){node.right_type})); _option_Array_v__ast__Type _t1 = {0}; if (_t2) { *((Array_v__ast__Type*)&_t1.data) = *((Array_v__ast__Type*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } ; if (_t1.state != 0) { IError err = _t1.err; Array_v__ast__Type left_variants = (*(Array_v__ast__Type*)map_get(ADDR(map, g->table->iface_types), &(string[]){left_sym->name}, &(Array_v__ast__Type[]){ __new_array(0, 0, sizeof(v__ast__Type)) })); Array_v__ast__Type right_variants = (*(Array_v__ast__Type*)map_get(ADDR(map, g->table->iface_types), &(string[]){right_sym->name}, &(Array_v__ast__Type[]){ __new_array(0, 0, sizeof(v__ast__Type)) })); Array_v__ast__Type _t3 = {0}; Array_v__ast__Type _t3_orig = left_variants; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__Type)); for (int _t4 = 0; _t4 < _t3_len; ++_t4) { v__ast__Type it = ((v__ast__Type*) _t3_orig.data)[_t4]; if ((Array_v__ast__Type_contains(right_variants, it))) { array_push((array*)&_t3, &it); } } Array_v__ast__Type c =_t3; (*(Array_v__ast__Type*)map_get_and_set((map*)&info.conversions->val, &(int[]){node.right_type}, &(Array_v__ast__Type[]){ __new_array(0, 0, sizeof(v__ast__Type)) })) = c; *(Array_v__ast__Type*) _t1.data = c; } Array_v__ast__Type common_variants = (*(Array_v__ast__Type*)_t1.data); left_sym->info = v__ast__Interface_to_sumtype_v__ast__TypeInfo(&info); if (common_variants.len == 0) { v__gen__c__Gen_write(g, _S("false")); sync__RwMutex_unlock(&info.conversions->mtx);return; } } sync__RwMutex_unlock(&info.conversions->mtx);; { v__gen__c__Gen_write(g, _S("I_")); v__gen__c__Gen_write(g, left_sym->cname); v__gen__c__Gen_write(g, _S("_is_I_")); v__gen__c__Gen_write(g, right_sym->cname); v__gen__c__Gen_write(g, _S("(")); } if (v__ast__Type_is_ptr(node.left_type)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); } VV_LOC void v__gen__c__Gen_infix_expr_arithmetic_op(v__gen__c__Gen* g, v__ast__InfixExpr node) { v__gen__c__Type left = v__gen__c__Gen_unwrap(g, v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, node.left, node.left_type)); v__gen__c__Type right = v__gen__c__Gen_unwrap(g, v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, node.right, node.right_type)); if ((left.sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((left.sym->info)._v__ast__Struct,(left.sym->info)._typ, 518)).generic_types.len > 0) { string method_name = string__plus(string__plus(left.sym->cname, _S("_")), v__util__replace_op(v__token__Kind_str(node.op))); method_name = v__gen__c__Gen_generic_fn_name(g, (*left.sym->info._v__ast__Struct).concrete_types, method_name); v__gen__c__Gen_write2(g, method_name, _S("(")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _S(")")); } else { v__ast__Fn method = ((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); string method_name = _S(""); if (v__ast__TypeSymbol_has_method(left.sym, v__token__Kind_str(node.op))) { _option_v__ast__Fn _t1 = v__ast__TypeSymbol_find_method(left.sym, v__token__Kind_str(node.op)); if (_t1.state != 0) { IError err = _t1.err; *(v__ast__Fn*) _t1.data = ((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); } method = (*(v__ast__Fn*)_t1.data); method_name = string__plus(string__plus(left.sym->cname, _S("_")), v__util__replace_op(v__token__Kind_str(node.op))); } else if (v__ast__TypeSymbol_has_method_with_generic_parent(left.unaliased_sym, v__token__Kind_str(node.op))) { _option_v__ast__Fn _t2 = v__ast__TypeSymbol_find_method_with_generic_parent(left.unaliased_sym, v__token__Kind_str(node.op)); if (_t2.state != 0) { IError err = _t2.err; *(v__ast__Fn*) _t2.data = ((v__ast__Fn){.is_variadic = 0,.is_c_variadic = 0,.language = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_must_use = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.is_static_type_method = 0,.no_body = 0,.is_file_translated = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.file_mode = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.return_type = 0,.receiver_type = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.params = __new_array(0, 0, sizeof(v__ast__Param)),.source_fn = 0,.usages = 0,.generic_names = __new_array(0, 0, sizeof(string)),.dep_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_conditional = 0,.ctdefine_idx = 0,.from_embedded_type = 0,.is_expand_simple_interpolation = 0,}); } method = (*(v__ast__Fn*)_t2.data); method_name = string__plus(string__plus(left.unaliased_sym->cname, _S("_")), v__util__replace_op(v__token__Kind_str(node.op))); if ((left.unaliased_sym->info)._typ == 518 /* v.ast.Struct */ && (*(v__ast__Struct*)__as_cast((left.unaliased_sym->info)._v__ast__Struct,(left.unaliased_sym->info)._typ, 518)).generic_types.len > 0) { method_name = v__gen__c__Gen_generic_fn_name(g, (*left.unaliased_sym->info._v__ast__Struct).concrete_types, method_name); } } else { v__gen__c__Gen_gen_plain_infix_expr(g, node); return; } string right_var = _S(""); if ((node.right)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node.right)._v__ast__Ident,(node.right)._typ, 358)).or_expr.kind != v__ast__OrKind__absent) { string cur_line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); right_var = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, right.typ)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, right_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_op_arg(g, node.right, (*(v__ast__Param*)array_get(method.params, 1)).typ, right.typ); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write(g, cur_line); } v__gen__c__Gen_write2(g, method_name, _S("(")); v__gen__c__Gen_op_arg(g, node.left, (*(v__ast__Param*)array_get(method.params, 0)).typ, left.typ); if ((right_var).len != 0) { { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, right_var); } } else { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_op_arg(g, node.right, (*(v__ast__Param*)array_get(method.params, 1)).typ, right.typ); } v__gen__c__Gen_write(g, _S(")")); if (left.typ != 0 && !v__ast__Type_has_option_or_result(left.typ) && v__ast__Table_final_sym(g->table, left.typ)->kind == v__ast__Kind__array_fixed) { v__gen__c__Gen_write(g, _S(".ret_arr")); } } } VV_LOC void v__gen__c__Gen_infix_expr_left_shift_op(v__gen__c__Gen* g, v__ast__InfixExpr node) { v__gen__c__Type left = v__gen__c__Gen_unwrap(g, node.left_type); v__gen__c__Type right = v__gen__c__Gen_unwrap(g, node.right_type); if (left.unaliased_sym->kind == v__ast__Kind__array) { string tmp_var = v__gen__c__Gen_new_tmp_var(g); v__ast__Array array_info = *(v__ast__Array*)__as_cast((left.unaliased_sym->info)._v__ast__Array,(left.unaliased_sym->info)._typ, 513); string noscan = v__gen__c__Gen_check_noscan(g, array_info.elem_type); bool elem_is_option = v__ast__Type_has_flag(array_info.elem_type, v__ast__TypeFlag__option); if ((right.unaliased_sym->kind == v__ast__Kind__array || (right.unaliased_sym->kind == v__ast__Kind__struct && fast_string_eq(right.unaliased_sym->name, _S("array")))) && v__ast__TypeSymbol_nr_dims(left.sym) == v__ast__TypeSymbol_nr_dims(right.sym) && array_info.elem_type != right.typ && !elem_is_option && !(right.sym->kind == v__ast__Kind__alias && v__ast__Table_sumtype_has_variant(g->table, array_info.elem_type, node.right_type, false))) { { v__gen__c__Gen_write(g, _S("_PUSH_MANY")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("(")); } v__ast__Type expected_push_many_atype = left.typ; bool is_shared = v__ast__Type_has_flag(expected_push_many_atype, v__ast__TypeFlag__shared_f); if (!v__ast__Type_is_ptr(expected_push_many_atype)) { v__gen__c__Gen_write(g, _S("&")); } else { expected_push_many_atype = v__ast__Type_deref(expected_push_many_atype); } if (is_shared) { v__gen__c__Gen_write(g, _S("&")); } if (is_shared) { expected_push_many_atype = v__ast__Type_clear_flag(expected_push_many_atype, v__ast__TypeFlag__shared_f); } v__gen__c__Gen_expr(g, node.left); if (v__ast__Type_has_flag(node.left_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("->val")); } if (v__ast__Type_is_ptr(left.typ) && v__ast__Type_is_ptr(right.typ)) { v__gen__c__Gen_write(g, _S(", *(")); } else { v__gen__c__Gen_write(g, _S(", (")); } v__gen__c__Gen_expr_with_cast(g, node.right, right.typ, v__ast__Type_clear_flag(left.unaliased, v__ast__TypeFlag__shared_f)); string styp = v__gen__c__Gen_styp(g, expected_push_many_atype); { v__gen__c__Gen_write(g, _S("), ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(")")); } } else { string elem_type_str = v__gen__c__Gen_styp(g, array_info.elem_type); v__ast__TypeSymbol* elem_sym = v__ast__Table_final_sym(g->table, array_info.elem_type); bool elem_is_array_var = !elem_is_option && (elem_sym->kind == v__ast__Kind__array || elem_sym->kind == v__ast__Kind__array_fixed) && (node.right)._typ == 358 /* v.ast.Ident */; { v__gen__c__Gen_write(g, _S("array_push")); v__gen__c__Gen_write(g, noscan); v__gen__c__Gen_write(g, _S("((array*)")); } bool needs_addr = false; if (!v__ast__Type_is_ptr(left.typ) || (v__ast__Type_has_flag(node.left_type, v__ast__TypeFlag__shared_f) && !v__ast__Type_is_ptr(v__ast__Type_deref(node.left_type)))) { if ((node.left)._typ == 344 /* v.ast.CallExpr */) { { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, node.left_type)); v__gen__c__Gen_write(g, _S(", ")); } needs_addr = true; } else { v__gen__c__Gen_write(g, _S("&")); } } v__gen__c__Gen_expr(g, node.left); if (v__ast__Type_has_flag(node.left_type, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("->val")); } if (needs_addr) { v__gen__c__Gen_write(g, _S(")")); } if (elem_sym->kind == v__ast__Kind__function) { v__gen__c__Gen_write(g, _S(", _MOV((voidptr[]){ ")); } else if (elem_is_array_var) { string addr = (elem_sym->kind == v__ast__Kind__array_fixed ? (_S("")) : (_S("&"))); { v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, addr); } } else { { v__gen__c__Gen_write(g, _S(", _MOV((")); v__gen__c__Gen_write(g, elem_type_str); v__gen__c__Gen_write(g, _S("[]){ ")); } } if (v__ast__Type_has_flag(array_info.elem_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_opt(g, node.right, right.typ, array_info.elem_type); } else { bool needs_clone = !g->is_builtin_mod && v__ast__Type_idx(array_info.elem_type) == 21 && v__ast__Type_nr_muls(array_info.elem_type) == 0 && !((node.right)._typ == 384 /* v.ast.StringLiteral */ || (node.right)._typ == 383 /* v.ast.StringInterLiteral */ || (node.right)._typ == 344 /* v.ast.CallExpr */ || (node.right)._typ == 361 /* v.ast.IndexExpr */ || (node.right)._typ == 362 /* v.ast.InfixExpr */); if (needs_clone) { v__gen__c__Gen_write(g, _S("string_clone(")); } if ((node.right)._typ == 345 /* v.ast.CastExpr */ && ((*(v__ast__CastExpr*)__as_cast((node.right)._v__ast__CastExpr,(node.right)._typ, 345)).expr)._typ == 338 /* v.ast.ArrayInit */) { v__gen__c__Gen_expr(g, (*node.right._v__ast__CastExpr).expr); } else if ((elem_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && ((node.right)._typ == 344 /* v.ast.CallExpr */ || (node.right)._typ == 353 /* v.ast.DumpExpr */)) { string tmpvar = v__gen__c__Gen_expr_with_var(g, node.right, array_info.elem_type, false); v__gen__c__Gen_fixed_array_var_init(g, tmpvar, false, (*elem_sym->info._v__ast__ArrayFixed).elem_type, (*elem_sym->info._v__ast__ArrayFixed).size); } else { v__gen__c__Gen_expr_with_cast(g, node.right, right.typ, array_info.elem_type); } if (needs_clone) { v__gen__c__Gen_write(g, _S(")")); } } if (elem_is_array_var) { v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_write(g, _S(" }))")); } } } else { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_gen_plain_infix_expr(g, node); v__gen__c__Gen_write(g, _S(")")); } } VV_LOC bool v__gen__c__Gen_need_tmp_var_in_array_call(v__gen__c__Gen* g, v__ast__Expr node) { if (node._typ == 344 /* v.ast.CallExpr */) { if ((*node._v__ast__CallExpr).left_type != 0 && v__ast__Table_sym(g->table, (*node._v__ast__CallExpr).left_type)->kind == v__ast__Kind__array && (fast_string_eq((*node._v__ast__CallExpr).name, _S("all")) || fast_string_eq((*node._v__ast__CallExpr).name, _S("any")) || fast_string_eq((*node._v__ast__CallExpr).name, _S("filter")) || fast_string_eq((*node._v__ast__CallExpr).name, _S("map")) || fast_string_eq((*node._v__ast__CallExpr).name, _S("count")))) { return true; } } else if (node._typ == 361 /* v.ast.IndexExpr */) { return v__gen__c__Gen_need_tmp_var_in_array_call(g, (*node._v__ast__IndexExpr).left); } else if (node._typ == 362 /* v.ast.InfixExpr */) { return v__gen__c__Gen_need_tmp_var_in_array_call(g, (*node._v__ast__InfixExpr).left) || v__gen__c__Gen_need_tmp_var_in_array_call(g, (*node._v__ast__InfixExpr).right); } else if (node._typ == 374 /* v.ast.ParExpr */) { return v__gen__c__Gen_need_tmp_var_in_array_call(g, (*node._v__ast__ParExpr).expr); } else if (node._typ == 375 /* v.ast.PostfixExpr */) { return v__gen__c__Gen_need_tmp_var_in_array_call(g, (*node._v__ast__PostfixExpr).expr); } else if (node._typ == 376 /* v.ast.PrefixExpr */) { return v__gen__c__Gen_need_tmp_var_in_array_call(g, (*node._v__ast__PrefixExpr).right); } else if (node._typ == 377 /* v.ast.RangeExpr */) { return v__gen__c__Gen_need_tmp_var_in_array_call(g, (*node._v__ast__RangeExpr).low) || v__gen__c__Gen_need_tmp_var_in_array_call(g, (*node._v__ast__RangeExpr).high); } else if (node._typ == 379 /* v.ast.SelectorExpr */) { return v__gen__c__Gen_need_tmp_var_in_array_call(g, (*node._v__ast__SelectorExpr).expr); } else { } return false; } VV_LOC void v__gen__c__Gen_infix_expr_and_or_op(v__gen__c__Gen* g, v__ast__InfixExpr node) { if (v__gen__c__Gen_need_tmp_var_in_array_call(g, node.right)) { string tmp = v__gen__c__Gen_new_tmp_var(g); string cur_line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; if (g->infix_left_var_name.len > 0) { { v__gen__c__Gen_write(g, _S("bool ")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S(" = ((")); v__gen__c__Gen_write(g, g->infix_left_var_name); v__gen__c__Gen_write(g, _S(") ")); v__gen__c__Gen_write(g, v__token__Kind_str(node.op)); v__gen__c__Gen_write(g, _S(" ")); } } else { { v__gen__c__Gen_write(g, _S("bool ")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S(" = (")); } } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_writeln(g, _S(");")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); { v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, v__token__Kind_str(node.op)); v__gen__c__Gen_write(g, _S(" ")); } g->infix_left_var_name = (node.op == v__token__Kind__and ? (tmp) : (str_intp(2, _MOV((StrIntpData[]){{_S("!"), 0xfe10, {.d_s = tmp}}, {_SLIT0, 0, { .d_c = 0 }}})))); v__gen__c__Gen_expr(g, node.right); g->infix_left_var_name = _S(""); } else if (v__gen__c__Gen_need_tmp_var_in_expr(g, node.right) && g->inside_ternary == 0) { int prev_inside_ternary = g->inside_ternary; g->inside_ternary = 0; string tmp = v__gen__c__Gen_new_tmp_var(g); string cur_line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; { v__gen__c__Gen_write(g, _S("bool ")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S(" = (")); } v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_writeln(g, _S(");")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); { v__gen__c__Gen_write(g, cur_line); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, v__token__Kind_str(node.op)); v__gen__c__Gen_write(g, _S(" ")); } g->infix_left_var_name = (node.op == v__token__Kind__and ? (tmp) : (str_intp(2, _MOV((StrIntpData[]){{_S("!"), 0xfe10, {.d_s = tmp}}, {_SLIT0, 0, { .d_c = 0 }}})))); v__gen__c__Gen_expr(g, node.right); g->infix_left_var_name = _S(""); g->inside_ternary = prev_inside_ternary; } else { v__gen__c__Gen_gen_plain_infix_expr(g, node); } } VV_LOC void v__gen__c__Gen_gen_is_none_check(v__gen__c__Gen* g, v__ast__InfixExpr node) { if ((node.left)._typ == 358 /* v.ast.Ident */ || (node.left)._typ == 379 /* v.ast.SelectorExpr */ || (node.left)._typ == 361 /* v.ast.IndexExpr */ || (node.left)._typ == 344 /* v.ast.CallExpr */) { bool old_inside_opt_or_res = g->inside_opt_or_res; g->inside_opt_or_res = true; v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_expr(g, node.left); v__gen__c__Gen_write(g, _S(")")); g->inside_opt_or_res = old_inside_opt_or_res; string dot_or_ptr = (!v__ast__Type_has_flag(node.left_type, v__ast__TypeFlag__option_mut_param_t) ? (_S(".")) : (_S("->"))); { v__gen__c__Gen_write(g, dot_or_ptr); v__gen__c__Gen_write(g, _S("state")); } } else { string stmt_str = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; string left_var = v__gen__c__Gen_expr_with_opt(g, node.left, node.left_type, node.left_type); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write2(g, stmt_str, _S(" ")); string dot_or_ptr = (!v__ast__Type_has_flag(node.left_type, v__ast__TypeFlag__option_mut_param_t) ? (_S(".")) : (_S("->"))); { v__gen__c__Gen_write(g, left_var); v__gen__c__Gen_write(g, dot_or_ptr); v__gen__c__Gen_write(g, _S("state")); } } { v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, v__token__Kind_str(node.op)); v__gen__c__Gen_write(g, _S(" 2")); } } VV_LOC void v__gen__c__Gen_gen_plain_infix_expr(v__gen__c__Gen* g, v__ast__InfixExpr node) { bool v__gen__c__Gen_gen_plain_infix_expr_defer_0 = false; bool inside_interface_deref_old; bool needs_cast = v__ast__Type_is_number(node.left_type) && v__ast__Type_is_number(node.right_type) && (node.op == v__token__Kind__plus || node.op == v__token__Kind__minus || node.op == v__token__Kind__mul || node.op == v__token__Kind__div || node.op == v__token__Kind__mod) && !(g->pref->translated || g->file->is_translated); v__ast__Type typ = node.promoted_type; string typ_str = v__gen__c__Gen_styp(g, typ); if (needs_cast) { typ = (node.left_ct_expr ? (v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, node.left, node.left_type)) : !((node.left)._typ == 358 /* v.ast.Ident */ || (node.left)._typ == 345 /* v.ast.CastExpr */) && node.right_ct_expr ? (v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, node.right, node.promoted_type)) : (node.promoted_type)); typ_str = v__gen__c__Gen_styp(g, typ); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, typ_str); v__gen__c__Gen_write(g, _S(")(")); } } bool is_safe_div = node.op == v__token__Kind__div && g->pref->div_by_zero_is_zero && v__ast__Type_is_int(typ); bool is_safe_mod = node.op == v__token__Kind__mod && g->pref->div_by_zero_is_zero && v__ast__Type_is_int(typ); if (v__ast__Type_is_ptr(node.left_type) && v__ast__Expr_is_auto_deref_var(node.left) && !v__ast__Type_is_pointer(node.right_type)) { v__gen__c__Gen_write(g, _S("*")); } else if (!g->inside_interface_deref && (node.left)._typ == 358 /* v.ast.Ident */ && v__ast__Table_is_interface_var(g->table, (*(v__ast__Ident*)__as_cast((node.left)._v__ast__Ident,(node.left)._typ, 358)).obj)) { inside_interface_deref_old = g->inside_interface_deref; g->inside_interface_deref = true; v__gen__c__Gen_gen_plain_infix_expr_defer_0 = true; } bool is_ctemp_fixed_ret = (node.op == v__token__Kind__eq || node.op == v__token__Kind__ne) && (node.left)._typ == 343 /* v.ast.CTempVar */ && (*(v__ast__CTempVar*)__as_cast((node.left)._v__ast__CTempVar,(node.left)._typ, 343)).is_fixed_ret; if (is_ctemp_fixed_ret) { if (node.op == v__token__Kind__eq) { v__gen__c__Gen_write(g, _S("!")); } v__gen__c__Gen_write(g, _S("memcmp(")); } string opstr = v__token__Kind_str(node.op); if (is_safe_div || is_safe_mod) { string vsafe_fn_name = (is_safe_div ? (str_intp(2, _MOV((StrIntpData[]){{_S("VSAFE_DIV_"), 0xfe10, {.d_s = typ_str}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("VSAFE_MOD_"), 0xfe10, {.d_s = typ_str}}, {_SLIT0, 0, { .d_c = 0 }}})))); v__gen__c__Gen_write(g, vsafe_fn_name); v__gen__c__Gen_write(g, _S("(")); (*(v__gen__c__VSafeArithmeticOp*)map_get_and_set((map*)&g->vsafe_arithmetic_ops, &(string[]){vsafe_fn_name}, &(v__gen__c__VSafeArithmeticOp[]){ (v__gen__c__VSafeArithmeticOp){.typ = 0,.op = 0,} })) = ((v__gen__c__VSafeArithmeticOp){.typ = typ,.op = node.op,}); opstr = _S(","); } v__gen__c__Gen_expr(g, node.left); if (!is_ctemp_fixed_ret) { v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, opstr); v__gen__c__Gen_write(g, _S(" ")); } else { v__gen__c__Gen_write(g, _S(", ")); } if (is_ctemp_fixed_ret) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, node.right_type)); v__gen__c__Gen_write(g, _S(")")); } } if (v__ast__Type_is_ptr(node.right_type) && v__ast__Expr_is_auto_deref_var(node.right) && !v__ast__Type_is_pointer(node.left_type)) { v__gen__c__Gen_write(g, _S("*")); v__gen__c__Gen_expr(g, node.right); } else { v__gen__c__Gen_expr_with_cast(g, node.right, node.right_type, node.left_type); } if (is_ctemp_fixed_ret) { { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, node.right_type)); v__gen__c__Gen_write(g, _S("))")); } } if (is_safe_div || is_safe_mod) { v__gen__c__Gen_write(g, _S(")")); } if (needs_cast) { v__gen__c__Gen_write(g, _S(")")); } // Defer begin if (v__gen__c__Gen_gen_plain_infix_expr_defer_0) { g->inside_interface_deref = inside_interface_deref_old; } // Defer end } VV_LOC void v__gen__c__Gen_op_arg(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type expected, v__ast__Type got) { bool needs_closing = false; int nr_muls = v__ast__Type_nr_muls(got); if (v__ast__Type_is_ptr(expected)) { if (nr_muls > 0) { nr_muls--; } else { if (v__ast__Expr_is_lvalue(expr)) { v__gen__c__Gen_write(g, _S("&")); } else { string styp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(got, 0)); { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(", ")); } needs_closing = true; } } } v__gen__c__Gen_write(g, string_repeat(_S("*"), nr_muls)); v__gen__c__Gen_expr(g, expr); if (needs_closing) { v__gen__c__Gen_write(g, _S(")")); } } VV_LOC void v__gen__c__Gen_gen_safe_integer_infix_expr(v__gen__c__Gen* g, v__gen__c__GenSafeIntegerCfg cfg) { int bitsize = (v__ast__Type_idx(cfg.unsigned_type) == 13 && v__ast__Type_idx(cfg.signed_type) != 9 ? (32) : (64)); int op_idx = (int)(((int)(cfg.op)) - ((int)(v__token__Kind__eq))); string op_str = (cfg.reverse ? ((*(string*)array_get(_const_v__gen__c__cmp_rev, op_idx))) : ((*(string*)array_get(_const_v__gen__c__cmp_str, op_idx)))); { v__gen__c__Gen_write(g, _S("_us")); v__gen__c__Gen_write_decimal(g, bitsize); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, op_str); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_expr(g, cfg.unsigned_expr); v__gen__c__Gen_write(g, _S(",")); v__gen__c__Gen_expr(g, cfg.signed_expr); v__gen__c__Gen_write(g, _S(")")); } VV_LOC void v__gen__c__Gen_gen_json_for_type(v__gen__c__Gen* g, v__ast__Type typ) { v__ast__Type utyp = v__gen__c__Gen_unwrap_generic(g, typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, utyp); if (v__gen__c__is_js_prim(sym->name) && !v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option) && !v__ast__Type_is_ptr(typ)) { return; } array_push((array*)&g->json_types, _MOV((v__ast__Type[]){ utyp })); } VV_LOC void v__gen__c__Gen_gen_jsons(v__gen__c__Gen* g) { Array_v__ast__Type done = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int i = 0; i < g->json_types.len; i++) { v__ast__Type utyp = (*(v__ast__Type*)array_get(g->json_types, i)); if ((Array_v__ast__Type_contains(done, utyp))) { continue; } array_push((array*)&done, _MOV((v__ast__Type[]){ utyp })); strings__Builder dec = strings__new_builder(100); strings__Builder enc = strings__new_builder(100); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, utyp); string styp = v__gen__c__Gen_styp(g, utyp); string ret_styp = string_replace(styp, _S("*"), _S("_ptr")); if (v__ast__Type_is_ptr(utyp) && v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { v__gen__c__Gen_register_option(g, v__ast__Type_set_nr_muls(utyp, 0)); } v__gen__c__Gen_register_result(g, utyp); string dec_fn_name = v__gen__c__js_dec_name(styp); string dec_fn_dec = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ret_styp}}, {_S(" "), 0xfe10, {.d_s = dec_fn_name}}, {_S("(cJSON* root)"), 0, { .d_c = 0 }}})); string init_styp = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" res"), 0, { .d_c = 0 }}})); if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { string none_str = v__gen__c__Gen_expr_string(g, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}))))); init_styp = string__plus(init_styp, str_intp(3, _MOV((StrIntpData[]){{_S(" = ("), 0xfe10, {.d_s = styp}}, {_S("){ .state=2, .err="), 0xfe10, {.d_s = none_str}}, {_S(", .data={E_STRUCT} }"), 0, { .d_c = 0 }}}))); } else { if (!v__ast__Type_is_ptr(utyp)) { init_styp = string__plus(init_styp, _S(" = ")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); int pos = g->out.len; v__gen__c__Gen_write(g, v__gen__c__Gen_type_default(g, utyp)); string init_generated = string_trim_space(strings__Builder_cut_to(&g->out, pos)); if (g->type_default_vars.len > 0) { string saved_init = init_styp; init_styp = Array_u8_bytestr(g->type_default_vars); init_styp = string__plus(init_styp, _S("\n")); init_styp = string__plus(init_styp, saved_init); array_clear(&g->type_default_vars); } init_styp = string__plus(init_styp, init_generated); } else if (v__ast__Type_is_ptr(utyp)) { string ptr_styp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(utyp, (int)(v__ast__Type_nr_muls(utyp) - 1))); init_styp = string__plus(init_styp, str_intp(2, _MOV((StrIntpData[]){{_S(" = HEAP("), 0xfe10, {.d_s = ptr_styp}}, {_S(", {0})"), 0, { .d_c = 0 }}}))); } } strings__Builder_writeln(&dec, str_intp(5, _MOV((StrIntpData[]){{_S("\n"), 0xfe10, {.d_s = dec_fn_dec}}, {_S(" {\n\011"), 0xfe10, {.d_s = init_styp}}, {_S(";\n\011if (!root) {\n\011\011const char *error_ptr = cJSON_GetErrorPtr();\n\011\011if (error_ptr != NULL) {\n\011\011\011const int error_pos = (int)cJSON_GetErrorPos();\n\011\011\011int maxcontext_chars = 30;\n\011\011\011byte *buf = vcalloc_noscan(maxcontext_chars + 10);\n\011\011\011if (error_pos > 0) {\n\011\011\011\011int backlines = 1;\n\011\011\011\011int backchars = error_pos < maxcontext_chars-7 ? (int)error_pos : maxcontext_chars-7 ;\n\011\011\011\011char *prevline_ptr = (char*)error_ptr;\n\011\011\011\011while(backchars--){\n\011\011\011\011\011char prevc = *(prevline_ptr - 1);\n\011\011\011\011\011if(0==prevc){\n\011\011\011\011\011\011break;\n\011\011\011\011\011}\n\011\011\011\011\011if(10==prevc && !backlines--){\n\011\011\011\011\011\011break;\n\011\011\011\011\011}\n\011\011\011\011\011prevline_ptr--;\n\011\011\011\011\011if(123==prevc) {\n\011\011\011\011\011\011break; // stop at `{` too\n\011\011\011\011\011}\n\011\011\011\011}\n\011\011\011\011int maxchars = vstrlen_char(prevline_ptr);\n\011\011\011\011vmemcpy(buf, prevline_ptr, (maxchars < maxcontext_chars ? maxchars : maxcontext_chars));\n\011\011\011}\n\011\011\011string msg;\n\011\011\011msg = _S(\"failed to decode JSON string\");\n\011\011\011if (buf[0] != \'\\0\') {\n\011\011\011\011msg = string__plus(msg, _S(\": \"));\n\011\011\011}\n\011\011\011return ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ret_styp}}, {_S("){.is_error = true,.err = _v_error(string__plus(msg, tos2(buf))),.data = {0}};\n\011\011}\n\011}\n"), 0, { .d_c = 0 }}}))); string extern_str = (g->pref->parallel_cc ? (_S("extern ")) : (_S(""))); strings__Builder_writeln(&g->json_forward_decls, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = extern_str}}, {_SLIT0, 0xfe10, {.d_s = dec_fn_dec}}, {_S(";"), 0, { .d_c = 0 }}}))); string enc_fn_name = v__gen__c__js_enc_name(styp); string enc_fn_dec = str_intp(3, _MOV((StrIntpData[]){{_S("cJSON* "), 0xfe10, {.d_s = enc_fn_name}}, {_S("("), 0xfe10, {.d_s = styp}}, {_S(" val)"), 0, { .d_c = 0 }}})); strings__Builder_writeln(&g->json_forward_decls, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = extern_str}}, {_SLIT0, 0xfe10, {.d_s = enc_fn_dec}}, {_S(";\n"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&enc, str_intp(2, _MOV((StrIntpData[]){{_S("\n"), 0xfe10, {.d_s = enc_fn_dec}}, {_S(" {\n\tcJSON *o;"), 0, { .d_c = 0 }}}))); if (v__gen__c__is_js_prim(sym->name) && v__ast__Type_is_ptr(utyp)) { v__gen__c__Gen_gen_prim_enc_dec(g, utyp, (voidptr)&enc, (voidptr)&dec); } else if (sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__array_fixed) { int array_size = (sym->kind == v__ast__Kind__array_fixed ? ((*(v__ast__ArrayFixed*)__as_cast((sym->info)._v__ast__ArrayFixed,(sym->info)._typ, 549)).size) : (-1)); v__ast__Type value_type = v__ast__Table_value_type(g->table, utyp); v__gen__c__Gen_gen_json_for_type(g, value_type); strings__Builder_writeln(&dec, v__gen__c__Gen_decode_array(g, utyp, value_type, array_size, ret_styp)); strings__Builder_writeln(&enc, v__gen__c__Gen_encode_array(g, utyp, value_type, array_size)); } else if (sym->kind == v__ast__Kind__map) { v__ast__Map m = *(v__ast__Map*)__as_cast((sym->info)._v__ast__Map,(sym->info)._typ, 514); v__gen__c__Gen_gen_json_for_type(g, m.key_type); v__gen__c__Gen_gen_json_for_type(g, m.value_type); strings__Builder_writeln(&dec, v__gen__c__Gen_decode_map(g, utyp, m.key_type, m.value_type, ret_styp)); strings__Builder_writeln(&enc, v__gen__c__Gen_encode_map(g, utyp, m.key_type, m.value_type)); } else if (sym->kind == v__ast__Kind__alias) { v__ast__Alias a = *(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539); v__ast__Type parent_typ = a.parent_type; v__ast__TypeSymbol* psym = v__ast__Table_sym(g->table, parent_typ); if (v__gen__c__is_js_prim(v__gen__c__Gen_styp(g, parent_typ))) { if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { v__gen__c__Gen_gen_json_for_type(g, v__ast__Type_set_flag(parent_typ, v__ast__TypeFlag__option)); v__gen__c__Gen_gen_option_enc_dec(g, v__ast__Type_set_flag(parent_typ, v__ast__TypeFlag__option), (voidptr)&enc, (voidptr)&dec); } else { v__gen__c__Gen_gen_json_for_type(g, parent_typ); v__gen__c__Gen_gen_prim_enc_dec(g, parent_typ, (voidptr)&enc, (voidptr)&dec); } } else if ((psym->info)._typ == 518 /* v.ast.Struct */) { strings__Builder_writeln(&enc, _S("\to = cJSON_CreateObject();")); v__gen__c__Gen_gen_struct_enc_dec(g, utyp, psym->info, ret_styp, (voidptr)&enc, (voidptr)&dec, _S("")); } else if (psym->kind == v__ast__Kind__enum) { v__gen__c__Gen_gen_enum_enc_dec(g, utyp, *psym, (voidptr)&enc, (voidptr)&dec); } else if (psym->kind == v__ast__Kind__sum_type) { v__gen__c__verror(str_intp(2, _MOV((StrIntpData[]){{_S("json: "), 0xfe10, {.d_s = sym->name}}, {_S(" aliased sumtypes does not work at the moment"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } else if (psym->kind == v__ast__Kind__map) { v__ast__Map m = *(v__ast__Map*)__as_cast((psym->info)._v__ast__Map,(psym->info)._typ, 514); v__gen__c__Gen_gen_json_for_type(g, m.key_type); v__gen__c__Gen_gen_json_for_type(g, m.value_type); strings__Builder_writeln(&dec, v__gen__c__Gen_decode_map(g, utyp, m.key_type, m.value_type, ret_styp)); strings__Builder_writeln(&enc, v__gen__c__Gen_encode_map(g, utyp, m.key_type, m.value_type)); } else if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { v__gen__c__Gen_gen_option_enc_dec(g, utyp, (voidptr)&enc, (voidptr)&dec); } else { v__gen__c__verror(str_intp(2, _MOV((StrIntpData[]){{_S("json: "), 0xfe10, {.d_s = sym->name}}, {_S(" is not struct"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } } else if (sym->kind == v__ast__Kind__sum_type) { strings__Builder_writeln(&enc, _S("\to = cJSON_CreateObject();")); if ((sym->info)._typ != 544 /* v.ast.SumType */) { v__gen__c__verror(str_intp(2, _MOV((StrIntpData[]){{_S("json: "), 0xfe10, {.d_s = sym->name}}, {_S(" is not a sumtype"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } v__gen__c__Gen_gen_sumtype_enc_dec(g, utyp, *sym, (voidptr)&enc, (voidptr)&dec, ret_styp); } else if (sym->kind == v__ast__Kind__enum) { v__gen__c__Gen_gen_enum_enc_dec(g, utyp, *sym, (voidptr)&enc, (voidptr)&dec); } else if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option) && (v__gen__c__is_js_prim(v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(utyp, v__ast__TypeFlag__option))) || (sym->info)._typ != 518 /* v.ast.Struct */)) { v__gen__c__Gen_gen_option_enc_dec(g, utyp, (voidptr)&enc, (voidptr)&dec); } else { strings__Builder_writeln(&enc, _S("\to = cJSON_CreateObject();")); if ((sym->info)._typ != 518 /* v.ast.Struct */) { v__gen__c__verror(str_intp(2, _MOV((StrIntpData[]){{_S("json: "), 0xfe10, {.d_s = sym->name}}, {_S(" is not struct"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } v__gen__c__Gen_gen_struct_enc_dec(g, utyp, sym->info, ret_styp, (voidptr)&enc, (voidptr)&dec, _S("")); } strings__Builder_writeln(&dec, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ret_styp}}, {_S(" ret;"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t_result_ok(&res, ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("*)&ret, sizeof(res));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&dec, _S("\treturn ret;\n}")); strings__Builder_writeln(&enc, _S("\treturn o;\n}")); strings__Builder_writeln(&g->gowrappers, strings__Builder_str(&dec)); strings__Builder_writeln(&g->gowrappers, strings__Builder_str(&enc)); } } inline VV_LOC void v__gen__c__Gen_gen_enum_to_str(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__TypeSymbol sym, string enum_var, string result_var, string ident, strings__Builder* enc) { string enum_prefix = v__gen__c__Gen_gen_enum_prefix(g, v__ast__Type_clear_flag(utyp, v__ast__TypeFlag__option)); strings__Builder_writeln(enc, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ident}}, {_S("switch ("), 0xfe10, {.d_s = enum_var}}, {_S(") {"), 0, { .d_c = 0 }}}))); for (int _t1 = 0; _t1 < (*(v__ast__Enum*)__as_cast((sym.info)._v__ast__Enum,(sym.info)._typ, 548)).vals.len; ++_t1) { string val = ((string*)(*(v__ast__Enum*)__as_cast((sym.info)._v__ast__Enum,(sym.info)._typ, 548)).vals.data)[_t1]; { strings__Builder_write_string(enc, ident); strings__Builder_write_string(enc, _S("\tcase ")); strings__Builder_write_string(enc, enum_prefix); strings__Builder_write_string(enc, val); strings__Builder_write_string(enc, _S(":\t")); } Array_v__ast__EnumField _t3 = {0}; Array_v__ast__EnumField _t3_orig = (*(v__ast__EnumDecl*)map_get(ADDR(map, g->table->enum_decls), &(string[]){sym.name}, &(v__ast__EnumDecl[]){ (v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},} })).fields; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(v__ast__EnumField)); for (int _t4 = 0; _t4 < _t3_len; ++_t4) { v__ast__EnumField it = ((v__ast__EnumField*) _t3_orig.data)[_t4]; if (string__eq(it.name, val)) { array_push((array*)&_t3, &it); } } _option_v__ast__Attr _t2 = Array_v__ast__Attr_find_first((*(v__ast__EnumField*)array_get(_t3, 0)).attrs, _S("json")); if (_t2.state != 0) { IError err = _t2.err; *(v__ast__Attr*) _t2.data = ((v__ast__Attr){.name = (string){.str=(byteptr)"", .is_lit=1},.has_arg = 0,.arg = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.ct_opt = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_at = 0,.ct_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.ct_evaled = 0,.ct_skip = 0,}); } v__ast__Attr attr = (*(v__ast__Attr*)_t2.data); if (attr.has_arg) { strings__Builder_writeln(enc, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = result_var}}, {_S(" = json__encode_string(_S(\""), 0xfe10, {.d_s = attr.arg}}, {_S("\")); break;"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(enc, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = result_var}}, {_S(" = json__encode_string(_S(\""), 0xfe10, {.d_s = val}}, {_S("\")); break;"), 0, { .d_c = 0 }}}))); } } strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ident}}, {_S("}"), 0, { .d_c = 0 }}}))); } inline VV_LOC void v__gen__c__Gen_gen_str_to_enum(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__TypeSymbol sym, string val_var, string result_var, string ident, strings__Builder* dec) { string enum_prefix = v__gen__c__Gen_gen_enum_prefix(g, v__ast__Type_clear_flag(utyp, v__ast__TypeFlag__option)); bool is_option = v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option); for (int k = 0; k < (*(v__ast__Enum*)__as_cast((sym.info)._v__ast__Enum,(sym.info)._typ, 548)).vals.len; ++k) { string val = ((string*)(*(v__ast__Enum*)__as_cast((sym.info)._v__ast__Enum,(sym.info)._typ, 548)).vals.data)[k]; Array_v__ast__EnumField _t2 = {0}; Array_v__ast__EnumField _t2_orig = (*(v__ast__EnumDecl*)map_get(ADDR(map, g->table->enum_decls), &(string[]){sym.name}, &(v__ast__EnumDecl[]){ (v__ast__EnumDecl){.name = (string){.str=(byteptr)"", .is_lit=1},.is_pub = 0,.is_flag = 0,.is_multi_allowed = 0,.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.fields = __new_array(0, 0, sizeof(v__ast__EnumField)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.typ = 0,.typ_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},} })).fields; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(v__ast__EnumField)); for (int _t3 = 0; _t3 < _t2_len; ++_t3) { v__ast__EnumField it = ((v__ast__EnumField*) _t2_orig.data)[_t3]; if (string__eq(it.name, val)) { array_push((array*)&_t2, &it); } } _option_v__ast__Attr _t1 = Array_v__ast__Attr_find_first((*(v__ast__EnumField*)array_get(_t2, 0)).attrs, _S("json")); if (_t1.state != 0) { IError err = _t1.err; *(v__ast__Attr*) _t1.data = ((v__ast__Attr){.name = (string){.str=(byteptr)"", .is_lit=1},.has_arg = 0,.arg = (string){.str=(byteptr)"", .is_lit=1},.kind = 0,.ct_opt = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.has_at = 0,.ct_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.ct_evaled = 0,.ct_skip = 0,}); } v__ast__Attr attr = (*(v__ast__Attr*)_t1.data); if (k == 0) { { strings__Builder_write_string(dec, ident); strings__Builder_write_string(dec, _S("if (string__eq(_S(\"")); strings__Builder_write_string(dec, val); strings__Builder_write_string(dec, _S("\"), ")); strings__Builder_write_string(dec, val_var); strings__Builder_write_string(dec, _S(")")); } } else { { strings__Builder_write_string(dec, ident); strings__Builder_write_string(dec, _S("else if (string__eq(_S(\"")); strings__Builder_write_string(dec, val); strings__Builder_write_string(dec, _S("\"), ")); strings__Builder_write_string(dec, val_var); strings__Builder_write_string(dec, _S(")")); } } if (attr.has_arg) { { strings__Builder_write_string(dec, _S(" || string__eq(_S(\"")); strings__Builder_write_string(dec, attr.arg); strings__Builder_write_string(dec, _S("\"), ")); strings__Builder_write_string(dec, val_var); strings__Builder_write_string(dec, _S(")")); } } strings__Builder_write_string(dec, _S(")\t")); if (is_option) { string base_typ = v__gen__c__Gen_base_type(g, utyp); strings__Builder_writeln(dec, str_intp(7, _MOV((StrIntpData[]){{_S("_option_ok(&("), 0xfe10, {.d_s = base_typ}}, {_S("[]){ "), 0xfe10, {.d_s = enum_prefix}}, {_SLIT0, 0xfe10, {.d_s = val}}, {_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)"), 0xfe10, {.d_s = result_var}}, {_S(", sizeof("), 0xfe10, {.d_s = base_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = result_var}}, {_S(" = "), 0xfe10, {.d_s = enum_prefix}}, {_SLIT0, 0xfe10, {.d_s = val}}, {_S(";"), 0, { .d_c = 0 }}}))); } } } inline VV_LOC bool v__gen__c__Gen_is_enum_as_int(v__gen__c__Gen* g, v__ast__TypeSymbol sym) { v__ast__EnumDecl* _t2 = (v__ast__EnumDecl*)(map_get_check(ADDR(map, g->table->enum_decls), &(string[]){sym.name})); _option_v__ast__EnumDecl _t1 = {0}; if (_t2) { *((v__ast__EnumDecl*)&_t1.data) = *((v__ast__EnumDecl*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } if (_t1.state == 0) { v__ast__EnumDecl enum_decl = (*(v__ast__EnumDecl*)_t1.data); _option_v__ast__Attr _t3; if (_t3 = Array_v__ast__Attr_find_first(enum_decl.attrs, _S("json_as_number")), _t3.state == 0) { return true; } } return false; } inline VV_LOC void v__gen__c__Gen_gen_enum_enc_dec(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__TypeSymbol sym, strings__Builder* enc, strings__Builder* dec) { bool is_option = v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option); if (v__gen__c__Gen_is_enum_as_int(g, sym)) { if (is_option) { string base_typ = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(utyp, v__ast__TypeFlag__option)); strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_S("\to = "), 0xfe10, {.d_s = v__gen__c__js_enc_name(_S("u64"))}}, {_S("(*val.data);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t_option_ok(&("), 0xfe10, {.d_s = base_typ}}, {_S("[]){ "), 0xfe10, {.d_s = v__gen__c__js_dec_name(_S("u64"))}}, {_S("(root) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&res, sizeof("), 0xfe10, {.d_s = base_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tres = "), 0xfe10, {.d_s = v__gen__c__js_dec_name(_S("u64"))}}, {_S("(root);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_S("\to = "), 0xfe10, {.d_s = v__gen__c__js_enc_name(_S("u64"))}}, {_S("(val);"), 0, { .d_c = 0 }}}))); } } else { string tmp = v__gen__c__Gen_new_tmp_var(g); strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\tstring "), 0xfe10, {.d_s = tmp}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__js_dec_name(_S("string"))}}, {_S("(root);"), 0, { .d_c = 0 }}}))); if (is_option) { v__gen__c__Gen_gen_str_to_enum(g, utyp, sym, tmp, _S("&res"), _S("\t"), dec); v__gen__c__Gen_gen_enum_to_str(g, utyp, sym, str_intp(2, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S("*)val.data"), 0, { .d_c = 0 }}})), _S("o"), _S("\t\t"), enc); } else { v__gen__c__Gen_gen_str_to_enum(g, utyp, sym, tmp, _S("res"), _S("\t"), dec); v__gen__c__Gen_gen_enum_to_str(g, utyp, sym, _S("val"), _S("o"), _S("\t"), enc); } } } inline VV_LOC void v__gen__c__Gen_gen_prim_enc_dec(v__gen__c__Gen* g, v__ast__Type typ, strings__Builder* enc, strings__Builder* dec) { if (v__ast__Type_is_ptr(typ)) { string type_str = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(v__ast__Type_clear_flag(typ, v__ast__TypeFlag__option), (int)(v__ast__Type_nr_muls(typ) - 1))); string type_str_0 = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(v__ast__Type_clear_flag(typ, v__ast__TypeFlag__option), 0)); string encode_name = v__gen__c__js_enc_name(type_str_0); string dec_name = v__gen__c__js_dec_name(type_str); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(enc, str_intp(5, _MOV((StrIntpData[]){{_S("\to = "), 0xfe10, {.d_s = encode_name}}, {_S("("), 0xfe10, {.d_s = string_repeat(_S("*"), (int)(v__ast__Type_nr_muls(typ) + 1))}}, {_S("("), 0xfe10, {.d_s = type_str_0}}, {_SLIT0, 0xfe10, {.d_s = string_repeat(_S("*"), v__ast__Type_nr_muls(typ))}}, {_S("*)&val.data);"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(enc, str_intp(3, _MOV((StrIntpData[]){{_S("\to = "), 0xfe10, {.d_s = encode_name}}, {_S("("), 0xfe10, {.d_s = string_repeat(_S("*"), v__ast__Type_nr_muls(typ))}}, {_S("val);"), 0, { .d_c = 0 }}}))); } if (v__ast__Type_nr_muls(typ) > 1) { v__gen__c__Gen_gen_json_for_type(g, v__ast__Type_set_nr_muls(v__ast__Type_clear_flag(typ, v__ast__TypeFlag__option), (int)(v__ast__Type_nr_muls(typ) - 1))); if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { string tmp_var = v__gen__c__Gen_new_tmp_var(g); strings__Builder_writeln(dec, str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_str}}, {_S("* "), 0xfe10, {.d_s = tmp_var}}, {_S(" = HEAP("), 0xfe10, {.d_s = type_str}}, {_S(", *("), 0xfe10, {.d_s = type_str}}, {_S("*) "), 0xfe10, {.d_s = dec_name}}, {_S("(root).data);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t_option_ok(&("), 0xfe10, {.d_s = type_str}}, {_S("*[]) { &(*("), 0xfe10, {.d_s = tmp_var}}, {_S(")) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&res, sizeof("), 0xfe10, {.d_s = type_str}}, {_S("*));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\tres = HEAP("), 0xfe10, {.d_s = type_str}}, {_S(", *("), 0xfe10, {.d_s = type_str}}, {_S("*) "), 0xfe10, {.d_s = dec_name}}, {_S("(root).data);"), 0, { .d_c = 0 }}}))); } } else { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { string tmp_var = v__gen__c__Gen_new_tmp_var(g); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = type_str}}, {_S("* "), 0xfe10, {.d_s = tmp_var}}, {_S(" = HEAP("), 0xfe10, {.d_s = type_str}}, {_S(", "), 0xfe10, {.d_s = dec_name}}, {_S("(root));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t_option_ok(&("), 0xfe10, {.d_s = type_str}}, {_S("*[]) { &(*("), 0xfe10, {.d_s = tmp_var}}, {_S(")) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&res, sizeof("), 0xfe10, {.d_s = type_str}}, {_S("*));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\tres = HEAP("), 0xfe10, {.d_s = type_str}}, {_S(", "), 0xfe10, {.d_s = dec_name}}, {_S("(root));"), 0, { .d_c = 0 }}}))); } } } else { string type_str = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(typ, v__ast__TypeFlag__option)); string encode_name = v__gen__c__js_enc_name(type_str); string dec_name = v__gen__c__js_dec_name(type_str); strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_S("\to = "), 0xfe10, {.d_s = encode_name}}, {_S("(val);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tres = "), 0xfe10, {.d_s = dec_name}}, {_S("(root);"), 0, { .d_c = 0 }}}))); } } inline VV_LOC void v__gen__c__Gen_gen_option_enc_dec(v__gen__c__Gen* g, v__ast__Type typ, strings__Builder* enc, strings__Builder* dec) { strings__Builder_writeln(enc, _S("\tif (val.state == 2) {")); strings__Builder_writeln(enc, _S("\t\treturn NULL;")); strings__Builder_writeln(enc, _S("\t}")); string type_str = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(typ, v__ast__TypeFlag__option)); string encode_name = v__gen__c__js_enc_name(type_str); strings__Builder_writeln(enc, str_intp(3, _MOV((StrIntpData[]){{_S("\to = "), 0xfe10, {.d_s = encode_name}}, {_S("(*("), 0xfe10, {.d_s = type_str}}, {_S("*)val.data);"), 0, { .d_c = 0 }}}))); string dec_name = v__gen__c__js_dec_name(type_str); strings__Builder_writeln(dec, _S("\tif (!cJSON_IsNull(root)) {")); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t_option_ok(&("), 0xfe10, {.d_s = type_str}}, {_S("[]){ "), 0xfe10, {.d_s = dec_name}}, {_S("(root) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&res, sizeof("), 0xfe10, {.d_s = type_str}}, {_S("));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, _S("\t} else {")); string default_init = (v__ast__Type_is_int(typ) || v__ast__Type_is_float(typ) || v__ast__Type_is_bool(typ) ? (_S("0")) : (_S("{0}"))); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t_option_none(&("), 0xfe10, {.d_s = type_str}}, {_S("[]){ "), 0xfe10, {.d_s = default_init}}, {_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&res, sizeof("), 0xfe10, {.d_s = type_str}}, {_S("));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, _S("\t}")); } inline VV_LOC void v__gen__c__Gen_gen_sumtype_enc_dec(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__TypeSymbol sym, strings__Builder* enc, strings__Builder* dec, string ret_styp) { v__ast__SumType info = *(v__ast__SumType*)__as_cast((sym.info)._v__ast__SumType,(sym.info)._typ, 544); string type_var = v__gen__c__Gen_new_tmp_var(g); v__ast__Type typ = v__ast__idx_to_type((*(int*)map_get(ADDR(map, g->table->type_idxs), &(string[]){sym.name}, &(int[]){ 0 }))); string prefix = (v__ast__Type_is_ptr(utyp) ? (_S("*")) : (_S(""))); string field_op = (v__ast__Type_is_ptr(utyp) ? (_S("->")) : (_S("."))); bool is_option = v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option); string var_data = (is_option ? (str_intp(2, _MOV((StrIntpData[]){{_S("(*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S("*)val.data)"), 0, { .d_c = 0 }}}))) : (_S("val"))); #if !defined(CUSTOM_DEFINE_json_no_inline_sumtypes) { string type_tmp = v__gen__c__Gen_new_tmp_var(g); v__ast__Type first_variant = (*(v__ast__Type*)array_get(info.variants, 0)); string variant_typ = v__gen__c__Gen_styp(g, first_variant); v__ast__TypeSymbol* fv_sym = v__ast__Table_sym(g->table, first_variant); string first_variant_name = fv_sym->cname; if (fv_sym->kind == v__ast__Kind__struct && !is_option && _SLIT_NE(field_op.str, field_op.len, "->")) { strings__Builder_writeln(dec, _S("\tif (root->type == cJSON_NULL) { ")); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tstruct "), 0xfe10, {.d_s = first_variant_name}}, {_S(" empty = {0};"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("res = "), 0xfe10, {.d_s = variant_typ}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = ret_styp}}, {_S("(&empty); } \n else "), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("if (cJSON_IsObject(root) || (cJSON_IsArray(root) && cJSON_IsObject(root->child))) {")); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tcJSON* "), 0xfe10, {.d_s = type_tmp}}, {_S(" = cJSON_IsObject(root) ? js_get(root, \"_type\") : js_get(root->child, \"_type\");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = type_tmp}}, {_S(" != 0) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t\tchar* "), 0xfe10, {.d_s = type_var}}, {_S(" = cJSON_GetStringValue("), 0xfe10, {.d_s = type_tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); } #endif Array_string variant_types = __new_array_with_default(0, 0, sizeof(string), 0); Array_v__ast__TypeSymbol variant_symbols = __new_array_with_default(0, 0, sizeof(v__ast__TypeSymbol), 0); bool at_least_one_prim = false; for (int _t2 = 0; _t2 < info.variants.len; ++_t2) { v__ast__Type variant = ((v__ast__Type*)info.variants.data)[_t2]; string variant_typ = v__gen__c__Gen_styp(g, variant); array_push((array*)&variant_types, _MOV((string[]){ string_clone(variant_typ) })); v__ast__TypeSymbol* variant_sym = v__ast__Table_sym(g->table, variant); array_push((array*)&variant_symbols, _MOV((v__ast__TypeSymbol[]){ *variant_sym })); at_least_one_prim = at_least_one_prim || v__gen__c__is_js_prim(variant_typ) || variant_sym->kind == v__ast__Kind__enum || fast_string_eq(variant_sym->name, _S("time.Time")); string unmangled_variant_name = (*(string*)array_last(string_split(variant_sym->name, _S(".")))); v__gen__c__Gen_gen_json_for_type(g, variant); v__gen__c__Gen_get_sumtype_casting_fn(g, variant, typ); strings__Builder_writeln(&g->definitions, str_intp(5, _MOV((StrIntpData[]){{_S("static inline "), 0xfe10, {.d_s = sym.cname}}, {_S(" "), 0xfe10, {.d_s = variant_typ}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("("), 0xfe10, {.d_s = variant_typ}}, {_S("* x);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(enc, str_intp(4, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = var_data}}, {_SLIT0, 0xfe10, {.d_s = field_op}}, {_S("_typ == "), 0xfe07, {.d_i32 = ((int)(v__ast__Type_idx(variant)))}}, {_S(") {"), 0, { .d_c = 0 }}}))); #if defined(CUSTOM_DEFINE_json_no_inline_sumtypes) { if (variant_sym->kind == v__ast__Kind__enum) { strings__Builder_writeln(enc, str_intp(6, _MOV((StrIntpData[]){{_S("\t\tcJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = unmangled_variant_name}}, {_S("\", "), 0xfe10, {.d_s = v__gen__c__js_enc_name(_S("u64"))}}, {_S("(*"), 0xfe10, {.d_s = var_data}}, {_SLIT0, 0xfe10, {.d_s = field_op}}, {_S("_"), 0xfe10, {.d_s = variant_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } else if (fast_string_eq(variant_sym->name, _S("time.Time"))) { strings__Builder_writeln(enc, str_intp(6, _MOV((StrIntpData[]){{_S("\t\tcJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = unmangled_variant_name}}, {_S("\", "), 0xfe10, {.d_s = v__gen__c__js_enc_name(_S("i64"))}}, {_S("("), 0xfe10, {.d_s = var_data}}, {_SLIT0, 0xfe10, {.d_s = field_op}}, {_S("_"), 0xfe10, {.d_s = variant_typ}}, {_S("->__v_unix));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(enc, str_intp(6, _MOV((StrIntpData[]){{_S("\t\tcJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = unmangled_variant_name}}, {_S("\", "), 0xfe10, {.d_s = v__gen__c__js_enc_name(variant_typ)}}, {_S("(*"), 0xfe10, {.d_s = var_data}}, {_SLIT0, 0xfe10, {.d_s = field_op}}, {_S("_"), 0xfe10, {.d_s = variant_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } } #else { if (v__gen__c__is_js_prim(variant_typ)) { strings__Builder_writeln(enc, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tcJSON_free(o); return "), 0xfe10, {.d_s = v__gen__c__js_enc_name(variant_typ)}}, {_S("(*"), 0xfe10, {.d_s = var_data}}, {_SLIT0, 0xfe10, {.d_s = field_op}}, {_S("_"), 0xfe10, {.d_s = variant_typ}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (variant_sym->kind == v__ast__Kind__enum) { if (v__gen__c__Gen_is_enum_as_int(g, *variant_sym)) { strings__Builder_writeln(enc, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tcJSON_free(o); return "), 0xfe10, {.d_s = v__gen__c__js_enc_name(_S("u64"))}}, {_S("(*"), 0xfe10, {.d_s = var_data}}, {_SLIT0, 0xfe10, {.d_s = field_op}}, {_S("_"), 0xfe10, {.d_s = variant_typ}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(enc, _S("\t\tcJSON_free(o);")); string tmp2 = v__gen__c__Gen_new_tmp_var(g); if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { strings__Builder_writeln(enc, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tu64 "), 0xfe10, {.d_s = tmp2}}, {_S(" = *"), 0xfe10, {.d_s = var_data}}, {_SLIT0, 0xfe10, {.d_s = field_op}}, {_S("_"), 0xfe10, {.d_s = variant_typ}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_gen_enum_to_str(g, variant, *variant_sym, tmp2, _S("o"), _S("\t\t"), enc); } else { strings__Builder_writeln(enc, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tu64 "), 0xfe10, {.d_s = tmp2}}, {_S(" = *"), 0xfe10, {.d_s = var_data}}, {_SLIT0, 0xfe10, {.d_s = field_op}}, {_S("_"), 0xfe10, {.d_s = variant_typ}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_gen_enum_to_str(g, variant, *variant_sym, tmp2, _S("o"), _S("\t\t"), enc); } } } else if (fast_string_eq(variant_sym->name, _S("time.Time"))) { strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tcJSON_AddItemToObject(o, \"_type\", cJSON_CreateString(\""), 0xfe10, {.d_s = unmangled_variant_name}}, {_S("\"));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(enc, str_intp(5, _MOV((StrIntpData[]){{_S("\t\tcJSON_AddItemToObject(o, \"value\", "), 0xfe10, {.d_s = v__gen__c__js_enc_name(_S("i64"))}}, {_S("("), 0xfe10, {.d_s = var_data}}, {_SLIT0, 0xfe10, {.d_s = field_op}}, {_S("_"), 0xfe10, {.d_s = variant_typ}}, {_S("->__v_unix));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(enc, _S("\t\tcJSON_free(o);")); strings__Builder_writeln(enc, str_intp(5, _MOV((StrIntpData[]){{_S("\t\to = "), 0xfe10, {.d_s = v__gen__c__js_enc_name(variant_typ)}}, {_S("(*"), 0xfe10, {.d_s = var_data}}, {_SLIT0, 0xfe10, {.d_s = field_op}}, {_S("_"), 0xfe10, {.d_s = variant_typ}}, {_S(");"), 0, { .d_c = 0 }}}))); if (variant_sym->kind == v__ast__Kind__array) { strings__Builder_writeln(enc, _S("\t\tif (cJSON_IsObject(o->child)) {")); strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tcJSON_AddItemToObject(o->child, \"_type\", cJSON_CreateString(\""), 0xfe10, {.d_s = unmangled_variant_name}}, {_S("\"));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(enc, _S("\t\t}")); } else { strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tcJSON_AddItemToObject(o, \"_type\", cJSON_CreateString(\""), 0xfe10, {.d_s = unmangled_variant_name}}, {_S("\"));"), 0, { .d_c = 0 }}}))); } } } #endif strings__Builder_writeln(enc, _S("\t}")); string tmp = v__gen__c__Gen_new_tmp_var(g); #if defined(CUSTOM_DEFINE_json_no_inline_sumtypes) { strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tif (strcmp(\""), 0xfe10, {.d_s = unmangled_variant_name}}, {_S("\", root->child->string) == 0) {"), 0, { .d_c = 0 }}}))); if (v__gen__c__is_js_prim(variant_typ)) { v__gen__c__gen_js_get(ret_styp, tmp, unmangled_variant_name, dec, true); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = variant_typ}}, {_S(" value = "), 0xfe10, {.d_s = v__gen__c__js_dec_name(variant_typ)}}, {_S("(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); } else if (variant_sym->kind == v__ast__Kind__enum) { if (v__gen__c__Gen_is_enum_as_int(g, *variant_sym)) { v__gen__c__gen_js_get(ret_styp, tmp, unmangled_variant_name, dec, true); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = variant_typ}}, {_S(" value = "), 0xfe10, {.d_s = v__gen__c__js_dec_name(_S("u64"))}}, {_S("(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__gen_js_get(ret_styp, tmp, unmangled_variant_name, dec, true); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = variant_typ}}, {_S(" value;"), 0, { .d_c = 0 }}}))); string tmp2 = v__gen__c__Gen_new_tmp_var(g); strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tstring "), 0xfe10, {.d_s = tmp2}}, {_S(" = json__decode_string(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_gen_enum_to_str(g, variant, *variant_sym, tmp2, _S("value"), _S("\t\t"), dec); } } else if (fast_string_eq(variant_sym->name, _S("time.Time"))) { v__gen__c__gen_js_get(ret_styp, tmp, unmangled_variant_name, dec, true); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = variant_typ}}, {_S(" value = time__unix("), 0xfe10, {.d_s = v__gen__c__js_dec_name(_S("i64"))}}, {_S("(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { v__gen__c__gen_js_get_opt(v__gen__c__js_dec_name(variant_typ), variant_typ, ret_styp, tmp, unmangled_variant_name, dec, true); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = variant_typ}}, {_S(" value = *("), 0xfe10, {.d_s = variant_typ}}, {_S("*)("), 0xfe10, {.d_s = tmp}}, {_S(".data);"), 0, { .d_c = 0 }}}))); } if (is_option) { strings__Builder_writeln(dec, str_intp(6, _MOV((StrIntpData[]){{_S("\t\t\t_option_ok(&("), 0xfe10, {.d_s = sym.cname}}, {_S("[]){ "), 0xfe10, {.d_s = variant_typ}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(&value) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&res, sizeof("), 0xfe10, {.d_s = sym.cname}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tres = "), 0xfe10, {.d_s = variant_typ}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = ret_styp}}, {_S("(&value);"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("\t}")); } #else { if (fast_string_eq(variant_sym->name, _S("time.Time"))) { strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tif (strcmp(\"Time\", "), 0xfe10, {.d_s = type_var}}, {_S(") == 0) {"), 0, { .d_c = 0 }}}))); v__gen__c__gen_js_get(ret_styp, tmp, _S("value"), dec, true); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t\t\t"), 0xfe10, {.d_s = variant_typ}}, {_S(" "), 0xfe10, {.d_s = tmp}}, {_S(" = time__unix("), 0xfe10, {.d_s = v__gen__c__js_dec_name(_S("i64"))}}, {_S("(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S("));"), 0, { .d_c = 0 }}}))); if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\t\t"), 0xfe10, {.d_s = prefix}}, {_S("res.state = 0;"), 0, { .d_c = 0 }}}))); string tmp_time_var = v__gen__c__Gen_new_tmp_var(g); strings__Builder_writeln(dec, str_intp(6, _MOV((StrIntpData[]){{_S("\t\t\t\t"), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S(" "), 0xfe10, {.d_s = tmp_time_var}}, {_S(" = "), 0xfe10, {.d_s = variant_typ}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(&"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t\t\tvmemcpy(&"), 0xfe10, {.d_s = prefix}}, {_S("res.data, "), 0xfe10, {.d_s = tmp_time_var}}, {_S("._time__Time, sizeof("), 0xfe10, {.d_s = variant_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t\t\t"), 0xfe10, {.d_s = prefix}}, {_S("res = "), 0xfe10, {.d_s = variant_typ}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(&"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("\t\t\t}")); } else if (!v__gen__c__is_js_prim(variant_typ) && variant_sym->kind != v__ast__Kind__enum) { strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t\tif (strcmp(\""), 0xfe10, {.d_s = unmangled_variant_name}}, {_S("\", "), 0xfe10, {.d_s = type_var}}, {_S(") == 0 && "), 0xfe10, {.d_s = variant_sym->kind == v__ast__Kind__array ? _S("true") : _S("false")}}, {_S(" == cJSON_IsArray(root)) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t\t\t"), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = variant_typ}}, {_S(" "), 0xfe10, {.d_s = tmp}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__js_dec_name(variant_typ)}}, {_S("(root);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\t\tif ("), 0xfe10, {.d_s = tmp}}, {_S(".is_error) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t\t\t\treturn ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ret_styp}}, {_S("){ .is_error = true, .err = "), 0xfe10, {.d_s = tmp}}, {_S(".err, .data = {0} };"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, _S("\t\t\t\t}")); if (is_option) { strings__Builder_writeln(dec, str_intp(8, _MOV((StrIntpData[]){{_S("\t\t\t\t_option_ok(&("), 0xfe10, {.d_s = sym.cname}}, {_S("[]){ "), 0xfe10, {.d_s = variant_typ}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(("), 0xfe10, {.d_s = variant_typ}}, {_S("*)"), 0xfe10, {.d_s = tmp}}, {_S(".data) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&res, sizeof("), 0xfe10, {.d_s = sym.cname}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(6, _MOV((StrIntpData[]){{_S("\t\t\t\t"), 0xfe10, {.d_s = prefix}}, {_S("res = "), 0xfe10, {.d_s = variant_typ}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(("), 0xfe10, {.d_s = variant_typ}}, {_S("*)"), 0xfe10, {.d_s = tmp}}, {_S(".data);"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("\t\t\t}")); } } #endif } #if !defined(CUSTOM_DEFINE_json_no_inline_sumtypes) { strings__Builder_writeln(dec, _S("\t\t}")); bool number_is_met = false; bool string_is_met = false; string last_number_type = _S(""); if (at_least_one_prim) { strings__Builder_writeln(dec, _S("\t} else {")); if ((Array_string_contains(variant_types, _S("bool")))) { string var_t = _S("bool"); strings__Builder_writeln(dec, _S("\t\tif (cJSON_IsBool(root)) {")); strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = var_t}}, {_S(" value = "), 0xfe10, {.d_s = v__gen__c__js_dec_name(var_t)}}, {_S("(root);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = prefix}}, {_S("res = "), 0xfe10, {.d_s = var_t}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(&value);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, _S("\t\t}")); } for (int i = 0; i < variant_types.len; ++i) { string var_t = ((string*)variant_types.data)[i]; if ((*(v__ast__TypeSymbol*)array_get(variant_symbols, i)).kind == v__ast__Kind__enum) { if (number_is_met) { string var_num = string_replace(var_t, _S("__"), _S(".")); string last_num = string_replace(last_number_type, _S("__"), _S(".")); v__gen__c__verror_suggest_json_no_inline_sumtypes(sym.name, last_num, var_num); VUNREACHABLE(); } number_is_met = true; last_number_type = var_t; strings__Builder_writeln(dec, _S("\t\tif (cJSON_IsNumber(root)) {")); strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = var_t}}, {_S(" value = "), 0xfe10, {.d_s = v__gen__c__js_dec_name(_S("u64"))}}, {_S("(root);"), 0, { .d_c = 0 }}}))); if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { strings__Builder_writeln(dec, str_intp(7, _MOV((StrIntpData[]){{_S("\t\t\t_option_ok(&("), 0xfe10, {.d_s = sym.cname}}, {_S("[]){ "), 0xfe10, {.d_s = var_t}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(&value) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = prefix}}, {_S("res, sizeof("), 0xfe10, {.d_s = sym.cname}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = prefix}}, {_S("res = "), 0xfe10, {.d_s = var_t}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(&value);"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("\t\t}")); } if (_SLIT_EQ(var_t.str, var_t.len, "string") || _SLIT_EQ(var_t.str, var_t.len, "rune")) { if (string_is_met) { string var_num = string_replace(var_t, _S("__"), _S(".")); v__gen__c__verror_suggest_json_no_inline_sumtypes(sym.name, _S("string"), var_num); VUNREACHABLE(); } string_is_met = true; strings__Builder_writeln(dec, _S("\t\tif (cJSON_IsString(root)) {")); strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = var_t}}, {_S(" value = "), 0xfe10, {.d_s = v__gen__c__js_dec_name(var_t)}}, {_S("(root);"), 0, { .d_c = 0 }}}))); if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { strings__Builder_writeln(dec, str_intp(7, _MOV((StrIntpData[]){{_S("\t\t\t_option_ok(&("), 0xfe10, {.d_s = sym.cname}}, {_S("[]){ "), 0xfe10, {.d_s = var_t}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(&value) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = prefix}}, {_S("res, sizeof("), 0xfe10, {.d_s = sym.cname}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = prefix}}, {_S("res = "), 0xfe10, {.d_s = var_t}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(&value);"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("\t\t}")); } if (string_starts_with(var_t, _S("Array_"))) { string tmp = v__gen__c__Gen_new_tmp_var(g); string judge_elem_typ = (string_ends_with(var_t, _S("string")) ? (_S("cJSON_IsString(root->child)")) : string_ends_with(var_t, _S("bool")) ? (_S("cJSON_IsBool(root->child)")) : v__ast__Table_sym(g->table, v__ast__Table_value_type(g->table, v__ast__idx_to_type((*(v__ast__TypeSymbol*)array_get(variant_symbols, i)).idx)))->kind == v__ast__Kind__struct ? (_S("cJSON_IsObject(root->child)")) : (_S("cJSON_IsNumber(root->child)"))); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif (cJSON_IsArray(root) && "), 0xfe10, {.d_s = judge_elem_typ}}, {_S(") {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = var_t}}, {_S(" "), 0xfe10, {.d_s = tmp}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__js_dec_name(var_t)}}, {_S("(root);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\tif ("), 0xfe10, {.d_s = tmp}}, {_S(".is_error) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t\t\treturn ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ret_styp}}, {_S("){ .is_error = true, .err = "), 0xfe10, {.d_s = tmp}}, {_S(".err, .data = {0} };"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, _S("\t\t\t}")); if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { strings__Builder_writeln(dec, str_intp(9, _MOV((StrIntpData[]){{_S("\t\t\t_option_ok(&("), 0xfe10, {.d_s = sym.cname}}, {_S("[]){ "), 0xfe10, {.d_s = var_t}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(("), 0xfe10, {.d_s = var_t}}, {_S("*)"), 0xfe10, {.d_s = tmp}}, {_S(".data) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = prefix}}, {_S("res, sizeof("), 0xfe10, {.d_s = sym.cname}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(6, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = prefix}}, {_S("res = "), 0xfe10, {.d_s = var_t}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(("), 0xfe10, {.d_s = var_t}}, {_S("*)"), 0xfe10, {.d_s = tmp}}, {_S(".data);"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("\t\t}")); } if (_SLIT_EQ(var_t.str, var_t.len, "i64") || _SLIT_EQ(var_t.str, var_t.len, "int") || _SLIT_EQ(var_t.str, var_t.len, "i8") || _SLIT_EQ(var_t.str, var_t.len, "u64") || _SLIT_EQ(var_t.str, var_t.len, "u32") || _SLIT_EQ(var_t.str, var_t.len, "u16") || _SLIT_EQ(var_t.str, var_t.len, "byte") || _SLIT_EQ(var_t.str, var_t.len, "u8") || _SLIT_EQ(var_t.str, var_t.len, "rune") || _SLIT_EQ(var_t.str, var_t.len, "f64") || _SLIT_EQ(var_t.str, var_t.len, "f32")) { if (number_is_met) { string var_num = string_replace(var_t, _S("__"), _S(".")); string last_num = string_replace(last_number_type, _S("__"), _S(".")); v__gen__c__verror_suggest_json_no_inline_sumtypes(sym.name, last_num, var_num); VUNREACHABLE(); } number_is_met = true; last_number_type = var_t; strings__Builder_writeln(dec, _S("\t\tif (cJSON_IsNumber(root)) {")); strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = var_t}}, {_S(" value = "), 0xfe10, {.d_s = v__gen__c__js_dec_name(var_t)}}, {_S("(root);"), 0, { .d_c = 0 }}}))); if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { strings__Builder_writeln(dec, str_intp(7, _MOV((StrIntpData[]){{_S("\t\t\t_option_ok(&("), 0xfe10, {.d_s = sym.cname}}, {_S("[]){ "), 0xfe10, {.d_s = var_t}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(&value) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = prefix}}, {_S("res, sizeof("), 0xfe10, {.d_s = sym.cname}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = prefix}}, {_S("res = "), 0xfe10, {.d_s = var_t}}, {_S("_to_sumtype_"), 0xfe10, {.d_s = sym.cname}}, {_S("(&value);"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("\t\t}")); } } } strings__Builder_writeln(dec, _S("\t}")); } #endif } VV_LOC void v__gen__c__Gen_gen_prim_type_validation(v__gen__c__Gen* g, string name, v__ast__Type typ, string tmp, bool is_required, string ret_styp, strings__Builder* dec) { string none_check = (!is_required ? (str_intp(2, _MOV((StrIntpData[]){{_S("cJSON_IsNull(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(") || "), 0, { .d_c = 0 }}}))) : (_S(""))); string type_check = (v__ast__Type_is_int(typ) || v__ast__Type_is_float(typ) ? (str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = none_check}}, {_S("cJSON_IsNumber(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(") || (cJSON_IsString(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(") && strlen(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S("->valuestring))"), 0, { .d_c = 0 }}}))) : v__ast__Type_is_string(typ) ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = none_check}}, {_S("cJSON_IsString(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(")"), 0, { .d_c = 0 }}}))) : v__ast__Type_is_bool(typ) ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = none_check}}, {_S("cJSON_IsBool(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(")"), 0, { .d_c = 0 }}}))) : (_S(""))); if ((type_check).len == 0) { return; } strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif (!("), 0xfe10, {.d_s = type_check}}, {_S(")) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t\treturn ("), 0xfe10, {.d_s = ret_styp}}, {_S("){ .is_error = true, .err = _v_error(string__plus(_S(\"type mismatch for field \'"), 0xfe10, {.d_s = name}}, {_S("\', expecting `"), 0xfe10, {.d_s = v__ast__Table_type_to_str(g->table, typ)}}, {_S("` type, got: \"), json__json_print(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S("))), .data = {0} };"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, _S("\t\t}")); } inline VV_LOC void v__gen__c__Gen_gen_struct_enc_dec(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__TypeInfo type_info, string styp, strings__Builder* enc, strings__Builder* dec, string embed_prefix) { v__ast__Struct info = *(v__ast__Struct*)__as_cast((type_info)._v__ast__Struct,(type_info)._typ, 518); for (int _t1 = 0; _t1 < info.fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[_t1]; string name = field.name; bool is_raw = false; bool is_skip = false; bool is_required = false; bool is_omit_empty = false; bool skip_embed = false; bool is_json_null = false; for (int _t2 = 0; _t2 < field.attrs.len; ++_t2) { v__ast__Attr attr = ((v__ast__Attr*)field.attrs.data)[_t2]; if (_SLIT_EQ(attr.name.str, attr.name.len, "json")) { if (fast_string_eq(attr.arg, _S("-"))) { is_skip = true; } else { name = attr.arg; } } else if (_SLIT_EQ(attr.name.str, attr.name.len, "skip")) { is_skip = true; } else if (_SLIT_EQ(attr.name.str, attr.name.len, "raw")) { is_raw = true; } else if (_SLIT_EQ(attr.name.str, attr.name.len, "required")) { is_required = true; } else if (_SLIT_EQ(attr.name.str, attr.name.len, "omitempty")) { is_omit_empty = true; } else if (_SLIT_EQ(attr.name.str, attr.name.len, "json_null")) { is_json_null = true; } else { } } if (is_skip) { continue; } string field_type = v__gen__c__Gen_styp(g, field.typ); v__ast__TypeSymbol* field_sym = v__ast__Table_sym(g->table, field.typ); string op = (v__ast__Type_is_ptr(utyp) ? (_S("->")) : (_S("."))); string embed_member = (embed_prefix.len > 0 ? (str_intp(2, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = embed_prefix}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (_S(""))); string prefix = (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option) ? (str_intp(3, _MOV((StrIntpData[]){{_S("(*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S("*)res"), 0xfe10, {.d_s = embed_member}}, {_S(".data)"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("res"), 0xfe10, {.d_s = embed_member}}, {_SLIT0, 0, { .d_c = 0 }}})))); if (is_raw) { if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_gen_json_for_type(g, field.typ); string base_typ = v__gen__c__Gen_base_type(g, field.typ); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tif (js_get(root, \""), 0xfe10, {.d_s = name}}, {_S("\") == NULL)"), 0, { .d_c = 0 }}}))); string default_init = (v__ast__Type_is_int(field.typ) || v__ast__Type_is_float(field.typ) || v__ast__Type_is_bool(field.typ) ? (_S("0")) : (_S("{0}"))); strings__Builder_writeln(dec, str_intp(8, _MOV((StrIntpData[]){{_S("\t\t_option_none(&("), 0xfe10, {.d_s = base_typ}}, {_S("[]) { "), 0xfe10, {.d_s = default_init}}, {_S(" }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(", sizeof("), 0xfe10, {.d_s = base_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, _S("\telse")); strings__Builder_writeln(dec, str_intp(8, _MOV((StrIntpData[]){{_S("\t\t_option_ok(&("), 0xfe10, {.d_s = base_typ}}, {_S("[]) { json__json_print(js_get(root, \""), 0xfe10, {.d_s = name}}, {_S("\")) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(", sizeof("), 0xfe10, {.d_s = base_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = json__json_print(js_get(root, \""), 0xfe10, {.d_s = name}}, {_S("\"));"), 0, { .d_c = 0 }}}))); } } else { v__gen__c__Gen_gen_json_for_type(g, field.typ); string dec_name = v__gen__c__js_dec_name(field_type); if (v__gen__c__is_js_prim(field_type)) { string tmp = v__gen__c__Gen_new_tmp_var(g); v__gen__c__gen_js_get(styp, tmp, name, dec, is_required); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tif (jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(") {"), 0, { .d_c = 0 }}}))); if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { strings__Builder_writeln(dec, _S("\t\tres.state = 0;")); } v__gen__c__Gen_gen_prim_type_validation(g, field.name, field.typ, tmp, is_required, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = styp}}, {_SLIT0, 0, { .d_c = 0 }}})), dec); strings__Builder_writeln(dec, str_intp(6, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = "), 0xfe10, {.d_s = dec_name}}, {_S("(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); if (field.has_default_expr) { strings__Builder_writeln(dec, _S("\t} else {")); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__Gen_expr_string_opt(g, field.typ, field.default_expr)}}, {_S(";"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("\t}")); } else if (field_sym->kind == v__ast__Kind__enum) { string tmp = v__gen__c__Gen_new_tmp_var(g); bool is_option_field = v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option); if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { v__gen__c__gen_js_get_opt(v__gen__c__js_dec_name(field_type), field_type, styp, tmp, name, dec, is_required); strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\tif (jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(" && !cJSON_IsNull(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(")) {"), 0, { .d_c = 0 }}}))); } else { v__gen__c__gen_js_get(styp, tmp, name, dec, is_required); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tif (jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(") {"), 0, { .d_c = 0 }}}))); } if (v__gen__c__Gen_is_enum_as_int(g, *field_sym)) { if (is_option_field) { string base_typ = v__gen__c__Gen_base_type(g, field.typ); strings__Builder_writeln(dec, str_intp(9, _MOV((StrIntpData[]){{_S("\t\t_option_ok(&("), 0xfe10, {.d_s = base_typ}}, {_S("[]) { "), 0xfe10, {.d_s = v__gen__c__js_dec_name(_S("u64"))}}, {_S("(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(") }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(", sizeof("), 0xfe10, {.d_s = base_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(6, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__js_dec_name(_S("u64"))}}, {_S("(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else { if (is_option_field) { string base_typ = v__gen__c__Gen_base_type(g, field.typ); strings__Builder_writeln(dec, str_intp(10, _MOV((StrIntpData[]){{_S("\t\t_option_ok(&("), 0xfe10, {.d_s = base_typ}}, {_S("[]) { *("), 0xfe10, {.d_s = base_typ}}, {_S("*)(("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, field.typ)}}, {_S("*)"), 0xfe10, {.d_s = tmp}}, {_S(".data)->data }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(", sizeof("), 0xfe10, {.d_s = base_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { string tmp2 = v__gen__c__Gen_new_tmp_var(g); strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\t\tstring "), 0xfe10, {.d_s = tmp2}}, {_S(" = json__decode_string(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_gen_str_to_enum(g, field.typ, *field_sym, tmp2, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("\t\t"), dec); } } if (field.has_default_expr) { strings__Builder_writeln(dec, _S("\t} else {")); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__Gen_expr_string_opt(g, field.typ, field.default_expr)}}, {_S(";"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("\t}")); } else if (fast_string_eq(field_sym->name, _S("time.Time"))) { string tmp = v__gen__c__Gen_new_tmp_var(g); v__gen__c__gen_js_get(styp, tmp, name, dec, is_required); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tif (jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(") {"), 0, { .d_c = 0 }}}))); if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif (!(cJSON_IsNull(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S("))) {\n"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(".state = 0;\n"), 0, { .d_c = 0 }}}))); string tmp_time_var = v__gen__c__Gen_new_tmp_var(g); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t\t"), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, field.typ)}}, {_S(" "), 0xfe10, {.d_s = tmp_time_var}}, {_S(" = time__unix(json__decode_u64(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S("));\n"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(6, _MOV((StrIntpData[]){{_S("\t\t\tvmemcpy(&"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(".data, &"), 0xfe10, {.d_s = tmp_time_var}}, {_S(", sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, field.typ)}}, {_S("));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, _S("\t\t}\n")); } else { strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = time__unix(json__decode_u64(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S("));"), 0, { .d_c = 0 }}}))); if (field.has_default_expr) { strings__Builder_writeln(dec, _S("\t} else {")); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__Gen_expr_string_opt(g, field.typ, field.default_expr)}}, {_S(";"), 0, { .d_c = 0 }}}))); } } strings__Builder_writeln(dec, _S("\t}")); } else if (field_sym->kind == v__ast__Kind__alias) { v__ast__Alias alias = *(v__ast__Alias*)__as_cast((field_sym->info)._v__ast__Alias,(field_sym->info)._typ, 539); v__ast__Type parent_type = (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option) ? (v__ast__Type_set_flag(alias.parent_type, v__ast__TypeFlag__option)) : (alias.parent_type)); string sparent_type = v__gen__c__Gen_styp(g, parent_type); string parent_dec_name = v__gen__c__js_dec_name(sparent_type); if (v__gen__c__is_js_prim(sparent_type)) { string tmp = v__gen__c__Gen_new_tmp_var(g); v__gen__c__gen_js_get(styp, tmp, name, dec, is_required); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tif (jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(") {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_gen_prim_type_validation(g, field.name, parent_type, tmp, is_required, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = styp}}, {_SLIT0, 0, { .d_c = 0 }}})), dec); strings__Builder_writeln(dec, str_intp(6, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = "), 0xfe10, {.d_s = parent_dec_name}}, {_S(" (jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); if (field.has_default_expr) { strings__Builder_writeln(dec, _S("\t} else {")); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__Gen_expr_string_opt(g, field.typ, field.default_expr)}}, {_S(";"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("\t}")); } else { v__gen__c__Gen_gen_json_for_type(g, parent_type); string tmp = v__gen__c__Gen_new_tmp_var(g); v__gen__c__gen_js_get_opt(dec_name, field_type, styp, tmp, name, dec, is_required); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tif (jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(") {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(6, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = *("), 0xfe10, {.d_s = field_type}}, {_S("*) "), 0xfe10, {.d_s = tmp}}, {_S(".data;"), 0, { .d_c = 0 }}}))); if (field.has_default_expr) { strings__Builder_writeln(dec, _S("\t} else {")); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__Gen_expr_string_opt(g, field.typ, field.default_expr)}}, {_S(";"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(dec, _S("\t}")); } } else { if (field.is_embed && (field_sym->info)._typ == 518 /* v.ast.Struct */) { for (int _t3 = 0; _t3 < info.embeds.len; ++_t3) { v__ast__Type embed = ((v__ast__Type*)info.embeds.data)[_t3]; if (_us32_eq(embed,((int)(field.typ)))) { string prefix_embed = ((embed_prefix).len != 0 ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = embed_prefix}}, {_S("."), 0xfe10, {.d_s = name}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (name)); v__gen__c__Gen_gen_struct_enc_dec(g, field.typ, v__ast__Table_sym(g->table, field.typ)->info, styp, enc, dec, prefix_embed); skip_embed = true; break; } } } string tmp = v__gen__c__Gen_new_tmp_var(g); v__gen__c__gen_js_get_opt(dec_name, field_type, styp, tmp, name, dec, is_required); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tif (jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(") {"), 0, { .d_c = 0 }}}))); if (v__gen__c__is_js_prim(v__gen__c__Gen_styp(g, v__ast__Type_clear_option_and_result(field.typ)))) { v__gen__c__Gen_gen_prim_type_validation(g, field.name, field.typ, tmp, is_required, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = styp}}, {_SLIT0, 0, { .d_c = 0 }}})), dec); } if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(dec, str_intp(7, _MOV((StrIntpData[]){{_S("\t\tvmemcpy(&"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(", ("), 0xfe10, {.d_s = field_type}}, {_S("*)"), 0xfe10, {.d_s = tmp}}, {_S(".data, sizeof("), 0xfe10, {.d_s = field_type}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { if (field_sym->kind == v__ast__Kind__array_fixed) { strings__Builder_writeln(dec, str_intp(7, _MOV((StrIntpData[]){{_S("\t\tvmemcpy("), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(",*("), 0xfe10, {.d_s = field_type}}, {_S("*)"), 0xfe10, {.d_s = tmp}}, {_S(".data,sizeof("), 0xfe10, {.d_s = field_type}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(6, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = *("), 0xfe10, {.d_s = field_type}}, {_S("*) "), 0xfe10, {.d_s = tmp}}, {_S(".data;"), 0, { .d_c = 0 }}}))); } } if (field.has_default_expr) { strings__Builder_writeln(dec, _S("\t} else {")); string default_str = v__gen__c__Gen_expr_string_opt(g, field.typ, field.default_expr); if (string_count(default_str, _S(";\n")) > 1) { strings__Builder_writeln(dec, string_all_before_last(default_str, _S("\n"))); strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = "), 0xfe10, {.d_s = string_all_after_last(default_str, _S("\n"))}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(dec, str_intp(5, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = prefix}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = "), 0xfe10, {.d_s = default_str}}, {_S(";"), 0, { .d_c = 0 }}}))); } } strings__Builder_writeln(dec, _S("\t}")); } } if (skip_embed) { continue; } string enc_name = v__gen__c__js_enc_name(field_type); string prefix_enc = (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option) ? (str_intp(3, _MOV((StrIntpData[]){{_S("(*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S("*)val"), 0xfe10, {.d_s = embed_member}}, {_S(".data)"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("val"), 0xfe10, {.d_s = embed_member}}, {_SLIT0, 0, { .d_c = 0 }}})))); bool is_option = v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option); string indent = (is_option ? (_S("\t\t")) : (_S("\t"))); if (is_option) { strings__Builder_writeln(enc, str_intp(4, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(".state != 2) {"), 0, { .d_c = 0 }}}))); } if (is_omit_empty) { if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(enc, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("if ("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(".state != 2)"), 0, { .d_c = 0 }}}))); } else if (field.typ == _const_v__ast__string_type) { strings__Builder_writeln(enc, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("if ("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(".len != 0)"), 0, { .d_c = 0 }}}))); } else { if (!v__ast__Type_is_ptr(field.typ) && (field_sym->kind == v__ast__Kind__alias || field_sym->kind == v__ast__Kind__sum_type || field_sym->kind == v__ast__Kind__map || field_sym->kind == v__ast__Kind__array || field_sym->kind == v__ast__Kind__struct)) { string ptr_typ = v__gen__c__Gen_equality_fn(g, field.typ); if (field_sym->kind == v__ast__Kind__alias) { strings__Builder_writeln(enc, str_intp(7, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("if (!"), 0xfe10, {.d_s = ptr_typ}}, {_S("_alias_eq("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(", "), 0xfe10, {.d_s = v__gen__c__Gen_type_default(g, field.typ)}}, {_S("))"), 0, { .d_c = 0 }}}))); } else if (field_sym->kind == v__ast__Kind__sum_type) { strings__Builder_writeln(enc, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("if ("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S("._typ != 0)"), 0, { .d_c = 0 }}}))); } else if (field_sym->kind == v__ast__Kind__map) { strings__Builder_writeln(enc, str_intp(7, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("if (!"), 0xfe10, {.d_s = ptr_typ}}, {_S("_map_eq("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(", "), 0xfe10, {.d_s = v__gen__c__Gen_type_default(g, field.typ)}}, {_S("))"), 0, { .d_c = 0 }}}))); } else if (field_sym->kind == v__ast__Kind__array) { strings__Builder_writeln(enc, str_intp(7, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("if (!"), 0xfe10, {.d_s = ptr_typ}}, {_S("_arr_eq("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(", "), 0xfe10, {.d_s = v__gen__c__Gen_type_default(g, field.typ)}}, {_S("))"), 0, { .d_c = 0 }}}))); } else if (field_sym->kind == v__ast__Kind__struct) { strings__Builder_writeln(enc, str_intp(7, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("if (!"), 0xfe10, {.d_s = ptr_typ}}, {_S("_struct_eq("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(", "), 0xfe10, {.d_s = v__gen__c__Gen_type_default(g, field.typ)}}, {_S("))"), 0, { .d_c = 0 }}}))); } } else { strings__Builder_writeln(enc, str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("if ("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" != "), 0xfe10, {.d_s = v__gen__c__Gen_type_default(g, field.typ)}}, {_S(")"), 0, { .d_c = 0 }}}))); } } } if (!v__gen__c__is_js_prim(field_type)) { if (field_sym->kind == v__ast__Kind__alias) { v__ast__Alias ainfo = *(v__ast__Alias*)__as_cast((field_sym->info)._v__ast__Alias,(field_sym->info)._typ, 539); if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { enc_name = v__gen__c__js_enc_name(v__gen__c__Gen_styp(g, v__ast__Type_set_flag(ainfo.parent_type, v__ast__TypeFlag__option))); } else { enc_name = v__gen__c__js_enc_name(v__gen__c__Gen_styp(g, ainfo.parent_type)); } } } if (field_sym->kind == v__ast__Kind__enum) { if (v__gen__c__Gen_is_enum_as_int(g, *field_sym)) { if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(enc, str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\tcJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = name}}, {_S("\", json__encode_u64(*"), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(".data));\n"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(enc, str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\tcJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = name}}, {_S("\", json__encode_u64("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S("));\n"), 0, { .d_c = 0 }}}))); } } else { if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\t{"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\t\tcJSON *enum_val;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_gen_enum_to_str(g, field.typ, *field_sym, str_intp(5, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, field.typ)}}, {_S("*)"), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(".data"), 0, { .d_c = 0 }}})), _S("enum_val"), str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\t\t"), 0, { .d_c = 0 }}})), enc); strings__Builder_writeln(enc, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\t\tcJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = name}}, {_S("\", enum_val);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\t}"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\t{"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\t\tcJSON *enum_val;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_gen_enum_to_str(g, field.typ, *field_sym, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("enum_val"), str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\t\t"), 0, { .d_c = 0 }}})), enc); strings__Builder_writeln(enc, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\t\tcJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = name}}, {_S("\", enum_val);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\t}"), 0, { .d_c = 0 }}}))); } } } else { if (fast_string_eq(field_sym->name, _S("time.Time"))) { if (is_option) { strings__Builder_writeln(enc, str_intp(7, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("cJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = name}}, {_S("\", json__encode_u64((*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, field.typ)}}, {_S("*)("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(".data)).__v_unix));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(enc, str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("cJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = name}}, {_S("\", json__encode_u64("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(".__v_unix));"), 0, { .d_c = 0 }}}))); } } else { if (!v__ast__Type_is_any_kind_of_pointer(field.typ)) { if (field_sym->kind == v__ast__Kind__alias && v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { v__ast__Type parent_type = v__ast__Type_set_flag(v__ast__Table_unaliased_type(g->table, field.typ), v__ast__TypeFlag__option); strings__Builder_writeln(enc, str_intp(8, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\tcJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = name}}, {_S("\", "), 0xfe10, {.d_s = enc_name}}, {_S("(*("), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, parent_type)}}, {_S("*)&"), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(enc, str_intp(7, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\tcJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = name}}, {_S("\", "), 0xfe10, {.d_s = enc_name}}, {_S("("), 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S("));"), 0, { .d_c = 0 }}}))); } } else { string arg_prefix = (v__ast__Type_is_ptr(field.typ) ? (_S("")) : (_S("*"))); string sptr_value = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = prefix_enc}}, {_SLIT0, 0xfe10, {.d_s = op}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_SLIT0, 0, { .d_c = 0 }}})); if (!v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { strings__Builder_writeln(enc, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("if ("), 0xfe10, {.d_s = sptr_value}}, {_S(" != 0) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(enc, str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("\tcJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = name}}, {_S("\", "), 0xfe10, {.d_s = enc_name}}, {_S("("), 0xfe10, {.d_s = arg_prefix}}, {_SLIT0, 0xfe10, {.d_s = sptr_value}}, {_S("));"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("}\n"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(enc, str_intp(6, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = indent}}, {_S("cJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = name}}, {_S("\", "), 0xfe10, {.d_s = enc_name}}, {_S("("), 0xfe10, {.d_s = arg_prefix}}, {_SLIT0, 0xfe10, {.d_s = sptr_value}}, {_S("));"), 0, { .d_c = 0 }}}))); } } } } if (is_option) { if (is_json_null) { strings__Builder_writeln(enc, _S("\t} else {")); strings__Builder_writeln(enc, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tcJSON_AddItemToObject(o, \""), 0xfe10, {.d_s = name}}, {_S("\", cJSON_CreateNull());"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(enc, _S("\t}")); } } } VV_LOC void v__gen__c__gen_js_get(string styp, string tmp, string name, strings__Builder* dec, bool is_required) { strings__Builder_writeln(dec, str_intp(3, _MOV((StrIntpData[]){{_S("\tcJSON *jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(" = js_get(root, \""), 0xfe10, {.d_s = name}}, {_S("\");"), 0, { .d_c = 0 }}}))); if (is_required) { strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tif (jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(" == 0) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\treturn ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = styp}}, {_S("){ .is_error = true, .err = _v_error(_S(\"expected field \'"), 0xfe10, {.d_s = name}}, {_S("\' is missing\")), .data = {0} };"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, _S("\t}")); } } VV_LOC void v__gen__c__gen_js_get_opt(string dec_name, string field_type, string styp, string tmp, string name, strings__Builder* dec, bool is_required) { v__gen__c__gen_js_get(styp, tmp, name, dec, is_required); string value_field_type = string_replace(field_type, _S("*"), _S("_ptr")); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = string_replace(value_field_type, _S("*"), _S("_ptr"))}}, {_S(" "), 0xfe10, {.d_s = tmp}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\tif (jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(") {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = tmp}}, {_S(" = "), 0xfe10, {.d_s = dec_name}}, {_S("(jsonroot_"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(2, _MOV((StrIntpData[]){{_S("\t\tif ("), 0xfe10, {.d_s = tmp}}, {_S(".is_error) {"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, str_intp(4, _MOV((StrIntpData[]){{_S("\t\t\treturn ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = styp}}, {_S("){ .is_error = true, .err = "), 0xfe10, {.d_s = tmp}}, {_S(".err, .data = {0} };"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(dec, _S("\t\t}")); strings__Builder_writeln(dec, _S("\t}")); } VV_LOC string v__gen__c__js_enc_name(string typ) { string suffix = string_replace(typ, _S("*"), _S("_ptr")); if (_SLIT_EQ(typ.str, typ.len, "i32")) { suffix = string_replace(typ, _S("i32"), _S("int")); } string name = str_intp(2, _MOV((StrIntpData[]){{_S("json__encode_"), 0xfe10, {.d_s = suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); return v__util__no_dots(name); } VV_LOC string v__gen__c__js_dec_name(string typ) { string suffix = string_replace(typ, _S("*"), _S("_ptr")); if (_SLIT_EQ(typ.str, typ.len, "i32")) { suffix = string_replace(typ, _S("i32"), _S("int")); } string name = str_intp(2, _MOV((StrIntpData[]){{_S("json__decode_"), 0xfe10, {.d_s = suffix}}, {_SLIT0, 0, { .d_c = 0 }}})); return v__util__no_dots(name); } VV_LOC bool v__gen__c__is_js_prim(string typ) { return (_SLIT_EQ(typ.str, typ.len, "int") || _SLIT_EQ(typ.str, typ.len, "rune") || _SLIT_EQ(typ.str, typ.len, "string") || _SLIT_EQ(typ.str, typ.len, "bool") || _SLIT_EQ(typ.str, typ.len, "f32") || _SLIT_EQ(typ.str, typ.len, "f64") || _SLIT_EQ(typ.str, typ.len, "i8") || _SLIT_EQ(typ.str, typ.len, "i16") || _SLIT_EQ(typ.str, typ.len, "i32") || _SLIT_EQ(typ.str, typ.len, "i64") || _SLIT_EQ(typ.str, typ.len, "u8") || _SLIT_EQ(typ.str, typ.len, "u16") || _SLIT_EQ(typ.str, typ.len, "u32") || _SLIT_EQ(typ.str, typ.len, "u64") || _SLIT_EQ(typ.str, typ.len, "byte")); } VV_LOC string v__gen__c__Gen_decode_array(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__Type value_type, int fixed_array_size, string ret_styp) { string styp = v__gen__c__Gen_styp(g, value_type); string fn_name = v__gen__c__js_dec_name(styp); string noscan = v__gen__c__Gen_check_noscan(g, value_type); string res_str = _S(""); string array_free_str = _S(""); string fixed_array_idx = _S(""); string fixed_array_idx_increment = _S(""); string array_element_assign = _S(""); bool is_array_fixed_val = v__ast__Table_final_sym(g->table, value_type)->kind == v__ast__Kind__array_fixed; if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { if (fixed_array_size > -1) { fixed_array_idx = string__plus(fixed_array_idx, _S("int fixed_array_idx = 0;")); array_element_assign = string__plus(array_element_assign, str_intp(2, _MOV((StrIntpData[]){{_S("(("), 0xfe10, {.d_s = styp}}, {_S("*)res.data)[fixed_array_idx] = val;"), 0, { .d_c = 0 }}}))); fixed_array_idx_increment = string__plus(fixed_array_idx_increment, _S("fixed_array_idx++; res.state = 0;")); } else { array_element_assign = string__plus(array_element_assign, str_intp(2, _MOV((StrIntpData[]){{_S("array_push"), 0xfe10, {.d_s = noscan}}, {_S("((array*)&res.data, &val);"), 0, { .d_c = 0 }}}))); res_str = string__plus(res_str, str_intp(6, _MOV((StrIntpData[]){{_S("_option_ok(&("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S("[]) { __new_array"), 0xfe10, {.d_s = noscan}}, {_S("(0, 0, sizeof("), 0xfe10, {.d_s = styp}}, {_S(")) }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&res, sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S("));"), 0, { .d_c = 0 }}}))); array_free_str = string__plus(array_free_str, _S("array_free(&res.data);")); } } else { if (is_array_fixed_val) { fixed_array_idx = string__plus(fixed_array_idx, _S("int fixed_array_idx = 0;")); array_element_assign = string__plus(array_element_assign, str_intp(2, _MOV((StrIntpData[]){{_S("memcpy(res[fixed_array_idx], val, sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); fixed_array_idx_increment = string__plus(fixed_array_idx_increment, _S("fixed_array_idx++;")); } else if (fixed_array_size > -1) { fixed_array_idx = string__plus(fixed_array_idx, _S("int fixed_array_idx = 0;")); array_element_assign = string__plus(array_element_assign, _S("res[fixed_array_idx] = val;")); fixed_array_idx_increment = string__plus(fixed_array_idx_increment, _S("fixed_array_idx++;")); } else { array_element_assign = string__plus(array_element_assign, str_intp(2, _MOV((StrIntpData[]){{_S("array_push"), 0xfe10, {.d_s = noscan}}, {_S("((array*)&res, &val);"), 0, { .d_c = 0 }}}))); res_str = string__plus(res_str, str_intp(3, _MOV((StrIntpData[]){{_S("res = __new_array"), 0xfe10, {.d_s = noscan}}, {_S("(0, 0, sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}}))); array_free_str = string__plus(array_free_str, _S("array_free(&res);")); } } string s = _S(""); if (v__gen__c__is_js_prim(styp)) { s = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" val = "), 0xfe10, {.d_s = fn_name}}, {_S("((cJSON *)jsval); "), 0, { .d_c = 0 }}})); } else if (is_array_fixed_val) { s = str_intp(10, _MOV((StrIntpData[]){{_S("\n\011\011"), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = string_replace(styp, _S("*"), _S("_ptr"))}}, {_S(" val2 = "), 0xfe10, {.d_s = fn_name}}, {_S(" ((cJSON *)jsval);\n\011\011if(val2.is_error) {\n\011\011\011"), 0xfe10, {.d_s = array_free_str}}, {_S("\n\011\011\011return *("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ret_styp}}, {_S("*)&val2;\n\011\011}\n\011\011"), 0xfe10, {.d_s = styp}}, {_S(" val;\n\011\011memcpy(&val, ("), 0xfe10, {.d_s = styp}}, {_S("*)val2.data, sizeof("), 0xfe10, {.d_s = styp}}, {_S("));"), 0, { .d_c = 0 }}})); } else { s = str_intp(9, _MOV((StrIntpData[]){{_S("\n\011\011"), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = string_replace(styp, _S("*"), _S("_ptr"))}}, {_S(" val2 = "), 0xfe10, {.d_s = fn_name}}, {_S(" ((cJSON *)jsval);\n\011\011if(val2.is_error) {\n\011\011\011"), 0xfe10, {.d_s = array_free_str}}, {_S("\n\011\011\011return *("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ret_styp}}, {_S("*)&val2;\n\011\011}\n\011\011"), 0xfe10, {.d_s = styp}}, {_S(" val = *("), 0xfe10, {.d_s = styp}}, {_S("*)val2.data;\n"), 0, { .d_c = 0 }}})); } return str_intp(8, _MOV((StrIntpData[]){{_S("\n\011if(root && !cJSON_IsArray(root) && !cJSON_IsNull(root)) {\n\011\011return ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ret_styp}}, {_S("){.is_error = true, .err = _v_error(string__plus(_S(\"Json element is not an array: \"), json__json_print(root))), .data = {0}};\n\011}\n\011"), 0xfe10, {.d_s = res_str}}, {_S("\n\011const cJSON *jsval = NULL;\n\011"), 0xfe10, {.d_s = fixed_array_idx}}, {_S("\n\011cJSON_ArrayForEach(jsval, root)\n\011{\n\011\011"), 0xfe10, {.d_s = s}}, {_S("\n\011\011"), 0xfe10, {.d_s = array_element_assign}}, {_S("\n\011\011"), 0xfe10, {.d_s = fixed_array_idx_increment}}, {_S("\n\011}\n"), 0, { .d_c = 0 }}})); } VV_LOC string v__gen__c__Gen_encode_array(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__Type value_type, int fixed_array_size) { string styp = v__gen__c__Gen_styp(g, value_type); string fn_name = v__gen__c__js_enc_name(styp); string data_str = _S(""); string size_str = _S(""); if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { multi_return_string_string mr_43542 = (fixed_array_size > -1 ? ((multi_return_string_string){.arg0=str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = styp}}, {_S("*)(*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S("*)val.data)"), 0, { .d_c = 0 }}})),.arg1=str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = fixed_array_size}}, {_SLIT0, 0, { .d_c = 0 }}}))}) : ((multi_return_string_string){.arg0=str_intp(3, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = styp}}, {_S("*)(*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S("*)val.data).data"), 0, { .d_c = 0 }}})),.arg1=str_intp(2, _MOV((StrIntpData[]){{_S("(*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S("*)val.data).len"), 0, { .d_c = 0 }}}))})); data_str = mr_43542.arg0; size_str = mr_43542.arg1; } else { multi_return_string_string mr_43805 = (fixed_array_size > -1 ? ((multi_return_string_string){.arg0=str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = styp}}, {_S("*)val"), 0, { .d_c = 0 }}})),.arg1=str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = fixed_array_size}}, {_SLIT0, 0, { .d_c = 0 }}}))}) : ((multi_return_string_string){.arg0=str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = styp}}, {_S("*)val.data"), 0, { .d_c = 0 }}})),.arg1=_S("val.len")})); data_str = mr_43805.arg0; size_str = mr_43805.arg1; } return str_intp(4, _MOV((StrIntpData[]){{_S("\n\011o = cJSON_CreateArray();\n\011for (int i = 0; i < "), 0xfe10, {.d_s = size_str}}, {_S("; i++){\n\011\011cJSON_AddItemToArray(o, "), 0xfe10, {.d_s = fn_name}}, {_S("( ("), 0xfe10, {.d_s = data_str}}, {_S(")[i] ));\n\011}\n"), 0, { .d_c = 0 }}})); } VV_LOC string v__gen__c__Gen_decode_map(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__Type key_type, v__ast__Type value_type, string ustyp) { string styp = v__gen__c__Gen_styp(g, key_type); string styp_v = v__gen__c__Gen_styp(g, value_type); string ret_styp = string_replace(styp_v, _S("*"), _S("_ptr")); v__ast__TypeSymbol* key_type_symbol = v__ast__Table_sym(g->table, key_type); multi_return_string_string_string_string mr_44377 = v__gen__c__Gen_map_fn_ptrs(g, *key_type_symbol); string hash_fn = mr_44377.arg0; string key_eq_fn = mr_44377.arg1; string clone_fn = mr_44377.arg2; string free_fn = mr_44377.arg3; string fn_name_v = v__gen__c__js_dec_name(styp_v); string s = _S(""); if (v__gen__c__is_js_prim(styp_v)) { s = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp_v}}, {_S(" val = "), 0xfe10, {.d_s = fn_name_v}}, {_S(" (js_get(root, jsval->string));"), 0, { .d_c = 0 }}})); } else { s = str_intp(8, _MOV((StrIntpData[]){{_S("\n\011\011"), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ret_styp}}, {_S(" val2 = "), 0xfe10, {.d_s = fn_name_v}}, {_S(" (js_get(root, jsval->string));\n\011\011if(val2.is_error) {\n\011\011\011map_free(&res);\n\011\011\011return *("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ustyp}}, {_S("*)&val2;\n\011\011}\n\011\011"), 0xfe10, {.d_s = styp_v}}, {_S(" val = *("), 0xfe10, {.d_s = styp_v}}, {_S("*)val2.data;\n"), 0, { .d_c = 0 }}})); } if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { return str_intp(13, _MOV((StrIntpData[]){{_S("\n\011\011if(!cJSON_IsObject(root) && !cJSON_IsNull(root)) {\n\011\011\011return ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ustyp}}, {_S("){ .is_error = true, .err = _v_error(string__plus(_S(\"Json element is not an object: \"), json__json_print(root))), .data = {0}};\n\011\011}\n\011\011_option_ok(&("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S("[]) { new_map(sizeof("), 0xfe10, {.d_s = styp}}, {_S("), sizeof("), 0xfe10, {.d_s = styp_v}}, {_S("), "), 0xfe10, {.d_s = hash_fn}}, {_S(", "), 0xfe10, {.d_s = key_eq_fn}}, {_S(", "), 0xfe10, {.d_s = clone_fn}}, {_S(", "), 0xfe10, {.d_s = free_fn}}, {_S(") }, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&res, sizeof("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, utyp)}}, {_S("));\n\011\011cJSON *jsval = NULL;\n\011\011cJSON_ArrayForEach(jsval, root)\n\011\011{\n\011\011\011"), 0xfe10, {.d_s = s}}, {_S("\n\011\011\011string key = tos2((byteptr)jsval->string);\n\011\011\011map_set((map*)res.data, &key, &val);\n\011\011}\n"), 0, { .d_c = 0 }}})); } else { return str_intp(10, _MOV((StrIntpData[]){{_S("\n\011\011if(!cJSON_IsObject(root) && !cJSON_IsNull(root)) {\n\011\011\011return ("), 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_"), 0xfe10, {.d_s = ustyp}}, {_S("){ .is_error = true, .err = _v_error(string__plus(_S(\"Json element is not an object: \"), json__json_print(root))), .data = {0}};\n\011\011}\n\011\011res = new_map(sizeof("), 0xfe10, {.d_s = styp}}, {_S("), sizeof("), 0xfe10, {.d_s = styp_v}}, {_S("), "), 0xfe10, {.d_s = hash_fn}}, {_S(", "), 0xfe10, {.d_s = key_eq_fn}}, {_S(", "), 0xfe10, {.d_s = clone_fn}}, {_S(", "), 0xfe10, {.d_s = free_fn}}, {_S(");\n\011\011cJSON *jsval = NULL;\n\011\011cJSON_ArrayForEach(jsval, root)\n\011\011{\n\011\011\011"), 0xfe10, {.d_s = s}}, {_S("\n\011\011\011string key = tos2((byteptr)jsval->string);\n\011\011\011map_set(&res, &key, &val);\n\011\011}\n"), 0, { .d_c = 0 }}})); } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC string v__gen__c__Gen_encode_map(v__gen__c__Gen* g, v__ast__Type utyp, v__ast__Type key_type, v__ast__Type value_type) { string styp = v__gen__c__Gen_styp(g, key_type); string styp_v = v__gen__c__Gen_styp(g, value_type); string fn_name_v = v__gen__c__js_enc_name(styp_v); string zero = v__gen__c__Gen_type_default(g, value_type); string keys_tmp = v__gen__c__Gen_new_tmp_var(g); string key = _S("string key = "); if (v__ast__Type_is_string(key_type)) { key = string__plus(key, str_intp(3, _MOV((StrIntpData[]){{_S("(("), 0xfe10, {.d_s = styp}}, {_S("*)"), 0xfe10, {.d_s = keys_tmp}}, {_S(".data)[i];"), 0, { .d_c = 0 }}}))); } else { v__gen__c__verror(_S("json: encode only maps with string keys")); VUNREACHABLE(); } if (v__ast__Type_has_flag(utyp, v__ast__TypeFlag__option)) { return str_intp(10, _MOV((StrIntpData[]){{_S("\n\011\011o = cJSON_CreateObject();\n\011\011Array_"), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = keys_tmp}}, {_S(" = map_keys((map*)val.data);\n\011\011for (int i = 0; i < "), 0xfe10, {.d_s = keys_tmp}}, {_S(".len; ++i) {\n\011\011\011"), 0xfe10, {.d_s = key}}, {_S("\n\011\011\011cJSON_AddItemToObject(o, (char*) key.str, "), 0xfe10, {.d_s = fn_name_v}}, {_S(" ( *("), 0xfe10, {.d_s = styp_v}}, {_S("*) map_get((map*)val.data, &key, &("), 0xfe10, {.d_s = styp_v}}, {_S("[]) { "), 0xfe10, {.d_s = zero}}, {_S(" } ) ) );\n\011\011}\n\011\011array_free(&"), 0xfe10, {.d_s = keys_tmp}}, {_S(");\n"), 0, { .d_c = 0 }}})); } else { return str_intp(10, _MOV((StrIntpData[]){{_S("\n\011\011o = cJSON_CreateObject();\n\011\011Array_"), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = keys_tmp}}, {_S(" = map_keys(&val);\n\011\011for (int i = 0; i < "), 0xfe10, {.d_s = keys_tmp}}, {_S(".len; ++i) {\n\011\011\011"), 0xfe10, {.d_s = key}}, {_S("\n\011\011\011cJSON_AddItemToObject(o, (char*) key.str, "), 0xfe10, {.d_s = fn_name_v}}, {_S(" ( *("), 0xfe10, {.d_s = styp_v}}, {_S("*) map_get(&val, &key, &("), 0xfe10, {.d_s = styp_v}}, {_S("[]) { "), 0xfe10, {.d_s = zero}}, {_S(" } ) ) );\n\011\011}\n\011\011array_free(&"), 0xfe10, {.d_s = keys_tmp}}, {_S(");\n"), 0, { .d_c = 0 }}})); } return (string){.str=(byteptr)"", .is_lit=1}; } VNORETURN VV_LOC void v__gen__c__verror_suggest_json_no_inline_sumtypes(string sumtype_name, string type_name1, string type_name2) { v__gen__c__verror(str_intp(5, _MOV((StrIntpData[]){{_S("json: can not decode `"), 0xfe10, {.d_s = sumtype_name}}, {_S("` sumtype, too many numeric types (conflict of `"), 0xfe10, {.d_s = type_name1}}, {_S("` and `"), 0xfe10, {.d_s = type_name2}}, {_S("`), you can try to use alias for `"), 0xfe10, {.d_s = type_name2}}, {_S("` or compile v with `json_no_inline_sumtypes` flag"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); while(1); } VV_LOC void v__gen__c__Gen_generate_hotcode_reloading_declarations(v__gen__c__Gen* g) { if (g->pref->os == v__pref__OS__windows) { if (g->pref->is_livemain) { strings__Builder_writeln(&g->hotcode_definitions, _S("HANDLE live_fn_mutex = 0;")); } if (g->pref->is_liveshared) { strings__Builder_writeln(&g->hotcode_definitions, _S("HANDLE live_fn_mutex;")); } strings__Builder_writeln(&g->hotcode_definitions, _S("\nvoid pthread_mutex_lock(HANDLE *m) {\n\011WaitForSingleObject(*m, INFINITE);\n}\nvoid pthread_mutex_unlock(HANDLE *m) {\n\011ReleaseMutex(*m);\n}\n")); } else { if (g->pref->is_livemain) { strings__Builder_writeln(&g->hotcode_definitions, _S("pthread_mutex_t live_fn_mutex = PTHREAD_MUTEX_INITIALIZER;")); } if (g->pref->is_liveshared) { strings__Builder_writeln(&g->hotcode_definitions, _S("pthread_mutex_t live_fn_mutex;")); } } } VV_LOC void v__gen__c__Gen_generate_hotcode_reloader_code(v__gen__c__Gen* g) { if (g->pref->is_liveshared) { strings__Builder_writeln(&g->hotcode_definitions, _S("")); return; } if (g->pref->is_livemain) { string phd = _S(""); Array_string load_code = __new_array_with_default(0, 0, sizeof(string), 0); if (g->pref->os != v__pref__OS__windows) { for (int _t1 = 0; _t1 < g->hotcode_fn_names.len; ++_t1) { string so_fn = ((string*)g->hotcode_fn_names.data)[_t1]; array_push((array*)&load_code, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_S("\timpl_live_"), 0xfe10, {.d_s = so_fn}}, {_S(" = dlsym(live_lib, \"impl_live_"), 0xfe10, {.d_s = so_fn}}, {_S("\");"), 0, { .d_c = 0 }}})) })); } array_push((array*)&load_code, _MOV((string[]){ _S("void (* fn_set_live_reload_pointer)(void *) = (void *)dlsym(live_lib, \"set_live_reload_pointer\");") })); phd = _const_v__gen__c__posix_hotcode_definitions_1; } else { for (int _t4 = 0; _t4 < g->hotcode_fn_names.len; ++_t4) { string so_fn = ((string*)g->hotcode_fn_names.data)[_t4]; array_push((array*)&load_code, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_S("\timpl_live_"), 0xfe10, {.d_s = so_fn}}, {_S(" = (void *)GetProcAddress(live_lib, \"impl_live_"), 0xfe10, {.d_s = so_fn}}, {_S("\"); "), 0, { .d_c = 0 }}})) })); } array_push((array*)&load_code, _MOV((string[]){ _S("void (* fn_set_live_reload_pointer)(void *) = (void *)GetProcAddress(live_lib, \"set_live_reload_pointer\");") })); phd = _const_v__gen__c__windows_hotcode_definitions_1; } array_push((array*)&load_code, _MOV((string[]){ _S("if(fn_set_live_reload_pointer){ fn_set_live_reload_pointer( g_live_reload_info ); }") })); strings__Builder_writeln(&g->hotcode_definitions, string_replace(phd, _S("@LOAD_FNS@"), Array_string_join(load_code, _S("\n")))); } } VV_LOC void v__gen__c__Gen_generate_hotcode_reloading_main_caller(v__gen__c__Gen* g) { if (!g->pref->is_livemain) { return; } v__gen__c__Gen_writeln(g, _S("")); v__gen__c__Gen_writeln2(g, _S("\t// live code initialization section:"), _S("\t{")); v__gen__c__Gen_writeln(g, _S("\t\t// initialization of live function pointers")); for (int _t1 = 0; _t1 < g->hotcode_fn_names.len; ++_t1) { string fname = ((string*)g->hotcode_fn_names.data)[_t1]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\timpl_live_"), 0xfe10, {.d_s = fname}}, {_S(" = 0;"), 0, { .d_c = 0 }}}))); } string vexe = v__util__cescaped_path(v__pref__vexe_path()); string file = v__util__cescaped_path(g->pref->path); string ccpath = v__util__cescaped_path(g->pref->ccompiler); string ccompiler = str_intp(2, _MOV((StrIntpData[]){{_S("-cc "), 0xfe10, {.d_s = ccpath}}, {_SLIT0, 0, { .d_c = 0 }}})); string so_debug_flag = (g->pref->is_debug ? (_S("-cg")) : (_S(""))); string vopts = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ccompiler}}, {_S(" "), 0xfe10, {.d_s = so_debug_flag}}, {_S(" -sharedlive -shared"), 0, { .d_c = 0 }}})); v__gen__c__Gen_writeln(g, _S("\t\t// start background reloading thread")); if (g->pref->os == v__pref__OS__windows) { v__gen__c__Gen_writeln(g, _S("\t\tlive_fn_mutex = CreateMutexA(0, 0, 0);")); } v__gen__c__Gen_writeln(g, _S("\t\tv__live__LiveReloadInfo* live_info = v__live__executable__new_live_reload_info(")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\t\t\t tos2(\""), 0xfe10, {.d_s = file}}, {_S("\"),"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\t\t\t tos2(\""), 0xfe10, {.d_s = vexe}}, {_S("\"),"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t\t\t\t tos2(\""), 0xfe10, {.d_s = vopts}}, {_S("\"),"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\t\t\t\t\t &live_fn_mutex,")); v__gen__c__Gen_writeln(g, _S("\t\t\t\t\t v_bind_live_symbols")); v__gen__c__Gen_writeln(g, _S("\t\t);")); Map_string_bool already_added = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int _t2 = 0; _t2 < g->hotcode_fpaths.len; ++_t2) { string f = ((string*)g->hotcode_fpaths.data)[_t2]; map_set(&already_added, &(string[]){f}, &(bool[]) { true }); } int idx = 0; int _t4 = already_added.key_values.len; for (int _t3 = 0; _t3 < _t4; ++_t3 ) { int _t5 = already_added.key_values.len - _t4; _t4 = already_added.key_values.len; if (_t5 < 0) { _t3 = -1; continue; } if (!DenseArray_has_index(&already_added.key_values, _t3)) {continue;} string f = *(string*)DenseArray_key(&already_added.key_values, _t3); f = string_clone(f); string fpath = os__real_path(f); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\t\tv__live__executable__add_live_monitored_file(live_info, "), 0xfe10, {.d_s = v__gen__c__ctoslit(fpath)}}, {_S("); // source V file with @[live] "), 0xfe07, {.d_i32 = (int)(idx + 1)}}, {_S("/"), 0xfe07, {.d_i32 = already_added.len}}, {_SLIT0, 0, { .d_c = 0 }}}))); idx++; } v__gen__c__Gen_writeln(g, _S("")); v__gen__c__Gen_writeln(g, _S("\t\tg_live_reload_info = (void*)live_info;")); v__gen__c__Gen_writeln(g, _S("\t\tv__live__executable__start_reloader(live_info);")); v__gen__c__Gen_writeln(g, _S("\t}\t// end of live code initialization section")); v__gen__c__Gen_writeln(g, _S("")); } VV_LOC bool v__gen__c__Gen_need_tmp_var_in_match(v__gen__c__Gen* g, v__ast__MatchExpr node) { if (node.is_expr && node.return_type != _const_v__ast__void_type && node.return_type != 0) { if (g->inside_struct_init) { return true; } if ((v__ast__Table_sym(g->table, node.return_type)->kind == v__ast__Kind__sum_type || v__ast__Table_sym(g->table, node.return_type)->kind == v__ast__Kind__multi_return) || v__ast__Type_has_option_or_result(node.return_type)) { return true; } if (v__ast__Table_final_sym(g->table, node.cond_type)->kind == v__ast__Kind__enum && node.branches.len > 5) { return true; } if (v__gen__c__Gen_need_tmp_var_in_expr(g, node.cond)) { return true; } for (int _t5 = 0; _t5 < node.branches.len; ++_t5) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)node.branches.data)[_t5]; if (branch.stmts.len > 1) { return true; } if (branch.stmts.len == 1) { if (((*(v__ast__Stmt*)array_get(branch.stmts, 0)))._typ == 401 /* v.ast.ExprStmt */) { v__ast__ExprStmt stmt = *(v__ast__ExprStmt*)__as_cast(((*(v__ast__Stmt*)array_get(branch.stmts, 0)))._v__ast__ExprStmt,((*(v__ast__Stmt*)array_get(branch.stmts, 0)))._typ, 401); if ((stmt.expr)._typ == 338 /* v.ast.ArrayInit */ && (*(v__ast__ArrayInit*)__as_cast((stmt.expr)._v__ast__ArrayInit,(stmt.expr)._typ, 338)).is_fixed) { return true; } if (v__gen__c__Gen_need_tmp_var_in_expr(g, stmt.expr)) { return true; } } else if (((*(v__ast__Stmt*)array_get(branch.stmts, 0)))._typ == 412 /* v.ast.Return */) { return true; } else if (((*(v__ast__Stmt*)array_get(branch.stmts, 0)))._typ == 394 /* v.ast.BranchStmt */) { return true; } } } } return false; } VV_LOC void v__gen__c__Gen_match_expr(v__gen__c__Gen* g, v__ast__MatchExpr node) { bool v__gen__c__Gen_match_expr_defer_0 = false; bool old; bool v__gen__c__Gen_match_expr_defer_1 = false; if (node.cond_type == 0) { v__gen__c__Gen_writeln(g, _S("// match 0")); return; } bool need_tmp_var = v__gen__c__Gen_need_tmp_var_in_match(g, node); bool is_expr = (node.is_expr && node.return_type != _const_v__ast__void_type) || g->inside_ternary > 0; string cond_var = _S(""); string tmp_var = _S(""); string cur_line = _S(""); if (is_expr && !need_tmp_var) { g->inside_ternary++; } if (is_expr) { if (v__ast__Type_has_flag(node.return_type, v__ast__TypeFlag__option)) { old = g->inside_match_option; v__gen__c__Gen_match_expr_defer_0 = true; g->inside_match_option = true; } else if (v__ast__Type_has_flag(node.return_type, v__ast__TypeFlag__result)) { old = g->inside_match_result; v__gen__c__Gen_match_expr_defer_1 = true; g->inside_match_result = true; } } if ((((node.cond)._typ == 358 /* v.ast.Ident */ || (node.cond)._typ == 363 /* v.ast.IntegerLiteral */ || (node.cond)._typ == 384 /* v.ast.StringLiteral */ || (node.cond)._typ == 356 /* v.ast.FloatLiteral */) && ((node.cond)._typ != 358 /* v.ast.Ident */ || ((node.cond)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((node.cond)._v__ast__Ident,(node.cond)._typ, 358)).or_expr.kind == v__ast__OrKind__absent))) || ((node.cond)._typ == 379 /* v.ast.SelectorExpr */ && (*(v__ast__SelectorExpr*)__as_cast((node.cond)._v__ast__SelectorExpr,(node.cond)._typ, 379)).or_block.kind == v__ast__OrKind__absent && (((*(v__ast__SelectorExpr*)__as_cast((node.cond)._v__ast__SelectorExpr,(node.cond)._typ, 379)).expr)._typ != 344 /* v.ast.CallExpr */ || (*(v__ast__CallExpr*)__as_cast(((*(v__ast__SelectorExpr*)__as_cast((node.cond)._v__ast__SelectorExpr,(node.cond)._typ, 379)).expr)._v__ast__CallExpr,((*(v__ast__SelectorExpr*)__as_cast((node.cond)._v__ast__SelectorExpr,(node.cond)._typ, 379)).expr)._typ, 344)).or_block.kind == v__ast__OrKind__absent))) { cond_var = v__gen__c__Gen_expr_string(g, node.cond); } else { string _t1; /* if prepend */ if (is_expr) { g->empty_line = true; _t1 = string_trim_left(v__gen__c__Gen_go_before_last_stmt(g), _S("\t")); } else { _t1 = _S(""); } string line = _t1; cond_var = v__gen__c__Gen_new_tmp_var(g); { v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, node.cond_type)); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, node.cond); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); v__gen__c__Gen_write(g, line); } if (need_tmp_var) { g->empty_line = true; cur_line = string_trim_left(v__gen__c__Gen_go_before_last_stmt(g), _S(" \t")); tmp_var = v__gen__c__Gen_new_tmp_var(g); string func_decl = _S(""); v__ast__TypeSymbol* ret_final_sym = v__ast__Table_final_sym(g->table, node.return_type); if (!v__ast__Type_has_option_or_result(node.return_type) && ret_final_sym->kind == v__ast__Kind__function) { if ((ret_final_sym->info)._typ == 553 /* v.ast.FnType */) { Array_v__ast__Type _t2 = {0}; Array_v__ast__Param _t2_orig = (*ret_final_sym->info._v__ast__FnType).func.params; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(v__ast__Type)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Param it = ((v__ast__Param*) _t2_orig.data)[_t4]; v__ast__Type _t3 = it.typ; array_push((array*)&_t2, &_t3); } string def = v__gen__c__Gen_fn_var_signature(g, (*ret_final_sym->info._v__ast__FnType).func.return_type,_t2, tmp_var); func_decl = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = def}}, {_S(" = &"), 0xfe10, {.d_s = v__gen__c__Gen_styp(g, node.return_type)}}, {_S(";"), 0, { .d_c = 0 }}})); } } if ((func_decl).len != 0) { v__gen__c__Gen_writeln(g, func_decl); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_styp(g, node.return_type)}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(" = "), 0xfe10, {.d_s = v__gen__c__Gen_type_default(g, node.return_type)}}, {_S(";"), 0, { .d_c = 0 }}}))); } g->empty_line = true; if (g->infix_left_var_name.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = g->infix_left_var_name}}, {_S(") {"), 0, { .d_c = 0 }}}))); g->indent++; } } if (is_expr && !need_tmp_var) { v__gen__c__Gen_write(g, _S("(")); } if (node.is_sum_type) { v__gen__c__Gen_match_expr_sumtype(g, node, is_expr, cond_var, tmp_var); } else { v__ast__TypeSymbol* cond_fsym = v__ast__Table_final_sym(g->table, node.cond_type); bool can_be_a_switch = true; all_branches: {} for (int _t5 = 0; _t5 < node.branches.len; ++_t5) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)node.branches.data)[_t5]; for (int _t6 = 0; _t6 < branch.exprs.len; ++_t6) { v__ast__Expr expr = ((v__ast__Expr*)branch.exprs.data)[_t6]; if (expr._typ == 342 /* v.ast.BoolLiteral */) { continue; } else if (expr._typ == 363 /* v.ast.IntegerLiteral */) { continue; } else if (expr._typ == 347 /* v.ast.CharLiteral */) { continue; } else if (expr._typ == 355 /* v.ast.EnumVal */) { continue; } else { can_be_a_switch = false; goto all_branches__break; } } all_branches__continue: {} } all_branches__break: {} if (can_be_a_switch && !is_expr && g->loop_depth == 0 && g->fn_decl != ((void*)0) && v__ast__TypeSymbol_is_int(cond_fsym)) { v__gen__c__Gen_match_expr_switch(g, node, is_expr, cond_var, tmp_var, *cond_fsym); } else if (cond_fsym->kind == v__ast__Kind__enum && g->loop_depth == 0 && node.branches.len > 5 && g->fn_decl != ((void*)0)) { v__gen__c__Gen_match_expr_switch(g, node, is_expr, cond_var, tmp_var, *cond_fsym); } else { v__gen__c__Gen_match_expr_classic(g, node, is_expr, cond_var, tmp_var); } } v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); if (need_tmp_var) { if (g->infix_left_var_name.len > 0) { v__gen__c__Gen_writeln(g, _S("")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } } v__gen__c__Gen_write(g, cur_line); if (need_tmp_var) { v__gen__c__Gen_write(g, tmp_var); } if (is_expr && !need_tmp_var) { v__gen__c__Gen_write(g, _S(")")); v__gen__c__Gen_decrement_inside_ternary(g); } // Defer begin if (v__gen__c__Gen_match_expr_defer_1) { g->inside_match_result = old; } // Defer end // Defer begin if (v__gen__c__Gen_match_expr_defer_0) { g->inside_match_option = old; } // Defer end } VV_LOC void v__gen__c__Gen_match_expr_sumtype(v__gen__c__Gen* g, v__ast__MatchExpr node, bool is_expr, string cond_var, string tmp_var) { string dot_or_ptr = v__gen__c__Gen_dot_or_ptr(g, node.cond_type); bool use_ternary = is_expr && (tmp_var).len == 0; v__ast__TypeSymbol* cond_sym = v__ast__Table_sym(g->table, node.cond_type); for (int j = 0; j < node.branches.len; ++j) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)node.branches.data)[j]; int sumtype_index = 0; for (;;) { g->aggregate_type_idx = sumtype_index; bool is_last = j == (int)(node.branches.len - 1) && sumtype_index == (int)(branch.exprs.len - 1); if (branch.is_else || (use_ternary && is_last)) { if (use_ternary) { v__gen__c__Gen_write(g, _S(" : ")); } else { v__gen__c__Gen_writeln(g, _S("")); v__gen__c__Gen_write_v_source_line_info(g, v__ast__MatchBranch_to_sumtype_v__ast__Node(&branch)); v__gen__c__Gen_writeln(g, _S("else {")); } } else { if (j > 0 || sumtype_index > 0) { if (use_ternary) { v__gen__c__Gen_write(g, _S(" : ")); } else { v__gen__c__Gen_write_v_source_line_info(g, v__ast__MatchBranch_to_sumtype_v__ast__Node(&branch)); v__gen__c__Gen_write(g, _S("else ")); } } if (use_ternary) { v__gen__c__Gen_write(g, _S("(")); } else { if (j == 0 && sumtype_index == 0) { g->empty_line = true; } v__gen__c__Gen_write_v_source_line_info(g, v__ast__MatchBranch_to_sumtype_v__ast__Node(&branch)); v__gen__c__Gen_write(g, _S("if (")); } bool need_deref = v__ast__Type_nr_muls(node.cond_type) > 1; if (need_deref) { v__gen__c__Gen_write2(g, _S("("), string_repeat(_S("*"), (int)(v__ast__Type_nr_muls(node.cond_type) - 1))); } v__gen__c__Gen_write(g, cond_var); if (need_deref) { v__gen__c__Gen_write(g, _S(")")); } v__ast__Expr* cur_expr = &(*(v__ast__Expr*)array_get(branch.exprs, sumtype_index)); if (cond_sym->kind == v__ast__Kind__sum_type) { if ((cur_expr)->_typ == 386 /* v.ast.TypeNode */) { v__type_resolver__TypeResolver_update_ct_type(&g->type_resolver, cond_var, (*cur_expr->_v__ast__TypeNode).typ); } { v__gen__c__Gen_write(g, dot_or_ptr); v__gen__c__Gen_write(g, _S("_typ == ")); } if ((cur_expr)->_typ == 371 /* v.ast.None */) { { v__gen__c__Gen_write_decimal(g, v__ast__Type_idx(_const_v__ast__none_type)); v__gen__c__Gen_write(g, _S(" /* none */")); } } else { v__gen__c__Gen_expr(g, *cur_expr); } } else if (cond_sym->kind == v__ast__Kind__interface) { if ((cur_expr)->_typ == 386 /* v.ast.TypeNode */) { v__ast__TypeSymbol* branch_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, (*cur_expr->_v__ast__TypeNode).typ)); { v__gen__c__Gen_write(g, dot_or_ptr); v__gen__c__Gen_write(g, _S("_typ == _")); v__gen__c__Gen_write(g, cond_sym->cname); v__gen__c__Gen_write(g, _S("_")); v__gen__c__Gen_write(g, branch_sym->cname); v__gen__c__Gen_write(g, _S("_index")); } } else if ((cur_expr)->_typ == 371 /* v.ast.None */ && cond_sym->idx == 30) { { v__gen__c__Gen_write(g, dot_or_ptr); v__gen__c__Gen_write(g, _S("_typ == _IError_None___index")); } } } if (use_ternary) { v__gen__c__Gen_write(g, _S(")? ")); } else { v__gen__c__Gen_writeln(g, _S(") {")); } } if (is_expr && tmp_var.len > 0 && v__ast__Table_sym(g->table, node.return_type)->kind == v__ast__Kind__sum_type) { g->expected_cast_type = node.return_type; } bool inside_interface_deref_old = g->inside_interface_deref; if (is_expr && branch.stmts.len > 0) { v__ast__Stmt stmt = (*(v__ast__Stmt*)array_last(branch.stmts)); if ((stmt)._typ == 401 /* v.ast.ExprStmt */) { if (((*stmt._v__ast__ExprStmt).expr)._typ == 358 /* v.ast.Ident */ && ((*(v__ast__Ident*)__as_cast(((*stmt._v__ast__ExprStmt).expr)._v__ast__Ident,((*stmt._v__ast__ExprStmt).expr)._typ, 358)).obj)._typ == 422 /* v.ast.Var */ && v__ast__Table_is_interface_var(g->table, (*(v__ast__Ident*)__as_cast(((*stmt._v__ast__ExprStmt).expr)._v__ast__Ident,((*stmt._v__ast__ExprStmt).expr)._typ, 358)).obj)) { g->inside_interface_deref = true; } else if (((*stmt._v__ast__ExprStmt).expr)._typ == 376 /* v.ast.PrefixExpr */ && ((*(v__ast__PrefixExpr*)__as_cast(((*stmt._v__ast__ExprStmt).expr)._v__ast__PrefixExpr,((*stmt._v__ast__ExprStmt).expr)._typ, 376)).right)._typ == 358 /* v.ast.Ident */) { v__ast__Ident ident = (*(*(*stmt._v__ast__ExprStmt).expr._v__ast__PrefixExpr).right._v__ast__Ident); if ((ident.obj)._typ == 422 /* v.ast.Var */ && v__ast__Table_is_interface_var(g->table, v__ast__Var_to_sumtype_v__ast__ScopeObject((v__ast__Var*)__as_cast((ident.obj)._v__ast__Var,(ident.obj)._typ, 422)))) { g->inside_interface_deref = true; } } } } v__gen__c__Gen_stmts_with_tmp_var(g, branch.stmts, tmp_var); g->inside_interface_deref = inside_interface_deref_old; g->expected_cast_type = 0; if (g->inside_ternary == 0) { v__gen__c__Gen_writeln(g, _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } sumtype_index++; if (branch.exprs.len == 0 || sumtype_index == branch.exprs.len) { break; } } g->aggregate_type_idx = 0; } } VV_LOC void v__gen__c__Gen_match_expr_switch(v__gen__c__Gen* g, v__ast__MatchExpr node, bool is_expr, string cond_var, string tmp_var, v__ast__TypeSymbol cond_fsym) { bool node_cond_type_unsigned = (node.cond_type == _const_v__ast__u16_type || node.cond_type == _const_v__ast__u32_type || node.cond_type == _const_v__ast__u64_type); int covered_enum_cap = ((cond_fsym.info)._typ == 548 /* v.ast.Enum */ ? ((*cond_fsym.info._v__ast__Enum).vals.len) : (0)); Array_string covered_enum = __new_array_with_default(0, covered_enum_cap, sizeof(string), 0); Array_v__ast__MatchBranch range_branches = __new_array_with_default(0, node.branches.len, sizeof(v__ast__MatchBranch), 0); bool default_generated = false; g->empty_line = true; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("switch ("), 0xfe10, {.d_s = cond_var}}, {_S(") {"), 0, { .d_c = 0 }}}))); g->indent++; for (int _t1 = 0; _t1 < node.branches.len; ++_t1) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)node.branches.data)[_t1]; if (branch.is_else) { if ((cond_fsym.info)._typ == 548 /* v.ast.Enum */) { string cname = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = cond_fsym.cname}}, {_S("__"), 0, { .d_c = 0 }}})); for (int _t2 = 0; _t2 < (*cond_fsym.info._v__ast__Enum).vals.len; ++_t2) { string val = ((string*)(*cond_fsym.info._v__ast__Enum).vals.data)[_t2]; if (!(Array_string_contains(covered_enum, val))) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("case "), 0xfe10, {.d_s = cname}}, {_SLIT0, 0xfe10, {.d_s = val}}, {_S(":"), 0, { .d_c = 0 }}}))); } } } v__gen__c__Gen_writeln(g, _S("default: {")); default_generated = true; g->indent++; if (range_branches.len > 0) { for (int _t3 = 0; _t3 < range_branches.len; ++_t3) { v__ast__MatchBranch range_branch = ((v__ast__MatchBranch*)range_branches.data)[_t3]; v__gen__c__Gen_write(g, _S("if (")); for (int i = 0; i < range_branch.exprs.len; ++i) { v__ast__Expr expr = ((v__ast__Expr*)range_branch.exprs.data)[i]; if (i > 0) { v__gen__c__Gen_write(g, _S(" || ")); } if ((expr)._typ == 377 /* v.ast.RangeExpr */) { v__gen__c__Gen_write(g, _S("(")); if (v__gen__c__Gen_should_check_low_bound_in_range_expr(g, (*expr._v__ast__RangeExpr), node_cond_type_unsigned)) { { v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" >= ")); } v__gen__c__Gen_expr(g, (*expr._v__ast__RangeExpr).low); v__gen__c__Gen_write(g, _S(" && ")); } { v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" <= ")); } v__gen__c__Gen_expr(g, (*expr._v__ast__RangeExpr).high); v__gen__c__Gen_write(g, _S(")")); } else { { v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" == (")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_writeln(g, _S(") {")); bool ends_with_return = v__gen__c__Gen_stmts_with_tmp_var(g, range_branch.stmts, tmp_var); if (!ends_with_return) { v__gen__c__Gen_writeln(g, _S("\tbreak;")); } v__gen__c__Gen_writeln(g, _S("}")); } } } else { bool _t4 = false; Array_v__ast__Expr _t4_orig = branch.exprs; int _t4_len = _t4_orig.len; for (int _t5 = 0; _t5 < _t4_len; ++_t5) { v__ast__Expr it = ((v__ast__Expr*) _t4_orig.data)[_t5]; if ((it)._typ == 377 /* v.ast.RangeExpr */) { _t4 = true; break; } } if (_t4) { array_push((array*)&range_branches, _MOV((v__ast__MatchBranch[]){ branch })); continue; } for (int _t7 = 0; _t7 < branch.exprs.len; ++_t7) { v__ast__Expr expr = ((v__ast__Expr*)branch.exprs.data)[_t7]; if ((expr)._typ == 355 /* v.ast.EnumVal */) { array_push((array*)&covered_enum, _MOV((string[]){ string_clone((*expr._v__ast__EnumVal).val) })); } v__gen__c__Gen_write(g, _S("case ")); v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(": ")); } } v__gen__c__Gen_writeln(g, _S("{")); if (is_expr && tmp_var.len > 0 && v__ast__Table_sym(g->table, node.return_type)->kind == v__ast__Kind__sum_type) { g->expected_cast_type = node.return_type; } bool ends_with_return = v__gen__c__Gen_stmts_with_tmp_var(g, branch.stmts, tmp_var); g->expected_cast_type = 0; if (!ends_with_return) { v__gen__c__Gen_writeln(g, _S("\tbreak;")); } v__gen__c__Gen_writeln(g, _S("}")); } if (range_branches.len > 0 && !default_generated) { v__gen__c__Gen_writeln(g, _S("default: {")); g->indent++; default_generated = true; for (int _t9 = 0; _t9 < range_branches.len; ++_t9) { v__ast__MatchBranch range_branch = ((v__ast__MatchBranch*)range_branches.data)[_t9]; v__gen__c__Gen_write(g, _S("if (")); for (int i = 0; i < range_branch.exprs.len; ++i) { v__ast__Expr expr = ((v__ast__Expr*)range_branch.exprs.data)[i]; if (i > 0) { v__gen__c__Gen_write(g, _S(" || ")); } if ((expr)._typ == 377 /* v.ast.RangeExpr */) { v__gen__c__Gen_write(g, _S("(")); if (v__gen__c__Gen_should_check_low_bound_in_range_expr(g, (*expr._v__ast__RangeExpr), node_cond_type_unsigned)) { { v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" >= ")); } v__gen__c__Gen_expr(g, (*expr._v__ast__RangeExpr).low); v__gen__c__Gen_write(g, _S(" && ")); } { v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" <= ")); } v__gen__c__Gen_expr(g, (*expr._v__ast__RangeExpr).high); v__gen__c__Gen_write(g, _S(")")); } else { { v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" == (")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_writeln(g, _S(") {")); bool ends_with_return = v__gen__c__Gen_stmts_with_tmp_var(g, range_branch.stmts, tmp_var); if (!ends_with_return) { v__gen__c__Gen_writeln(g, _S("\tbreak;")); } v__gen__c__Gen_writeln(g, _S("}")); } } if (default_generated) { g->indent--; v__gen__c__Gen_writeln(g, _S("}")); } g->indent--; v__gen__c__Gen_writeln(g, _S("}")); } VV_LOC bool v__gen__c__Gen_should_check_low_bound_in_range_expr(v__gen__c__Gen* g, v__ast__RangeExpr expr, bool node_cond_type_unsigned) { bool should_check_low_bound = true; if (node_cond_type_unsigned) { if ((expr.low)._typ == 363 /* v.ast.IntegerLiteral */) { if (fast_string_eq((*expr.low._v__ast__IntegerLiteral).val, _S("0"))) { should_check_low_bound = false; } } else if ((expr.low)._typ == 358 /* v.ast.Ident */) { v__ast__Ident elow = (*expr.low._v__ast__Ident); _option_v__ast__ConstField_ptr _t1; if (_t1 = v__ast__Scope_find_const(g->table->global_scope, v__ast__Ident_full_name(&elow)), _t1.state == 0) { v__ast__ConstField* obj = *(v__ast__ConstField**)_t1.data; if ((obj->expr)._typ == 363 /* v.ast.IntegerLiteral */) { if (fast_string_eq((*obj->expr._v__ast__IntegerLiteral).val, _S("0"))) { should_check_low_bound = false; } } } } } return should_check_low_bound; } VV_LOC void v__gen__c__Gen_match_expr_classic(v__gen__c__Gen* g, v__ast__MatchExpr node, bool is_expr, string cond_var, string tmp_var) { bool node_cond_type_unsigned = (node.cond_type == _const_v__ast__u16_type || node.cond_type == _const_v__ast__u32_type || node.cond_type == _const_v__ast__u64_type); v__ast__TypeSymbol* type_sym = v__ast__Table_final_sym(g->table, node.cond_type); bool use_ternary = is_expr && (tmp_var).len == 0; bool reset_if = false; bool has_goto = false; for (int j = 0; j < node.branches.len; ++j) { v__ast__MatchBranch branch = ((v__ast__MatchBranch*)node.branches.data)[j]; bool is_last = j == (int)(node.branches.len - 1); if (branch.is_else || (use_ternary && is_last)) { if (node.branches.len > 1) { if (use_ternary) { v__gen__c__Gen_write(g, _S(" : ")); } else { v__gen__c__Gen_writeln(g, _S("")); v__gen__c__Gen_write_v_source_line_info(g, v__ast__MatchBranch_to_sumtype_v__ast__Node(&branch)); v__gen__c__Gen_writeln(g, _S("else {")); } } } else { if (j > 0) { if (use_ternary) { v__gen__c__Gen_write(g, _S(" : ")); } else { v__gen__c__Gen_writeln(g, _S("")); v__gen__c__Gen_write_v_source_line_info(g, v__ast__MatchBranch_to_sumtype_v__ast__Node(&branch)); if (!reset_if) { v__gen__c__Gen_write(g, _S("else ")); } else { reset_if = false; } } } if (use_ternary) { v__gen__c__Gen_write(g, _S("(")); } else { if (j == 0) { v__gen__c__Gen_writeln(g, _S("")); } v__gen__c__Gen_write_v_source_line_info(g, v__ast__MatchBranch_to_sumtype_v__ast__Node(&branch)); v__gen__c__Gen_write(g, _S("if (")); } bool _t1 = false; Array_v__ast__Expr _t1_orig = branch.exprs; int _t1_len = _t1_orig.len; for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__ast__Expr it = ((v__ast__Expr*) _t1_orig.data)[_t2]; if (v__gen__c__Gen_match_must_reset_if(g, it)) { _t1 = true; break; } } reset_if =_t1; for (int i = 0; i < branch.exprs.len; ++i) { v__ast__Expr expr = ((v__ast__Expr*)branch.exprs.data)[i]; if (i > 0) { v__gen__c__Gen_write(g, _S(" || ")); } if ((expr)._typ == 371 /* v.ast.None */) { bool old_left_is_opt = g->left_is_opt; g->left_is_opt = true; v__gen__c__Gen_expr(g, node.cond); g->left_is_opt = old_left_is_opt; v__gen__c__Gen_write(g, _S(".state == 2")); continue; } if (type_sym->kind == (v__ast__Kind__array)) { string ptr_typ = v__gen__c__Gen_equality_fn(g, node.cond_type); { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_arr_eq(")); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(", ")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } else if (type_sym->kind == (v__ast__Kind__array_fixed)) { string ptr_typ = v__gen__c__Gen_equality_fn(g, node.cond_type); { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_arr_eq(")); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(", ")); } if ((expr)._typ == 338 /* v.ast.ArrayInit */) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, node.cond_type)); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } else if (type_sym->kind == (v__ast__Kind__map)) { string ptr_typ = v__gen__c__Gen_equality_fn(g, node.cond_type); { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_map_eq(")); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(", ")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } else if (type_sym->kind == (v__ast__Kind__string)) { if ((expr)._typ == 384 /* v.ast.StringLiteral */) { string slit = v__gen__c__cescape_nonascii(v__util__smart_quote((*expr._v__ast__StringLiteral).val, (*expr._v__ast__StringLiteral).is_raw)); if (v__ast__Type_is_ptr(node.cond_type)) { { v__gen__c__Gen_write(g, _S("_SLIT_EQ(")); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S("->str, ")); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S("->len, \"")); v__gen__c__Gen_write(g, slit); v__gen__c__Gen_write(g, _S("\")")); } } else { { v__gen__c__Gen_write(g, _S("_SLIT_EQ(")); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(".str, ")); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(".len, \"")); v__gen__c__Gen_write(g, slit); v__gen__c__Gen_write(g, _S("\")")); } } } else { string ptr_str = (v__ast__Type_is_ptr(node.cond_type) ? (_S("*")) : (_S(""))); { v__gen__c__Gen_write(g, _S("fast_string_eq(")); v__gen__c__Gen_write(g, ptr_str); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(", ")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } } else if (type_sym->kind == (v__ast__Kind__struct)) { string derefs_expr = string_repeat(_S("*"), v__ast__Type_nr_muls(v__gen__c__Gen_get_expr_type(g, expr))); string derefs_ctype = string_repeat(_S("*"), v__ast__Type_nr_muls(node.cond_type)); string ptr_typ = v__gen__c__Gen_equality_fn(g, node.cond_type); { v__gen__c__Gen_write(g, ptr_typ); v__gen__c__Gen_write(g, _S("_struct_eq(")); v__gen__c__Gen_write(g, derefs_ctype); v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write(g, derefs_expr); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } else { if ((expr)._typ == 377 /* v.ast.RangeExpr */) { v__gen__c__Gen_write(g, _S("(")); if (v__gen__c__Gen_should_check_low_bound_in_range_expr(g, (*expr._v__ast__RangeExpr), node_cond_type_unsigned)) { { v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" >= ")); } v__gen__c__Gen_expr(g, (*expr._v__ast__RangeExpr).low); v__gen__c__Gen_write(g, _S(" && ")); } { v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" <= ")); } v__gen__c__Gen_expr(g, (*expr._v__ast__RangeExpr).high); v__gen__c__Gen_write(g, _S(")")); } else if ((expr)._typ == 371 /* v.ast.None */) { bool old_left_is_opt = g->left_is_opt; g->left_is_opt = true; v__gen__c__Gen_expr(g, node.cond); g->left_is_opt = old_left_is_opt; v__gen__c__Gen_write(g, _S(".state == 2")); } else { { v__gen__c__Gen_write(g, cond_var); v__gen__c__Gen_write(g, _S(" == (")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } } } if (use_ternary) { v__gen__c__Gen_write(g, _S(")? ")); } else { v__gen__c__Gen_writeln(g, _S(") {")); } } if (is_expr && tmp_var.len > 0 && v__ast__Table_sym(g->table, node.return_type)->kind == v__ast__Kind__sum_type) { g->expected_cast_type = node.return_type; } v__gen__c__Gen_stmts_with_tmp_var(g, branch.stmts, tmp_var); g->expected_cast_type = 0; if (g->inside_ternary == 0 && node.branches.len >= 1) { if (reset_if) { has_goto = true; v__gen__c__Gen_writeln2(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tgoto end_block_"), 0xfe07, {.d_i32 = node.pos.line_nr}}, {_S(";"), 0, { .d_c = 0 }}})), _S("}")); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } else { v__gen__c__Gen_write(g, _S("}")); } } } if (has_goto) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("end_block_"), 0xfe07, {.d_i32 = node.pos.line_nr}}, {_S(": {}"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_set_current_pos_as_last_stmt_pos(g); } } VV_LOC bool v__gen__c__Gen_match_must_reset_if(v__gen__c__Gen* g, v__ast__Expr node) { return ((node._typ == 344 /* v.ast.CallExpr */)? ((*node._v__ast__CallExpr).or_block.kind != v__ast__OrKind__absent) : (node._typ == 362 /* v.ast.InfixExpr */)? (v__gen__c__Gen_match_must_reset_if(g, (*node._v__ast__InfixExpr).left) || v__gen__c__Gen_match_must_reset_if(g, (*node._v__ast__InfixExpr).right)) : (false)); } VV_LOC void v__gen__c__Gen_sql_select_expr(v__gen__c__Gen* g, v__ast__SqlExpr node) { string left = v__gen__c__Gen_go_before_last_stmt(g); string connection_var_name = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, _S("")); v__gen__c__Gen_write_orm_connection_init(g, connection_var_name, &node.db_expr); string result_var = v__gen__c__Gen_new_tmp_var(g); string result_c_typ = v__gen__c__Gen_styp(g, node.typ); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = result_c_typ}}, {_S(" "), 0xfe10, {.d_s = result_var}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write_orm_select(g, node, connection_var_name, result_var); string unwrapped_c_typ = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(node.typ, v__ast__TypeFlag__result)); { v__gen__c__Gen_write(g, left); v__gen__c__Gen_write(g, _S(" *(")); v__gen__c__Gen_write(g, unwrapped_c_typ); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, result_var); v__gen__c__Gen_write(g, _S(".data")); } } VV_LOC void v__gen__c__Gen_sql_insert_expr(v__gen__c__Gen* g, v__ast__SqlExpr node) { string left = v__gen__c__Gen_go_before_last_stmt(g); v__gen__c__Gen_writeln(g, _S("")); string connection_var_name = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_write_orm_connection_init(g, connection_var_name, &node.db_expr); string table_name = v__gen__c__Gen_get_table_name_by_struct_type(g, node.table_expr.typ); Array_v__ast__Attr table_attrs = v__gen__c__Gen_get_table_attrs_by_struct_type(g, node.table_expr.typ); string result_var_name = v__gen__c__Gen_new_tmp_var(g); g->sql_table_name = v__ast__Table_sym(g->table, node.table_expr.typ)->name; v__ast__SqlStmtLine hack_stmt_line = ((v__ast__SqlStmtLine){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.is_generated = 0,.scope = ((void*)0),.object_var = node.inserted_var,.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = node.table_expr,.fields = node.fields,.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),}); v__gen__c__Gen_write_orm_insert(g, (voidptr)&hack_stmt_line, table_name, connection_var_name, result_var_name, (voidptr)&node.or_expr, table_attrs); v__gen__c__Gen_write2(g, left, str_intp(3, _MOV((StrIntpData[]){{_S("orm__Connection_name_table["), 0xfe10, {.d_s = connection_var_name}}, {_S("._typ]._method_last_id("), 0xfe10, {.d_s = connection_var_name}}, {_S("._object)"), 0, { .d_c = 0 }}}))); } VV_LOC void v__gen__c__Gen_sql_stmt(v__gen__c__Gen* g, v__ast__SqlStmt node) { string connection_var_name = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_write_orm_connection_init(g, connection_var_name, &node.db_expr); for (int _t1 = 0; _t1 < node.lines.len; ++_t1) { v__ast__SqlStmtLine line = ((v__ast__SqlStmtLine*)node.lines.data)[_t1]; v__gen__c__Gen_sql_stmt_line(g, line, connection_var_name, node.or_expr); } } VV_LOC void v__gen__c__Gen_sql_stmt_line(v__gen__c__Gen* g, v__ast__SqlStmtLine stmt_line, string connection_var_name, v__ast__OrExpr or_expr) { g->sql_last_stmt_out_len = g->out.len; v__ast__SqlStmtLine node = stmt_line; string table_name = v__gen__c__Gen_get_table_name_by_struct_type(g, node.table_expr.typ); Array_v__ast__Attr table_attrs = v__gen__c__Gen_get_table_attrs_by_struct_type(g, node.table_expr.typ); string result_var_name = v__gen__c__Gen_new_tmp_var(g); g->sql_table_name = v__ast__Table_sym(g->table, node.table_expr.typ)->name; if (node.kind != v__ast__SqlStmtKind__create) { node.fields = v__gen__c__Gen_filter_struct_fields_by_orm_attrs(g, node.fields); } if (node.kind == v__ast__SqlStmtKind__create) { v__gen__c__Gen_write_orm_create_table(g, node, table_name, connection_var_name, result_var_name, table_attrs); } else if (node.kind == v__ast__SqlStmtKind__drop) { v__gen__c__Gen_write_orm_drop_table(g, node, table_name, connection_var_name, result_var_name, table_attrs); } else if (node.kind == v__ast__SqlStmtKind__insert) { v__gen__c__Gen_write_orm_insert(g, (voidptr)&node, table_name, connection_var_name, result_var_name, (voidptr)&or_expr, table_attrs); } else if (node.kind == v__ast__SqlStmtKind__update) { v__gen__c__Gen_write_orm_update(g, (voidptr)&node, table_name, connection_var_name, result_var_name, table_attrs); } else if (node.kind == v__ast__SqlStmtKind__delete) { v__gen__c__Gen_write_orm_delete(g, (voidptr)&node, table_name, connection_var_name, result_var_name, table_attrs); } v__gen__c__Gen_or_block(g, result_var_name, or_expr, v__ast__Type_set_flag(_const_v__ast__int_type, v__ast__TypeFlag__result)); } VV_LOC void v__gen__c__Gen_write_orm_connection_init(v__gen__c__Gen* g, string connection_var_name, v__ast__Expr* db_expr) { _option_v__ast__Type _t1 = v__gen__c__Gen_get_db_expr_type(g, *db_expr); if (_t1.state != 0) { IError err = _t1.err; v__gen__c__verror(str_intp(2, _MOV((StrIntpData[]){{_S("ORM: unknown db type for "), 0xfe10, {.d_s = str_intp(1, _MOV((StrIntpData[]){{_S("&"), 0xfe10 ,{.d_s = isnil(db_expr) ? _S("nil") : v__ast__Expr_str(db_expr)}}}))}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } v__ast__Type db_expr_type = (*(v__ast__Type*)_t1.data); string db_ctype_name = v__gen__c__Gen_styp(g, db_expr_type); bool is_pointer = string_ends_with(db_ctype_name, _S("*")); string reference_sign = (is_pointer ? (_S("")) : (_S("&"))); db_ctype_name = string_trim_right(db_ctype_name, _S("*")); v__gen__c__Gen_writeln(g, _S("// ORM")); { v__gen__c__Gen_write(g, _S("orm__Connection ")); v__gen__c__Gen_write(g, connection_var_name); v__gen__c__Gen_write(g, _S(" = ")); } if (_SLIT_EQ(db_ctype_name.str, db_ctype_name.len, "orm__Connection")) { v__gen__c__Gen_expr(g, *db_expr); v__gen__c__Gen_writeln(g, _S(";")); } else { { v__gen__c__Gen_write(g, _S("(orm__Connection){._")); v__gen__c__Gen_write(g, db_ctype_name); v__gen__c__Gen_write(g, _S(" = ")); v__gen__c__Gen_write(g, reference_sign); } v__gen__c__Gen_expr(g, *db_expr); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(", ._typ = _orm__Connection_"), 0xfe10, {.d_s = db_ctype_name}}, {_S("_index};"), 0, { .d_c = 0 }}}))); } } VV_LOC void v__gen__c__Gen_write_orm_table_struct(v__gen__c__Gen* g, v__ast__Type typ) { string table_name = v__gen__c__Gen_get_table_name_by_struct_type(g, typ); Array_v__ast__Attr table_attrs = v__gen__c__Gen_get_table_attrs_by_struct_type(g, typ); v__gen__c__Gen_writeln(g, _S("((orm__Table){")); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".name = _S(\""), 0xfe10, {.d_s = table_name}}, {_S("\"),"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".attrs = new_array_from_c_array("), 0xfe07, {.d_i32 = table_attrs.len}}, {_S(", "), 0xfe07, {.d_i32 = table_attrs.len}}, {_S(", sizeof(VAttribute),"), 0, { .d_c = 0 }}}))); g->indent++; if (table_attrs.len > 0) { { v__gen__c__Gen_write(g, _S("_MOV((VAttribute[")); v__gen__c__Gen_write_decimal(g, table_attrs.len); v__gen__c__Gen_write(g, _S("]){")); } g->indent++; for (int _t1 = 0; _t1 < table_attrs.len; ++_t1) { v__ast__Attr attr = ((v__ast__Attr*)table_attrs.data)[_t1]; v__gen__c__Gen_write(g, _S("(VAttribute){")); g->indent++; string name1 = v__util__smart_quote(attr.name, false); string name = v__gen__c__cescape_nonascii(name1); { v__gen__c__Gen_write(g, _S(" .name = _S(\"")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S("\"),")); } v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_S(" .has_arg = "), 0xfe10, {.d_s = attr.has_arg ? _S("true") : _S("false")}}, {_S(","), 0, { .d_c = 0 }}}))); string arg1 = v__util__smart_quote(attr.arg, false); string arg = v__gen__c__cescape_nonascii(arg1); { v__gen__c__Gen_write(g, _S(" .arg = _S(\"")); v__gen__c__Gen_write(g, arg); v__gen__c__Gen_write(g, _S("\"),")); } { v__gen__c__Gen_write(g, _S(" .kind = ")); v__gen__c__Gen_write_decimal(g, ((int)(attr.kind))); v__gen__c__Gen_write(g, _S(",")); } g->indent--; v__gen__c__Gen_write(g, _S("},")); } g->indent--; v__gen__c__Gen_writeln(g, _S("})")); } else { v__gen__c__Gen_writeln(g, _S("NULL // No attrs")); } g->indent--; v__gen__c__Gen_writeln(g, _S(")")); g->indent--; v__gen__c__Gen_write(g, _S("})")); } VV_LOC void v__gen__c__Gen_write_orm_create_table(v__gen__c__Gen* g, v__ast__SqlStmtLine node, string table_name, string connection_var_name, string result_var_name, Array_v__ast__Attr table_attrs) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("// sql { create table `"), 0xfe10, {.d_s = table_name}}, {_S("` }"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_void "), 0xfe10, {.d_s = result_var_name}}, {_S(" = orm__Connection_name_table["), 0xfe10, {.d_s = connection_var_name}}, {_S("._typ]._method_create("), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = connection_var_name}}, {_S("._object, // Connection object"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write_orm_table_struct(g, node.table_expr.typ); v__gen__c__Gen_writeln(g, _S(",")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("new_array_from_c_array("), 0xfe07, {.d_i32 = node.fields.len}}, {_S(", "), 0xfe07, {.d_i32 = node.fields.len}}, {_S(", sizeof(orm__TableField),"), 0, { .d_c = 0 }}}))); g->indent++; if (node.fields.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_MOV((orm__TableField["), 0xfe07, {.d_i32 = node.fields.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); g->indent++; for (int _t1 = 0; _t1 < node.fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)node.fields.data)[_t1]; v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("// `"), 0xfe10, {.d_s = table_name}}, {_S("`.`"), 0xfe10, {.d_s = field.name}}, {_S("`"), 0, { .d_c = 0 }}}))); v__ast__Type final_field_typ = v__ast__Table_final_type(g->table, field.typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, final_field_typ); bool _t2 = true; string typ = ((_t2 == (fast_string_eq(sym->name, _S("time.Time"))))? (_S("_const_orm__time_")) : (_t2 == (sym->kind == v__ast__Kind__enum))? (_S("_const_orm__enum_")) : (int_str(v__ast__Type_idx(final_field_typ)))); v__gen__c__Gen_writeln(g, _S("(orm__TableField){")); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".name = _S(\""), 0xfe10, {.d_s = field.name}}, {_S("\"),"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".typ = "), 0xfe10, {.d_s = typ}}, {_S(", // `"), 0xfe10, {.d_s = sym->name}}, {_S("`"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".is_arr = "), 0xfe10, {.d_s = sym->kind == v__ast__Kind__array ? _S("true") : _S("false")}}, {_S(", "), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".nullable = "), 0xfe10, {.d_s = v__ast__Type_has_flag(final_field_typ, v__ast__TypeFlag__option) ? _S("true") : _S("false")}}, {_S(","), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".default_val = (string){ .str = (byteptr) \""), 0xfe10, {.d_s = field.default_val}}, {_S("\", .is_lit = 1 },"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".attrs = new_array_from_c_array("), 0xfe07, {.d_i32 = field.attrs.len}}, {_S(", "), 0xfe07, {.d_i32 = field.attrs.len}}, {_S(", sizeof(VAttribute),"), 0, { .d_c = 0 }}}))); g->indent++; if (field.attrs.len > 0) { { v__gen__c__Gen_write(g, _S("_MOV((VAttribute[")); v__gen__c__Gen_write_decimal(g, field.attrs.len); v__gen__c__Gen_write(g, _S("]){")); } g->indent++; for (int _t3 = 0; _t3 < field.attrs.len; ++_t3) { v__ast__Attr attr = ((v__ast__Attr*)field.attrs.data)[_t3]; v__gen__c__Gen_write(g, _S("(VAttribute){")); g->indent++; string name1 = v__util__smart_quote(attr.name, false); string name = v__gen__c__cescape_nonascii(name1); { v__gen__c__Gen_write(g, _S(" .name = _S(\"")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S("\"),")); } v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_S(" .has_arg = "), 0xfe10, {.d_s = attr.has_arg ? _S("true") : _S("false")}}, {_S(","), 0, { .d_c = 0 }}}))); string arg1 = v__util__smart_quote(attr.arg, false); string arg = v__gen__c__cescape_nonascii(arg1); { v__gen__c__Gen_write(g, _S(" .arg = _S(\"")); v__gen__c__Gen_write(g, arg); v__gen__c__Gen_write(g, _S("\"),")); } { v__gen__c__Gen_write(g, _S(" .kind = ")); v__gen__c__Gen_write_decimal(g, ((int)(attr.kind))); v__gen__c__Gen_write(g, _S(",")); } g->indent--; v__gen__c__Gen_write(g, _S("},")); } g->indent--; v__gen__c__Gen_writeln(g, _S("})")); } else { v__gen__c__Gen_writeln(g, _S("NULL // No attrs")); } g->indent--; v__gen__c__Gen_writeln(g, _S(")")); g->indent--; v__gen__c__Gen_writeln(g, _S("},")); } g->indent--; v__gen__c__Gen_writeln(g, _S("})")); } else { v__gen__c__Gen_writeln(g, _S("NULL")); } g->indent--; v__gen__c__Gen_writeln(g, _S(")")); g->indent--; v__gen__c__Gen_writeln(g, _S(");")); } VV_LOC void v__gen__c__Gen_write_orm_drop_table(v__gen__c__Gen* g, v__ast__SqlStmtLine node, string table_name, string connection_var_name, string result_var_name, Array_v__ast__Attr table_attrs) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("// sql { drop table `"), 0xfe10, {.d_s = table_name}}, {_S("` }"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_void "), 0xfe10, {.d_s = result_var_name}}, {_S(" = orm__Connection_name_table["), 0xfe10, {.d_s = connection_var_name}}, {_S("._typ]._method_drop("), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = connection_var_name}}, {_S("._object, // Connection object"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write_orm_table_struct(g, node.table_expr.typ); g->indent--; v__gen__c__Gen_writeln(g, _S(");")); } VV_LOC void v__gen__c__Gen_write_orm_insert(v__gen__c__Gen* g, v__ast__SqlStmtLine* node, string table_name, string connection_var_name, string result_var_name, v__ast__OrExpr* or_expr, Array_v__ast__Attr table_attrs) { string last_ids_variable_name = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("Array_orm__Primitive "), 0xfe10, {.d_s = last_ids_variable_name}}, {_S(" = __new_array_with_default_noscan(0, 0, sizeof(orm__Primitive), 0);"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write_orm_insert_with_last_ids(g, *node, connection_var_name, table_name, last_ids_variable_name, result_var_name, _S(""), _S(""), *or_expr); } VV_LOC void v__gen__c__Gen_write_orm_update(v__gen__c__Gen* g, v__ast__SqlStmtLine* node, string table_name, string connection_var_name, string result_var_name, Array_v__ast__Attr table_attrs) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("// sql { update `"), 0xfe10, {.d_s = table_name}}, {_S("` }"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_void "), 0xfe10, {.d_s = result_var_name}}, {_S(" = orm__Connection_name_table["), 0xfe10, {.d_s = connection_var_name}}, {_S("._typ]._method_update("), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = connection_var_name}}, {_S("._object, // Connection object"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write_orm_table_struct(g, node->table_expr.typ); v__gen__c__Gen_writeln(g, _S(",")); v__gen__c__Gen_writeln(g, _S("(orm__QueryData){")); g->indent++; v__gen__c__Gen_writeln(g, _S(".kinds = __new_array_with_default_noscan(0, 0, sizeof(orm__OperationKind), 0),")); v__gen__c__Gen_writeln(g, _S(".is_and = __new_array_with_default_noscan(0, 0, sizeof(bool), 0),")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".types = __new_array_with_default_noscan(0, 0, sizeof("), 0xfe10, {.d_s = _const_v__ast__int_type_name}}, {_S("), 0),"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S(".parentheses = __new_array_with_default_noscan(0, 0, sizeof(Array_int), 0),")); if (node->updated_columns.len > 0) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".fields = new_array_from_c_array("), 0xfe07, {.d_i32 = node->updated_columns.len}}, {_S(", "), 0xfe07, {.d_i32 = node->updated_columns.len}}, {_S(", sizeof(string),"), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_MOV((string["), 0xfe07, {.d_i32 = node->updated_columns.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); g->indent++; for (int _t1 = 0; _t1 < node->updated_columns.len; ++_t1) { string field = ((string*)node->updated_columns.data)[_t1]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_S(\""), 0xfe10, {.d_s = field}}, {_S("\"),"), 0, { .d_c = 0 }}}))); } g->indent--; v__gen__c__Gen_writeln(g, _S("})")); g->indent--; } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".fields = __new_array_with_default_noscan("), 0xfe07, {.d_i32 = node->updated_columns.len}}, {_S(", "), 0xfe07, {.d_i32 = node->updated_columns.len}}, {_S(", sizeof(string), 0"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln2(g, _S("),"), str_intp(3, _MOV((StrIntpData[]){{_S(".data = new_array_from_c_array("), 0xfe07, {.d_i32 = node->update_exprs.len}}, {_S(", "), 0xfe07, {.d_i32 = node->update_exprs.len}}, {_S(", sizeof(orm__Primitive),"), 0, { .d_c = 0 }}}))); if (node->update_exprs.len > 0) { g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_MOV((orm__Primitive["), 0xfe07, {.d_i32 = node->update_exprs.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); g->indent++; for (int _t2 = 0; _t2 < node->update_exprs.len; ++_t2) { v__ast__Expr e = ((v__ast__Expr*)node->update_exprs.data)[_t2]; v__gen__c__Gen_write_orm_expr_to_primitive(g, e); } g->indent--; v__gen__c__Gen_writeln(g, _S("})")); g->indent--; } v__gen__c__Gen_writeln(g, _S("),")); g->indent--; v__gen__c__Gen_writeln(g, _S("},")); v__gen__c__Gen_write_orm_where(g, node->where_expr); g->indent--; v__gen__c__Gen_writeln(g, _S(");")); } VV_LOC void v__gen__c__Gen_write_orm_delete(v__gen__c__Gen* g, v__ast__SqlStmtLine* node, string table_name, string connection_var_name, string result_var_name, Array_v__ast__Attr table_attrs) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("// sql { delete from `"), 0xfe10, {.d_s = table_name}}, {_S("` }"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_void "), 0xfe10, {.d_s = result_var_name}}, {_S(" = orm__Connection_name_table["), 0xfe10, {.d_s = connection_var_name}}, {_S("._typ]._method__v_delete("), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = connection_var_name}}, {_S("._object, // Connection object"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write_orm_table_struct(g, node->table_expr.typ); v__gen__c__Gen_writeln(g, _S(",")); v__gen__c__Gen_write_orm_where(g, node->where_expr); g->indent--; v__gen__c__Gen_writeln(g, _S(");")); } VV_LOC void v__gen__c__Gen_write_orm_insert_with_last_ids(v__gen__c__Gen* g, v__ast__SqlStmtLine node, string connection_var_name, string table_name, string last_ids_arr, string res, string pid, string fkey, v__ast__OrExpr or_expr) { Array_v__ast__SqlStmtLine subs = __new_array_with_default(0, 0, sizeof(v__ast__SqlStmtLine), 0); Array_string subs_unwrapped_c_typ = __new_array_with_default(0, 0, sizeof(string), 0); Array_v__ast__SqlStmtLine arrs = __new_array_with_default(0, 0, sizeof(v__ast__SqlStmtLine), 0); Array_string fkeys = __new_array_with_default(0, 0, sizeof(string), 0); Array_string field_names = __new_array_with_default(0, 0, sizeof(string), 0); Array_int opt_fields = __new_array_with_default(0, 0, sizeof(int), 0); for (int _t1 = 0; _t1 < node.fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)node.fields.data)[_t1]; v__ast__Type final_field_typ = v__ast__Table_final_type(g->table, field.typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, final_field_typ); if (sym->kind == v__ast__Kind__struct && !fast_string_eq(sym->name, _S("time.Time"))) { array_push((array*)&subs, _MOV((v__ast__SqlStmtLine[]){ (*(v__ast__SqlStmtLine*)map_get((map*)&node.sub_structs, &(int[]){((int)(final_field_typ))}, &(v__ast__SqlStmtLine[]){ (v__ast__SqlStmtLine){.kind = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = (v__ast__TypeNode){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),},.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),} })) })); string unwrapped_c_typ = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(final_field_typ, v__ast__TypeFlag__option)); array_push((array*)&subs_unwrapped_c_typ, _MOV((string[]){ string_clone((v__ast__Type_has_flag(final_field_typ, v__ast__TypeFlag__option) ? (unwrapped_c_typ) : (_S("")))) })); } else if (sym->kind == v__ast__Kind__array) { _option_v__ast__Attr _t4; if (_t4 = Array_v__ast__Attr_find_first(field.attrs, _S("fkey")), _t4.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t4.data; array_push((array*)&fkeys, _MOV((string[]){ string_clone(attr.arg) })); } else { IError err = _t4.err; v__gen__c__verror(_S("missing fkey attribute")); VUNREACHABLE(); } if (v__ast__Type_has_flag(final_field_typ, v__ast__TypeFlag__option)) { array_push((array*)&opt_fields, _MOV((int[]){ arrs.len })); } if (node.sub_structs.len > 0) { array_push((array*)&arrs, _MOV((v__ast__SqlStmtLine[]){ (*(v__ast__SqlStmtLine*)map_get((map*)&node.sub_structs, &(int[]){((int)(final_field_typ))}, &(v__ast__SqlStmtLine[]){ (v__ast__SqlStmtLine){.kind = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.is_generated = 0,.scope = ((void*)0),.object_var = (string){.str=(byteptr)"", .is_lit=1},.updated_columns = __new_array(0, 0, sizeof(string)),.table_expr = (v__ast__TypeNode){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),},.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlStmtLine), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_exprs = __new_array(0, 0, sizeof(v__ast__Expr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),} })) })); } array_push((array*)&field_names, _MOV((string[]){ string_clone(field.name) })); } } Array_v__ast__StructField _t9 = {0}; Array_v__ast__StructField _t9_orig = node.fields; int _t9_len = _t9_orig.len; _t9 = __new_array(0, _t9_len, sizeof(v__ast__StructField)); for (int _t10 = 0; _t10 < _t9_len; ++_t10) { v__ast__StructField it = ((v__ast__StructField*) _t9_orig.data)[_t10]; if (v__ast__Table_sym(g->table, it.typ)->kind != v__ast__Kind__array) { array_push((array*)&_t9, &it); } } Array_v__ast__StructField fields =_t9; Array_int auto_fields = v__gen__c__get_auto_field_idxs(fields); _option_v__ast__StructField _t11 = v__gen__c__Gen_get_orm_struct_primary_field(g, fields); if (_t11.state != 0) { IError err = _t11.err; *(v__ast__StructField*) _t11.data = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}); } v__ast__StructField primary_field = (*(v__ast__StructField*)_t11.data); bool _t12 = (Array_v__ast__Attr_contains_arg(primary_field.attrs, _S("sql"), _S("serial"))); bool is_serial = ( _t12 || Array_v__ast__Attr_contains(primary_field.attrs, _S("serial"))) && primary_field.typ == _const_v__ast__int_type; v__ast__Type inserting_object_type = _const_v__ast__void_type; string member_access_type = _S("."); if (node.scope != ((void*)0)) { _option_v__ast__ScopeObject _t13 = v__ast__Scope_find(node.scope, node.object_var); if (_t13.state != 0) { IError err = _t13.err; v__gen__c__verror(str_intp(2, _MOV((StrIntpData[]){{_S("`"), 0xfe10, {.d_s = node.object_var}}, {_S("` is not found in scope"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } v__ast__ScopeObject inserting_object = (*(v__ast__ScopeObject*)_t13.data); if (v__ast__Type_is_ptr((*(inserting_object.typ)))) { member_access_type = _S("->"); } inserting_object_type = (*(inserting_object.typ)); } v__ast__TypeSymbol* inserting_object_sym = v__ast__Table_sym(g->table, inserting_object_type); for (int i = 0; i < subs.len; ++i) { v__ast__SqlStmtLine* sub = ((v__ast__SqlStmtLine*)subs.data) + i; if ((*(string*)array_get(subs_unwrapped_c_typ, i)).len > 0) { string var = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.object_var}}, {_SLIT0, 0xfe10, {.d_s = member_access_type}}, {_SLIT0, 0xfe10, {.d_s = sub->object_var}}, {_SLIT0, 0, { .d_c = 0 }}})); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if("), 0xfe10, {.d_s = var}}, {_S(".state == 0) {"), 0, { .d_c = 0 }}}))); g->indent++; sub->object_var = str_intp(5, _MOV((StrIntpData[]){{_S("(*("), 0xfe10, {.d_s = (*(string*)array_get(subs_unwrapped_c_typ, i))}}, {_S("*)"), 0xfe10, {.d_s = node.object_var}}, {_SLIT0, 0xfe10, {.d_s = member_access_type}}, {_SLIT0, 0xfe10, {.d_s = sub->object_var}}, {_S(".data)"), 0, { .d_c = 0 }}})); } else { sub->object_var = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.object_var}}, {_SLIT0, 0xfe10, {.d_s = member_access_type}}, {_SLIT0, 0xfe10, {.d_s = sub->object_var}}, {_SLIT0, 0, { .d_c = 0 }}})); } v__gen__c__Gen_sql_stmt_line(g, *sub, connection_var_name, or_expr); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("array_push(&"), 0xfe10, {.d_s = last_ids_arr}}, {_S(", _MOV((orm__Primitive[1]){"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\torm__int_to_primitive(orm__Connection_name_table["), 0xfe10, {.d_s = connection_var_name}}, {_S("._typ]._method_last_id("), 0xfe10, {.d_s = connection_var_name}}, {_S("._object))}));"), 0, { .d_c = 0 }}}))); if ((*(string*)array_get(subs_unwrapped_c_typ, i)).len > 0) { g->indent--; v__gen__c__Gen_writeln(g, _S("} else {")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tarray_push(&"), 0xfe10, {.d_s = last_ids_arr}}, {_S(", _MOV((orm__Primitive[1]){ _const_orm__null_primitive }));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("}")); } } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("// sql { insert into `"), 0xfe10, {.d_s = table_name}}, {_S("` }"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_void "), 0xfe10, {.d_s = res}}, {_S(" = orm__Connection_name_table["), 0xfe10, {.d_s = connection_var_name}}, {_S("._typ]._method_insert("), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = connection_var_name}}, {_S("._object, // Connection object"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write_orm_table_struct(g, node.table_expr.typ); v__gen__c__Gen_writeln(g, _S(",")); v__gen__c__Gen_writeln(g, _S("(orm__QueryData){")); g->indent++; v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".fields = new_array_from_c_array("), 0xfe07, {.d_i32 = fields.len}}, {_S(", "), 0xfe07, {.d_i32 = fields.len}}, {_S(", sizeof(string),"), 0, { .d_c = 0 }}}))); g->indent++; if (fields.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_MOV((string["), 0xfe07, {.d_i32 = fields.len}}, {_S("]){ "), 0, { .d_c = 0 }}}))); g->indent++; for (int _t14 = 0; _t14 < fields.len; ++_t14) { v__ast__StructField f = ((v__ast__StructField*)fields.data)[_t14]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_S(\""), 0xfe10, {.d_s = v__gen__c__Gen_get_orm_column_name_from_struct_field(g, f)}}, {_S("\"),"), 0, { .d_c = 0 }}}))); } g->indent--; v__gen__c__Gen_writeln(g, _S("})")); } else { v__gen__c__Gen_writeln(g, _S("NULL")); } g->indent--; v__gen__c__Gen_writeln(g, _S("),")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".data = new_array_from_c_array("), 0xfe07, {.d_i32 = fields.len}}, {_S(", "), 0xfe07, {.d_i32 = fields.len}}, {_S(", sizeof(orm__Primitive),"), 0, { .d_c = 0 }}}))); g->indent++; if (fields.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_MOV((orm__Primitive["), 0xfe07, {.d_i32 = fields.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); g->indent++; int structs = 0; for (int _t15 = 0; _t15 < fields.len; ++_t15) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t15]; if (string__eq(field.name, fkey)) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = pid}}, {_S(", "), 0, { .d_c = 0 }}}))); continue; } v__ast__Type final_field_typ = v__ast__Table_final_type(g->table, field.typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, final_field_typ); string typ = sym->cname; string ctyp = sym->cname; if (sym->kind == v__ast__Kind__struct && _SLIT_NE(typ.str, typ.len, "time__Time")) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("(*(orm__Primitive*) array_get("), 0xfe10, {.d_s = last_ids_arr}}, {_S(", "), 0xfe07, {.d_i32 = structs}}, {_S(")),"), 0, { .d_c = 0 }}}))); structs++; continue; } if (_SLIT_EQ(typ.str, typ.len, "time__Time")) { ctyp = _S("time__Time"); typ = _S("time"); } else if (sym->kind == v__ast__Kind__enum) { typ = v__ast__Table_sym(g->table, final_field_typ)->cname; } string var = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = node.object_var}}, {_SLIT0, 0xfe10, {.d_s = member_access_type}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_SLIT0, 0, { .d_c = 0 }}})); if (v__ast__Type_has_flag(final_field_typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = var}}, {_S(".state == 2? _const_orm__null_primitive : orm__"), 0xfe10, {.d_s = typ}}, {_S("_to_primitive(*("), 0xfe10, {.d_s = ctyp}}, {_S("*)("), 0xfe10, {.d_s = var}}, {_S(".data)),"), 0, { .d_c = 0 }}}))); } else if (inserting_object_sym->kind == v__ast__Kind__sum_type) { v__ast__TypeSymbol* table_sym = v__ast__Table_sym(g->table, node.table_expr.typ); string sum_type_var = str_intp(5, _MOV((StrIntpData[]){{_S("(*"), 0xfe10, {.d_s = node.object_var}}, {_S("._"), 0xfe10, {.d_s = table_sym->cname}}, {_S(")"), 0xfe10, {.d_s = member_access_type}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_SLIT0, 0, { .d_c = 0 }}})); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("orm__"), 0xfe10, {.d_s = typ}}, {_S("_to_primitive("), 0xfe10, {.d_s = sum_type_var}}, {_S("),"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("orm__"), 0xfe10, {.d_s = typ}}, {_S("_to_primitive("), 0xfe10, {.d_s = var}}, {_S("),"), 0, { .d_c = 0 }}}))); } } g->indent--; v__gen__c__Gen_writeln(g, _S("})")); } else { v__gen__c__Gen_write(g, _S("NULL")); } g->indent--; v__gen__c__Gen_writeln(g, _S("),")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".types = __new_array_with_default_noscan(0, 0, sizeof("), 0xfe10, {.d_s = _const_v__ast__int_type_name}}, {_S("), 0),"), 0, { .d_c = 0 }}}))); if (auto_fields.len > 0) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S(".auto_fields = new_array_from_c_array("), 0xfe07, {.d_i32 = auto_fields.len}}, {_S(", "), 0xfe07, {.d_i32 = auto_fields.len}}, {_S(", sizeof("), 0xfe10, {.d_s = _const_v__ast__int_type_name}}, {_S("),"), 0, { .d_c = 0 }}}))); g->indent++; { v__gen__c__Gen_write(g, _S("_MOV((int[")); v__gen__c__Gen_write_decimal(g, auto_fields.len); v__gen__c__Gen_write(g, _S("]){")); } for (int _t16 = 0; _t16 < auto_fields.len; ++_t16) { int i = ((int*)auto_fields.data)[_t16]; { v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write_decimal(g, i); v__gen__c__Gen_write(g, _S(",")); } } v__gen__c__Gen_writeln(g, _S(" })),")); g->indent--; } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".auto_fields = __new_array_with_default_noscan(0, 0, sizeof("), 0xfe10, {.d_s = _const_v__ast__int_type_name}}, {_S("), 0),"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, _S(".kinds = __new_array_with_default_noscan(0, 0, sizeof(orm__OperationKind), 0),")); v__gen__c__Gen_writeln(g, _S(".is_and = __new_array_with_default_noscan(0, 0, sizeof(bool), 0),")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); g->indent--; v__gen__c__Gen_writeln(g, _S(");")); v__gen__c__Gen_or_block(g, res, or_expr, v__ast__Type_set_flag(_const_v__ast__int_type, v__ast__TypeFlag__result)); if (arrs.len > 0) { string id_name = v__gen__c__Gen_new_tmp_var(g); if (is_serial) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("orm__Primitive "), 0xfe10, {.d_s = id_name}}, {_S(" = orm__int_to_primitive(orm__Connection_name_table["), 0xfe10, {.d_s = connection_var_name}}, {_S("._typ]._method_last_id("), 0xfe10, {.d_s = connection_var_name}}, {_S("._object));"), 0, { .d_c = 0 }}}))); } else { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, primary_field.typ); string typ = sym->cname; if (_SLIT_EQ(typ.str, typ.len, "time__Time")) { typ = _S("time"); } v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("orm__Primitive "), 0xfe10, {.d_s = id_name}}, {_S(" = orm__"), 0xfe10, {.d_s = typ}}, {_S("_to_primitive("), 0xfe10, {.d_s = node.object_var}}, {_SLIT0, 0xfe10, {.d_s = member_access_type}}, {_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(primary_field.name)}}, {_S(");"), 0, { .d_c = 0 }}}))); } for (int i = 0; i < arrs.len; ++i) { v__ast__SqlStmtLine* arr = ((v__ast__SqlStmtLine*)arrs.data) + i; string idx = v__gen__c__Gen_new_tmp_var(g); string ctyp = v__gen__c__Gen_styp(g, arr->table_expr.typ); bool is_option = Array_int_contains(opt_fields, i); if (is_option) { v__gen__c__Gen_writeln(g, str_intp(11, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = idx}}, {_S(" = 0; "), 0xfe10, {.d_s = node.object_var}}, {_SLIT0, 0xfe10, {.d_s = member_access_type}}, {_SLIT0, 0xfe10, {.d_s = arr->object_var}}, {_S(".state != 2 && "), 0xfe10, {.d_s = idx}}, {_S(" < (*(Array_"), 0xfe10, {.d_s = ctyp}}, {_S("*)"), 0xfe10, {.d_s = node.object_var}}, {_SLIT0, 0xfe10, {.d_s = member_access_type}}, {_SLIT0, 0xfe10, {.d_s = arr->object_var}}, {_S(".data).len; "), 0xfe10, {.d_s = idx}}, {_S("++) {"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(7, _MOV((StrIntpData[]){{_S("for (int "), 0xfe10, {.d_s = idx}}, {_S(" = 0; "), 0xfe10, {.d_s = idx}}, {_S(" < "), 0xfe10, {.d_s = node.object_var}}, {_SLIT0, 0xfe10, {.d_s = member_access_type}}, {_SLIT0, 0xfe10, {.d_s = arr->object_var}}, {_S(".len; "), 0xfe10, {.d_s = idx}}, {_S("++) {"), 0, { .d_c = 0 }}}))); } g->indent++; string last_ids = v__gen__c__Gen_new_tmp_var(g); string res_ = v__gen__c__Gen_new_tmp_var(g); string tmp_var = v__gen__c__Gen_new_tmp_var(g); if (is_option) { v__gen__c__Gen_writeln(g, str_intp(9, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ctyp}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(" = (*("), 0xfe10, {.d_s = ctyp}}, {_S("*)array_get(*(Array_"), 0xfe10, {.d_s = ctyp}}, {_S("*)"), 0xfe10, {.d_s = node.object_var}}, {_SLIT0, 0xfe10, {.d_s = member_access_type}}, {_SLIT0, 0xfe10, {.d_s = arr->object_var}}, {_S(".data, "), 0xfe10, {.d_s = idx}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(8, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ctyp}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(" = (*("), 0xfe10, {.d_s = ctyp}}, {_S("*)array_get("), 0xfe10, {.d_s = node.object_var}}, {_SLIT0, 0xfe10, {.d_s = member_access_type}}, {_SLIT0, 0xfe10, {.d_s = arr->object_var}}, {_S(", "), 0xfe10, {.d_s = idx}}, {_S("));"), 0, { .d_c = 0 }}}))); } arr->object_var = tmp_var; Array_v__ast__StructField fff = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); for (int _t17 = 0; _t17 < arr->fields.len; ++_t17) { v__ast__StructField f = ((v__ast__StructField*)arr->fields.data)[_t17]; bool skip = false; for (int _t18 = 0; _t18 < f.attrs.len; ++_t18) { v__ast__Attr attr = ((v__ast__Attr*)f.attrs.data)[_t18]; if (fast_string_eq(attr.name, _S("skip"))) { skip = true; } if (fast_string_eq(attr.name, _S("sql")) && fast_string_eq(attr.arg, _S("-"))) { skip = true; } } if (!skip) { array_push((array*)&fff, _MOV((v__ast__StructField[]){ f })); } } arr->fields = array_clone_to_depth(&fff, 0); array_free(&fff); v__gen__c__Gen_write_orm_insert_with_last_ids(g, *arr, connection_var_name, v__gen__c__Gen_get_table_name_by_struct_type(g, arr->table_expr.typ), last_ids, res_, id_name, (*(string*)array_get(fkeys, i)), or_expr); v__gen__c__Gen_or_block(g, res_, or_expr, v__ast__Type_set_flag(_const_v__ast__int_type, v__ast__TypeFlag__result)); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); } } } VV_LOC void v__gen__c__Gen_write_orm_expr_to_primitive(v__gen__c__Gen* g, v__ast__Expr expr) { if (expr._typ == 362 /* v.ast.InfixExpr */) { v__gen__c__Gen_write_orm_primitive(g, v__ast__Table_find_type(g->table, _S("orm.InfixType")), expr); } else if (expr._typ == 384 /* v.ast.StringLiteral */) { v__gen__c__Gen_write_orm_primitive(g, _const_v__ast__string_type, expr); } else if (expr._typ == 383 /* v.ast.StringInterLiteral */) { v__gen__c__Gen_write_orm_primitive(g, _const_v__ast__string_type, expr); } else if (expr._typ == 363 /* v.ast.IntegerLiteral */) { v__gen__c__Gen_write_orm_primitive(g, _const_v__ast__int_type, expr); } else if (expr._typ == 342 /* v.ast.BoolLiteral */) { v__gen__c__Gen_write_orm_primitive(g, _const_v__ast__bool_type, expr); } else if (expr._typ == 355 /* v.ast.EnumVal */) { v__gen__c__Gen_write_orm_primitive(g, _const_v__ast__i64_type, expr); } else if (expr._typ == 358 /* v.ast.Ident */) { v__ast__IdentVar info = *(v__ast__IdentVar*)__as_cast(((*expr._v__ast__Ident).info)._v__ast__IdentVar,((*expr._v__ast__Ident).info)._typ, 477); v__gen__c__Gen_write_orm_primitive(g, info.typ, expr); } else if (expr._typ == 379 /* v.ast.SelectorExpr */) { v__gen__c__Gen_write_orm_primitive(g, (*expr._v__ast__SelectorExpr).typ, expr); } else if (expr._typ == 344 /* v.ast.CallExpr */) { v__gen__c__Gen_write_orm_primitive(g, (*expr._v__ast__CallExpr).return_type, expr); } else if (expr._typ == 371 /* v.ast.None */) { v__gen__c__Gen_write_orm_primitive(g, _const_v__ast__none_type, expr); } else { eprintln(v__ast__Expr_str(&expr)); v__gen__c__verror(str_intp(2, _MOV((StrIntpData[]){{_S("ORM: "), 0xfe10, {.d_s = charptr_vstring_literal(v_typeof_sumtype_v__ast__Expr( (expr)._typ ))}}, {_S(" is not supported"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } } VV_LOC void v__gen__c__Gen_write_orm_primitive(v__gen__c__Gen* g, v__ast__Type t, v__ast__Expr expr) { if (t == 0) { v__gen__c__verror(str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->file->path}}, {_S(":"), 0xfe07, {.d_i32 = (int)(v__ast__Expr_pos(expr).line_nr + 1)}}, {_S(": ORM: unknown type t == 0\nexpr: "), 0xfe10, {.d_s = v__ast__Expr_str(&expr)}}, {_S("\nlast SQL stmt:\n"), 0xfe10, {.d_s = strings__Builder_after(&g->out, g->sql_last_stmt_out_len)}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } v__ast__Type final_field_typ = v__ast__Table_final_type(g->table, t); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, final_field_typ); string typ = sym->cname; if (_SLIT_EQ(typ.str, typ.len, "orm__Primitive")) { v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_writeln(g, _S(",")); return; } if (_SLIT_EQ(typ.str, typ.len, "none")) { v__gen__c__Gen_writeln(g, _S("_const_orm__null_primitive,")); return; } if ((expr)._typ == 362 /* v.ast.InfixExpr */) { v__gen__c__Gen_writeln(g, _S("orm__infix_to_primitive((orm__InfixType){")); g->indent++; v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_S(".name = _S(\""), 0xfe10, {.d_s = v__ast__Expr_str(&(*expr._v__ast__InfixExpr).left)}}, {_S("\"),"), 0, { .d_c = 0 }}}))); string kind = (((*expr._v__ast__InfixExpr).op == (v__token__Kind__plus))? (_S("orm__MathOperationKind__add")) : ((*expr._v__ast__InfixExpr).op == (v__token__Kind__minus))? (_S("orm__MathOperationKind__sub")) : ((*expr._v__ast__InfixExpr).op == (v__token__Kind__div))? (_S("orm__MathOperationKind__div")) : ((*expr._v__ast__InfixExpr).op == (v__token__Kind__mul))? (_S("orm__MathOperationKind__mul")) : (_S(""))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(" .operator = "), 0xfe10, {.d_s = kind}}, {_S(","), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write(g, _S(" .right = ")); v__gen__c__Gen_write_orm_expr_to_primitive(g, (*expr._v__ast__InfixExpr).right); g->indent--; v__gen__c__Gen_writeln(g, _S(" }),")); } else { if (_SLIT_EQ(typ.str, typ.len, "time__Time")) { typ = _S("time"); } if (v__ast__Type_has_flag(t, v__ast__TypeFlag__option)) { typ = str_intp(2, _MOV((StrIntpData[]){{_S("option_"), 0xfe10, {.d_s = typ}}, {_SLIT0, 0, { .d_c = 0 }}})); } else if (v__ast__Table_final_sym(g->table, t)->kind == v__ast__Kind__enum) { typ = v__ast__Table_sym(g->table, v__ast__Table_final_type(g->table, t))->cname; } else if (v__ast__Table_final_sym(g->table, t)->kind == v__ast__Kind__array) { typ = string_to_lower(v__ast__Table_sym(g->table, v__ast__Table_final_type(g->table, t))->cname); } { v__gen__c__Gen_write(g, _S("orm__")); v__gen__c__Gen_write(g, typ); v__gen__c__Gen_write(g, _S("_to_primitive(")); } if ((expr)._typ == 344 /* v.ast.CallExpr */) { v__gen__c__Gen_call_expr(g, (*expr._v__ast__CallExpr)); } else { g->left_is_opt = true; v__gen__c__Gen_expr(g, expr); } v__gen__c__Gen_writeln(g, _S("),")); } } VV_LOC void v__gen__c__Gen_write_orm_where(v__gen__c__Gen* g, v__ast__Expr where_expr) { Array_string fields = __new_array_with_default(0, 0, sizeof(string), 0); Array_string kinds = __new_array_with_default(0, 0, sizeof(string), 0); Array_Array_int parentheses = __new_array_with_default(0, 0, sizeof(Array_int), 0); Array_v__ast__Expr data = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); Array_bool is_ands = __new_array_with_default(0, 0, sizeof(bool), 0); v__gen__c__Gen_writeln(g, _S("// ORM where")); v__gen__c__Gen_writeln(g, _S("(orm__QueryData){")); g->indent++; v__gen__c__Gen_write_orm_where_expr(g, where_expr, &fields, &parentheses, &kinds, &data, &is_ands); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".types = __new_array_with_default_noscan(0, 0, sizeof("), 0xfe10, {.d_s = _const_v__ast__int_type_name}}, {_S("), 0),"), 0, { .d_c = 0 }}}))); if (fields.len > 0) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".fields = new_array_from_c_array("), 0xfe07, {.d_i32 = fields.len}}, {_S(", "), 0xfe07, {.d_i32 = fields.len}}, {_S(", sizeof(string),"), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_MOV((string["), 0xfe07, {.d_i32 = fields.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); g->indent++; for (int _t1 = 0; _t1 < fields.len; ++_t1) { string field = ((string*)fields.data)[_t1]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_S(\""), 0xfe10, {.d_s = field}}, {_S("\"),"), 0, { .d_c = 0 }}}))); } g->indent--; v__gen__c__Gen_writeln(g, _S("})")); g->indent--; } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".fields = __new_array_with_default_noscan("), 0xfe07, {.d_i32 = fields.len}}, {_S(", "), 0xfe07, {.d_i32 = fields.len}}, {_S(", sizeof(string), 0"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, _S("),")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".data = new_array_from_c_array("), 0xfe07, {.d_i32 = data.len}}, {_S(", "), 0xfe07, {.d_i32 = data.len}}, {_S(", sizeof(orm__Primitive),"), 0, { .d_c = 0 }}}))); g->indent++; if (data.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_MOV((orm__Primitive["), 0xfe07, {.d_i32 = data.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); g->indent++; for (int _t2 = 0; _t2 < data.len; ++_t2) { v__ast__Expr e = ((v__ast__Expr*)data.data)[_t2]; v__gen__c__Gen_write_orm_expr_to_primitive(g, e); } g->indent--; v__gen__c__Gen_writeln(g, _S("})")); } else { v__gen__c__Gen_writeln(g, _S("0")); } g->indent--; v__gen__c__Gen_writeln(g, _S("),")); v__gen__c__Gen_write(g, _S(".parentheses = ")); if (parentheses.len > 0) { { v__gen__c__Gen_write(g, _S("new_array_from_c_array(")); v__gen__c__Gen_write_decimal(g, parentheses.len); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, parentheses.len); v__gen__c__Gen_write(g, _S(", sizeof(Array_int), _MOV((Array_int[")); v__gen__c__Gen_write_decimal(g, parentheses.len); v__gen__c__Gen_write(g, _S("]){")); } for (int _t3 = 0; _t3 < parentheses.len; ++_t3) { Array_int par = ((Array_int*)parentheses.data)[_t3]; if (par.len > 0) { { v__gen__c__Gen_write(g, _S("new_array_from_c_array(")); v__gen__c__Gen_write_decimal(g, par.len); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, par.len); v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, _const_v__ast__int_type_name); v__gen__c__Gen_write(g, _S("), _MOV((int[")); v__gen__c__Gen_write_decimal(g, par.len); v__gen__c__Gen_write(g, _S("]){")); } for (int _t4 = 0; _t4 < par.len; ++_t4) { int val = ((int*)par.data)[_t4]; { v__gen__c__Gen_write_decimal(g, val); v__gen__c__Gen_write(g, _S(",")); } } v__gen__c__Gen_write(g, _S("})),")); } else { { v__gen__c__Gen_write(g, _S("__new_array_with_default_noscan(0, 0, sizeof(")); v__gen__c__Gen_write(g, _const_v__ast__int_type_name); v__gen__c__Gen_write(g, _S("), 0),")); } } } v__gen__c__Gen_write(g, _S("}))")); } else { v__gen__c__Gen_write(g, _S("__new_array_with_default_noscan(0, 0, sizeof(Array_int), 0)")); } v__gen__c__Gen_writeln(g, _S(",")); if (kinds.len > 0) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".kinds = new_array_from_c_array("), 0xfe07, {.d_i32 = kinds.len}}, {_S(", "), 0xfe07, {.d_i32 = kinds.len}}, {_S(", sizeof(orm__OperationKind),"), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_MOV((orm__OperationKind["), 0xfe07, {.d_i32 = kinds.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); g->indent++; for (int _t5 = 0; _t5 < kinds.len; ++_t5) { string k = ((string*)kinds.data)[_t5]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = k}}, {_S(","), 0, { .d_c = 0 }}}))); } g->indent--; v__gen__c__Gen_writeln(g, _S("})")); g->indent--; } else { { v__gen__c__Gen_write(g, _S(".kinds = __new_array_with_default_noscan(")); v__gen__c__Gen_write_decimal(g, kinds.len); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, kinds.len); v__gen__c__Gen_write(g, _S(", sizeof(orm__OperationKind), 0")); } } v__gen__c__Gen_writeln(g, _S("),")); if (is_ands.len > 0) { { v__gen__c__Gen_write(g, _S(".is_and = new_array_from_c_array(")); v__gen__c__Gen_write_decimal(g, is_ands.len); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, is_ands.len); v__gen__c__Gen_write(g, _S(", sizeof(bool),")); } g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_MOV((bool["), 0xfe07, {.d_i32 = is_ands.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); g->indent++; for (int _t6 = 0; _t6 < is_ands.len; ++_t6) { bool is_and = ((bool*)is_ands.data)[_t6]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = is_and ? _S("true") : _S("false")}}, {_S(","), 0, { .d_c = 0 }}}))); } g->indent--; v__gen__c__Gen_write(g, _S("})")); g->indent--; } else { { v__gen__c__Gen_write(g, _S(".is_and = __new_array_with_default_noscan(")); v__gen__c__Gen_write_decimal(g, is_ands.len); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, is_ands.len); v__gen__c__Gen_write(g, _S(", sizeof(bool), 0")); } } g->indent--; v__gen__c__Gen_writeln2(g, _S("),"), _S("}")); } VV_LOC void v__gen__c__Gen_write_orm_where_expr(v__gen__c__Gen* g, v__ast__Expr expr, Array_string* fields, Array_Array_int* parentheses, Array_string* kinds, Array_v__ast__Expr* data, Array_bool* is_and) { if (expr._typ == 362 /* v.ast.InfixExpr */) { g->sql_side = v__gen__c__SqlExprSide__left; v__gen__c__Gen_write_orm_where_expr(g, (*expr._v__ast__InfixExpr).left, fields, parentheses, kinds, data, is_and); string _t1 = (string){.str=(byteptr)"", .is_lit=1}; switch ((*expr._v__ast__InfixExpr).op) { case v__token__Kind__ne: { _t1 = _S("orm__OperationKind__neq"); break; } case v__token__Kind__eq: { _t1 = _S("orm__OperationKind__eq"); break; } case v__token__Kind__lt: { _t1 = _S("orm__OperationKind__lt"); break; } case v__token__Kind__gt: { _t1 = _S("orm__OperationKind__gt"); break; } case v__token__Kind__ge: { _t1 = _S("orm__OperationKind__ge"); break; } case v__token__Kind__le: { _t1 = _S("orm__OperationKind__le"); break; } case v__token__Kind__key_like: { _t1 = _S("orm__OperationKind__orm_like"); break; } case v__token__Kind__key_ilike: { _t1 = _S("orm__OperationKind__orm_ilike"); break; } case v__token__Kind__key_is: { _t1 = _S("orm__OperationKind__is_null"); break; } case v__token__Kind__not_is: { _t1 = _S("orm__OperationKind__is_not_null"); break; } case v__token__Kind__key_in: { _t1 = _S("orm__OperationKind__in"); break; } case v__token__Kind__not_in: { _t1 = _S("orm__OperationKind__not_in"); break; } case v__token__Kind__unknown: case v__token__Kind__eof: case v__token__Kind__name: case v__token__Kind__number: case v__token__Kind__string: case v__token__Kind__str_inter: case v__token__Kind__chartoken: case v__token__Kind__plus: case v__token__Kind__minus: case v__token__Kind__mul: case v__token__Kind__div: case v__token__Kind__mod: case v__token__Kind__xor: case v__token__Kind__pipe: case v__token__Kind__inc: case v__token__Kind__dec: case v__token__Kind__and: case v__token__Kind__logical_or: case v__token__Kind__not: case v__token__Kind__bit_not: case v__token__Kind__question: case v__token__Kind__comma: case v__token__Kind__semicolon: case v__token__Kind__colon: case v__token__Kind__arrow: case v__token__Kind__amp: case v__token__Kind__hash: case v__token__Kind__dollar: case v__token__Kind__at: case v__token__Kind__str_dollar: case v__token__Kind__left_shift: case v__token__Kind__right_shift: case v__token__Kind__unsigned_right_shift: case v__token__Kind__assign: case v__token__Kind__decl_assign: case v__token__Kind__plus_assign: case v__token__Kind__minus_assign: case v__token__Kind__div_assign: case v__token__Kind__mult_assign: case v__token__Kind__xor_assign: case v__token__Kind__mod_assign: case v__token__Kind__or_assign: case v__token__Kind__and_assign: case v__token__Kind__right_shift_assign: case v__token__Kind__left_shift_assign: case v__token__Kind__unsigned_right_shift_assign: case v__token__Kind__boolean_and_assign: case v__token__Kind__boolean_or_assign: case v__token__Kind__lcbr: case v__token__Kind__rcbr: case v__token__Kind__lpar: case v__token__Kind__rpar: case v__token__Kind__lsbr: case v__token__Kind__nilsbr: case v__token__Kind__rsbr: case v__token__Kind__comment: case v__token__Kind__nl: case v__token__Kind__dot: case v__token__Kind__dotdot: case v__token__Kind__ellipsis: case v__token__Kind__keyword_beg: case v__token__Kind__key_as: case v__token__Kind__key_asm: case v__token__Kind__key_assert: case v__token__Kind__key_atomic: case v__token__Kind__key_break: case v__token__Kind__key_const: case v__token__Kind__key_continue: case v__token__Kind__key_defer: case v__token__Kind__key_else: case v__token__Kind__key_enum: case v__token__Kind__key_false: case v__token__Kind__key_for: case v__token__Kind__key_fn: case v__token__Kind__key_global: case v__token__Kind__key_go: case v__token__Kind__key_goto: case v__token__Kind__key_if: case v__token__Kind__key_import: case v__token__Kind__key_interface: case v__token__Kind__key_match: case v__token__Kind__key_module: case v__token__Kind__key_mut: case v__token__Kind__key_nil: case v__token__Kind__key_shared: case v__token__Kind__key_lock: case v__token__Kind__key_rlock: case v__token__Kind__key_none: case v__token__Kind__key_return: case v__token__Kind__key_select: case v__token__Kind__key_sizeof: case v__token__Kind__key_isreftype: case v__token__Kind__key_likely: case v__token__Kind__key_unlikely: case v__token__Kind__key_offsetof: case v__token__Kind__key_struct: case v__token__Kind__key_true: case v__token__Kind__key_type: case v__token__Kind__key_typeof: case v__token__Kind__key_dump: case v__token__Kind__key_orelse: case v__token__Kind__key_union: case v__token__Kind__key_pub: case v__token__Kind__key_static: case v__token__Kind__key_volatile: case v__token__Kind__key_unsafe: case v__token__Kind__key_spawn: case v__token__Kind__key_implements: case v__token__Kind__keyword_end: case v__token__Kind___end_: default: { { _t1 = _S(""); break; } } } string kind = _t1; if ((kind).len == 0) { if ((*expr._v__ast__InfixExpr).op == v__token__Kind__logical_or) { array_push((array*)is_and, _MOV((bool[]){ false })); } else if ((*expr._v__ast__InfixExpr).op == v__token__Kind__and) { array_push((array*)is_and, _MOV((bool[]){ true })); } else { kind = _S("orm__OperationKind__eq"); } } if (((*expr._v__ast__InfixExpr).left)._typ != 362 /* v.ast.InfixExpr */ && ((*expr._v__ast__InfixExpr).right)._typ != 362 /* v.ast.InfixExpr */ && (kind).len != 0) { array_push((array*)kinds, _MOV((string[]){ string_clone(kind) })); } if (!((*expr._v__ast__InfixExpr).op == v__token__Kind__key_is || (*expr._v__ast__InfixExpr).op == v__token__Kind__not_is)) { g->sql_side = v__gen__c__SqlExprSide__right; v__gen__c__Gen_write_orm_where_expr(g, (*expr._v__ast__InfixExpr).right, fields, parentheses, kinds, data, is_and); } } else if (expr._typ == 374 /* v.ast.ParExpr */) { Array_int par = new_array_from_c_array(1, 1, sizeof(int), _MOV((int[1]){fields->len})); v__gen__c__Gen_write_orm_where_expr(g, (*expr._v__ast__ParExpr).expr, fields, parentheses, kinds, data, is_and); array_push((array*)&par, _MOV((int[]){ (int)(fields->len - 1) })); array_push((array*)parentheses, &par); } else if (expr._typ == 358 /* v.ast.Ident */) { if (g->sql_side == v__gen__c__SqlExprSide__left) { _option_v__ast__StructField _t7 = v__gen__c__Gen_get_orm_current_table_field(g, (*expr._v__ast__Ident).name); if (_t7.state != 0) { IError err = _t7.err; v__gen__c__verror(str_intp(3, _MOV((StrIntpData[]){{_S("field \""), 0xfe10, {.d_s = (*expr._v__ast__Ident).name}}, {_S("\" does not exist on \""), 0xfe10, {.d_s = g->sql_table_name}}, {_S("\""), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } v__ast__StructField field = (*(v__ast__StructField*)_t7.data); array_push((array*)fields, _MOV((string[]){ v__gen__c__Gen_get_orm_column_name_from_struct_field(g, field) })); } else { array_push((array*)data, _MOV((v__ast__Expr[]){ expr })); } } else if (expr._typ == 384 /* v.ast.StringLiteral */) { array_push((array*)data, _MOV((v__ast__Expr[]){ expr })); } else if (expr._typ == 383 /* v.ast.StringInterLiteral */) { array_push((array*)data, _MOV((v__ast__Expr[]){ expr })); } else if (expr._typ == 363 /* v.ast.IntegerLiteral */) { array_push((array*)data, _MOV((v__ast__Expr[]){ expr })); } else if (expr._typ == 379 /* v.ast.SelectorExpr */) { if (v__type_resolver__ResolverInfo_is_comptime_selector_field_name(g->comptime, (*expr._v__ast__SelectorExpr), _S("name"))) { array_push((array*)fields, _MOV((string[]){ string_clone(g->comptime->comptime_for_field_value.name) })); } else { array_push((array*)data, _MOV((v__ast__Expr[]){ expr })); } } else if (expr._typ == 342 /* v.ast.BoolLiteral */) { array_push((array*)data, _MOV((v__ast__Expr[]){ expr })); } else if (expr._typ == 355 /* v.ast.EnumVal */) { array_push((array*)data, _MOV((v__ast__Expr[]){ expr })); } else if (expr._typ == 344 /* v.ast.CallExpr */) { array_push((array*)data, _MOV((v__ast__Expr[]){ expr })); } else if (expr._typ == 371 /* v.ast.None */) { array_push((array*)data, _MOV((v__ast__Expr[]){ expr })); } else { } } VV_LOC void v__gen__c__Gen_write_orm_select(v__gen__c__Gen* g, v__ast__SqlExpr node, string connection_var_name, string result_var) { Array_v__ast__StructField fields = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); _option_v__ast__StructField _t1 = v__gen__c__Gen_get_orm_struct_primary_field(g, node.fields); if (_t1.state != 0) { IError err = _t1.err; *(v__ast__StructField*) _t1.data = ((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}); } v__ast__StructField primary_field = (*(v__ast__StructField*)_t1.data); for (int _t2 = 0; _t2 < node.fields.len; ++_t2) { v__ast__StructField field = ((v__ast__StructField*)node.fields.data)[_t2]; bool skip = false; for (int _t3 = 0; _t3 < field.attrs.len; ++_t3) { v__ast__Attr attr = ((v__ast__Attr*)field.attrs.data)[_t3]; if (fast_string_eq(attr.name, _S("skip"))) { skip = true; } if (fast_string_eq(attr.name, _S("sql")) && fast_string_eq(attr.arg, _S("-"))) { skip = true; } } if (!skip) { array_push((array*)&fields, _MOV((v__ast__StructField[]){ field })); } } string select_result_var_name = v__gen__c__Gen_new_tmp_var(g); string table_name = v__gen__c__Gen_get_table_name_by_struct_type(g, node.table_expr.typ); g->sql_table_name = v__ast__Table_sym(g->table, node.table_expr.typ)->name; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("// sql { select from `"), 0xfe10, {.d_s = table_name}}, {_S("` }"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__result_name}}, {_S("_Array_Array_orm__Primitive "), 0xfe10, {.d_s = select_result_var_name}}, {_S(" = orm__Connection_name_table["), 0xfe10, {.d_s = connection_var_name}}, {_S("._typ]._method_select("), 0, { .d_c = 0 }}}))); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = connection_var_name}}, {_S("._object, // Connection object"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("(orm__SelectConfig){")); g->indent++; v__gen__c__Gen_writeln(g, _S(".table = ")); v__gen__c__Gen_write_orm_table_struct(g, node.table_expr.typ); v__gen__c__Gen_writeln(g, _S(",")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".is_count = "), 0xfe10, {.d_s = node.is_count ? _S("true") : _S("false")}}, {_S(","), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".has_where = "), 0xfe10, {.d_s = node.has_where ? _S("true") : _S("false")}}, {_S(","), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".has_order = "), 0xfe10, {.d_s = node.has_order ? _S("true") : _S("false")}}, {_S(","), 0, { .d_c = 0 }}}))); if (node.has_order) { v__gen__c__Gen_write(g, _S(".order = _S(\"")); if ((node.order_expr)._typ == 358 /* v.ast.Ident */) { _option_v__ast__StructField _t5 = v__gen__c__Gen_get_orm_current_table_field(g, (*node.order_expr._v__ast__Ident).name); if (_t5.state != 0) { IError err = _t5.err; v__gen__c__verror(str_intp(3, _MOV((StrIntpData[]){{_S("field \""), 0xfe10, {.d_s = (*node.order_expr._v__ast__Ident).name}}, {_S("\" does not exist on \""), 0xfe10, {.d_s = g->sql_table_name}}, {_S("\""), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } v__ast__StructField field = (*(v__ast__StructField*)_t5.data); v__gen__c__Gen_write(g, v__gen__c__Gen_get_orm_column_name_from_struct_field(g, field)); } else { v__gen__c__Gen_expr(g, node.order_expr); } v__gen__c__Gen_writeln(g, _S("\"),")); if (node.has_desc) { v__gen__c__Gen_writeln(g, _S(".order_type = orm__OrderType__desc,")); } else { v__gen__c__Gen_writeln(g, _S(".order_type = orm__OrderType__asc,")); } } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".has_limit = "), 0xfe10, {.d_s = node.has_limit ? _S("true") : _S("false")}}, {_S(","), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".has_offset = "), 0xfe10, {.d_s = node.has_offset ? _S("true") : _S("false")}}, {_S(","), 0, { .d_c = 0 }}}))); if ((primary_field.name).len != 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".primary = _S(\""), 0xfe10, {.d_s = primary_field.name}}, {_S("\"),"), 0, { .d_c = 0 }}}))); } Array_v__ast__StructField _t6 = {0}; Array_v__ast__StructField _t6_orig = fields; int _t6_len = _t6_orig.len; _t6 = __new_array(0, _t6_len, sizeof(v__ast__StructField)); for (int _t7 = 0; _t7 < _t6_len; ++_t7) { v__ast__StructField it = ((v__ast__StructField*) _t6_orig.data)[_t7]; if (v__ast__Table_sym(g->table, it.typ)->kind != v__ast__Kind__array) { array_push((array*)&_t6, &it); } } Array_v__ast__StructField select_fields =_t6; v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".fields = new_array_from_c_array("), 0xfe07, {.d_i32 = select_fields.len}}, {_S(", "), 0xfe07, {.d_i32 = select_fields.len}}, {_S(", sizeof(string),"), 0, { .d_c = 0 }}}))); g->indent++; Array_string types = __new_array_with_default(0, 0, sizeof(string), 0); if (select_fields.len > 0) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_MOV((string["), 0xfe07, {.d_i32 = select_fields.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); g->indent++; for (int _t8 = 0; _t8 < select_fields.len; ++_t8) { v__ast__StructField field = ((v__ast__StructField*)select_fields.data)[_t8]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("_S(\""), 0xfe10, {.d_s = v__gen__c__Gen_get_orm_column_name_from_struct_field(g, field)}}, {_S("\"),"), 0, { .d_c = 0 }}}))); v__ast__Type final_field_typ = v__ast__Table_final_type(g->table, field.typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, final_field_typ); if (fast_string_eq(sym->name, _S("time.Time"))) { array_push((array*)&types, _MOV((string[]){ _S("_const_orm__time_") })); continue; } if (sym->kind == v__ast__Kind__struct) { array_push((array*)&types, _MOV((string[]){ int_str(((int)(_const_v__ast__int_type))) })); continue; } else if (sym->kind == v__ast__Kind__enum) { array_push((array*)&types, _MOV((string[]){ _S("_const_orm__enum_") })); continue; } array_push((array*)&types, _MOV((string[]){ int_str(v__ast__Type_idx(final_field_typ)) })); } g->indent--; v__gen__c__Gen_writeln(g, _S("})")); } else { v__gen__c__Gen_writeln(g, _S("NULL")); } g->indent--; v__gen__c__Gen_writeln2(g, _S("),"), str_intp(4, _MOV((StrIntpData[]){{_S(".types = new_array_from_c_array("), 0xfe07, {.d_i32 = types.len}}, {_S(", "), 0xfe07, {.d_i32 = types.len}}, {_S(", sizeof("), 0xfe10, {.d_s = _const_v__ast__int_type_name}}, {_S("),"), 0, { .d_c = 0 }}}))); g->indent++; if (types.len > 0) { { v__gen__c__Gen_write(g, _S("_MOV((int[")); v__gen__c__Gen_write_decimal(g, types.len); v__gen__c__Gen_write(g, _S("]){")); } for (int _t13 = 0; _t13 < types.len; ++_t13) { string typ = ((string*)types.data)[_t13]; { v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, typ); v__gen__c__Gen_write(g, _S(",")); } } v__gen__c__Gen_writeln(g, _S(" })")); } else { v__gen__c__Gen_writeln(g, _S("NULL")); } g->indent--; v__gen__c__Gen_writeln(g, _S("),")); g->indent--; v__gen__c__Gen_writeln(g, _S("},")); Array_v__ast__Expr exprs = __new_array_with_default(0, 0, sizeof(v__ast__Expr), 0); if (node.has_limit) { array_push((array*)&exprs, _MOV((v__ast__Expr[]){ node.limit_expr })); } if (node.has_offset) { array_push((array*)&exprs, _MOV((v__ast__Expr[]){ node.offset_expr })); } v__gen__c__Gen_writeln(g, _S("(orm__QueryData) {")); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".types = __new_array_with_default_noscan(0, 0, sizeof("), 0xfe10, {.d_s = _const_v__ast__int_type_name}}, {_S("), 0),"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S(".kinds = __new_array_with_default_noscan(0, 0, sizeof(orm__OperationKind), 0),")); v__gen__c__Gen_writeln(g, _S(".is_and = __new_array_with_default_noscan(0, 0, sizeof(bool), 0),")); v__gen__c__Gen_writeln(g, _S(".parentheses = __new_array_with_default_noscan(0, 0, sizeof(Array_int), 0),")); if (exprs.len > 0) { { v__gen__c__Gen_write(g, _S(".data = new_array_from_c_array(")); v__gen__c__Gen_write_decimal(g, exprs.len); v__gen__c__Gen_write(g, _S(", ")); v__gen__c__Gen_write_decimal(g, exprs.len); v__gen__c__Gen_write(g, _S(", sizeof(orm__Primitive),")); } { v__gen__c__Gen_write(g, _S(" _MOV((orm__Primitive[")); v__gen__c__Gen_write_decimal(g, exprs.len); v__gen__c__Gen_write(g, _S("]){")); } for (int _t16 = 0; _t16 < exprs.len; ++_t16) { v__ast__Expr e = ((v__ast__Expr*)exprs.data)[_t16]; v__gen__c__Gen_write_orm_expr_to_primitive(g, e); } v__gen__c__Gen_writeln(g, _S("})")); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S(".data = __new_array_with_default_noscan("), 0xfe07, {.d_i32 = exprs.len}}, {_S(", "), 0xfe07, {.d_i32 = exprs.len}}, {_S(", sizeof(orm__Primitive), 0"), 0, { .d_c = 0 }}}))); } g->indent--; v__gen__c__Gen_writeln(g, _S(")},")); if (node.has_where) { v__gen__c__Gen_write_orm_where(g, node.where_expr); } else { v__gen__c__Gen_writeln(g, _S("(orm__QueryData) {")); g->indent++; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S(".types = __new_array_with_default_noscan(0, 0, sizeof("), 0xfe10, {.d_s = _const_v__ast__int_type_name}}, {_S("), 0),"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S(".kinds = __new_array_with_default_noscan(0, 0, sizeof(orm__OperationKind), 0),")); v__gen__c__Gen_writeln(g, _S(".is_and = __new_array_with_default_noscan(0, 0, sizeof(bool), 0),")); v__gen__c__Gen_writeln(g, _S(".parentheses = __new_array_with_default_noscan(0, 0, sizeof(Array_int), 0),")); v__gen__c__Gen_writeln(g, _S(".data = __new_array_with_default_noscan(0, 0, sizeof(orm__Primitive), 0)")); g->indent--; v__gen__c__Gen_writeln(g, _S("}")); } g->indent--; v__gen__c__Gen_writeln(g, _S(");")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = result_var}}, {_S(".is_error = "), 0xfe10, {.d_s = select_result_var_name}}, {_S(".is_error;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = result_var}}, {_S(".err = "), 0xfe10, {.d_s = select_result_var_name}}, {_S(".err;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_or_block(g, result_var, node.or_expr, node.typ); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if (!"), 0xfe10, {.d_s = result_var}}, {_S(".is_error) {"), 0, { .d_c = 0 }}}))); g->indent++; string unwrapped_c_typ = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(node.typ, v__ast__TypeFlag__result)); string select_unwrapped_result_var_name = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("Array_Array_orm__Primitive "), 0xfe10, {.d_s = select_unwrapped_result_var_name}}, {_S(" = (*(Array_Array_orm__Primitive*)"), 0xfe10, {.d_s = select_result_var_name}}, {_S(".data);"), 0, { .d_c = 0 }}}))); if (node.is_count) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = unwrapped_c_typ}}, {_S("*) "), 0xfe10, {.d_s = result_var}}, {_S(".data = *((*(orm__Primitive*) array_get((*(Array_orm__Primitive*)array_get("), 0xfe10, {.d_s = select_unwrapped_result_var_name}}, {_S(", 0)), 0))._int);"), 0, { .d_c = 0 }}}))); } else { string tmp = v__gen__c__Gen_new_tmp_var(g); string idx = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("int "), 0xfe10, {.d_s = idx}}, {_S(" = 0;"), 0, { .d_c = 0 }}}))); string typ_str = _S(""); if (node.is_array) { v__ast__Array info = v__ast__TypeSymbol_array_info(v__ast__Table_sym(g->table, node.typ)); typ_str = v__gen__c__Gen_styp(g, info.elem_type); string base_typ = v__gen__c__Gen_base_type(g, node.typ); if (v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = unwrapped_c_typ}}, {_S(" "), 0xfe10, {.d_s = tmp}}, {_S("_array = { .state = 2, .err = _const_none__, .data = {E_STRUCT} };"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("_option_ok(&("), 0xfe10, {.d_s = base_typ}}, {_S("[]) { __new_array(0, "), 0xfe10, {.d_s = select_unwrapped_result_var_name}}, {_S(".len, sizeof("), 0xfe10, {.d_s = typ_str}}, {_S(")) }, (_option *)&"), 0xfe10, {.d_s = tmp}}, {_S("_array, sizeof("), 0xfe10, {.d_s = base_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = unwrapped_c_typ}}, {_S(" "), 0xfe10, {.d_s = tmp}}, {_S("_array = __new_array(0, "), 0xfe10, {.d_s = select_unwrapped_result_var_name}}, {_S(".len, sizeof("), 0xfe10, {.d_s = typ_str}}, {_S("));"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("for (; "), 0xfe10, {.d_s = idx}}, {_S(" < "), 0xfe10, {.d_s = select_unwrapped_result_var_name}}, {_S(".len; "), 0xfe10, {.d_s = idx}}, {_S("++) {"), 0, { .d_c = 0 }}}))); g->indent++; { v__gen__c__Gen_write(g, typ_str); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S(" = (")); v__gen__c__Gen_write(g, typ_str); v__gen__c__Gen_write(g, _S(") {")); } v__ast__Struct inf = v__ast__TypeSymbol_struct_info(v__ast__Table_sym(g->table, info.elem_type)); for (int i = 0; i < inf.fields.len; ++i) { v__ast__StructField field = ((v__ast__StructField*)inf.fields.data)[i]; v__gen__c__Gen_zero_struct_field(g, field); if (i != (int)(inf.fields.len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } } v__gen__c__Gen_writeln(g, _S("};")); } else { { v__gen__c__Gen_write(g, unwrapped_c_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp); v__gen__c__Gen_write(g, _S(" = (")); v__gen__c__Gen_write(g, unwrapped_c_typ); v__gen__c__Gen_write(g, _S("){")); } v__ast__Struct info = v__ast__TypeSymbol_struct_info(v__ast__Table_sym(g->table, node.typ)); for (int i = 0; i < info.fields.len; ++i) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[i]; v__gen__c__Gen_zero_struct_field(g, field); if (i != (int)(info.fields.len - 1)) { v__gen__c__Gen_write(g, _S(", ")); } } v__gen__c__Gen_writeln(g, _S("};")); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = select_unwrapped_result_var_name}}, {_S(".len > 0) {"), 0, { .d_c = 0 }}}))); g->indent++; int fields_idx = 0; for (int _t17 = 0; _t17 < fields.len; ++_t17) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t17]; string array_get_call_code = str_intp(4, _MOV((StrIntpData[]){{_S("(*(orm__Primitive*) array_get((*(Array_orm__Primitive*) array_get("), 0xfe10, {.d_s = select_unwrapped_result_var_name}}, {_S(", "), 0xfe10, {.d_s = idx}}, {_S(")), "), 0xfe07, {.d_i32 = fields_idx}}, {_S("))"), 0, { .d_c = 0 }}})); v__ast__Type final_field_typ = v__ast__Table_final_type(g->table, field.typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, final_field_typ); string field_var = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp}}, {_S("."), 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_SLIT0, 0, { .d_c = 0 }}})); string field_c_typ = v__gen__c__Gen_styp(g, final_field_typ); if (sym->kind == v__ast__Kind__struct && !fast_string_eq(sym->name, _S("time.Time"))) { v__ast__SqlExpr sub = (*(v__ast__SqlExpr*)map_get(ADDR(map, node.sub_structs), &(int[]){((int)(final_field_typ))}, &(v__ast__SqlExpr[]){ (v__ast__SqlExpr){.is_count = 0,.is_insert = 0,.inserted_var = (string){.str=(byteptr)"", .is_lit=1},.has_where = 0,.has_order = 0,.has_limit = 0,.has_offset = 0,.has_desc = 0,.is_array = 0,.is_generated = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.db_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.order_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.limit_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.offset_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.table_expr = (v__ast__TypeNode){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),},.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlExpr), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.or_expr = (v__ast__OrExpr){.kind = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),},} })); v__ast__InfixExpr where_expr = *(v__ast__InfixExpr*)__as_cast((sub.where_expr)._v__ast__InfixExpr,(sub.where_expr)._typ, 362); v__ast__Ident ident = *(v__ast__Ident*)__as_cast((where_expr.right)._v__ast__Ident,(where_expr.right)._typ, 358); v__ast__Type primitive_type_index = v__ast__Table_find_type(g->table, _S("orm.Primitive")); if (primitive_type_index != 0) { if ((ident.info)._typ == 477 /* v.ast.IdentVar */) { (*ident.info._v__ast__IdentVar).typ = primitive_type_index; } } ident.name = array_get_call_code; where_expr.right = v__ast__Ident_to_sumtype_v__ast__Expr(&ident); sub.where_expr = v__ast__InfixExpr_to_sumtype_v__ast__Expr(&where_expr); string sub_result_var = v__gen__c__Gen_new_tmp_var(g); string sub_result_c_typ = v__gen__c__Gen_styp(g, sub.typ); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sub_result_c_typ}}, {_S(" "), 0xfe10, {.d_s = sub_result_var}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write_orm_select(g, sub, connection_var_name, sub_result_var); if (v__ast__Type_has_flag(final_field_typ, v__ast__TypeFlag__option)) { string unwrapped_field_c_typ = v__gen__c__Gen_styp(g, v__ast__Type_clear_flag(final_field_typ, v__ast__TypeFlag__option)); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if (!"), 0xfe10, {.d_s = sub_result_var}}, {_S(".is_error)"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\t_option_ok("), 0xfe10, {.d_s = sub_result_var}}, {_S(".data, (_option *)&"), 0xfe10, {.d_s = field_var}}, {_S(", sizeof("), 0xfe10, {.d_s = unwrapped_field_c_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("else")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = field_var}}, {_S(" = ("), 0xfe10, {.d_s = field_c_typ}}, {_S("){ .state = 2, .err = _const_none__, .data = {E_STRUCT} };"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if (!"), 0xfe10, {.d_s = sub_result_var}}, {_S(".is_error)"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = field_var}}, {_S(" = *("), 0xfe10, {.d_s = field_c_typ}}, {_S("*)"), 0xfe10, {.d_s = sub_result_var}}, {_S(".data;"), 0, { .d_c = 0 }}}))); } fields_idx++; } else if (sym->kind == v__ast__Kind__array) { string fkey = _S(""); _option_v__ast__Attr _t18; if (_t18 = Array_v__ast__Attr_find_first(field.attrs, _S("fkey")), _t18.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t18.data; fkey = attr.arg; } else { IError err = _t18.err; v__gen__c__verror(_S("missing fkey attribute")); VUNREACHABLE(); } v__ast__SqlExpr sub = (*(v__ast__SqlExpr*)map_get(ADDR(map, node.sub_structs), &(int[]){final_field_typ}, &(v__ast__SqlExpr[]){ (v__ast__SqlExpr){.is_count = 0,.is_insert = 0,.inserted_var = (string){.str=(byteptr)"", .is_lit=1},.has_where = 0,.has_order = 0,.has_limit = 0,.has_offset = 0,.has_desc = 0,.is_array = 0,.is_generated = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.db_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.where_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.order_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.limit_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.offset_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.table_expr = (v__ast__TypeNode){.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = 0,.stmt = _const_v__ast__empty_stmt,.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),},.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlExpr), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop),.or_expr = (v__ast__OrExpr){.kind = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),},} })); if (sub.has_where) { v__ast__InfixExpr where_expr = *(v__ast__InfixExpr*)__as_cast((sub.where_expr)._v__ast__InfixExpr,(sub.where_expr)._typ, 362); v__ast__Ident left_where_expr = *(v__ast__Ident*)__as_cast((where_expr.left)._v__ast__Ident,(where_expr.left)._typ, 358); v__ast__Ident right_where_expr = *(v__ast__Ident*)__as_cast((where_expr.right)._v__ast__Ident,(where_expr.right)._typ, 358); left_where_expr.name = fkey; right_where_expr.name = tmp; where_expr.left = v__ast__Ident_to_sumtype_v__ast__Expr(&left_where_expr); where_expr.right = v__ast__SelectorExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__SelectorExpr, (((v__ast__SelectorExpr){ .pos = right_where_expr.pos, .field_name = primary_field.name, .is_mut = false, .mut_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}), .next_token = 0, .expr = v__ast__Ident_to_sumtype_v__ast__Expr(&right_where_expr), .expr_type = (*(v__ast__IdentVar*)__as_cast((right_where_expr.info)._v__ast__IdentVar,(right_where_expr.info)._typ, 477)).typ, .typ = (*(v__ast__IdentVar*)__as_cast((right_where_expr.info)._v__ast__IdentVar,(right_where_expr.info)._typ, 477)).typ, .name_type = 0, .or_block = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), .gkind_field = 0, .scope = ((void*)0), .from_embed_types = __new_array(0, 0, sizeof(v__ast__Type)), .generic_from_embed_types = __new_array(0, 0, sizeof(Array_v__ast__Type)), .has_hidden_receiver = 0, .is_field_typ = 0, })))); v__ast__SqlExpr sql_expr_select_array = ((v__ast__SqlExpr){ .is_count = sub.is_count, .is_insert = 0, .inserted_var = (string){.str=(byteptr)"", .is_lit=1}, .has_where = sub.has_where, .has_order = sub.has_order, .has_limit = sub.has_limit, .has_offset = sub.has_offset, .has_desc = sub.has_desc, .is_array = true, .is_generated = true, .pos = sub.pos, .typ = v__ast__Type_set_flag(final_field_typ, v__ast__TypeFlag__result), .db_expr = sub.db_expr, .where_expr = v__ast__InfixExpr_to_sumtype_v__ast__Expr(&where_expr), .order_expr = sub.order_expr, .limit_expr = sub.limit_expr, .offset_expr = sub.offset_expr, .table_expr = sub.table_expr, .fields = sub.fields, .sub_structs = new_map(sizeof(int), sizeof(v__ast__SqlExpr), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop), .or_expr = ((v__ast__OrExpr){.kind = 0,.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),}), }); string sub_result_var = v__gen__c__Gen_new_tmp_var(g); string sub_result_c_typ = v__gen__c__Gen_styp(g, sub.typ); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sub_result_c_typ}}, {_S(" "), 0xfe10, {.d_s = sub_result_var}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_write_orm_select(g, sql_expr_select_array, connection_var_name, sub_result_var); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("if (!"), 0xfe10, {.d_s = sub_result_var}}, {_S(".is_error) {"), 0, { .d_c = 0 }}}))); if (v__ast__Type_has_flag(final_field_typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = field_var}}, {_S(".state = 0;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\t*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, final_field_typ)}}, {_S("*)"), 0xfe10, {.d_s = field_var}}, {_S(".data = *("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, final_field_typ)}}, {_S("*)"), 0xfe10, {.d_s = sub_result_var}}, {_S(".data;"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = field_var}}, {_S(" = *("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, field.typ)}}, {_S("*)"), 0xfe10, {.d_s = sub_result_var}}, {_S(".data;"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, _S("}")); } } else if (v__ast__Type_has_flag(final_field_typ, v__ast__TypeFlag__option)) { string prim_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("orm__Primitive *"), 0xfe10, {.d_s = prim_var}}, {_S(" = &"), 0xfe10, {.d_s = array_get_call_code}}, {_S(";"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = prim_var}}, {_S("->_typ == "), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("orm.Null"))}}, {_S(")"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = field_var}}, {_S(" = ("), 0xfe10, {.d_s = field_c_typ}}, {_S("){ .state = 2, .err = _const_none__, .data = {E_STRUCT} };"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("else")); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\t_option_ok("), 0xfe10, {.d_s = prim_var}}, {_S("->_"), 0xfe10, {.d_s = sym->cname}}, {_S(", (_option *)&"), 0xfe10, {.d_s = field_var}}, {_S(", sizeof("), 0xfe10, {.d_s = sym->cname}}, {_S("));"), 0, { .d_c = 0 }}}))); fields_idx++; } else if (sym->kind == v__ast__Kind__enum) { string typ = sym->cname; v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp}}, {_S("."), 0xfe10, {.d_s = v__gen__c__c_name(field.name)}}, {_S(" = ("), 0xfe10, {.d_s = typ}}, {_S(") (*("), 0xfe10, {.d_s = array_get_call_code}}, {_S("._i64));"), 0, { .d_c = 0 }}}))); fields_idx++; } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = field_var}}, {_S(" = *("), 0xfe10, {.d_s = array_get_call_code}}, {_S("._"), 0xfe10, {.d_s = sym->cname}}, {_S(");"), 0, { .d_c = 0 }}}))); fields_idx++; } } if (node.is_array) { if (v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp}}, {_S("_array.state = 0;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("array_push(("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, node.typ)}}, {_S("*)&"), 0xfe10, {.d_s = tmp}}, {_S("_array.data, _MOV(("), 0xfe10, {.d_s = typ_str}}, {_S("[]){ "), 0xfe10, {.d_s = tmp}}, {_S(" }));"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("array_push(&"), 0xfe10, {.d_s = tmp}}, {_S("_array, _MOV(("), 0xfe10, {.d_s = typ_str}}, {_S("[]){ "), 0xfe10, {.d_s = tmp}}, {_S(" }));"), 0, { .d_c = 0 }}}))); } g->indent--; v__gen__c__Gen_writeln(g, _S("}")); } g->indent--; if (!node.is_array) { v__gen__c__Gen_writeln(g, _S("} else {")); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = result_var}}, {_S(".is_error = true;"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_writeln(g, _S("}")); if (node.is_array) { if (v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, node.typ)}}, {_S("*) "), 0xfe10, {.d_s = result_var}}, {_S(".data = *("), 0xfe10, {.d_s = v__gen__c__Gen_base_type(g, node.typ)}}, {_S("*)"), 0xfe10, {.d_s = tmp}}, {_S("_array.data;"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = unwrapped_c_typ}}, {_S("*) "), 0xfe10, {.d_s = result_var}}, {_S(".data = "), 0xfe10, {.d_s = tmp}}, {_S("_array;"), 0, { .d_c = 0 }}}))); } } else { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("*("), 0xfe10, {.d_s = unwrapped_c_typ}}, {_S("*) "), 0xfe10, {.d_s = result_var}}, {_S(".data = "), 0xfe10, {.d_s = tmp}}, {_S(";"), 0, { .d_c = 0 }}}))); } } g->indent--; v__gen__c__Gen_writeln(g, _S("}")); if (node.is_generated) { v__gen__c__Gen_writeln(g, _S(";")); } } VV_LOC Array_v__ast__StructField v__gen__c__Gen_filter_struct_fields_by_orm_attrs(v__gen__c__Gen* _d1, Array_v__ast__StructField fields) { Array_v__ast__StructField ret = __new_array_with_default(0, 0, sizeof(v__ast__StructField), 0); for (int _t1 = 0; _t1 < fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t1]; bool _t2 = (Array_v__ast__Attr_contains(field.attrs, _S("skip"))); if ( _t2 || Array_v__ast__Attr_contains_arg(field.attrs, _S("sql"), _S("-"))) { continue; } array_push((array*)&ret, _MOV((v__ast__StructField[]){ field })); } return ret; } VV_LOC _option_v__ast__Type v__gen__c__Gen_get_db_expr_type(v__gen__c__Gen* g, v__ast__Expr expr) { if ((expr)._typ == 358 /* v.ast.Ident */) { if (((*expr._v__ast__Ident).info)._typ == 477 /* v.ast.IdentVar */) { _option_v__ast__Type _t1; _option_ok(&(v__ast__Type[]) { v__ast__Table_unaliased_type(g->table, (*(*expr._v__ast__Ident).info._v__ast__IdentVar).typ) }, (_option*)(&_t1), sizeof(v__ast__Type)); return _t1; } } else if ((expr)._typ == 379 /* v.ast.SelectorExpr */) { _option_v__ast__Type _t2; _option_ok(&(v__ast__Type[]) { v__ast__Table_unaliased_type(g->table, (*expr._v__ast__SelectorExpr).typ) }, (_option*)(&_t2), sizeof(v__ast__Type)); return _t2; } return (_option_v__ast__Type){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } VV_LOC Array_v__ast__Attr v__gen__c__Gen_get_table_attrs_by_struct_type(v__gen__c__Gen* g, v__ast__Type typ) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); v__ast__Struct info = v__ast__TypeSymbol_struct_info(sym); return info.attrs; } VV_LOC string v__gen__c__Gen_get_table_name_by_struct_type(v__gen__c__Gen* g, v__ast__Type typ) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); v__ast__Struct info = v__ast__TypeSymbol_struct_info(sym); string table_name = v__util__strip_mod_name(sym->name); _option_v__ast__Attr _t1; if (_t1 = Array_v__ast__Attr_find_first(info.attrs, _S("table")), _t1.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t1.data; table_name = attr.arg; } string escaped_table_name = v__gen__c__cescape_nonascii(v__util__smart_quote(table_name, false)); return escaped_table_name; } VV_LOC _option_v__ast__StructField v__gen__c__Gen_get_orm_current_table_field(v__gen__c__Gen* g, string name) { v__ast__Struct info = v__ast__TypeSymbol_struct_info(v__ast__Table_sym(g->table, v__ast__idx_to_type((*(int*)map_get(ADDR(map, g->table->type_idxs), &(string[]){g->sql_table_name}, &(int[]){ 0 }))))); for (int _t1 = 0; _t1 < info.fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)info.fields.data)[_t1]; if (string__eq(field.name, name)) { _option_v__ast__StructField _t2; _option_ok(&(v__ast__StructField[]) { field }, (_option*)(&_t2), sizeof(v__ast__StructField)); return _t2; } } return (_option_v__ast__StructField){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } VV_LOC string v__gen__c__Gen_get_orm_column_name_from_struct_field(v__gen__c__Gen* g, v__ast__StructField field) { string name = field.name; _option_v__ast__Attr _t1; if (_t1 = Array_v__ast__Attr_find_first(field.attrs, _S("sql")), _t1.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t1.data; if (!(fast_string_eq(attr.arg, _S("serial")) || fast_string_eq(attr.arg, _S("i8")) || fast_string_eq(attr.arg, _S("i16")) || fast_string_eq(attr.arg, _S("int")) || fast_string_eq(attr.arg, _S("i64")) || fast_string_eq(attr.arg, _S("u8")) || fast_string_eq(attr.arg, _S("u16")) || fast_string_eq(attr.arg, _S("u32")) || fast_string_eq(attr.arg, _S("u64")) || fast_string_eq(attr.arg, _S("f32")) || fast_string_eq(attr.arg, _S("f64")) || fast_string_eq(attr.arg, _S("bool")) || fast_string_eq(attr.arg, _S("string")))) { name = attr.arg; } } v__ast__Type final_field_typ = v__ast__Table_final_type(g->table, field.typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, final_field_typ); if (sym->kind == v__ast__Kind__struct && !fast_string_eq(sym->name, _S("time.Time"))) { name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = name}}, {_S("_id"), 0, { .d_c = 0 }}})); } return name; } VV_LOC _option_v__ast__StructField v__gen__c__Gen_get_orm_struct_primary_field(v__gen__c__Gen* _d1, Array_v__ast__StructField fields) { for (int _t1 = 0; _t1 < fields.len; ++_t1) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[_t1]; _option_v__ast__Attr _t2; if (_t2 = Array_v__ast__Attr_find_first(field.attrs, _S("primary")), _t2.state == 0) { _option_v__ast__StructField _t3; _option_ok(&(v__ast__StructField[]) { field }, (_option*)(&_t3), sizeof(v__ast__StructField)); return _t3; } } return (_option_v__ast__StructField){ .state=2, .err=_const_none__, .data={E_STRUCT} }; } VV_LOC Array_int v__gen__c__get_auto_field_idxs(Array_v__ast__StructField fields) { Array_int ret = __new_array_with_default(0, 0, sizeof(int), 0); for (int i = 0; i < fields.len; ++i) { v__ast__StructField field = ((v__ast__StructField*)fields.data)[i]; for (int _t1 = 0; _t1 < field.attrs.len; ++_t1) { v__ast__Attr attr = ((v__ast__Attr*)field.attrs.data)[_t1]; if (fast_string_eq(attr.name, _S("default"))) { array_push((array*)&ret, _MOV((int[]){ i })); } else if (fast_string_eq(attr.name, _S("sql")) && fast_string_eq(attr.arg, _S("serial"))) { array_push((array*)&ret, _MOV((int[]){ i })); } else if (fast_string_eq(attr.name, _S("serial")) && attr.kind == v__ast__AttrKind__plain && !attr.has_arg) { array_push((array*)&ret, _MOV((int[]){ i })); } } } return ret; } VV_LOC v__gen__c__PastTmpVar v__gen__c__Gen_past_tmp_var_new(v__gen__c__Gen* g) { string tmp_var = v__gen__c__Gen_new_tmp_var(g); string s = v__gen__c__Gen_go_before_last_stmt(g); bool s_ends_with_ln = string_ends_with(s, _S("\n")); s = string_trim_space(s); g->empty_line = true; return ((v__gen__c__PastTmpVar){.var_name = (string){.str=(byteptr)"", .is_lit=1},.tmp_var = tmp_var,.s = s,.s_ends_with_ln = s_ends_with_ln,}); } VV_LOC v__gen__c__PastTmpVar v__gen__c__Gen_past_tmp_var_from_var_name(v__gen__c__Gen* g, string var_name) { string tmp_var = v__gen__c__Gen_new_tmp_var(g); string s = _S(""); if ((var_name).len != 0) { tmp_var = var_name; } else { s = v__gen__c__Gen_go_before_last_stmt(g); } bool s_ends_with_ln = string_ends_with(s, _S("\n")); s = string_trim_space(s); g->empty_line = true; return ((v__gen__c__PastTmpVar){.var_name = var_name,.tmp_var = tmp_var,.s = s,.s_ends_with_ln = s_ends_with_ln,}); } VV_LOC void v__gen__c__Gen_past_tmp_var_done(v__gen__c__Gen* g, v__gen__c__PastTmpVar* p) { if (p->var_name.len == 0) { if (p->s_ends_with_ln) { v__gen__c__Gen_writeln(g, p->s); } else { v__gen__c__Gen_write(g, p->s); } if (g->inside_return) { v__gen__c__Gen_write(g, _S(" ")); } v__gen__c__Gen_write(g, p->tmp_var); } } VV_LOC void v__gen__c__Gen_profile_fn(v__gen__c__Gen* g, v__ast__FnDecl fn_decl) { bool _t1 = (g->pref->profile_no_inline); if ( _t1 && Array_v__ast__Attr_contains(fn_decl.attrs, _S("inline"))) { g->defer_profile_code = _S(""); return; } string fn_name = fn_decl.name; string cfn_name = g->last_fn_c_name; if (string_starts_with(fn_name, _S("time.vpc_now")) || string_starts_with(fn_name, _S("v.profile."))) { g->defer_profile_code = _S(""); } else { string measure_fn_name = (g->pref->os == v__pref__OS__macos ? (_S("time__vpc_now_darwin")) : (_S("time__vpc_now"))); string fn_profile_counter_name = str_intp(2, _MOV((StrIntpData[]){{_S("vpc_"), 0xfe10, {.d_s = cfn_name}}, {_SLIT0, 0, { .d_c = 0 }}})); string fn_profile_counter_name_calls = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = fn_profile_counter_name}}, {_S("_calls"), 0, { .d_c = 0 }}})); v__gen__c__Gen_writeln(g, _S("")); bool should_restore_v__profile_enabled = g->pref->profile_fns.len > 0 && (Array_string_contains(g->pref->profile_fns, cfn_name)); if (should_restore_v__profile_enabled) { #if defined(CUSTOM_DEFINE_trace_profile_fns) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("> profile_fn | "), 0xfe10, {.d_s = Array_string_str(g->pref->profile_fns)}}, {_S(" | "), 0xfe10, {.d_s = cfn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v__gen__c__Gen_writeln(g, _S("\tbool _prev_v__profile_enabled = v__profile_enabled;")); v__gen__c__Gen_writeln(g, _S("\tv__profile_enabled = true;")); } v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\tdouble _PROF_FN_START = "), 0xfe10, {.d_s = measure_fn_name}}, {_S("();"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("\tdouble _PROF_PREV_MEASURED_TIME = prof_measured_time;")); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("if(v__profile_enabled) { "), 0xfe10, {.d_s = fn_profile_counter_name_calls}}, {_S("++; } // "), 0xfe10, {.d_s = fn_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, _S("")); g->defer_profile_code = str_intp(2, _MOV((StrIntpData[]){{_S("\tif(v__profile_enabled) { \n\t\tdouble _PROF_ELAPSED = "), 0xfe10, {.d_s = measure_fn_name}}, {_S("() - _PROF_FN_START;\n"), 0, { .d_c = 0 }}})); g->defer_profile_code = string__plus(g->defer_profile_code, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = fn_profile_counter_name}}, {_S(" += _PROF_ELAPSED;\n"), 0, { .d_c = 0 }}}))); g->defer_profile_code = string__plus(g->defer_profile_code, str_intp(2, _MOV((StrIntpData[]){{_S("\t\t"), 0xfe10, {.d_s = fn_profile_counter_name}}, {_S("_only_current += _PROF_ELAPSED - (prof_measured_time - _PROF_PREV_MEASURED_TIME);\n"), 0, { .d_c = 0 }}}))); g->defer_profile_code = string__plus(g->defer_profile_code, _S("\t\tprof_measured_time = _PROF_PREV_MEASURED_TIME + _PROF_ELAPSED;\n\t}")); if (should_restore_v__profile_enabled) { g->defer_profile_code = string__plus(g->defer_profile_code, _S("\n\t\tv__profile_enabled = _prev_v__profile_enabled;")); } strings__Builder_writeln(&g->pcs_declarations, str_intp(4, _MOV((StrIntpData[]){{_S("double "), 0xfe10, {.d_s = fn_profile_counter_name}}, {_S(" = 0.0; double "), 0xfe10, {.d_s = fn_profile_counter_name}}, {_S("_only_current = 0.0; u64 "), 0xfe10, {.d_s = fn_profile_counter_name_calls}}, {_S(" = 0;"), 0, { .d_c = 0 }}}))); array_push((array*)&g->pcs, _MOV((v__gen__c__ProfileCounterMeta[]){ ((v__gen__c__ProfileCounterMeta){.fn_name = cfn_name,.vpc_name = fn_profile_counter_name,.vpc_calls = fn_profile_counter_name_calls,}) })); } } void v__gen__c__Gen_gen_vprint_profile_stats(v__gen__c__Gen* g) { strings__Builder_writeln(&g->pcs_declarations, _S("void vprint_profile_stats(){")); string fstring = _S("\"%14llu %14.3fms %14.3fms %14.0fns %s \\n\""); strings__Builder_writeln(&g->pcs_declarations, _S("\tf64 f = 1.0;")); if (g->pref->os == v__pref__OS__windows) { strings__Builder_writeln(&g->pcs_declarations, _S("\tu64 freq_time = 0;")); strings__Builder_writeln(&g->pcs_declarations, _S("\tQueryPerformanceFrequency(((voidptr)(&freq_time)));")); strings__Builder_writeln(&g->pcs_declarations, _S("\tf = (f64)1000000000.0/(f64)freq_time;")); } if (fast_string_eq(g->pref->profile_file, _S("-"))) { for (int _t1 = 0; _t1 < g->pcs.len; ++_t1) { v__gen__c__ProfileCounterMeta pc_meta = ((v__gen__c__ProfileCounterMeta*)g->pcs.data)[_t1]; strings__Builder_writeln(&g->pcs_declarations, str_intp(9, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = pc_meta.vpc_calls}}, {_S(") printf("), 0xfe10, {.d_s = fstring}}, {_S(", "), 0xfe10, {.d_s = pc_meta.vpc_calls}}, {_S(", ("), 0xfe10, {.d_s = pc_meta.vpc_name}}, {_S("*f)/1000000.0, ("), 0xfe10, {.d_s = pc_meta.vpc_name}}, {_S("_only_current*f)/1000000.0, ("), 0xfe10, {.d_s = pc_meta.vpc_name}}, {_S("*f)/"), 0xfe10, {.d_s = pc_meta.vpc_calls}}, {_S(", \""), 0xfe10, {.d_s = pc_meta.fn_name}}, {_S("\" );"), 0, { .d_c = 0 }}}))); } } else { strings__Builder_writeln(&g->pcs_declarations, _S("\tFILE * fp;")); strings__Builder_writeln(&g->pcs_declarations, str_intp(2, _MOV((StrIntpData[]){{_S("\tfp = fopen (\""), 0xfe10, {.d_s = g->pref->profile_file}}, {_S("\", \"w+\");"), 0, { .d_c = 0 }}}))); for (int _t2 = 0; _t2 < g->pcs.len; ++_t2) { v__gen__c__ProfileCounterMeta pc_meta = ((v__gen__c__ProfileCounterMeta*)g->pcs.data)[_t2]; strings__Builder_writeln(&g->pcs_declarations, str_intp(9, _MOV((StrIntpData[]){{_S("\tif ("), 0xfe10, {.d_s = pc_meta.vpc_calls}}, {_S(") fprintf(fp, "), 0xfe10, {.d_s = fstring}}, {_S(", "), 0xfe10, {.d_s = pc_meta.vpc_calls}}, {_S(", ("), 0xfe10, {.d_s = pc_meta.vpc_name}}, {_S("*f)/1000000.0, ("), 0xfe10, {.d_s = pc_meta.vpc_name}}, {_S("_only_current*f)/1000000.0, ("), 0xfe10, {.d_s = pc_meta.vpc_name}}, {_S("*f)/"), 0xfe10, {.d_s = pc_meta.vpc_calls}}, {_S(", \""), 0xfe10, {.d_s = pc_meta.fn_name}}, {_S("\" );"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->pcs_declarations, _S("\tfclose(fp);")); } strings__Builder_writeln(&g->pcs_declarations, _S("}")); strings__Builder_writeln(&g->pcs_declarations, _S("")); strings__Builder_writeln(&g->pcs_declarations, _S("void vreset_profile_stats(){")); for (int _t3 = 0; _t3 < g->pcs.len; ++_t3) { v__gen__c__ProfileCounterMeta pc_meta = ((v__gen__c__ProfileCounterMeta*)g->pcs.data)[_t3]; strings__Builder_writeln(&g->pcs_declarations, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = pc_meta.vpc_calls}}, {_S(" = 0;"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->pcs_declarations, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = pc_meta.vpc_name}}, {_S(" = 0.0;"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->pcs_declarations, _S("}")); strings__Builder_writeln(&g->pcs_declarations, _S("")); strings__Builder_writeln(&g->pcs_declarations, _S("void vprint_profile_stats_on_signal(int sig){")); strings__Builder_writeln(&g->pcs_declarations, _S("\texit(130);")); strings__Builder_writeln(&g->pcs_declarations, _S("}")); strings__Builder_writeln(&g->pcs_declarations, _S("")); } VV_LOC int v__gen__c__Gen_reflection_string(v__gen__c__Gen* g, string str) { int* _t3 = (int*)(map_get_check((g->reflection_strings), &(string[]){str})); _option_int _t2 = {0}; if (_t3) { *((int*)&_t2.data) = *((int*)_t3); } else { _t2.state = 2; _t2.err = _v_error(_S("map key does not exist")); } ; if (_t2.state != 0) { IError err = _t2.err; map_set(g->reflection_strings, &(string[]){str}, &(int[]) { g->reflection_strings->len }); *(int*) _t2.data = (int)(g->reflection_strings->len - 1); } return (*(int*)_t2.data); } inline VV_LOC void v__gen__c__Gen_gen_reflection_strings(v__gen__c__Gen* g) { Map_string_int* _t1 = g->reflection_strings; int _t3 = _t1->key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1->key_values.len - _t3; _t3 = _t1->key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1->key_values, _t2)) {continue;} string str = *(string*)DenseArray_key(&_t1->key_values, _t2); str = string_clone(str); int idx = (*(int*)DenseArray_value(&_t1->key_values, _t2)); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("add_string(_S(\""), 0xfe10, {.d_s = str}}, {_S("\"), "), 0xfe07, {.d_i32 = idx}}, {_S(");"), 0, { .d_c = 0 }}}))); } } inline VV_LOC string v__gen__c__Gen_gen_empty_array(v__gen__c__Gen* g, string type_name) { return str_intp(2, _MOV((StrIntpData[]){{_S("__new_array_with_default(0, 0, sizeof("), 0xfe10, {.d_s = type_name}}, {_S("), 0)"), 0, { .d_c = 0 }}})); } inline VV_LOC string v__gen__c__Gen_gen_functionarg_array(v__gen__c__Gen* g, string type_name, v__ast__Fn node) { if (node.params.len == 0) { return v__gen__c__Gen_gen_empty_array(g, type_name); } string out = str_intp(4, _MOV((StrIntpData[]){{_S("new_array_from_c_array("), 0xfe07, {.d_i32 = node.params.len}}, {_S(","), 0xfe07, {.d_i32 = node.params.len}}, {_S(",sizeof("), 0xfe10, {.d_s = type_name}}, {_S("),"), 0, { .d_c = 0 }}})); out = string__plus(out, str_intp(3, _MOV((StrIntpData[]){{_S("_MOV(("), 0xfe10, {.d_s = type_name}}, {_S("["), 0xfe07, {.d_i32 = node.params.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); Array_string _t2 = {0}; Array_v__ast__Param _t2_orig = node.params; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Param it = ((v__ast__Param*) _t2_orig.data)[_t4]; string _t3 = str_intp(5, _MOV((StrIntpData[]){{_S("(("), 0xfe10, {.d_s = type_name}}, {_S("){.name=_S(\""), 0xfe10, {.d_s = it.name}}, {_S("\"),.typ="), 0xfe07, {.d_i32 = ((int)(it.typ))}}, {_S(",.is_mut="), 0xfe10, {.d_s = it.is_mut ? _S("true") : _S("false")}}, {_S("})"), 0, { .d_c = 0 }}})); array_push((array*)&_t2, &_t3); } out = string__plus(out, Array_string_join(_t2, _S(","))); out = string__plus(out, _S("}))")); return out; } inline VV_LOC string v__gen__c__Gen_gen_function_array(v__gen__c__Gen* g, Array_v__ast__Fn nodes) { string type_name = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Function"), 0, { .d_c = 0 }}})); if (nodes.len == 0) { return v__gen__c__Gen_gen_empty_array(g, type_name); } string out = str_intp(4, _MOV((StrIntpData[]){{_S("new_array_from_c_array("), 0xfe07, {.d_i32 = nodes.len}}, {_S(","), 0xfe07, {.d_i32 = nodes.len}}, {_S(",sizeof("), 0xfe10, {.d_s = type_name}}, {_S("),"), 0, { .d_c = 0 }}})); out = string__plus(out, str_intp(3, _MOV((StrIntpData[]){{_S("_MOV(("), 0xfe10, {.d_s = type_name}}, {_S("["), 0xfe07, {.d_i32 = nodes.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); Array_string _t2 = {0}; Array_v__ast__Fn _t2_orig = nodes; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Fn it = ((v__ast__Fn*) _t2_orig.data)[_t4]; string _t3 = v__gen__c__Gen_gen_reflection_fn(g, it); array_push((array*)&_t2, &_t3); } out = string__plus(out, Array_string_join(_t2, _S(","))); out = string__plus(out, _S("}))")); return out; } inline VV_LOC string v__gen__c__Gen_gen_reflection_fn(v__gen__c__Gen* g, v__ast__Fn node) { string arg_str = str_intp(2, _MOV((StrIntpData[]){{_S("(("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Function){"), 0, { .d_c = 0 }}})); string v_name = string_all_after_last(node.name, _S(".")); arg_str = string__plus(arg_str, str_intp(2, _MOV((StrIntpData[]){{_S(".mod_name=_S(\""), 0xfe10, {.d_s = node.mod}}, {_S("\"),"), 0, { .d_c = 0 }}}))); arg_str = string__plus(arg_str, str_intp(2, _MOV((StrIntpData[]){{_S(".name=_S(\""), 0xfe10, {.d_s = v_name}}, {_S("\"),"), 0, { .d_c = 0 }}}))); arg_str = string__plus(arg_str, str_intp(2, _MOV((StrIntpData[]){{_S(".args="), 0xfe10, {.d_s = v__gen__c__Gen_gen_functionarg_array(g, _S("v__reflection__FunctionArg"), node)}}, {_S(","), 0, { .d_c = 0 }}}))); arg_str = string__plus(arg_str, str_intp(2, _MOV((StrIntpData[]){{_S(".file_idx="), 0xfe07, {.d_i32 = v__gen__c__Gen_reflection_string(g, v__util__cescaped_path(node.file))}}, {_S(","), 0, { .d_c = 0 }}}))); arg_str = string__plus(arg_str, str_intp(2, _MOV((StrIntpData[]){{_S(".line_start="), 0xfe07, {.d_i32 = node.pos.line_nr}}, {_S(","), 0, { .d_c = 0 }}}))); arg_str = string__plus(arg_str, str_intp(2, _MOV((StrIntpData[]){{_S(".line_end="), 0xfe07, {.d_i32 = node.pos.last_line}}, {_S(","), 0, { .d_c = 0 }}}))); arg_str = string__plus(arg_str, str_intp(2, _MOV((StrIntpData[]){{_S(".is_variadic="), 0xfe10, {.d_s = node.is_variadic ? _S("true") : _S("false")}}, {_S(","), 0, { .d_c = 0 }}}))); arg_str = string__plus(arg_str, str_intp(2, _MOV((StrIntpData[]){{_S(".return_typ="), 0xfe07, {.d_i32 = ((int)(node.return_type))}}, {_S(","), 0, { .d_c = 0 }}}))); arg_str = string__plus(arg_str, str_intp(2, _MOV((StrIntpData[]){{_S(".receiver_typ="), 0xfe07, {.d_i32 = ((int)(node.receiver_type))}}, {_S(","), 0, { .d_c = 0 }}}))); arg_str = string__plus(arg_str, str_intp(2, _MOV((StrIntpData[]){{_S(".is_pub="), 0xfe10, {.d_s = node.is_pub ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); arg_str = string__plus(arg_str, _S("})")); return arg_str; } inline VV_LOC string v__gen__c__Gen_gen_reflection_sym(v__gen__c__Gen* g, v__ast__TypeSymbol tsym) { string kind_name = v__ast__Kind_str(tsym.kind); string name = string_all_after_last(tsym.name, _S(".")); string info = v__gen__c__Gen_gen_reflection_sym_info(g, tsym); string methods = v__gen__c__Gen_gen_function_array(g, tsym.methods); return str_intp(12, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeSymbol){.name=_S(\""), 0xfe10, {.d_s = name}}, {_S("\"),.mod=_S(\""), 0xfe10, {.d_s = tsym.mod}}, {_S("\"),.idx="), 0xfe07, {.d_i32 = tsym.idx}}, {_S(",.parent_idx="), 0xfe07, {.d_i32 = tsym.parent_idx}}, {_S(",.language="), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("VLanguage__"), 0xfe10, {.d_s = v__ast__Language_str(tsym.language)}}, {_S(",.kind="), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("VKind__"), 0xfe10, {.d_s = kind_name}}, {_S(",.info="), 0xfe10, {.d_s = info}}, {_S(",.methods="), 0xfe10, {.d_s = methods}}, {_S("}"), 0, { .d_c = 0 }}})); } inline VV_LOC string v__gen__c__Gen_gen_attrs_array(v__gen__c__Gen* g, Array_v__ast__Attr attrs) { if (attrs.len == 0) { return v__gen__c__Gen_gen_empty_array(g, _S("string")); } string out = str_intp(3, _MOV((StrIntpData[]){{_S("new_array_from_c_array("), 0xfe07, {.d_i32 = attrs.len}}, {_S(","), 0xfe07, {.d_i32 = attrs.len}}, {_S(",sizeof(string),"), 0, { .d_c = 0 }}})); out = string__plus(out, str_intp(2, _MOV((StrIntpData[]){{_S("_MOV((string["), 0xfe07, {.d_i32 = attrs.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); Array_string _t2 = {0}; Array_v__ast__Attr _t2_orig = attrs; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__Attr it = ((v__ast__Attr*) _t2_orig.data)[_t4]; string _t3 = (it.has_arg ? (str_intp(3, _MOV((StrIntpData[]){{_S("_S(\""), 0xfe10, {.d_s = it.name}}, {_S("="), 0xfe10, {.d_s = v__gen__c__escape_quotes(it.arg)}}, {_S("\")"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("_S(\""), 0xfe10, {.d_s = it.name}}, {_S("\")"), 0, { .d_c = 0 }}})))); array_push((array*)&_t2, &_t3); } out = string__plus(out, Array_string_join(_t2, _S(","))); out = string__plus(out, _S("}))")); return out; } inline VV_LOC string v__gen__c__Gen_gen_fields_array(v__gen__c__Gen* g, Array_v__ast__StructField fields) { if (fields.len == 0) { return v__gen__c__Gen_gen_empty_array(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("StructField"), 0, { .d_c = 0 }}}))); } string out = str_intp(4, _MOV((StrIntpData[]){{_S("new_array_from_c_array("), 0xfe07, {.d_i32 = fields.len}}, {_S(","), 0xfe07, {.d_i32 = fields.len}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("StructField),"), 0, { .d_c = 0 }}})); out = string__plus(out, str_intp(3, _MOV((StrIntpData[]){{_S("_MOV(("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("StructField["), 0xfe07, {.d_i32 = fields.len}}, {_S("]){"), 0, { .d_c = 0 }}}))); Array_string _t2 = {0}; Array_v__ast__StructField _t2_orig = fields; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__StructField it = ((v__ast__StructField*) _t2_orig.data)[_t4]; string _t3 = str_intp(7, _MOV((StrIntpData[]){{_S("(("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("StructField){.name=_S(\""), 0xfe10, {.d_s = it.name}}, {_S("\"),.typ="), 0xfe07, {.d_i32 = ((int)(it.typ))}}, {_S(",.attrs="), 0xfe10, {.d_s = v__gen__c__Gen_gen_attrs_array(g, it.attrs)}}, {_S(",.is_pub="), 0xfe10, {.d_s = it.is_pub ? _S("true") : _S("false")}}, {_S(",.is_mut="), 0xfe10, {.d_s = it.is_mut ? _S("true") : _S("false")}}, {_S("})"), 0, { .d_c = 0 }}})); array_push((array*)&_t2, &_t3); } out = string__plus(out, Array_string_join(_t2, _S(","))); out = string__plus(out, _S("}))")); return out; } inline VV_LOC string v__gen__c__Gen_gen_type_array(v__gen__c__Gen* g, Array_v__ast__Type types) { if (types.len == 0) { return v__gen__c__Gen_gen_empty_array(g, _const_v__ast__int_type_name); } Array_string _t3 = {0}; Array_v__ast__Type _t3_orig = types; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(string)); for (int _t5 = 0; _t5 < _t3_len; ++_t5) { v__ast__Type it = ((v__ast__Type*) _t3_orig.data)[_t5]; string _t4 = int_str(((int)(it))); array_push((array*)&_t3, &_t4); } return str_intp(6, _MOV((StrIntpData[]){{_S("new_array_from_c_array("), 0xfe07, {.d_i32 = types.len}}, {_S(","), 0xfe07, {.d_i32 = types.len}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__ast__int_type_name}}, {_S("),_MOV((int["), 0xfe07, {.d_i32 = types.len}}, {_S("]){"), 0xfe10, {.d_s = Array_string_join( _t3, _S(","))}}, {_S("}))"), 0, { .d_c = 0 }}})); } inline VV_LOC string v__gen__c__Gen_gen_string_array(v__gen__c__Gen* g, Array_string strs) { if (strs.len == 0) { return v__gen__c__Gen_gen_empty_array(g, _S("string")); } Array_string _t2 = {0}; Array_string _t2_orig = strs; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { string it = ((string*) _t2_orig.data)[_t4]; string _t3 = str_intp(2, _MOV((StrIntpData[]){{_S("_S(\""), 0xfe10, {.d_s = it}}, {_S("\")"), 0, { .d_c = 0 }}})); array_push((array*)&_t2, &_t3); } string items = Array_string_join(_t2, _S(",")); return str_intp(5, _MOV((StrIntpData[]){{_S("new_array_from_c_array("), 0xfe07, {.d_i32 = strs.len}}, {_S(","), 0xfe07, {.d_i32 = strs.len}}, {_S(",sizeof(string),_MOV((string["), 0xfe07, {.d_i32 = strs.len}}, {_S("]){"), 0xfe10, {.d_s = items}}, {_S("}))"), 0, { .d_c = 0 }}})); } inline VV_LOC string v__gen__c__Gen_gen_reflection_sym_info(v__gen__c__Gen* g, v__ast__TypeSymbol tsym) { switch (tsym.kind) { case v__ast__Kind__array: { v__ast__Array info = *(v__ast__Array*)__as_cast((tsym.info)._v__ast__Array,(tsym.info)._typ, 513); string s = str_intp(5, _MOV((StrIntpData[]){{_S("ADDR("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Array,((("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Array){.nr_dims="), 0xfe07, {.d_i32 = info.nr_dims}}, {_S(",.elem_type="), 0xfe07, {.d_i32 = ((int)(info.elem_type))}}, {_S("})))"), 0, { .d_c = 0 }}})); return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeInfo){._"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Array = memdup("), 0xfe10, {.d_s = s}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Array)),._typ="), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("v.reflection.Array"))}}, {_S("}"), 0, { .d_c = 0 }}})); } case v__ast__Kind__array_fixed: { v__ast__ArrayFixed info = *(v__ast__ArrayFixed*)__as_cast((tsym.info)._v__ast__ArrayFixed,(tsym.info)._typ, 549); string s = str_intp(5, _MOV((StrIntpData[]){{_S("ADDR("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("ArrayFixed,((("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("ArrayFixed){.size="), 0xfe07, {.d_i32 = info.size}}, {_S(",.elem_type="), 0xfe07, {.d_i32 = ((int)(info.elem_type))}}, {_S("})))"), 0, { .d_c = 0 }}})); return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeInfo){._"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("ArrayFixed=memdup("), 0xfe10, {.d_s = s}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("ArrayFixed)),._typ="), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("v.reflection.ArrayFixed"))}}, {_S("}"), 0, { .d_c = 0 }}})); } case v__ast__Kind__map: { v__ast__Map info = *(v__ast__Map*)__as_cast((tsym.info)._v__ast__Map,(tsym.info)._typ, 514); string s = str_intp(5, _MOV((StrIntpData[]){{_S("ADDR("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Map,((("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Map){.key_type="), 0xfe07, {.d_i32 = ((int)(info.key_type))}}, {_S(",.value_type="), 0xfe07, {.d_i32 = ((int)(info.value_type))}}, {_S("})))"), 0, { .d_c = 0 }}})); return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeInfo){._"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Map=memdup("), 0xfe10, {.d_s = s}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Map)),._typ="), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("v.reflection.Map"))}}, {_S("}"), 0, { .d_c = 0 }}})); } case v__ast__Kind__sum_type: { v__ast__SumType info = *(v__ast__SumType*)__as_cast((tsym.info)._v__ast__SumType,(tsym.info)._typ, 544); string s = str_intp(5, _MOV((StrIntpData[]){{_S("ADDR("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("SumType,((("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("SumType){.parent_idx="), 0xfe07, {.d_i32 = v__ast__Type_idx(info.parent_type)}}, {_S(",.variants="), 0xfe10, {.d_s = v__gen__c__Gen_gen_type_array(g, info.variants)}}, {_S("})))"), 0, { .d_c = 0 }}})); return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeInfo){._"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("SumType=memdup("), 0xfe10, {.d_s = s}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("SumType)),._typ="), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("v.reflection.SumType"))}}, {_S("}"), 0, { .d_c = 0 }}})); } case v__ast__Kind__struct: { v__ast__Struct info = *(v__ast__Struct*)__as_cast((tsym.info)._v__ast__Struct,(tsym.info)._typ, 518); string attrs = v__gen__c__Gen_gen_attrs_array(g, info.attrs); string fields = v__gen__c__Gen_gen_fields_array(g, info.fields); string s = str_intp(6, _MOV((StrIntpData[]){{_S("ADDR("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Struct,((("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Struct){.parent_idx="), 0xfe07, {.d_i32 = v__ast__Type_idx((*(v__ast__Struct*)__as_cast((tsym.info)._v__ast__Struct,(tsym.info)._typ, 518)).parent_type)}}, {_S(",.attrs="), 0xfe10, {.d_s = attrs}}, {_S(",.fields="), 0xfe10, {.d_s = fields}}, {_S("})))"), 0, { .d_c = 0 }}})); return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeInfo){._"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Struct=memdup("), 0xfe10, {.d_s = s}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Struct)),._typ="), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("v.reflection.Struct"))}}, {_S("}"), 0, { .d_c = 0 }}})); } case v__ast__Kind__enum: { v__ast__Enum info = *(v__ast__Enum*)__as_cast((tsym.info)._v__ast__Enum,(tsym.info)._typ, 548); string vals = v__gen__c__Gen_gen_string_array(g, info.vals); string s = str_intp(5, _MOV((StrIntpData[]){{_S("ADDR("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Enum,((("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Enum){.vals="), 0xfe10, {.d_s = vals}}, {_S(",.is_flag="), 0xfe10, {.d_s = info.is_flag ? _S("true") : _S("false")}}, {_S("})))"), 0, { .d_c = 0 }}})); return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeInfo){._"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Enum=memdup("), 0xfe10, {.d_s = s}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Enum)),._typ="), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("v.reflection.Enum"))}}, {_S("}"), 0, { .d_c = 0 }}})); } case v__ast__Kind__function: { v__ast__FnType info = *(v__ast__FnType*)__as_cast((tsym.info)._v__ast__FnType,(tsym.info)._typ, 553); string s = str_intp(3, _MOV((StrIntpData[]){{_S("ADDR("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Function,"), 0xfe10, {.d_s = v__gen__c__Gen_gen_reflection_fn(g, info.func)}}, {_S(")"), 0, { .d_c = 0 }}})); return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeInfo){._"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Function=memdup("), 0xfe10, {.d_s = s}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Function)),._typ="), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("v.reflection.Function"))}}, {_S("}"), 0, { .d_c = 0 }}})); } case v__ast__Kind__interface: { string name = string_all_after_last(tsym.name, _S(".")); v__ast__Interface info = *(v__ast__Interface*)__as_cast((tsym.info)._v__ast__Interface,(tsym.info)._typ, 542); string methods = v__gen__c__Gen_gen_function_array(g, info.methods); string fields = v__gen__c__Gen_gen_fields_array(g, info.fields); string s = str_intp(7, _MOV((StrIntpData[]){{_S("ADDR("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Interface,((("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Interface){.name=_S(\""), 0xfe10, {.d_s = name}}, {_S("\"),.methods="), 0xfe10, {.d_s = methods}}, {_S(",.fields="), 0xfe10, {.d_s = fields}}, {_S(",.is_generic="), 0xfe10, {.d_s = info.is_generic ? _S("true") : _S("false")}}, {_S("})))"), 0, { .d_c = 0 }}})); return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeInfo){._"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Interface=memdup("), 0xfe10, {.d_s = s}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Interface)),._typ="), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("v.reflection.Interface"))}}, {_S("}"), 0, { .d_c = 0 }}})); } case v__ast__Kind__alias: { v__ast__Alias info = *(v__ast__Alias*)__as_cast((tsym.info)._v__ast__Alias,(tsym.info)._typ, 539); string s = str_intp(6, _MOV((StrIntpData[]){{_S("ADDR("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Alias,((("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Alias){.parent_idx="), 0xfe07, {.d_i32 = v__ast__Type_idx(info.parent_type)}}, {_S(",.language="), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("VLanguage__"), 0xfe10, {.d_s = v__ast__Language_str(info.language)}}, {_S("})))"), 0, { .d_c = 0 }}})); return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeInfo){._"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Alias=memdup("), 0xfe10, {.d_s = s}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Alias)),._typ="), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("v.reflection.Alias"))}}, {_S("}"), 0, { .d_c = 0 }}})); } case v__ast__Kind__multi_return: { v__ast__MultiReturn info = *(v__ast__MultiReturn*)__as_cast((tsym.info)._v__ast__MultiReturn,(tsym.info)._typ, 552); string s = str_intp(4, _MOV((StrIntpData[]){{_S("ADDR("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("MultiReturn,((("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("MultiReturn){.types="), 0xfe10, {.d_s = v__gen__c__Gen_gen_type_array(g, info.types)}}, {_S("})))"), 0, { .d_c = 0 }}})); return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeInfo){._"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("MultiReturn=memdup("), 0xfe10, {.d_s = s}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("MultiReturn)),._typ="), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("v.reflection.MultiReturn"))}}, {_S("}"), 0, { .d_c = 0 }}})); } case v__ast__Kind__placeholder: case v__ast__Kind__void: case v__ast__Kind__voidptr: case v__ast__Kind__byteptr: case v__ast__Kind__charptr: case v__ast__Kind__i8: case v__ast__Kind__i16: case v__ast__Kind__i32: case v__ast__Kind__int: case v__ast__Kind__i64: case v__ast__Kind__isize: case v__ast__Kind__u8: case v__ast__Kind__u16: case v__ast__Kind__u32: case v__ast__Kind__u64: case v__ast__Kind__usize: case v__ast__Kind__f32: case v__ast__Kind__f64: case v__ast__Kind__char: case v__ast__Kind__rune: case v__ast__Kind__bool: case v__ast__Kind__none: case v__ast__Kind__string: case v__ast__Kind__chan: case v__ast__Kind__any: case v__ast__Kind__generic_inst: case v__ast__Kind__float_literal: case v__ast__Kind__int_literal: case v__ast__Kind__aggregate: case v__ast__Kind__thread: default: { { string s = str_intp(4, _MOV((StrIntpData[]){{_S("ADDR("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("None,((("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("None){.parent_idx="), 0xfe07, {.d_i32 = tsym.parent_idx}}, {_S(",})))"), 0, { .d_c = 0 }}})); return str_intp(6, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("TypeInfo){._"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("None=memdup("), 0xfe10, {.d_s = s}}, {_S(",sizeof("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("None)),._typ="), 0xfe07, {.d_i32 = v__ast__Table_find_type_idx(g->table, _S("v.reflection.None"))}}, {_S("}"), 0, { .d_c = 0 }}})); } } } return (string){.str=(byteptr)"", .is_lit=1}; } VV_LOC void v__gen__c__Gen_gen_reflection_data(v__gen__c__Gen* g) { for (int _t1 = 0; _t1 < g->table->modules.len; ++_t1) { string mod_name = ((string*)g->table->modules.data)[_t1]; v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("add_module(_S(\""), 0xfe10, {.d_s = mod_name}}, {_S("\"));"), 0, { .d_c = 0 }}}))); } for (int _t2 = 0; _t2 < g->table->type_symbols.len; ++_t2) { v__ast__TypeSymbol* tsym = ((v__ast__TypeSymbol**)g->table->type_symbols.data)[_t2]; string sym = v__gen__c__Gen_gen_reflection_sym(g, *tsym); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("add_type_symbol("), 0xfe10, {.d_s = sym}}, {_S(");"), 0, { .d_c = 0 }}}))); } Map_string_int _t3 = g->table->type_idxs; int _t5 = _t3.key_values.len; for (int _t4 = 0; _t4 < _t5; ++_t4 ) { int _t6 = _t3.key_values.len - _t5; _t5 = _t3.key_values.len; if (_t6 < 0) { _t4 = -1; continue; } if (!DenseArray_has_index(&_t3.key_values, _t4)) {continue;} string full_name = *(string*)DenseArray_key(&_t3.key_values, _t4); full_name = string_clone(full_name); int idx = (*(int*)DenseArray_value(&_t3.key_values, _t4)); string name = string_all_after_last(full_name, _S(".")); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("add_type(("), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("Type){.name=_S(\""), 0xfe10, {.d_s = name}}, {_S("\"),.idx="), 0xfe07, {.d_i32 = idx}}, {_S("});"), 0, { .d_c = 0 }}}))); } Map_string_v__ast__Fn _t7 = g->table->fns; int _t9 = _t7.key_values.len; for (int _t8 = 0; _t8 < _t9; ++_t8 ) { int _t10 = _t7.key_values.len - _t9; _t9 = _t7.key_values.len; if (_t10 < 0) { _t8 = -1; continue; } if (!DenseArray_has_index(&_t7.key_values, _t8)) {continue;} v__ast__Fn fn_ = (*(v__ast__Fn*)DenseArray_value(&_t7.key_values, _t8)); if (fn_.no_body || fn_.is_method || fn_.language != v__ast__Language__v) { continue; } string func = v__gen__c__Gen_gen_reflection_fn(g, fn_); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = _const_v__gen__c__cprefix}}, {_S("add_func("), 0xfe10, {.d_s = func}}, {_S(");"), 0, { .d_c = 0 }}}))); } v__gen__c__Gen_gen_reflection_strings(g); } VV_LOC void v__gen__c__Gen_spawn_and_go_expr(v__gen__c__Gen* g, v__ast__SpawnExpr node, v__gen__c__SpawnGoMode mode) { if (node.call_expr.should_be_skipped) { return; } bool is_spawn = mode == v__gen__c__SpawnGoMode__spawn_; bool is_go = mode == v__gen__c__SpawnGoMode__go_; if (is_spawn) { v__gen__c__Gen_writeln(g, _S("/*spawn (thread) */")); } else { v__gen__c__Gen_writeln(g, _S("/*go (coroutine) */")); } string line = v__gen__c__Gen_go_before_last_stmt(g); string handle = _S(""); string tmp = v__gen__c__Gen_new_tmp_var(g); v__ast__CallExpr expr = node.call_expr; string name = expr.name; bool use_tmp_fn_var = false; string tmp_fn = v__gen__c__Gen_new_tmp_var(g); if (expr.is_fn_var) { name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = name}}, {_S("_"), 0xfe07, {.d_i32 = node.pos.pos}}, {_SLIT0, 0, { .d_c = 0 }}})); } if (expr.concrete_types.len > 0) { name = v__gen__c__Gen_generic_fn_name(g, expr.concrete_types, name); } else if (expr.is_fn_var && v__ast__Type_has_flag(expr.fn_var_type, v__ast__TypeFlag__generic)) { v__ast__Type fn_var_type = v__gen__c__Gen_unwrap_generic(g, expr.fn_var_type); name = v__gen__c__Gen_styp(g, fn_var_type); } if (expr.is_method) { v__ast__TypeSymbol* receiver_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, expr.receiver_type)); name = string__plus(string__plus(receiver_sym->cname, _S("_")), name); } else if ((expr.left)._typ == 336 /* v.ast.AnonFn */) { if ((*expr.left._v__ast__AnonFn).inherited_vars.len > 0) { Array_v__ast__Type _t1 = {0}; Array_v__ast__Param _t1_orig = (*expr.left._v__ast__AnonFn).decl.params; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Param it = ((v__ast__Param*) _t1_orig.data)[_t3]; v__ast__Type _t2 = it.typ; array_push((array*)&_t1, &_t2); } string fn_var = v__gen__c__Gen_fn_var_signature(g, (*expr.left._v__ast__AnonFn).decl.return_type,_t1, tmp_fn); { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, fn_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_gen_anon_fn(g, (voidptr)&(*expr.left._v__ast__AnonFn)); v__gen__c__Gen_writeln(g, _S(";")); use_tmp_fn_var = true; Array_v__ast__Type _t4 = {0}; Array_v__ast__Param _t4_orig = (*expr.left._v__ast__AnonFn).decl.params; int _t4_len = _t4_orig.len; _t4 = __new_array(0, _t4_len, sizeof(v__ast__Type)); for (int _t6 = 0; _t6 < _t4_len; ++_t6) { v__ast__Param it = ((v__ast__Param*) _t4_orig.data)[_t6]; v__ast__Type _t5 = it.typ; array_push((array*)&_t4, &_t5); } name = v__gen__c__Gen_anon_fn_cname(g, (*expr.left._v__ast__AnonFn).decl.return_type,_t4); } else { v__gen__c__Gen_gen_anon_fn_decl(g, (voidptr)&(*expr.left._v__ast__AnonFn)); name = (*expr.left._v__ast__AnonFn).decl.name; } } else if ((expr.left)._typ == 361 /* v.ast.IndexExpr */) { if (expr.is_fn_var) { v__ast__TypeSymbol* fn_sym = v__ast__Table_sym(g->table, expr.fn_var_type); v__ast__Fn func = (*(v__ast__FnType*)__as_cast((fn_sym->info)._v__ast__FnType,(fn_sym->info)._typ, 553)).func; Array_v__ast__Type _t7 = {0}; Array_v__ast__Param _t7_orig = func.params; int _t7_len = _t7_orig.len; _t7 = __new_array(0, _t7_len, sizeof(v__ast__Type)); for (int _t9 = 0; _t9 < _t7_len; ++_t9) { v__ast__Param it = ((v__ast__Param*) _t7_orig.data)[_t9]; v__ast__Type _t8 = it.typ; array_push((array*)&_t7, &_t8); } string fn_var = v__gen__c__Gen_fn_var_signature(g, func.return_type,_t7, tmp_fn); { v__gen__c__Gen_write(g, _S("\t")); v__gen__c__Gen_write(g, fn_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, expr.left); v__gen__c__Gen_writeln(g, _S(";")); name = fn_sym->cname; use_tmp_fn_var = true; } } name = v__util__no_dots(name); g->empty_line = true; v__gen__c__Gen_writeln(g, _S("// start go")); string wrapper_struct_name = string__plus(_S("thread_arg_"), name); string wrapper_fn_name = string__plus(name, _S("_thread_wrapper")); string arg_tmp_var = string__plus(_S("arg_"), tmp); if (is_spawn) { v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = wrapper_struct_name}}, {_S(" *"), 0xfe10, {.d_s = arg_tmp_var}}, {_S(" = ("), 0xfe10, {.d_s = wrapper_struct_name}}, {_S(" *) _v_malloc(sizeof(thread_arg_"), 0xfe10, {.d_s = name}}, {_S("));"), 0, { .d_c = 0 }}}))); } else if (is_go) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = wrapper_struct_name}}, {_S(" "), 0xfe10, {.d_s = arg_tmp_var}}, {_S(";"), 0, { .d_c = 0 }}}))); } string dot = (is_spawn ? (_S("->")) : (_S("."))); string fn_name = (use_tmp_fn_var ? (tmp_fn) : expr.is_fn_var ? (expr.name) : (name)); if (!(expr.is_method && (v__ast__Table_sym(g->table, expr.receiver_type)->kind == v__ast__Kind__interface || (v__ast__Table_sym(g->table, expr.receiver_type)->kind == v__ast__Kind__struct && expr.is_field)))) { v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg_tmp_var}}, {_SLIT0, 0xfe10, {.d_s = dot}}, {_S("fn = "), 0xfe10, {.d_s = fn_name}}, {_S(";"), 0, { .d_c = 0 }}}))); } if (expr.is_method) { { v__gen__c__Gen_write(g, arg_tmp_var); v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("arg0 = ")); } if ((expr.left)._typ == 358 /* v.ast.Ident */ && v__ast__Type_is_ptr((*((*(v__ast__Ident*)__as_cast((expr.left)._v__ast__Ident,(expr.left)._typ, 358)).obj.typ))) && !v__ast__Type_is_ptr(node.call_expr.receiver_type)) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls((*((*expr.left._v__ast__Ident).obj.typ))))); } v__gen__c__Gen_expr(g, expr.left); v__gen__c__Gen_writeln(g, _S(";")); } for (int i = 0; i < expr.args.len; ++i) { v__ast__CallArg arg = ((v__ast__CallArg*)expr.args.data)[i]; { v__gen__c__Gen_write(g, arg_tmp_var); v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("arg")); v__gen__c__Gen_write_decimal(g, (int)(i + 1)); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, arg.expr); v__gen__c__Gen_writeln(g, _S(";")); } v__ast__Type call_ret_type = node.call_expr.return_type; string s_ret_typ = v__gen__c__Gen_styp(g, call_ret_type); if (g->pref->os == v__pref__OS__windows && call_ret_type != _const_v__ast__void_type) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = arg_tmp_var}}, {_S("->ret_ptr = (void *) _v_malloc(sizeof("), 0xfe10, {.d_s = s_ret_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); } string gohandle_name = v__gen__c__Gen_gen_gohandle_name(g, call_ret_type); if (is_spawn) { if (g->pref->os == v__pref__OS__windows) { string simple_handle = (node.is_expr && call_ret_type != _const_v__ast__void_type ? (str_intp(2, _MOV((StrIntpData[]){{_S("thread_handle_"), 0xfe10, {.d_s = tmp}}, {_SLIT0, 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S("thread_"), 0xfe10, {.d_s = tmp}}, {_SLIT0, 0, { .d_c = 0 }}})))); string stack_size = v__gen__c__Gen_get_cur_thread_stack_size(g, expr.name); v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("HANDLE "), 0xfe10, {.d_s = simple_handle}}, {_S(" = CreateThread(0, "), 0xfe10, {.d_s = stack_size}}, {_S(", (LPTHREAD_START_ROUTINE)"), 0xfe10, {.d_s = wrapper_fn_name}}, {_S(", "), 0xfe10, {.d_s = arg_tmp_var}}, {_S(", 0, 0); // fn: "), 0xfe10, {.d_s = expr.name}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("if (!"), 0xfe10, {.d_s = simple_handle}}, {_S(") panic_lasterr(tos3(\"`go "), 0xfe10, {.d_s = name}}, {_S("()`: \"));"), 0, { .d_c = 0 }}}))); if (node.is_expr && call_ret_type != _const_v__ast__void_type) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = gohandle_name}}, {_S(" thread_"), 0xfe10, {.d_s = tmp}}, {_S(" = {"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t.ret_ptr = "), 0xfe10, {.d_s = arg_tmp_var}}, {_S("->ret_ptr,"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln2(g, str_intp(2, _MOV((StrIntpData[]){{_S("\t.handle = thread_handle_"), 0xfe10, {.d_s = tmp}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("};")); } if (!node.is_expr) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("CloseHandle(thread_"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); } } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("pthread_t thread_"), 0xfe10, {.d_s = tmp}}, {_S(";"), 0, { .d_c = 0 }}}))); string sthread_attributes = _S("NULL"); if (g->pref->os != v__pref__OS__vinix) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("pthread_attr_t thread_"), 0xfe10, {.d_s = tmp}}, {_S("_attributes;"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("pthread_attr_init(&thread_"), 0xfe10, {.d_s = tmp}}, {_S("_attributes);"), 0, { .d_c = 0 }}}))); string size = v__gen__c__Gen_get_cur_thread_stack_size(g, expr.name); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("pthread_attr_setstacksize(&thread_"), 0xfe10, {.d_s = tmp}}, {_S("_attributes, "), 0xfe10, {.d_s = size}}, {_S("); // fn: "), 0xfe10, {.d_s = expr.name}}, {_SLIT0, 0, { .d_c = 0 }}}))); sthread_attributes = str_intp(2, _MOV((StrIntpData[]){{_S("&thread_"), 0xfe10, {.d_s = tmp}}, {_S("_attributes"), 0, { .d_c = 0 }}})); } v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_S("int "), 0xfe10, {.d_s = tmp}}, {_S("_thr_res = pthread_create(&thread_"), 0xfe10, {.d_s = tmp}}, {_S(", "), 0xfe10, {.d_s = sthread_attributes}}, {_S(", (void*)"), 0xfe10, {.d_s = wrapper_fn_name}}, {_S(", "), 0xfe10, {.d_s = arg_tmp_var}}, {_S(");"), 0, { .d_c = 0 }}}))); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("if ("), 0xfe10, {.d_s = tmp}}, {_S("_thr_res) panic_error_number(tos3(\"`go "), 0xfe10, {.d_s = name}}, {_S("()`: \"), "), 0xfe10, {.d_s = tmp}}, {_S("_thr_res);"), 0, { .d_c = 0 }}}))); if (!node.is_expr) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("pthread_detach(thread_"), 0xfe10, {.d_s = tmp}}, {_S(");"), 0, { .d_c = 0 }}}))); } } } else if (is_go) { if (_const_v__util__nr_jobs > 1) { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("photon_thread_create_and_migrate_to_work_pool((void*)"), 0xfe10, {.d_s = wrapper_fn_name}}, {_S(", &"), 0xfe10, {.d_s = arg_tmp_var}}, {_S(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_S("photon_thread_create((void*)"), 0xfe10, {.d_s = wrapper_fn_name}}, {_S(", &"), 0xfe10, {.d_s = arg_tmp_var}}, {_S(", 8 * 1024);"), 0, { .d_c = 0 }}}))); } } v__gen__c__Gen_writeln(g, _S("// end go")); if (node.is_expr) { handle = str_intp(2, _MOV((StrIntpData[]){{_S("thread_"), 0xfe10, {.d_s = tmp}}, {_SLIT0, 0, { .d_c = 0 }}})); v__gen__c__Gen_create_waiter_handler(g, call_ret_type, s_ret_typ, gohandle_name); } bool should_register = false; sync__RwMutex_lock(&g->threaded_fns->mtx); /*lock*/ { if (!(Array_string_contains(g->threaded_fns->val, name))) { array_push((array*)&g->threaded_fns->val, _MOV((string[]){ string_clone(name) })); should_register = true; } } sync__RwMutex_unlock(&g->threaded_fns->mtx);; if (should_register) { strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("\ntypedef struct "), 0xfe10, {.d_s = wrapper_struct_name}}, {_S(" {"), 0, { .d_c = 0 }}}))); string fn_var = _S(""); if (node.call_expr.is_fn_var) { v__ast__TypeSymbol* fn_sym = v__ast__Table_sym(g->table, node.call_expr.fn_var_type); v__ast__FnType info = *(v__ast__FnType*)__as_cast((fn_sym->info)._v__ast__FnType,(fn_sym->info)._typ, 553); Array_v__ast__Type _t11 = {0}; Array_v__ast__Param _t11_orig = info.func.params; int _t11_len = _t11_orig.len; _t11 = __new_array(0, _t11_len, sizeof(v__ast__Type)); for (int _t13 = 0; _t13 < _t11_len; ++_t13) { v__ast__Param it = ((v__ast__Param*) _t11_orig.data)[_t13]; v__ast__Type _t12 = it.typ; array_push((array*)&_t11, &_t12); } fn_var = v__gen__c__Gen_fn_var_signature(g, info.func.return_type,_t11, _S("fn")); } else if ((node.call_expr.left)._typ == 336 /* v.ast.AnonFn */) { v__ast__FnDecl f = (*node.call_expr.left._v__ast__AnonFn).decl; Array_v__ast__Type _t14 = {0}; Array_v__ast__Param _t14_orig = f.params; int _t14_len = _t14_orig.len; _t14 = __new_array(0, _t14_len, sizeof(v__ast__Type)); for (int _t16 = 0; _t16 < _t14_len; ++_t16) { v__ast__Param it = ((v__ast__Param*) _t14_orig.data)[_t16]; v__ast__Type _t15 = it.typ; array_push((array*)&_t14, &_t15); } fn_var = v__gen__c__Gen_fn_var_signature(g, f.return_type,_t14, _S("fn")); } else { if (node.call_expr.is_method) { v__ast__TypeSymbol* rec_sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, node.call_expr.receiver_type)); _option_v__ast__Fn _t17; if (_t17 = v__ast__TypeSymbol_find_method_with_generic_parent(rec_sym, node.call_expr.name), _t17.state == 0) { v__ast__Fn f = *(v__ast__Fn*)_t17.data; v__ast__Table* muttable = ((v__ast__Table*)(g->table)); _option_v__ast__Type _t18 = v__ast__Table_convert_generic_type(muttable, f.return_type, f.generic_names, node.call_expr.concrete_types); if (_t18.state != 0) { IError err = _t18.err; *(v__ast__Type*) _t18.data = f.return_type; } v__ast__Type return_type = (*(v__ast__Type*)_t18.data); Array_v__ast__Type _t19 = {0}; Array_v__ast__Param _t19_orig = f.params; int _t19_len = _t19_orig.len; _t19 = __new_array(0, _t19_len, sizeof(v__ast__Type)); for (int _t21 = 0; _t21 < _t19_len; ++_t21) { v__ast__Param it = ((v__ast__Param*) _t19_orig.data)[_t21]; v__ast__Type _t20 = it.typ; array_push((array*)&_t19, &_t20); } Array_v__ast__Type arg_types =_t19; Array_v__ast__Type _t22 = {0}; Array_v__ast__Type _t22_orig = arg_types; int _t22_len = _t22_orig.len; _t22 = __new_array(0, _t22_len, sizeof(v__ast__Type)); for (int _t24 = 0; _t24 < _t22_len; ++_t24) { v__ast__Type it = ((v__ast__Type*) _t22_orig.data)[_t24]; _option_v__ast__Type _t25 = v__ast__Table_convert_generic_type(muttable, it, f.generic_names, node.call_expr.concrete_types); if (_t25.state != 0) { IError err = _t25.err; *(v__ast__Type*) _t25.data = it; } v__ast__Type _t23 = (*(v__ast__Type*)_t25.data); array_push((array*)&_t22, &_t23); } arg_types =_t22; fn_var = v__gen__c__Gen_fn_var_signature(g, return_type, arg_types, _S("fn")); } } else { _option_v__ast__Fn _t26; if (_t26 = v__ast__Table_find_fn(g->table, node.call_expr.name), _t26.state == 0) { v__ast__Fn f = *(v__ast__Fn*)_t26.data; Array_v__ast__Type _t27 = {0}; Array_v__ast__Type _t27_orig = node.call_expr.concrete_types; int _t27_len = _t27_orig.len; _t27 = __new_array(0, _t27_len, sizeof(v__ast__Type)); for (int _t29 = 0; _t29 < _t27_len; ++_t29) { v__ast__Type it = ((v__ast__Type*) _t27_orig.data)[_t29]; v__ast__Type _t28 = v__gen__c__Gen_unwrap_generic(g, it); array_push((array*)&_t27, &_t28); } Array_v__ast__Type concrete_types =_t27; _option_v__ast__Type _t30 = v__ast__Table_convert_generic_type(g->table, f.return_type, f.generic_names, concrete_types); if (_t30.state != 0) { IError err = _t30.err; *(v__ast__Type*) _t30.data = f.return_type; } v__ast__Type return_type = (*(v__ast__Type*)_t30.data); Array_v__ast__Type _t31 = {0}; Array_v__ast__Param _t31_orig = f.params; int _t31_len = _t31_orig.len; _t31 = __new_array(0, _t31_len, sizeof(v__ast__Type)); for (int _t33 = 0; _t33 < _t31_len; ++_t33) { v__ast__Param it = ((v__ast__Param*) _t31_orig.data)[_t33]; v__ast__Type _t32 = it.typ; array_push((array*)&_t31, &_t32); } Array_v__ast__Type arg_types =_t31; Array_v__ast__Type _t34 = {0}; Array_v__ast__Type _t34_orig = arg_types; int _t34_len = _t34_orig.len; _t34 = __new_array(0, _t34_len, sizeof(v__ast__Type)); for (int _t36 = 0; _t36 < _t34_len; ++_t36) { v__ast__Type it = ((v__ast__Type*) _t34_orig.data)[_t36]; _option_v__ast__Type _t37 = v__ast__Table_convert_generic_type(g->table, it, f.generic_names, concrete_types); if (_t37.state != 0) { IError err = _t37.err; *(v__ast__Type*) _t37.data = it; } v__ast__Type _t35 = (*(v__ast__Type*)_t37.data); array_push((array*)&_t34, &_t35); } arg_types =_t34; for (int i = 0; i < arg_types.len; ++i) { v__ast__Type typ = ((v__ast__Type*)arg_types.data)[i]; v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(g->table, typ); for (;;) { if ((typ_sym->info)._typ == 513 /* v.ast.Array */) { typ_sym = v__ast__Table_sym(g->table, (*typ_sym->info._v__ast__Array).elem_type); } else { if ((typ_sym->info)._typ == 553 /* v.ast.FnType */) { array_set(&arg_types, i, &(v__ast__Type[]) { (*(v__ast__CallArg*)array_get(expr.args, i)).typ }); } break; } } } fn_var = v__gen__c__Gen_fn_var_signature(g, return_type, arg_types, _S("fn")); } } } if ((fn_var).len != 0) { strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = fn_var}}, {_S(";"), 0, { .d_c = 0 }}}))); } if (expr.is_method) { string styp = v__gen__c__Gen_styp(g, expr.receiver_type); strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S(" arg0;"), 0, { .d_c = 0 }}}))); } bool need_return_ptr = g->pref->os == v__pref__OS__windows && call_ret_type != _const_v__ast__void_type; for (int i = 0; i < expr.args.len; ++i) { v__ast__CallArg arg = ((v__ast__CallArg*)expr.args.data)[i]; v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(g->table, arg.typ); if ((arg_sym->info)._typ == 553 /* v.ast.FnType */) { Array_v__ast__Type _t38 = {0}; Array_v__ast__Param _t38_orig = (*arg_sym->info._v__ast__FnType).func.params; int _t38_len = _t38_orig.len; _t38 = __new_array(0, _t38_len, sizeof(v__ast__Type)); for (int _t40 = 0; _t40 < _t38_len; ++_t40) { v__ast__Param it = ((v__ast__Param*) _t38_orig.data)[_t40]; v__ast__Type _t39 = it.typ; array_push((array*)&_t38, &_t39); } string sig = v__gen__c__Gen_fn_var_signature(g, (*arg_sym->info._v__ast__FnType).func.return_type,_t38, str_intp(2, _MOV((StrIntpData[]){{_S("arg"), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_SLIT0, 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, string__plus(string__plus(_S("\t"), sig), _S(";"))); } else { string styp = v__gen__c__Gen_styp(g, arg.typ); strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = styp}}, {_S(" arg"), 0xfe07, {.d_i32 = (int)(i + 1)}}, {_S(";"), 0, { .d_c = 0 }}}))); } } if (need_return_ptr) { strings__Builder_writeln(&g->type_definitions, _S("\tvoid* ret_ptr;")); } strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("} "), 0xfe10, {.d_s = wrapper_struct_name}}, {_S(";"), 0, { .d_c = 0 }}}))); string thread_ret_type = (g->pref->os == v__pref__OS__windows ? (_S("u32")) : (_S("void*"))); strings__Builder_writeln(&g->waiter_fn_definitions, str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = g->static_non_parallel}}, {_SLIT0, 0xfe10, {.d_s = thread_ret_type}}, {_S(" "), 0xfe10, {.d_s = wrapper_fn_name}}, {_S("("), 0xfe10, {.d_s = wrapper_struct_name}}, {_S(" *arg);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->gowrappers, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = thread_ret_type}}, {_S(" "), 0xfe10, {.d_s = wrapper_fn_name}}, {_S("("), 0xfe10, {.d_s = wrapper_struct_name}}, {_S(" *arg) {"), 0, { .d_c = 0 }}}))); if (call_ret_type != _const_v__ast__void_type) { if (g->pref->os == v__pref__OS__windows) { { strings__Builder_write_string(&g->gowrappers, _S("\t*((")); strings__Builder_write_string(&g->gowrappers, s_ret_typ); strings__Builder_write_string(&g->gowrappers, _S("*)(arg->ret_ptr)) = ")); } } else { strings__Builder_writeln(&g->gowrappers, str_intp(4, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = s_ret_typ}}, {_S("* ret_ptr = ("), 0xfe10, {.d_s = s_ret_typ}}, {_S("*) _v_malloc(sizeof("), 0xfe10, {.d_s = s_ret_typ}}, {_S("));"), 0, { .d_c = 0 }}}))); #if defined(__TINYC__) && defined(__V_arm64) { strings__Builder_write_string(&g->gowrappers, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = s_ret_typ}}, {_S(" tcc_bug_tmp_var = "), 0, { .d_c = 0 }}}))); } #else { strings__Builder_write_string(&g->gowrappers, _S("\t*ret_ptr = ")); } #endif } } else { strings__Builder_write_string(&g->gowrappers, _S("\t")); } if (expr.is_method) { v__ast__Type unwrapped_rec_type = v__gen__c__Gen_unwrap_generic(g, expr.receiver_type); v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(g->table, unwrapped_rec_type); if (typ_sym->kind == v__ast__Kind__interface && v__ast__Interface_defines_method((*(v__ast__Interface*)__as_cast((typ_sym->info)._v__ast__Interface,(typ_sym->info)._typ, 542)), expr.name)) { string rec_cc_type = v__gen__c__Gen_cc_type(g, unwrapped_rec_type, false); string receiver_type_name = v__util__no_dots(rec_cc_type); strings__Builder_write_string2(&g->gowrappers, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__c_name(receiver_type_name)}}, {_S("_name_table["), 0, { .d_c = 0 }}})), _S("arg->arg0")); string dot_or_ptr = v__gen__c__Gen_dot_or_ptr(g, unwrapped_rec_type); string mname = v__gen__c__c_name(expr.name); strings__Builder_write_string2(&g->gowrappers, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = dot_or_ptr}}, {_S("_typ]._method_"), 0xfe10, {.d_s = mname}}, {_S("("), 0, { .d_c = 0 }}})), _S("arg->arg0")); { strings__Builder_write_string(&g->gowrappers, dot_or_ptr); strings__Builder_write_string(&g->gowrappers, _S("_object")); } } else if (typ_sym->kind == v__ast__Kind__struct && expr.is_field) { strings__Builder_write_string(&g->gowrappers, _S("arg->arg0")); string idot = (v__ast__Type_is_ptr(expr.left_type) ? (_S("->")) : (_S("."))); string mname = v__gen__c__c_name(expr.name); { strings__Builder_write_string(&g->gowrappers, idot); strings__Builder_write_string(&g->gowrappers, mname); strings__Builder_write_string(&g->gowrappers, _S("(")); } } else { strings__Builder_write_string2(&g->gowrappers, _S("arg->fn("), _S("arg->arg0")); } if (expr.args.len > 0 && (typ_sym->kind != v__ast__Kind__struct || !expr.is_field)) { strings__Builder_write_string(&g->gowrappers, _S(", ")); } } else { strings__Builder_write_string(&g->gowrappers, _S("arg->fn(")); } if (expr.args.len > 0) { bool has_cast = false; for (int i = 0; i < expr.args.len; ++i) { if (v__ast__Table_sym(g->table, (*(v__ast__Type*)array_get(expr.expected_arg_types, i)))->kind == v__ast__Kind__interface && v__ast__Table_sym(g->table, (*(v__ast__CallArg*)array_get(expr.args, i)).typ)->kind != v__ast__Kind__interface) { has_cast = true; break; } } if (has_cast) { int pos = g->out.len; v__gen__c__Gen_call_args(g, expr); string call_args_str = string_trim_space(strings__Builder_after(&g->out, pos)); v__gen__c__Gen_go_back(g, call_args_str.len); Array_string rep_group = __new_array_with_default(0, (int)(2 * expr.args.len), sizeof(string), 0); for (int i = 0; i < expr.args.len; ++i) { array_push((array*)&rep_group, _MOV((string[]){ v__gen__c__Gen_expr_string(g, (*(v__ast__CallArg*)array_get(expr.args, i)).expr) })); array_push((array*)&rep_group, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("arg->arg"), 0xfe07, {.d_i32 = (int_literal)(i + 1)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } if (string_starts_with(call_args_str, _S("I_"))) { strings__Builder_write_string(&g->gowrappers, string_all_before(call_args_str, _S("("))); strings__Builder_write_string(&g->gowrappers, _S("(")); strings__Builder_write_string(&g->gowrappers, string_replace_each(string_all_after(call_args_str, _S("(")), rep_group)); } else { call_args_str = string_replace_each(call_args_str, rep_group); strings__Builder_write_string(&g->gowrappers, call_args_str); } } else if ((fast_string_eq(expr.name, _S("print")) || fast_string_eq(expr.name, _S("println")) || fast_string_eq(expr.name, _S("eprint")) || fast_string_eq(expr.name, _S("eprintln")) || fast_string_eq(expr.name, _S("panic"))) && (*(v__ast__CallArg*)array_get(expr.args, 0)).typ != _const_v__ast__string_type) { int pos = g->out.len; v__gen__c__Gen_gen_expr_to_string(g, (*(v__ast__CallArg*)array_get(expr.args, 0)).expr, (*(v__ast__CallArg*)array_get(expr.args, 0)).typ); string call_args_str = strings__Builder_after(&g->out, pos); strings__Builder_go_back(&g->out, call_args_str.len); Array_string rep_group = __new_array_with_default(0, (int)(2 * expr.args.len), sizeof(string), 0); for (int i = 0; i < expr.args.len; ++i) { array_push((array*)&rep_group, _MOV((string[]){ v__gen__c__Gen_expr_string(g, (*(v__ast__CallArg*)array_get(expr.args, i)).expr) })); array_push((array*)&rep_group, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("arg->arg"), 0xfe07, {.d_i32 = (int_literal)(i + 1)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } call_args_str = string_replace_each(call_args_str, rep_group); strings__Builder_write_string(&g->gowrappers, call_args_str); } else { for (int i = 0; i < expr.args.len; ++i) { int expected_nr_muls = v__ast__Type_nr_muls((*(v__ast__Type*)array_get(expr.expected_arg_types, i))); int arg_nr_muls = v__ast__Type_nr_muls((*(v__ast__CallArg*)array_get(expr.args, i)).typ); if (arg_nr_muls > expected_nr_muls) { strings__Builder_write_string(&g->gowrappers, string_repeat(_S("*"), (int)(arg_nr_muls - expected_nr_muls))); } else if (arg_nr_muls < expected_nr_muls) { strings__Builder_write_string(&g->gowrappers, string_repeat(_S("&"), (int)(expected_nr_muls - arg_nr_muls))); } { strings__Builder_write_string(&g->gowrappers, _S("arg->arg")); strings__Builder_write_decimal(&g->gowrappers, (int_literal)(i + 1)); } if (i != (int)(expr.args.len - 1)) { strings__Builder_write_string(&g->gowrappers, _S(", ")); } } } } strings__Builder_writeln(&g->gowrappers, _S(");")); #if defined(__TINYC__) && defined(__V_arm64) { if (g->pref->os != v__pref__OS__windows && call_ret_type != _const_v__ast__void_type) { strings__Builder_writeln(&g->gowrappers, _S("\t*ret_ptr = tcc_bug_tmp_var;")); } } #endif if (is_spawn) { strings__Builder_writeln(&g->gowrappers, _S("\t_v_free(arg);")); } if (g->pref->os != v__pref__OS__windows && call_ret_type != _const_v__ast__void_type) { strings__Builder_writeln(&g->gowrappers, _S("\treturn ret_ptr;")); } else { strings__Builder_writeln(&g->gowrappers, _S("\treturn 0;")); } strings__Builder_writeln(&g->gowrappers, _S("}")); } if (node.is_expr) { g->empty_line = false; v__gen__c__Gen_write2(g, line, handle); } } inline VV_LOC string v__gen__c__Gen_get_cur_thread_stack_size(v__gen__c__Gen* g, string name) { v__ast__Fn* _t2 = (v__ast__Fn*)(map_get_check(ADDR(map, g->table->fns), &(string[]){name})); _option_v__ast__Fn _t1 = {0}; if (_t2) { *((v__ast__Fn*)&_t1.data) = *((v__ast__Fn*)_t2); } else { _t1.state = 2; _t1.err = _v_error(_S("map key does not exist")); } ; if (_t1.state != 0) { IError err = _t1.err; return str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = g->pref->thread_stack_size}}, {_SLIT0, 0, { .d_c = 0 }}})); } v__ast__Fn ast_fn = (*(v__ast__Fn*)_t1.data); Array_v__ast__Attr attrs = ast_fn.attrs; if (isnil((voidptr)&attrs)) { return str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = g->pref->thread_stack_size}}, {_SLIT0, 0, { .d_c = 0 }}})); } for (int _t5 = 0; _t5 < attrs.len; ++_t5) { v__ast__Attr attr = ((v__ast__Attr*)attrs.data)[_t5]; if (fast_string_eq(attr.name, _S("spawn_stack"))) { return attr.arg; } } return str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = g->pref->thread_stack_size}}, {_SLIT0, 0, { .d_c = 0 }}})); } VV_LOC string v__gen__c__Gen_gen_gohandle_name(v__gen__c__Gen* g, v__ast__Type typ) { string gohandle_name = _S(""); if (typ == _const_v__ast__void_type) { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { gohandle_name = _S("__v_thread_Option_void"); } else if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__result)) { gohandle_name = _S("__v_thread_Result_void"); } else { gohandle_name = _S("__v_thread"); } } else { string ret_styp = string_replace(v__gen__c__Gen_styp(g, v__gen__c__Gen_unwrap_generic(g, typ)), _S("*"), _S("_ptr")); gohandle_name = str_intp(2, _MOV((StrIntpData[]){{_S("__v_thread_"), 0xfe10, {.d_s = ret_styp}}, {_SLIT0, 0, { .d_c = 0 }}})); } return gohandle_name; } VV_LOC void v__gen__c__Gen_create_waiter_handler(v__gen__c__Gen* g, v__ast__Type call_ret_type, string s_ret_typ, string gohandle_name) { string waiter_fn_name = string__plus(gohandle_name, _S("_wait")); bool should_register = false; sync__RwMutex_lock(&g->waiter_fns->mtx); /*lock*/ { if (!(Array_string_contains(g->waiter_fns->val, waiter_fn_name))) { array_push((array*)&g->waiter_fns->val, _MOV((string[]){ string_clone(waiter_fn_name) })); should_register = true; } } sync__RwMutex_unlock(&g->waiter_fns->mtx);; if (!should_register) { return; } strings__Builder_writeln(&g->waiter_fn_definitions, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = s_ret_typ}}, {_S(" "), 0xfe10, {.d_s = waiter_fn_name}}, {_S("("), 0xfe10, {.d_s = gohandle_name}}, {_S(" thread);"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->gowrappers, str_intp(4, _MOV((StrIntpData[]){{_S("\n"), 0xfe10, {.d_s = s_ret_typ}}, {_S(" "), 0xfe10, {.d_s = waiter_fn_name}}, {_S("("), 0xfe10, {.d_s = gohandle_name}}, {_S(" thread) {"), 0, { .d_c = 0 }}}))); string c_ret_ptr_ptr = _S("NULL"); if (call_ret_type != _const_v__ast__void_type) { strings__Builder_writeln(&g->gowrappers, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = s_ret_typ}}, {_S("* ret_ptr;"), 0, { .d_c = 0 }}}))); c_ret_ptr_ptr = _S("&ret_ptr"); } if (g->pref->os == v__pref__OS__windows) { if (call_ret_type == _const_v__ast__void_type) { strings__Builder_writeln(&g->gowrappers, _S("\tu32 stat = WaitForSingleObject(thread, INFINITE);")); } else { strings__Builder_writeln(&g->gowrappers, _S("\tu32 stat = WaitForSingleObject(thread.handle, INFINITE);")); strings__Builder_writeln(&g->gowrappers, _S("\tret_ptr = thread.ret_ptr;")); } } else { strings__Builder_writeln(&g->gowrappers, _S("\tif ((unsigned long int)thread == 0) { _v_panic(_S(\"unable to join thread\")); }")); strings__Builder_writeln(&g->gowrappers, str_intp(2, _MOV((StrIntpData[]){{_S("\tint stat = pthread_join(thread, (void **)"), 0xfe10, {.d_s = c_ret_ptr_ptr}}, {_S(");"), 0, { .d_c = 0 }}}))); } strings__Builder_writeln(&g->gowrappers, _S("\tif (stat != 0) { _v_panic(_S(\"unable to join thread\")); }")); if (g->pref->os == v__pref__OS__windows) { if (call_ret_type == _const_v__ast__void_type) { strings__Builder_writeln(&g->gowrappers, _S("\tCloseHandle(thread);")); } else { strings__Builder_writeln(&g->gowrappers, _S("\tCloseHandle(thread.handle);")); } } if (call_ret_type != _const_v__ast__void_type) { strings__Builder_writeln(&g->gowrappers, str_intp(2, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = s_ret_typ}}, {_S(" ret = *ret_ptr;"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->gowrappers, _S("\t_v_free(ret_ptr);")); strings__Builder_writeln(&g->gowrappers, _S("\treturn ret;")); } strings__Builder_writeln(&g->gowrappers, _S("}")); } VV_LOC void v__gen__c__Gen_string_literal(v__gen__c__Gen* g, v__ast__StringLiteral node) { string escaped_val = v__gen__c__cescape_nonascii(v__util__smart_quote(node.val, node.is_raw)); if (node.language == v__ast__Language__c) { v__gen__c__Gen_write2(g, _S("\""), escaped_val); v__gen__c__Gen_write(g, _S("\"")); } else { v__gen__c__Gen_write2(g, _S("_S(\""), escaped_val); v__gen__c__Gen_write(g, _S("\")")); } } VV_LOC void v__gen__c__Gen_string_inter_literal_sb_optimized(v__gen__c__Gen* g, v__ast__CallExpr call_expr) { v__ast__StringInterLiteral node = *(v__ast__StringInterLiteral*)__as_cast(((*(v__ast__CallArg*)array_get(call_expr.args, 0)).expr)._v__ast__StringInterLiteral,((*(v__ast__CallArg*)array_get(call_expr.args, 0)).expr)._typ, 383); v__gen__c__Gen_writeln(g, _S("// sb inter opt")); bool is_nl = fast_string_eq(call_expr.name, _S("writeln")); for (int i = 0; i < node.vals.len; ++i) { string val = ((string*)node.vals.data)[i]; string escaped_val = v__gen__c__cescape_nonascii(v__util__smart_quote(val, false)); v__gen__c__Gen_write(g, _S("strings__Builder_write_string(&")); v__gen__c__Gen_expr(g, call_expr.left); v__gen__c__Gen_write2(g, _S(", _S(\""), escaped_val); v__gen__c__Gen_writeln(g, _S("\"));")); if (i >= node.exprs.len) { break; } if (is_nl && i == (int)(node.exprs.len - 1)) { v__gen__c__Gen_write(g, _S("strings__Builder_writeln(&")); } else { v__gen__c__Gen_write(g, _S("strings__Builder_write_string(&")); } v__gen__c__Gen_expr(g, call_expr.left); v__gen__c__Gen_write(g, _S(", ")); v__ast__Type typ = (*(v__ast__Type*)array_get(node.expr_types, i)); v__gen__c__Gen_write2(g, v__gen__c__Gen_styp(g, typ), _S("_str(")); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); if (sym->kind != v__ast__Kind__function) { v__gen__c__Gen_expr(g, (*(v__ast__Expr*)array_get(node.exprs, i))); } v__gen__c__Gen_writeln(g, _S("));")); } v__gen__c__Gen_writeln(g, _S("")); return; } VV_LOC void v__gen__c__Gen_gen_expr_to_string(v__gen__c__Gen* g, v__ast__Expr expr, v__ast__Type etype) { bool v__gen__c__Gen_gen_expr_to_string_defer_0 = false; bool old_inside_opt_or_res; bool v__gen__c__Gen_gen_expr_to_string_defer_1 = false; bool inside_interface_deref_old; bool v__gen__c__Gen_gen_expr_to_string_defer_2 = false; old_inside_opt_or_res = g->inside_opt_or_res; g->inside_opt_or_res = true; g->expected_fixed_arr = true; v__gen__c__Gen_gen_expr_to_string_defer_0 = true; bool is_shared = v__ast__Type_has_flag(etype, v__ast__TypeFlag__shared_f); v__ast__Type typ = etype; if (is_shared) { typ = v__ast__Type_set_nr_muls(v__ast__Type_clear_flag(typ, v__ast__TypeFlag__shared_f), 0); } bool is_ptr = v__ast__Type_is_ptr(typ); v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); if ((sym->info)._typ == 539 /* v.ast.Alias */ && !v__ast__TypeSymbol_has_method(sym, _S("str")) && !v__ast__Type_has_flag(etype, v__ast__TypeFlag__option)) { v__ast__TypeSymbol* parent_sym = v__ast__Table_sym(g->table, (*sym->info._v__ast__Alias).parent_type); if (v__ast__TypeSymbol_has_method(parent_sym, _S("str"))) { typ = (*sym->info._v__ast__Alias).parent_type; sym = parent_sym; } } multi_return_bool_bool_int mr_2298 = v__ast__TypeSymbol_str_method_info(sym); bool sym_has_str_method = mr_2298.arg0; bool str_method_expects_ptr = mr_2298.arg1; if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__variadic)) { string str_fn_name = v__gen__c__Gen_get_str_fn(g, typ); { v__gen__c__Gen_write(g, str_fn_name); v__gen__c__Gen_write(g, _S("(")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } else if (typ == _const_v__ast__string_type) { if (v__ast__Type_is_ptr(etype)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, expr); } else if (typ == _const_v__ast__bool_type) { v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(" ? _S(\"true\") : _S(\"false\")")); } else if (sym->kind == v__ast__Kind__none || typ == v__ast__Type_set_flag(_const_v__ast__void_type, v__ast__TypeFlag__option)) { if ((expr)._typ == 344 /* v.ast.CallExpr */) { string stmt_str = v__gen__c__Gen_go_before_last_stmt(g); v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write(g, stmt_str); } v__gen__c__Gen_write(g, _S("_S(\"\")")); } else if (sym->kind == v__ast__Kind__enum) { if ((expr)._typ != 355 /* v.ast.EnumVal */ || v__ast__TypeSymbol_has_method(sym, _S("str"))) { string str_fn_name = v__gen__c__Gen_get_str_fn(g, typ); { v__gen__c__Gen_write(g, str_fn_name); v__gen__c__Gen_write(g, _S("(")); } if (v__ast__Type_nr_muls(typ) > 0) { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(typ))); } if ((expr)._typ == 355 /* v.ast.EnumVal */) { v__gen__c__Gen_write2(g, sym->cname, _S("__")); } v__gen__c__Gen_enum_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_write(g, _S("_S(\"")); v__gen__c__Gen_enum_expr(g, expr); v__gen__c__Gen_write(g, _S("\")")); } } else if (sym_has_str_method || (sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__array_fixed || sym->kind == v__ast__Kind__map || sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__multi_return || sym->kind == v__ast__Kind__sum_type || sym->kind == v__ast__Kind__interface)) { bool unwrap_option = (expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).or_expr.kind == v__ast__OrKind__propagate_option; v__ast__Type exp_typ = (unwrap_option ? (v__ast__Type_clear_flag(typ, v__ast__TypeFlag__option)) : (typ)); bool is_dump_expr = (expr)._typ == 353 /* v.ast.DumpExpr */; bool is_var_mut = v__ast__Expr_is_auto_deref_var(expr); string str_fn_name = v__gen__c__Gen_get_str_fn(g, exp_typ); bool temp_var_needed = (expr)._typ == 344 /* v.ast.CallExpr */ && (v__ast__Type_is_ptr((*(v__ast__CallExpr*)__as_cast((expr)._v__ast__CallExpr,(expr)._typ, 344)).return_type) || v__ast__TypeSymbol_is_c_struct(v__ast__Table_sym(g->table, (*(v__ast__CallExpr*)__as_cast((expr)._v__ast__CallExpr,(expr)._typ, 344)).return_type))); string tmp_var = _S(""); if (temp_var_needed) { tmp_var = v__gen__c__Gen_new_tmp_var(g); string ret_typ = v__gen__c__Gen_styp(g, exp_typ); string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; { v__gen__c__Gen_write(g, ret_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write(g, line); } if (is_ptr && !is_var_mut) { string ref_str = string_repeat(_S("&"), v__ast__Type_nr_muls(typ)); { v__gen__c__Gen_write(g, _S("str_intp(1, _MOV((StrIntpData[]){{_S(\"")); v__gen__c__Gen_write(g, ref_str); v__gen__c__Gen_write(g, _S("\"), ")); v__gen__c__Gen_write(g, _const_v__gen__c__si_s_code); v__gen__c__Gen_write(g, _S(" ,{.d_s = isnil(")); } if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, exp_typ)); v__gen__c__Gen_write(g, _S("*)&")); } if (temp_var_needed) { v__gen__c__Gen_write(g, tmp_var); } else { v__gen__c__Gen_expr(g, expr); } v__gen__c__Gen_write(g, _S(".data) ? _S(\"Option(&nil)\") : ")); } else { inside_interface_deref_old = g->inside_interface_deref; g->inside_interface_deref = false; v__gen__c__Gen_gen_expr_to_string_defer_1 = true; if (temp_var_needed) { v__gen__c__Gen_write(g, tmp_var); } else { v__gen__c__Gen_expr(g, expr); } v__gen__c__Gen_write(g, _S(") ? _S(\"nil\") : ")); } } v__gen__c__Gen_write2(g, str_fn_name, _S("(")); if (str_method_expects_ptr && !is_ptr) { if (is_dump_expr || (g->pref->ccompiler_type != v__pref__CompilerType__tinyc && (expr)._typ == 344 /* v.ast.CallExpr */)) { { v__gen__c__Gen_write(g, _S("ADDR(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, typ)); v__gen__c__Gen_write(g, _S(", ")); } v__gen__c__Gen_gen_expr_to_string_defer_2 = true; } else { v__gen__c__Gen_write(g, _S("&")); } } else if (is_ptr && v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option_mut_param_t)) { v__gen__c__Gen_write(g, _S("*")); } else { { v__gen__c__Gen_write(g, _S("*(")); v__gen__c__Gen_write(g, v__gen__c__Gen_styp(g, typ)); v__gen__c__Gen_write(g, _S("*)&")); } } } else if (!str_method_expects_ptr && !is_shared && (is_ptr || is_var_mut)) { if (v__ast__TypeSymbol_is_c_struct(sym)) { v__gen__c__Gen_write(g, v__gen__c__c_struct_ptr(sym, typ, str_method_expects_ptr)); } else { v__gen__c__Gen_write(g, string_repeat(_S("*"), v__ast__Type_nr_muls(etype))); } } else if (v__ast__TypeSymbol_is_c_struct(sym)) { v__gen__c__Gen_write(g, v__gen__c__c_struct_ptr(sym, typ, str_method_expects_ptr)); } if ((expr)._typ == 338 /* v.ast.ArrayInit */) { if ((*expr._v__ast__ArrayInit).is_fixed) { string s = v__gen__c__Gen_styp(g, (*expr._v__ast__ArrayInit).typ); if (!(*expr._v__ast__ArrayInit).has_index) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, s); v__gen__c__Gen_write(g, _S(")")); } } } } if (unwrap_option) { v__gen__c__Gen_expr(g, expr); } else { if (temp_var_needed) { v__gen__c__Gen_write(g, tmp_var); } else { v__gen__c__Gen_expr_with_cast(g, expr, typ, typ); } } if (is_shared) { v__gen__c__Gen_write(g, _S("->val")); } v__gen__c__Gen_write(g, _S(")")); if (is_ptr && !is_var_mut) { v__gen__c__Gen_write(g, _S("}}}))")); } } else { bool is_var_mut = v__ast__Expr_is_auto_deref_var(expr); string str_fn_name = v__gen__c__Gen_get_str_fn(g, typ); { v__gen__c__Gen_write(g, str_fn_name); v__gen__c__Gen_write(g, _S("(")); } if (sym->kind != v__ast__Kind__function) { bool unwrap_option = (expr)._typ == 358 /* v.ast.Ident */ && (*(v__ast__Ident*)__as_cast((expr)._v__ast__Ident,(expr)._typ, 358)).or_expr.kind == v__ast__OrKind__propagate_option; v__ast__Type exp_typ = (unwrap_option ? (v__ast__Type_clear_flag(typ, v__ast__TypeFlag__option)) : (typ)); bool temp_var_needed = (expr)._typ == 344 /* v.ast.CallExpr */ && (v__ast__Type_is_ptr((*(v__ast__CallExpr*)__as_cast((expr)._v__ast__CallExpr,(expr)._typ, 344)).return_type) || v__ast__TypeSymbol_is_c_struct(v__ast__Table_sym(g->table, (*(v__ast__CallExpr*)__as_cast((expr)._v__ast__CallExpr,(expr)._typ, 344)).return_type))); string tmp_var = _S(""); if (temp_var_needed) { tmp_var = v__gen__c__Gen_new_tmp_var(g); string ret_typ = v__gen__c__Gen_styp(g, exp_typ); string line = string_trim_space(v__gen__c__Gen_go_before_last_stmt(g)); g->empty_line = true; { v__gen__c__Gen_write(g, ret_typ); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_writeln(g, _S(";")); v__gen__c__Gen_write(g, line); } if (str_method_expects_ptr && !is_ptr && !v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_write(g, _S("&")); } else if ((!str_method_expects_ptr && is_ptr && !is_shared) || is_var_mut) { v__gen__c__Gen_write(g, _S("*")); } else { if (v__ast__TypeSymbol_is_c_struct(sym)) { v__gen__c__Gen_write(g, v__gen__c__c_struct_ptr(sym, typ, str_method_expects_ptr)); } } if (temp_var_needed) { v__gen__c__Gen_write(g, tmp_var); } else { if ((expr)._typ == 385 /* v.ast.StructInit */ && v__ast__TypeSymbol_is_primitive_fixed_array(v__ast__Table_final_sym(g->table, (*(v__ast__StructInit*)__as_cast((expr)._v__ast__StructInit,(expr)._typ, 385)).typ))) { string s = v__gen__c__Gen_styp(g, (*expr._v__ast__StructInit).typ); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, s); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_expr_with_cast(g, expr, typ, typ); } } else if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_cast(g, expr, typ, typ); } v__gen__c__Gen_write(g, _S(")")); } // Defer begin if (v__gen__c__Gen_gen_expr_to_string_defer_2) { v__gen__c__Gen_write(g, _S(")")); } // Defer end // Defer begin if (v__gen__c__Gen_gen_expr_to_string_defer_1) { g->inside_interface_deref = inside_interface_deref_old; } // Defer end // Defer begin if (v__gen__c__Gen_gen_expr_to_string_defer_0) { g->inside_opt_or_res = old_inside_opt_or_res; g->expected_fixed_arr = false; } // Defer end } VV_LOC u8 v__gen__c__Gen_get_default_fmt(v__gen__c__Gen* g, v__ast__Type ftyp, v__ast__Type typ) { if (v__ast__Type_has_option_or_result(ftyp)) { return 's'; } else if (v__ast__Type_is_float(typ)) { return 'g'; } else if (v__ast__Type_is_signed(typ) || v__ast__Type_is_int_literal(typ)) { return 'd'; } else if (v__ast__Type_is_unsigned(typ)) { return 'u'; } else if (v__ast__Type_is_pointer(typ)) { return 'p'; } else { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, v__gen__c__Gen_unwrap_generic(g, ftyp)); if (sym->kind == v__ast__Kind__alias) { v__ast__Alias info = *(v__ast__Alias*)__as_cast((sym->info)._v__ast__Alias,(sym->info)._typ, 539); sym = v__ast__Table_sym(g->table, info.parent_type); if (info.parent_type == _const_v__ast__string_type) { return 's'; } } if (sym->kind == v__ast__Kind__function) { return 's'; } if ((ftyp == _const_v__ast__string_type || ftyp == _const_v__ast__bool_type) || (sym->kind == v__ast__Kind__enum || sym->kind == v__ast__Kind__array || sym->kind == v__ast__Kind__array_fixed || sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__map || sym->kind == v__ast__Kind__multi_return || sym->kind == v__ast__Kind__sum_type || sym->kind == v__ast__Kind__interface || sym->kind == v__ast__Kind__none) || v__ast__Type_has_option_or_result(ftyp) || v__ast__TypeSymbol_has_method(sym, _S("str"))) { return 's'; } else { return '_'; } } return 0; } VV_LOC multi_return_u64_string v__gen__c__Gen_str_format(v__gen__c__Gen* g, v__ast__StringInterLiteral node, int i, Array_u8 fmts) { int base = 0; bool upper_case = false; v__ast__Type typ = v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Type*)array_get(node.expr_types, i))); if (v__ast__Expr_is_auto_deref_var((*(v__ast__Expr*)array_get(node.exprs, i)))) { typ = v__ast__Type_deref(typ); } typ = v__ast__Table_final_type(g->table, typ); bool remove_tail_zeros = false; u8 fspec = (*(u8*)array_get(fmts, i)); StrIntpType fmt_type = StrIntpType__si_no_str; if (((rune)(fspec - 'A')) <= ((rune)('Z' - 'A'))) { upper_case = true; } if (fspec == 's' || fspec == 'S') { fmt_type = StrIntpType__si_s; } else if (fspec == 'r' || fspec == 'R') { fmt_type = StrIntpType__si_r; } else if (v__ast__Type_is_float(typ)) { if (fspec == 'g' || fspec == 'G') { if (typ == (_const_v__ast__f32_type)) { fmt_type = StrIntpType__si_g32; } else { fmt_type = StrIntpType__si_g64; } remove_tail_zeros = true; } else if (fspec == 'e' || fspec == 'E') { if (typ == (_const_v__ast__f32_type)) { fmt_type = StrIntpType__si_e32; } else { fmt_type = StrIntpType__si_e64; } } else if (fspec == 'f' || fspec == 'F') { if (typ == (_const_v__ast__f32_type)) { fmt_type = StrIntpType__si_f32; } else { fmt_type = StrIntpType__si_f64; } } } else if (v__ast__Type_is_pointer(typ)) { if (fspec == 'x' || fspec == 'X') { base = 14; } if (fspec == 'p' || fspec == 'x' || fspec == 'X') { fmt_type = StrIntpType__si_p; } else { fmt_type = StrIntpType__si_vp; } } else if (v__ast__Type_is_int(typ)) { if (fspec == 'x' || fspec == 'X') { base = 14; } if (fspec == 'o') { base = 6; } if (fspec == 'b') { base = 1; } if (fspec == 'c') { fmt_type = StrIntpType__si_c; } else { if (typ == (_const_v__ast__i8_type)) { fmt_type = StrIntpType__si_i8; } else if (typ == (_const_v__ast__u8_type)) { fmt_type = StrIntpType__si_u8; } else if (typ == (_const_v__ast__i16_type)) { fmt_type = StrIntpType__si_i16; } else if (typ == (_const_v__ast__u16_type)) { fmt_type = StrIntpType__si_u16; } else if (typ == (_const_v__ast__i64_type)) { fmt_type = StrIntpType__si_i64; } else if (typ == (_const_v__ast__u64_type)) { fmt_type = StrIntpType__si_u64; } else if (typ == (_const_v__ast__u32_type)) { fmt_type = StrIntpType__si_u32; } else if (typ == (_const_v__ast__usize_type)) { fmt_type = StrIntpType__si_u64; } else if (typ == (_const_v__ast__isize_type)) { fmt_type = StrIntpType__si_i64; } else { fmt_type = StrIntpType__si_i32; } } } else { fmt_type = StrIntpType__si_p; } int pad_ch = 0; if ((*(bool*)array_get(node.fills, i))) { pad_ch = 1; } u32 res = get_str_intp_u32_format(fmt_type, (*(int*)array_get(node.fwidths, i)), (*(int*)array_get(node.precisions, i)), remove_tail_zeros, (*(bool*)array_get(node.pluss, i)), ((u8)(pad_ch)), base, upper_case); return (multi_return_u64_string){.arg0=res, .arg1=StrIntpType_str(fmt_type)}; } VV_LOC void v__gen__c__Gen_str_val(v__gen__c__Gen* g, v__ast__StringInterLiteral node, int i, Array_u8 fmts) { v__ast__Expr expr = (*(v__ast__Expr*)array_get(node.exprs, i)); u8 fmt = (*(u8*)array_get(fmts, i)); v__ast__Type typ = v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Type*)array_get(node.expr_types, i))); v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(g->table, typ); if (typ == _const_v__ast__string_type && g->comptime->comptime_for_method == ((void*)0)) { if (g->inside_vweb_tmpl) { { v__gen__c__Gen_write(g, g->vweb_filter_fn_name); v__gen__c__Gen_write(g, _S("(")); } if (v__ast__Expr_is_auto_deref_var(expr) && fmt != 'p') { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } else { if (v__ast__Expr_is_auto_deref_var(expr) && fmt != 'p') { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, expr); } } else if (typ_sym->kind == v__ast__Kind__interface && v__ast__Interface_defines_method((*(v__ast__Interface*)__as_cast((typ_sym->info)._v__ast__Interface,(typ_sym->info)._typ, 542)), _S("str"))) { string rec_type_name = v__util__no_dots(v__gen__c__Gen_cc_type(g, typ, false)); { v__gen__c__Gen_write(g, v__gen__c__c_name(rec_type_name)); v__gen__c__Gen_write(g, _S("_name_table[")); } v__gen__c__Gen_expr(g, expr); string dot = (v__ast__Type_is_ptr(typ) ? (_S("->")) : (_S("."))); { v__gen__c__Gen_write(g, dot); v__gen__c__Gen_write(g, _S("_typ]._method_str(")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write2(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = dot}}, {_S("_object"), 0, { .d_c = 0 }}})), _S(")")); } else if (fmt == 's' || v__ast__Type_has_flag(typ, v__ast__TypeFlag__variadic)) { v__ast__Type exp_typ = typ; if ((expr)._typ == 358 /* v.ast.Ident */) { if (v__type_resolver__ResolverInfo_get_ct_type_var(g->comptime, expr) == v__ast__ComptimeVarKind__smartcast) { exp_typ = v__type_resolver__TypeResolver_get_type(&g->type_resolver, expr); } else if (((*expr._v__ast__Ident).obj)._typ == 422 /* v.ast.Var */) { if ((*(*expr._v__ast__Ident).obj._v__ast__Var).smartcasts.len > 0) { exp_typ = v__gen__c__Gen_unwrap_generic(g, (*(v__ast__Type*)array_last((*(*expr._v__ast__Ident).obj._v__ast__Var).smartcasts))); v__ast__TypeSymbol* cast_sym = v__ast__Table_sym(g->table, exp_typ); if ((cast_sym->info)._typ == 537 /* v.ast.Aggregate */) { exp_typ = (*(v__ast__Type*)array_get((*cast_sym->info._v__ast__Aggregate).types, g->aggregate_type_idx)); } } } } v__gen__c__Gen_gen_expr_to_string(g, expr, exp_typ); } else if (v__ast__Type_is_number(typ) || v__ast__Type_is_pointer(typ) || fmt == 'd') { if (v__ast__Type_is_signed(typ) && (fmt == 'x' || fmt == 'X' || fmt == 'o')) { if (typ == _const_v__ast__i8_type) { v__gen__c__Gen_write(g, _S("(byte)(")); } else if (typ == _const_v__ast__i16_type) { v__gen__c__Gen_write(g, _S("(u16)(")); } else if (typ == _const_v__ast__int_type) { v__gen__c__Gen_write(g, _S("(u32)(")); } else { v__gen__c__Gen_write(g, _S("(u64)(")); } if (v__ast__Expr_is_auto_deref_var(expr)) { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, expr); v__gen__c__Gen_write(g, _S(")")); } else { if (v__ast__Expr_is_auto_deref_var(expr) && fmt != 'p') { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, expr); } } else { if (v__ast__Expr_is_auto_deref_var(expr) && fmt != 'p') { v__gen__c__Gen_write(g, _S("*")); } v__gen__c__Gen_expr(g, expr); } } VV_LOC void v__gen__c__Gen_string_inter_literal(v__gen__c__Gen* g, v__ast__StringInterLiteral node) { bool v__gen__c__Gen_string_inter_literal_defer_0 = false; bool inside_interface_deref_old; inside_interface_deref_old = g->inside_interface_deref; g->inside_interface_deref = true; v__gen__c__Gen_string_inter_literal_defer_0 = true; v__ast__StringInterLiteral node_ = node; Array_u8 fmts = array_clone_to_depth(&node_.fmts, 0); for (int i = 0; i < node_.exprs.len; ++i) { v__ast__Expr* expr = ((v__ast__Expr*)node_.exprs.data) + i; if (v__type_resolver__ResolverInfo_is_comptime(g->comptime, *expr)) { v__ast__Type ctyp = v__type_resolver__TypeResolver_get_type_or_default(&g->type_resolver, *expr, (*(v__ast__Type*)array_get(node_.expr_types, i))); if (ctyp != _const_v__ast__void_type) { array_set(&node_.expr_types, i, &(v__ast__Type[]) { ctyp }); if ((*(u8*)array_get(node_.fmts, i)) == '_') { v__ast__TypeSymbol* ftyp_sym = v__ast__Table_sym(g->table, ctyp); v__ast__Type typ = (ftyp_sym->kind == v__ast__Kind__alias && !v__ast__TypeSymbol_has_method(ftyp_sym, _S("str")) ? (v__ast__Table_unalias_num_type(g->table, ctyp)) : (ctyp)); array_set(&fmts, i, &(u8[]) { v__gen__c__Gen_get_default_fmt(g, ctyp, typ) }); } } } } v__gen__c__Gen_write2(g, _S("str_intp("), int_str(node.vals.len)); v__gen__c__Gen_write(g, _S(", _MOV((StrIntpData[]){")); for (int i = 0; i < node.vals.len; ++i) { string val = ((string*)node.vals.data)[i]; string escaped_val = v__gen__c__cescape_nonascii(v__util__smart_quote(val, false)); escaped_val = string_replace(escaped_val, _S("\0"), _S("\\0")); if (escaped_val.len > 0) { v__gen__c__Gen_write2(g, _S("{_S(\""), escaped_val); v__gen__c__Gen_write(g, _S("\"), ")); } else { v__gen__c__Gen_write(g, _S("{_SLIT0, ")); } if (i >= node.exprs.len) { v__gen__c__Gen_write(g, _S("0, { .d_c = 0 }}")); break; } multi_return_u64_string mr_7201 = v__gen__c__Gen_str_format(g, node, i, fmts); u64 ft_u64 = mr_7201.arg0; string ft_str = mr_7201.arg1; v__gen__c__Gen_write2(g, _S("0x"), u64_hex(ft_u64)); v__gen__c__Gen_write2(g, _S(", {.d_"), ft_str); v__gen__c__Gen_write(g, _S(" = ")); if (ft_str.str[0] == 'p') { v__gen__c__Gen_write(g, _S("(void*)(")); v__gen__c__Gen_str_val(g, node, i, fmts); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_str_val(g, node, i, fmts); } v__gen__c__Gen_write(g, _S("}}")); if (i < ((int)(node.vals.len - 1))) { v__gen__c__Gen_write(g, _S(", ")); } } v__gen__c__Gen_write(g, _S("}))")); // Defer begin if (v__gen__c__Gen_string_inter_literal_defer_0) { g->inside_interface_deref = inside_interface_deref_old; } // Defer end } VV_LOC void v__gen__c__Gen_struct_init(v__gen__c__Gen* g, v__ast__StructInit node) { bool v__gen__c__Gen_struct_init_defer_0 = false; bool v__gen__c__Gen_struct_init_defer_1 = false; bool save_inside_array_fixed_struct; bool is_update_tmp_var = false; string tmp_update_var = _S(""); if (node.has_update_expr && !v__ast__Expr_is_lvalue(node.update_expr)) { is_update_tmp_var = true; tmp_update_var = v__gen__c__Gen_new_tmp_var(g); string s = v__gen__c__Gen_go_before_last_stmt(g); g->empty_line = true; string styp = v__gen__c__Gen_styp(g, node.update_expr_type); { v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(" ")); v__gen__c__Gen_write(g, tmp_update_var); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_expr(g, node.update_expr); v__gen__c__Gen_writeln(g, _S(";")); g->empty_line = false; v__gen__c__Gen_write(g, s); } v__ast__Type unalised_typ = v__ast__Table_unaliased_type(g->table, node.typ); string styp = (v__ast__Table_sym(g->table, unalised_typ)->language == v__ast__Language__v ? (string_replace(v__gen__c__Gen_styp(g, unalised_typ), _S("*"), _S(""))) : (v__gen__c__Gen_styp(g, node.typ))); string shared_styp = _S(""); if ((Array_string_contains(_const_v__gen__c__skip_struct_init, styp))) { v__gen__c__Gen_go_back(g, 3); return; } v__ast__Type unwrapped_typ = v__gen__c__Gen_unwrap_generic(g, node.typ); v__ast__TypeSymbol* sym = v__ast__Table_final_sym(g->table, unwrapped_typ); if (sym->kind == v__ast__Kind__sum_type) { if (v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__generic) && v__ast__Type_is_ptr(unwrapped_typ)) { v__gen__c__Gen_write(g, _S("&(")); v__gen__c__Gen_write(g, v__gen__c__Gen_type_default_sumtype(g, v__ast__Type_set_nr_muls(unwrapped_typ, 0), *sym)); v__gen__c__Gen_write(g, _S(")")); } else { v__gen__c__Gen_write(g, v__gen__c__Gen_type_default_sumtype(g, unwrapped_typ, *sym)); } return; } else if (sym->kind == v__ast__Kind__map) { v__gen__c__Gen_write(g, v__gen__c__Gen_type_default(g, unwrapped_typ)); return; } bool is_amp = g->is_amp; bool is_multiline = node.init_fields.len > 5; g->is_amp = false; if (is_amp) { v__gen__c__Gen_go_back(g, 1); } int aligned = 0; bool is_anon = false; bool is_array_fixed_struct_init = false; if ((sym->info)._typ == 518 /* v.ast.Struct */) { _option_v__ast__Attr _t1; if (_t1 = Array_v__ast__Attr_find_first((*sym->info._v__ast__Struct).attrs, _S("aligned")), _t1.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t1.data; aligned = ((attr.arg).len == 0 ? (0) : (string_int(attr.arg))); } is_anon = (*sym->info._v__ast__Struct).is_anon; } bool is_generic_default = !(sym->kind == v__ast__Kind__struct || sym->kind == v__ast__Kind__array_fixed) && v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__generic); bool is_array = (sym->kind == v__ast__Kind__array_fixed || sym->kind == v__ast__Kind__array); if (sym->kind == v__ast__Kind__array_fixed) { v__ast__ArrayFixed arr_info = v__ast__TypeSymbol_array_fixed_info(sym); is_array_fixed_struct_init = g->inside_return && v__ast__Table_final_sym(g->table, arr_info.elem_type)->kind == v__ast__Kind__struct; } bool const_msvc_init = g->is_cc_msvc && g->inside_const && !g->inside_cast && g->inside_array_item; if (!g->inside_cinit && !is_anon && !is_generic_default && !is_array && !const_msvc_init) { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_struct_init_defer_0 = true; } if (is_anon && !v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__option)) { if (node.language == v__ast__Language__v) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S(")")); } } v__gen__c__Gen_writeln(g, _S("{")); } else if (g->is_shared && !g->inside_opt_data && !g->is_arraymap_set) { v__ast__Type shared_typ = v__ast__Type_set_flag(node.typ, v__ast__TypeFlag__shared_f); shared_styp = v__gen__c__Gen_styp(g, shared_typ); v__gen__c__Gen_writeln(g, str_intp(5, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = shared_styp}}, {_S("*)__dup"), 0xfe10, {.d_s = shared_styp}}, {_S("(&("), 0xfe10, {.d_s = shared_styp}}, {_S("){.mtx = {0}, .val =("), 0xfe10, {.d_s = styp}}, {_S("){"), 0, { .d_c = 0 }}}))); } else if (is_amp || g->inside_cast_in_heap > 0) { if (v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__option)) { string basetyp = v__gen__c__Gen_base_type(g, node.typ); if (aligned != 0) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, basetyp); v__gen__c__Gen_write(g, _S("*)memdup_align(&(")); v__gen__c__Gen_write(g, basetyp); v__gen__c__Gen_write(g, _S("){")); } } else { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, basetyp); v__gen__c__Gen_write(g, _S("*)memdup(&(")); v__gen__c__Gen_write(g, basetyp); v__gen__c__Gen_write(g, _S("){")); } } } else { if (aligned != 0) { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)memdup_align(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("){")); } } else { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)memdup(&(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("){")); } } } } else if (v__ast__Type_is_ptr(node.typ)) { string basetyp = v__gen__c__Gen_styp(g, v__ast__Type_set_nr_muls(node.typ, 0)); if (is_multiline) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("&("), 0xfe10, {.d_s = basetyp}}, {_S("){"), 0, { .d_c = 0 }}}))); } else { { v__gen__c__Gen_write(g, _S("&(")); v__gen__c__Gen_write(g, basetyp); v__gen__c__Gen_write(g, _S("){")); } } } else if (v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__option)) { string tmp_var = v__gen__c__Gen_new_tmp_var(g); string s = v__gen__c__Gen_go_before_last_stmt(g); g->empty_line = true; string base_styp = v__gen__c__Gen_styp(g, v__ast__Type_clear_option_and_result(node.typ)); v__gen__c__Gen_writeln(g, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = tmp_var}}, {_S(" = {0};"), 0, { .d_c = 0 }}}))); if (node.init_fields.len > 0) { { v__gen__c__Gen_write(g, _S("_option_ok(&(")); v__gen__c__Gen_write(g, base_styp); v__gen__c__Gen_write(g, _S("[]) { ")); } } else { { v__gen__c__Gen_write(g, _S("_option_none(&(")); v__gen__c__Gen_write(g, base_styp); v__gen__c__Gen_write(g, _S("[]) { ")); } } v__gen__c__Gen_struct_init(g, ((v__ast__StructInit){.pos = (node).pos,.name_pos = (node).name_pos,.no_keys = (node).no_keys,.is_short_syntax = (node).is_short_syntax,.is_anon = (node).is_anon,.unresolved = (node).unresolved,.pre_comments = (node).pre_comments,.typ_str = (node).typ_str,.typ = v__ast__Type_clear_option_and_result(node.typ),.update_expr = (node).update_expr,.update_expr_type = (node).update_expr_type,.update_expr_pos = (node).update_expr_pos,.update_expr_comments = (node).update_expr_comments,.is_update_embed = (node).is_update_embed,.has_update_expr = (node).has_update_expr,.init_fields = (node).init_fields,.generic_types = (node).generic_types,.language = (node).language,})); v__gen__c__Gen_writeln(g, str_intp(4, _MOV((StrIntpData[]){{_S("}, ("), 0xfe10, {.d_s = _const_v__gen__c__option_name}}, {_S("*)&"), 0xfe10, {.d_s = tmp_var}}, {_S(", sizeof("), 0xfe10, {.d_s = base_styp}}, {_S("));"), 0, { .d_c = 0 }}}))); g->empty_line = false; v__gen__c__Gen_write2(g, s, tmp_var); // Defer begin if (v__gen__c__Gen_struct_init_defer_0) { v__gen__c__Gen_write(g, _S(")")); } // Defer end return; } else if (g->inside_cinit) { if (is_multiline) { v__gen__c__Gen_writeln(g, _S("{")); } else { v__gen__c__Gen_write(g, _S("{")); } } else { if ((v__ast__Table_sym(g->table, node.typ)->kind == v__ast__Kind__alias && v__ast__Type_is_ptr(v__ast__Table_unaliased_type(g->table, node.typ))) || (!v__ast__TypeSymbol_is_int(sym) && v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__generic) && v__ast__Type_is_ptr(unwrapped_typ))) { v__gen__c__Gen_write(g, _S("&")); } if (is_array || const_msvc_init) { if (!is_array_fixed_struct_init) { v__gen__c__Gen_write(g, _S("{")); } } else if (is_multiline) { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_S("("), 0xfe10, {.d_s = styp}}, {_S("){"), 0, { .d_c = 0 }}}))); } else if (is_generic_default) { v__gen__c__Gen_write(g, v__gen__c__Gen_type_default(g, node.typ)); } else { { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("){")); } } } Map_string_int inited_fields = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; if (is_multiline) { g->indent++; } bool initialized = false; bool old_is_shared = g->is_shared; for (int i = 0; i < node.init_fields.len; ++i) { v__ast__StructInitField init_field = ((v__ast__StructInitField*)node.init_fields.data)[i]; if (!v__ast__Type_has_flag(init_field.typ, v__ast__TypeFlag__shared_f)) { g->is_shared = false; } string field_name = init_field.name; if (node.no_keys && sym->kind == v__ast__Kind__struct) { v__ast__Struct info = *(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518); if (info.fields.len == node.init_fields.len) { field_name = (*(v__ast__StructField*)array_get(info.fields, i)).name; } } map_set(&inited_fields, &(string[]){field_name}, &(int[]) { i }); if (sym->kind != v__ast__Kind__struct && (sym->kind == v__ast__Kind__string || !v__ast__TypeSymbol_is_primitive(sym))) { if (init_field.typ == 0) { v__gen__c__Gen_checker_bug(g, _S("struct init, field.typ is 0"), init_field.pos); } v__gen__c__Gen_struct_init_field(g, init_field, sym->language); if (i != (int)(node.init_fields.len - 1)) { if (is_multiline) { v__gen__c__Gen_writeln(g, _S(",")); } else { v__gen__c__Gen_write(g, _S(", ")); } } initialized = true; } g->is_shared = old_is_shared; } g->is_shared = old_is_shared; int nr_fields = 1; if (sym->kind == v__ast__Kind__struct) { v__ast__Struct info = *(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518); nr_fields = info.fields.len; if (info.is_union && node.init_fields.len > 1) { v__gen__c__verror(_S("union must not have more than 1 initializer")); VUNREACHABLE(); } if (!info.is_union) { bool old_is_shared2 = g->is_shared; Array_string used_embed_fields = __new_array_with_default(0, 0, sizeof(string), 0); Array_string _t2 = {0}; Array_v__ast__StructField _t2_orig = info.fields; int _t2_len = _t2_orig.len; _t2 = __new_array(0, _t2_len, sizeof(string)); for (int _t4 = 0; _t4 < _t2_len; ++_t4) { v__ast__StructField it = ((v__ast__StructField*) _t2_orig.data)[_t4]; string _t3 = it.name; array_push((array*)&_t2, &_t3); } Array_string init_field_names =_t2; Array_v__ast__StructInitField _t5 = {0}; Array_v__ast__StructInitField _t5_orig = node.init_fields; int _t5_len = _t5_orig.len; _t5 = __new_array(0, _t5_len, sizeof(v__ast__StructInitField)); for (int _t6 = 0; _t6 < _t5_len; ++_t6) { v__ast__StructInitField it = ((v__ast__StructInitField*) _t5_orig.data)[_t6]; if (!(Array_string_contains(init_field_names, it.name))) { array_push((array*)&_t5, &it); } } Array_v__ast__StructInitField init_fields_to_embed =_t5; for (int _t7 = 0; _t7 < info.embeds.len; ++_t7) { v__ast__Type embed = ((v__ast__Type*)info.embeds.data)[_t7]; v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(g->table, embed); string embed_name = v__ast__TypeSymbol_embed_name(embed_sym); if (!_IN_MAP(ADDR(string, embed_name), ADDR(map, inited_fields))) { v__ast__Struct embed_info = ((embed_sym->info)._typ == 518 /* v.ast.Struct */ ? ((*embed_sym->info._v__ast__Struct)) : (({ v__ast__TypeInfo _t8 = v__ast__Table_final_sym(g->table, embed)->info; *(v__ast__Struct*)__as_cast(_t8._v__ast__Struct,_t8._typ, 518); }))); Array_string _t9 = {0}; Array_v__ast__StructField _t9_orig = embed_info.fields; int _t9_len = _t9_orig.len; _t9 = __new_array(0, _t9_len, sizeof(string)); for (int _t11 = 0; _t11 < _t9_len; ++_t11) { v__ast__StructField it = ((v__ast__StructField*) _t9_orig.data)[_t11]; string _t10 = it.name; array_push((array*)&_t9, &_t10); } Array_string embed_field_names =_t9; Array_v__ast__StructInitField _t12 = {0}; Array_v__ast__StructInitField _t12_orig = init_fields_to_embed; int _t12_len = _t12_orig.len; _t12 = __new_array(0, _t12_len, sizeof(v__ast__StructInitField)); for (int _t13 = 0; _t13 < _t12_len; ++_t13) { v__ast__StructInitField it = ((v__ast__StructInitField*) _t12_orig.data)[_t13]; if (!(Array_string_contains(used_embed_fields, it.name)) && (Array_string_contains(embed_field_names, it.name))) { array_push((array*)&_t12, &it); } } Array_v__ast__StructInitField fields_to_embed =_t12; Array_string _t15 = {0}; Array_v__ast__StructInitField _t15_orig = fields_to_embed; int _t15_len = _t15_orig.len; _t15 = __new_array(0, _t15_len, sizeof(string)); for (int _t17 = 0; _t17 < _t15_len; ++_t17) { v__ast__StructInitField it = ((v__ast__StructInitField*) _t15_orig.data)[_t17]; string _t16 = it.name; array_push((array*)&_t15, &_t16); } _PUSH_MANY(&used_embed_fields, (_t15), _t14, Array_string); v__ast__StructInit default_init = ((v__ast__StructInit){.pos = (node).pos,.name_pos = (node).name_pos,.no_keys = (node).no_keys,.is_short_syntax = (node).is_short_syntax,.is_anon = (node).is_anon,.unresolved = (node).unresolved,.pre_comments = (node).pre_comments,.typ_str = (node).typ_str,.typ = embed,.update_expr = (node).update_expr,.update_expr_type = (node).update_expr_type,.update_expr_pos = (node).update_expr_pos,.update_expr_comments = (node).update_expr_comments,.is_update_embed = true,.has_update_expr = (node).has_update_expr,.init_fields = init_fields_to_embed,.generic_types = (node).generic_types,.language = (node).language,}); int inside_cast_in_heap = g->inside_cast_in_heap; g->inside_cast_in_heap = 0; { v__gen__c__Gen_write(g, _S(".")); v__gen__c__Gen_write(g, embed_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_struct_init(g, default_init); g->inside_cast_in_heap = inside_cast_in_heap; if (is_multiline) { v__gen__c__Gen_writeln(g, _S(",")); } else { v__gen__c__Gen_write(g, _S(",")); } initialized = true; } } g->is_shared = old_is_shared2; } for (int _t18 = 0; _t18 < info.fields.len; ++_t18) { v__ast__StructField* field = ((v__ast__StructField*)info.fields.data) + _t18; g->is_shared = v__ast__Type_has_flag(field->typ, v__ast__TypeFlag__shared_f); if ((sym->info)._typ == 518 /* v.ast.Struct */) { int found_equal_fields = 0; string field_name = field->name; int field_name_len = field->name.len; for (int _t19 = 0; _t19 < (*sym->info._v__ast__Struct).fields.len; ++_t19) { v__ast__StructField* sifield = ((v__ast__StructField*)(*sym->info._v__ast__Struct).fields.data) + _t19; if (sifield->name.len == field_name_len && string__eq(sifield->name, field_name)) { found_equal_fields++; break; } } if (found_equal_fields == 0) { continue; } } int* _t21 = (int*)(map_get_check(ADDR(map, inited_fields), &(string[]){field->name})); _option_int _t20 = {0}; if (_t21) { *((int*)&_t20.data) = *((int*)_t21); } else { _t20.state = 2; _t20.err = _v_error(_S("map key does not exist")); } if (_t20.state == 0) { int already_inited_node_field_index = (*(int*)_t20.data); v__ast__StructInitField sfield = (*(v__ast__StructInitField*)array_get(node.init_fields, already_inited_node_field_index)); if (sfield.typ == 0) { continue; } if (v__ast__Type_has_flag(sfield.expected_type, v__ast__TypeFlag__generic) && g->cur_fn != ((void*)0)) { Array_string t_generic_names = array_clone_to_depth(&g->table->cur_fn->generic_names, 0); Array_v__ast__Type t_concrete_types = array_clone_to_depth(&g->cur_concrete_types, 0); v__ast__TypeSymbol* ts = v__ast__Table_sym(g->table, node.typ); if (ts->generic_types.len > 0 && ts->generic_types.len == info.generic_types.len && !Array_v__ast__Type_arr_eq(ts->generic_types, info.generic_types)) { Array_string _t22 = {0}; Array_v__ast__Type _t22_orig = info.generic_types; int _t22_len = _t22_orig.len; _t22 = __new_array(0, _t22_len, sizeof(string)); for (int _t24 = 0; _t24 < _t22_len; ++_t24) { v__ast__Type it = ((v__ast__Type*) _t22_orig.data)[_t24]; string _t23 = v__ast__Table_sym(g->table, it)->name; array_push((array*)&_t22, &_t23); } t_generic_names =_t22; t_concrete_types = __new_array_with_default(0, 0, sizeof(v__ast__Type), 0); for (int _t25 = 0; _t25 < ts->generic_types.len; ++_t25) { v__ast__Type t_typ = ((v__ast__Type*)ts->generic_types.data)[_t25]; if (!v__ast__Type_has_flag(t_typ, v__ast__TypeFlag__generic)) { array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ t_typ })); } else if (v__ast__Table_sym(g->table, t_typ)->kind == v__ast__Kind__any) { string tname = v__ast__Table_sym(g->table, t_typ)->name; int index = Array_string_index(g->table->cur_fn->generic_names, tname); if (index >= 0 && index < g->cur_concrete_types.len) { array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ (*(v__ast__Type*)array_get(g->cur_concrete_types, index)) })); } } else { _option_v__ast__Type _t28; if (_t28 = v__ast__Table_convert_generic_type(g->table, t_typ, g->table->cur_fn->generic_names, g->cur_concrete_types), _t28.state == 0) { v__ast__Type tt = *(v__ast__Type*)_t28.data; array_push((array*)&t_concrete_types, _MOV((v__ast__Type[]){ tt })); } } } } _option_v__ast__Type _t30; if (_t30 = v__ast__Table_convert_generic_type(g->table, sfield.expected_type, t_generic_names, t_concrete_types), _t30.state == 0) { v__ast__Type tt = *(v__ast__Type*)_t30.data; sfield.expected_type = tt; } } if (node.no_keys && sym->kind == v__ast__Kind__struct) { v__ast__Struct sym_info = *(v__ast__Struct*)__as_cast((sym->info)._v__ast__Struct,(sym->info)._typ, 518); if (sym_info.fields.len == node.init_fields.len) { sfield.name = (*(v__ast__StructField*)array_get(sym_info.fields, already_inited_node_field_index)).name; } } v__gen__c__Gen_struct_init_field(g, sfield, sym->language); if (is_multiline) { v__gen__c__Gen_writeln(g, _S(",")); } else { v__gen__c__Gen_write(g, _S(",")); } initialized = true; continue; } if (info.is_union) { continue; } string field_name = v__gen__c__c_name(field->name); if ((Array_v__ast__Type_contains(info.embeds, field->typ))) { continue; } if (node.has_update_expr) { bool is_arr_fixed = false; { v__gen__c__Gen_write(g, _S(".")); v__gen__c__Gen_write(g, field_name); v__gen__c__Gen_write(g, _S(" = ")); } if (is_update_tmp_var) { v__gen__c__Gen_write(g, tmp_update_var); } else { v__ast__TypeSymbol* update_expr_sym = v__ast__Table_final_sym(g->table, field->typ); if ((update_expr_sym->info)._typ == 549 /* v.ast.ArrayFixed */) { is_arr_fixed = true; bool is_auto_deref_var = v__ast__Expr_is_auto_deref_var(node.update_expr); v__gen__c__Gen_fixed_array_update_expr_field(g, v__gen__c__Gen_expr_string(g, node.update_expr), node.update_expr_type, field->name, is_auto_deref_var, (*update_expr_sym->info._v__ast__ArrayFixed).elem_type, (*update_expr_sym->info._v__ast__ArrayFixed).size, node.is_update_embed); } else { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_expr(g, node.update_expr); v__gen__c__Gen_write(g, _S(")")); } } if (!is_arr_fixed) { if (v__ast__Type_is_ptr(node.update_expr_type)) { v__gen__c__Gen_write(g, _S("->")); } else { v__gen__c__Gen_write(g, _S(".")); } if (node.is_update_embed) { v__gen__c__Gen_write(g, v__gen__c__Gen_get_embed_field_name(g, node.update_expr_type, field->name)); } v__gen__c__Gen_write(g, v__gen__c__c_name(field->name)); } } else { if (!v__gen__c__Gen_zero_struct_field(g, *field)) { nr_fields--; continue; } } if (is_multiline) { v__gen__c__Gen_writeln(g, _S(",")); } else { v__gen__c__Gen_write(g, _S(",")); } initialized = true; } g->is_shared = old_is_shared; } else if (is_array_fixed_struct_init) { v__ast__ArrayFixed arr_info = v__ast__TypeSymbol_array_fixed_info(sym); save_inside_array_fixed_struct = g->inside_array_fixed_struct; g->inside_array_fixed_struct = is_array_fixed_struct_init; v__gen__c__Gen_struct_init_defer_1 = true; v__gen__c__Gen_fixed_array_init(g, ((v__ast__ArrayInit){.pos = node.pos,.elem_type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.ecmnts = __new_array(0, 0, sizeof(Array_v__ast__Comment)),.pre_cmnts = __new_array(0, 0, sizeof(v__ast__Comment)),.is_fixed = true,.is_option = 0,.has_val = 0,.mod = (string){.str=(byteptr)"", .is_lit=1},.has_len = 0,.has_cap = 0,.has_init = 0,.has_index = 0,.exprs = new_array_from_c_array(1, 1, sizeof(v__ast__Expr), _MOV((v__ast__Expr[1]){_const_v__ast__empty_expr})),.len_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.cap_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.init_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.expr_types = __new_array(0, 0, sizeof(v__ast__Type)),.elem_type = arr_info.elem_type,.init_type = 0,.typ = unwrapped_typ,.alias_type = 0,.has_callexpr = 0,}), v__gen__c__Gen_unwrap(g, unwrapped_typ), _S(""), g->is_amp); initialized = true; } if (is_multiline) { g->indent--; } if (!initialized && !is_generic_default) { if (nr_fields > 0) { v__gen__c__Gen_write(g, _S("0")); } else { v__gen__c__Gen_write(g, _S("E_STRUCT")); } } if (!is_array_fixed_struct_init && !is_generic_default) { v__gen__c__Gen_write(g, _S("}")); } if (g->is_shared && !g->inside_opt_data && !g->is_arraymap_set) { if (aligned != 0) { { v__gen__c__Gen_write(g, _S("}, sizeof(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("), ")); v__gen__c__Gen_write_decimal(g, aligned); v__gen__c__Gen_write(g, _S(")")); } } else { { v__gen__c__Gen_write(g, _S("}, sizeof(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("))")); } } } else if (is_amp || g->inside_cast_in_heap > 0) { if (v__ast__Type_has_flag(node.typ, v__ast__TypeFlag__option)) { string basetyp = v__gen__c__Gen_base_type(g, node.typ); if (aligned != 0) { { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, basetyp); v__gen__c__Gen_write(g, _S("), ")); v__gen__c__Gen_write_decimal(g, aligned); v__gen__c__Gen_write(g, _S(")")); } } else { { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, basetyp); v__gen__c__Gen_write(g, _S("))")); } } } else { if (aligned != 0) { { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("), ")); v__gen__c__Gen_write_decimal(g, aligned); v__gen__c__Gen_write(g, _S(")")); } } else { { v__gen__c__Gen_write(g, _S(", sizeof(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("))")); } } } } // Defer begin if (v__gen__c__Gen_struct_init_defer_1) { g->inside_array_fixed_struct = save_inside_array_fixed_struct; } // Defer end // Defer begin if (v__gen__c__Gen_struct_init_defer_0) { v__gen__c__Gen_write(g, _S(")")); } // Defer end } VV_LOC string v__gen__c__Gen_get_embed_field_name(v__gen__c__Gen* g, v__ast__Type field_type, string field_name) { v__ast__TypeSymbol* update_sym = v__ast__Table_sym(g->table, field_type); _result_multi_return_v__ast__StructField_Array_v__ast__Type _t1 = v__ast__Table_find_field_from_embeds(g->table, update_sym, field_name); if (_t1.is_error) { IError err = _t1.err; *(multi_return_v__ast__StructField_Array_v__ast__Type*) _t1.data = (multi_return_v__ast__StructField_Array_v__ast__Type){.arg0=((v__ast__StructField){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.type_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.option_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.i = 0,.has_default_expr = 0,.has_prev_newline = 0,.has_break_line = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.is_pub = 0,.default_val = (string){.str=(byteptr)"", .is_lit=1},.is_mut = 0,.is_global = 0,.is_volatile = 0,.is_deprecated = 0,.is_embed = 0,.next_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_recursive = 0,.is_part_of_union = 0,.container_typ = 0,.default_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.default_expr_typ = 0,.name = (string){.str=(byteptr)"", .is_lit=1},.typ = 0,.unaliased_typ = 0,.anon_struct_decl = ((v__ast__StructDecl){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name = (string){.str=(byteptr)"", .is_lit=1},.scoped_name = (string){.str=(byteptr)"", .is_lit=1},.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.is_pub = 0,.mut_pos = -1,.pub_pos = -1,.pub_mut_pos = -1,.global_pos = -1,.module_pos = -1,.is_union = 0,.is_option = 0,.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.end_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.embeds = __new_array(0, 0, sizeof(v__ast__Embed)),.is_implements = 0,.implements_types = __new_array(0, 0, sizeof(v__ast__TypeNode)),.language = 0,.fields = __new_array(0, 0, sizeof(v__ast__StructField)),.idx = 0,}),}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } multi_return_v__ast__StructField_Array_v__ast__Type mr_12553 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t1.data); Array_v__ast__Type embeds = mr_12553.arg1; string s = _S(""); for (int _t2 = 0; _t2 < embeds.len; ++_t2) { v__ast__Type embed = ((v__ast__Type*)embeds.data)[_t2]; v__ast__TypeSymbol* esym = v__ast__Table_sym(g->table, embed); string ename = v__ast__TypeSymbol_embed_name(esym); if (v__ast__Type_is_ptr(embed)) { s = string__plus(s, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ename}}, {_S("->"), 0, { .d_c = 0 }}}))); } else { s = string__plus(s, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ename}}, {_S("."), 0, { .d_c = 0 }}}))); } } return s; } VV_LOC void v__gen__c__Gen_init_shared_field(v__gen__c__Gen* g, v__ast__StructField field) { v__ast__Type field_typ = v__ast__Type_deref(field.typ); string shared_styp = v__gen__c__Gen_styp(g, field_typ); { v__gen__c__Gen_write(g, _S("(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("*)__dup")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("(&(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("){.mtx= {0}, .val=")); } v__gen__c__Gen_write(g, v__gen__c__Gen_type_default(g, v__ast__Type_clear_flag(field_typ, v__ast__TypeFlag__shared_f))); { v__gen__c__Gen_write(g, _S("}, sizeof(")); v__gen__c__Gen_write(g, shared_styp); v__gen__c__Gen_write(g, _S("))")); } } VV_LOC bool v__gen__c__Gen_zero_struct_field(v__gen__c__Gen* g, v__ast__StructField field) { bool v__gen__c__Gen_zero_struct_field_defer_0 = false; int old_inside_cast_in_heap; old_inside_cast_in_heap = g->inside_cast_in_heap; g->inside_cast_in_heap = 0; v__gen__c__Gen_zero_struct_field_defer_0 = true; v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, field.typ); v__ast__TypeSymbol* final_sym = v__ast__Table_final_sym(g->table, field.typ); string field_name = (sym->language == v__ast__Language__v ? (v__gen__c__c_name(field.name)) : (field.name)); if ((sym->info)._typ == 518 /* v.ast.Struct */) { if ((*sym->info._v__ast__Struct).fields.len == 0) { bool _t1 = false; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t1; } else if (!field.has_default_expr) { bool has_option_field = false; if ((*sym->info._v__ast__Struct).is_shared || v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__shared_f)) { { v__gen__c__Gen_write(g, _S(".")); v__gen__c__Gen_write(g, field_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_init_shared_field(g, field); bool _t2 = true; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t2; } for (int _t3 = 0; _t3 < (*sym->info._v__ast__Struct).fields.len; ++_t3) { v__ast__StructField fd = ((v__ast__StructField*)(*sym->info._v__ast__Struct).fields.data)[_t3]; if (v__ast__Type_has_flag(fd.typ, v__ast__TypeFlag__option)) { has_option_field = true; break; } } if (has_option_field || field.anon_struct_decl.fields.len > 0) { v__ast__StructInit default_init = ((v__ast__StructInit){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.no_keys = 0,.is_short_syntax = 0,.is_anon = 0,.unresolved = 0,.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.typ_str = (string){.str=(byteptr)"", .is_lit=1},.typ = field.typ,.update_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_expr_type = 0,.update_expr_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.update_expr_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_update_embed = 0,.has_update_expr = 0,.init_fields = __new_array(0, 0, sizeof(v__ast__StructInitField)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.language = field.anon_struct_decl.language,}); { v__gen__c__Gen_write(g, _S(".")); v__gen__c__Gen_write(g, field_name); v__gen__c__Gen_write(g, _S(" = ")); } if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { if (field.is_recursive || v__ast__Type_is_ptr(field.typ)) { v__gen__c__Gen_expr_with_opt(g, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))), _const_v__ast__none_type, field.typ); } else { string tmp_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_expr_with_tmp_var(g, v__ast__StructInit_to_sumtype_v__ast__Expr(&default_init), field.typ, field.typ, tmp_var); } } else { v__gen__c__Gen_struct_init(g, default_init); } bool _t4 = true; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t4; } else if (sym->language == v__ast__Language__v && !v__ast__Type_is_ptr(field.typ) && !fast_string_eq(sym->mod, _S("builtin")) && !v__ast__Struct_is_empty_struct(&(*sym->info._v__ast__Struct))) { v__ast__StructInit default_init = ((v__ast__StructInit){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.name_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.no_keys = 0,.is_short_syntax = 0,.is_anon = 0,.unresolved = 0,.pre_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.typ_str = (string){.str=(byteptr)"", .is_lit=1},.typ = field.typ,.update_expr = (v__ast__Expr){._v__ast__NodeError=HEAP(v__ast__NodeError, ((v__ast__NodeError){.idx = 0,.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},})),._typ=335},.update_expr_type = 0,.update_expr_pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.update_expr_comments = __new_array(0, 0, sizeof(v__ast__Comment)),.is_update_embed = 0,.has_update_expr = 0,.init_fields = __new_array(0, 0, sizeof(v__ast__StructInitField)),.generic_types = __new_array(0, 0, sizeof(v__ast__Type)),.language = 0,}); { v__gen__c__Gen_write(g, _S(".")); v__gen__c__Gen_write(g, field_name); v__gen__c__Gen_write(g, _S(" = ")); } v__gen__c__Gen_struct_init(g, default_init); bool _t5 = true; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t5; } } } { v__gen__c__Gen_write(g, _S(".")); v__gen__c__Gen_write(g, field_name); v__gen__c__Gen_write(g, _S(" = ")); } if (field.has_default_expr) { if (sym->kind == v__ast__Kind__sum_type || sym->kind == v__ast__Kind__interface) { if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_with_opt(g, field.default_expr, field.default_expr_typ, field.typ); } else { v__gen__c__Gen_expr_with_cast(g, field.default_expr, field.default_expr_typ, field.typ); } bool _t6 = true; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t6; } if ((field.default_expr)._typ == 371 /* v.ast.None */) { v__gen__c__Gen_gen_option_error(g, field.typ, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}))))); bool _t7 = true; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t7; } else if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { string tmp_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_expr_with_tmp_var(g, field.default_expr, field.default_expr_typ, field.typ, tmp_var); bool _t8 = true; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t8; } else if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__result) && !v__ast__Type_has_flag(field.default_expr_typ, v__ast__TypeFlag__result)) { string tmp_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_expr_with_tmp_var(g, field.default_expr, field.default_expr_typ, field.typ, tmp_var); bool _t9 = true; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t9; } else if ((final_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && (field.default_expr)._typ != 338 /* v.ast.ArrayInit */) { bool old_inside_memset = g->inside_memset; g->inside_memset = true; string tmp_var = v__gen__c__Gen_expr_with_var(g, field.default_expr, field.default_expr_typ, (field.default_expr)._typ != 344 /* v.ast.CallExpr */); v__gen__c__Gen_fixed_array_var_init(g, tmp_var, false, (*final_sym->info._v__ast__ArrayFixed).elem_type, (*final_sym->info._v__ast__ArrayFixed).size); g->inside_memset = old_inside_memset; bool _t10 = true; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t10; } v__gen__c__Gen_expr(g, field.default_expr); } else if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_gen_option_error(g, field.typ, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}))))); bool _t11 = true; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t11; } else if ((sym->info)._typ == 544 /* v.ast.SumType */) { v__gen__c__Gen_write(g, v__gen__c__Gen_type_default_sumtype(g, field.typ, *sym)); bool _t12 = true; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t12; } else if ((sym->info)._typ == 549 /* v.ast.ArrayFixed */) { bool elem_is_option = v__ast__Type_has_flag((*sym->info._v__ast__ArrayFixed).elem_type, v__ast__TypeFlag__option); v__gen__c__Gen_write(g, _S("{")); if (!elem_is_option && v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_write(g, _S("0")); } else { string default_str = v__gen__c__Gen_type_default(g, (*sym->info._v__ast__ArrayFixed).elem_type); for (int i = 0; i < (*sym->info._v__ast__ArrayFixed).size; ++i) { if (elem_is_option) { v__gen__c__Gen_gen_option_error(g, (*sym->info._v__ast__ArrayFixed).elem_type, v__ast__None_to_sumtype_v__ast__Expr(ADDR(v__ast__None, (((v__ast__None){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),}))))); } else { v__gen__c__Gen_write(g, default_str); } if (i != (int)((*sym->info._v__ast__ArrayFixed).size - 1)) { v__gen__c__Gen_write(g, _S(", ")); } } } v__gen__c__Gen_write(g, _S("}")); } else if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__shared_f)) { v__gen__c__Gen_init_shared_field(g, field); } else { v__gen__c__Gen_write(g, v__gen__c__Gen_type_default(g, field.typ)); } bool _t13 = true; // Defer begin if (v__gen__c__Gen_zero_struct_field_defer_0) { g->inside_cast_in_heap = old_inside_cast_in_heap; } // Defer end return _t13; } VV_LOC void v__gen__c__Gen_struct_decl(v__gen__c__Gen* g, v__ast__Struct s, string name, bool is_anon, bool is_option) { if (s.is_generic) { return; } if (string_contains(name, _S("_T_"))) { if (s.is_union) { strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef union "), 0xfe10, {.d_s = name}}, {_S(" "), 0xfe10, {.d_s = name}}, {_S(";"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = name}}, {_S(" "), 0xfe10, {.d_s = name}}, {_S(";"), 0, { .d_c = 0 }}}))); } } int start_pos = g->type_definitions.len; string pre_pragma = _S(""); string post_pragma = _S(""); for (int _t1 = 0; _t1 < s.attrs.len; ++_t1) { v__ast__Attr attr = ((v__ast__Attr*)s.attrs.data)[_t1]; if (_SLIT_EQ(attr.name.str, attr.name.len, "_pack")) { pre_pragma = string__plus(pre_pragma, str_intp(2, _MOV((StrIntpData[]){{_S("#pragma pack(push, "), 0xfe10, {.d_s = attr.arg}}, {_S(")\n"), 0, { .d_c = 0 }}}))); post_pragma = string__plus(post_pragma, _S("#pragma pack(pop)")); } else if (_SLIT_EQ(attr.name.str, attr.name.len, "packed")) { pre_pragma = string__plus(pre_pragma, _S("#pragma pack(push, 1)\n")); post_pragma = string__plus(post_pragma, _S("#pragma pack(pop)")); } else { } } bool is_minify = s.is_minify; strings__Builder_writeln(&g->type_definitions, pre_pragma); string aligned_attr = _S(""); _option_v__ast__Attr _t2; if (_t2 = Array_v__ast__Attr_find_first(s.attrs, _S("aligned")), _t2.state == 0) { v__ast__Attr attr = *(v__ast__Attr*)_t2.data; string attr_arg = ((attr.arg).len == 0 ? (_S("")) : (str_intp(2, _MOV((StrIntpData[]){{_S(" ("), 0xfe10, {.d_s = attr.arg}}, {_S(")"), 0, { .d_c = 0 }}})))); aligned_attr = string__plus(aligned_attr, (g->is_cc_msvc ? (str_intp(2, _MOV((StrIntpData[]){{_S("__declspec(align"), 0xfe10, {.d_s = attr_arg}}, {_S(")"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_S(" __attribute__((aligned"), 0xfe10, {.d_s = attr_arg}}, {_S("))"), 0, { .d_c = 0 }}}))))); } if (is_anon) { string option_prefix = (is_option ? (_S("_option_")) : (_S(""))); if (s.is_shared) { { strings__Builder_write_string(&g->type_definitions, _S("\t")); strings__Builder_write_string(&g->type_definitions, option_prefix); strings__Builder_write_string(&g->type_definitions, _S("__shared__")); strings__Builder_write_string(&g->type_definitions, name); strings__Builder_write_string(&g->type_definitions, _S("* ")); } } else { { strings__Builder_write_string(&g->type_definitions, _S("\t")); strings__Builder_write_string(&g->type_definitions, option_prefix); strings__Builder_write_string(&g->type_definitions, name); strings__Builder_write_string(&g->type_definitions, _S(" ")); } } return; } else if (s.is_union) { if (g->is_cc_msvc && (aligned_attr).len != 0) { strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("union "), 0xfe10, {.d_s = aligned_attr}}, {_S(" "), 0xfe10, {.d_s = name}}, {_S(" {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("union "), 0xfe10, {.d_s = name}}, {_S(" {"), 0, { .d_c = 0 }}}))); } } else { if (g->is_cc_msvc && (aligned_attr).len != 0) { strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S("struct "), 0xfe10, {.d_s = aligned_attr}}, {_S(" "), 0xfe10, {.d_s = name}}, {_S(" {"), 0, { .d_c = 0 }}}))); } else { strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_S("struct "), 0xfe10, {.d_s = name}}, {_S(" {"), 0, { .d_c = 0 }}}))); } } if (s.fields.len > 0 || s.embeds.len > 0) { for (int _t3 = 0; _t3 < s.fields.len; ++_t3) { v__ast__StructField field = ((v__ast__StructField*)s.fields.data)[_t3]; if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)) { multi_return_string_string mr_19019 = v__gen__c__Gen_option_type_name(g, field.typ); string styp = mr_19019.arg0; string base = mr_19019.arg1; sync__RwMutex_lock(&g->done_options->mtx); /*lock*/ { if (!(Array_string_contains(g->done_options->val, base))) { array_push((array*)&g->done_options->val, _MOV((string[]){ string_clone(base) })); string last_text = string_clone(strings__Builder_after(&g->type_definitions, start_pos)); strings__Builder_go_back_to(&g->type_definitions, start_pos); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = styp}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_option_type_text(g, styp, base)}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_write_string(&g->type_definitions, last_text); } } sync__RwMutex_unlock(&g->done_options->mtx);; } if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__result)) { multi_return_string_string mr_19591 = v__gen__c__Gen_result_type_name(g, field.typ); string styp = mr_19591.arg0; string base = mr_19591.arg1; sync__RwMutex_lock(&g->done_results->mtx); /*lock*/ { if (!(Array_string_contains(g->done_results->val, base))) { array_push((array*)&g->done_results->val, _MOV((string[]){ string_clone(base) })); string last_text = string_clone(strings__Builder_after(&g->type_definitions, start_pos)); strings__Builder_go_back_to(&g->type_definitions, start_pos); strings__Builder_writeln(&g->typedefs, str_intp(3, _MOV((StrIntpData[]){{_S("typedef struct "), 0xfe10, {.d_s = styp}}, {_S(" "), 0xfe10, {.d_s = styp}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_writeln(&g->type_definitions, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__gen__c__Gen_result_type_text(g, styp, base)}}, {_S(";"), 0, { .d_c = 0 }}}))); strings__Builder_write_string(&g->type_definitions, last_text); } } sync__RwMutex_unlock(&g->done_results->mtx);; } string type_name = v__gen__c__Gen_styp(g, field.typ); string field_name = v__gen__c__c_name(field.name); string volatile_prefix = (field.is_volatile ? (_S("volatile ")) : (_S(""))); string size_suffix = _S(""); if (is_minify && !g->is_cc_msvc && !g->pref->output_cross_c) { if (field.typ == 19) { size_suffix = _S(" : 1"); } else { v__ast__TypeSymbol* field_sym = v__ast__Table_sym(g->table, field.typ); if ((field_sym->info)._typ == 548 /* v.ast.Enum */) { if (!(*field_sym->info._v__ast__Enum).is_flag && !(*field_sym->info._v__ast__Enum).uses_exprs) { int bits_needed = 0; int l = (*field_sym->info._v__ast__Enum).vals.len; for (;;) { if (!(l > 0)) break; bits_needed++; l >>= 1; } size_suffix = str_intp(2, _MOV((StrIntpData[]){{_S(" : "), 0xfe07, {.d_i32 = bits_needed}}, {_SLIT0, 0, { .d_c = 0 }}})); } } } } v__ast__TypeSymbol* field_sym = v__ast__Table_sym(g->table, field.typ); bool field_is_anon = false; if ((field_sym->info)._typ == 518 /* v.ast.Struct */) { if ((*field_sym->info._v__ast__Struct).is_anon) { field_is_anon = true; v__gen__c__Gen_struct_decl(g, (*field_sym->info._v__ast__Struct), field_sym->cname, true, v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__option)); strings__Builder_writeln(&g->type_definitions, str_intp(3, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = field_name}}, {_SLIT0, 0xfe10, {.d_s = size_suffix}}, {_S(";"), 0, { .d_c = 0 }}}))); } } if (!field_is_anon) { strings__Builder_writeln(&g->type_definitions, str_intp(5, _MOV((StrIntpData[]){{_S("\t"), 0xfe10, {.d_s = volatile_prefix}}, {_SLIT0, 0xfe10, {.d_s = type_name}}, {_S(" "), 0xfe10, {.d_s = field_name}}, {_SLIT0, 0xfe10, {.d_s = size_suffix}}, {_S(";"), 0, { .d_c = 0 }}}))); } } } else { strings__Builder_writeln(&g->type_definitions, _S("\tEMPTY_STRUCT_DECLARATION;")); } bool _t7 = (!g->is_cc_msvc); string _t6; /* if prepend */ if ( _t7 && Array_v__ast__Attr_contains(s.attrs, _S("packed"))) { _t6 = _S("__attribute__((__packed__))"); } else { _t6 = _S(""); } string ti_attrs = _t6; { strings__Builder_write_string(&g->type_definitions, _S("}")); strings__Builder_write_string(&g->type_definitions, ti_attrs); } if (!g->is_cc_msvc && (aligned_attr).len != 0) { { strings__Builder_write_string(&g->type_definitions, _S(" ")); strings__Builder_write_string(&g->type_definitions, aligned_attr); } } if (!is_anon) { strings__Builder_write_string(&g->type_definitions, _S(";")); } strings__Builder_writeln(&g->type_definitions, _S("")); if ((post_pragma).len != 0) { strings__Builder_writeln(&g->type_definitions, post_pragma); } } VV_LOC void v__gen__c__Gen_struct_init_field(v__gen__c__Gen* g, v__ast__StructInitField sfield, v__ast__Language language) { string field_name = (language == v__ast__Language__v ? (v__gen__c__c_name(sfield.name)) : (sfield.name)); { v__gen__c__Gen_write(g, _S(".")); v__gen__c__Gen_write(g, field_name); v__gen__c__Gen_write(g, _S(" = ")); } v__ast__TypeSymbol* field_type_sym = v__ast__Table_sym(g->table, sfield.typ); bool cloned = false; if (g->is_autofree && !v__ast__Type_is_ptr(sfield.typ) && (field_type_sym->kind == v__ast__Kind__array || field_type_sym->kind == v__ast__Kind__string)) { if (v__gen__c__Gen_gen_clone_assignment(g, sfield.expected_type, sfield.expr, sfield.typ, false)) { cloned = true; } } if (!cloned) { int inside_cast_in_heap = g->inside_cast_in_heap; g->inside_cast_in_heap = 0; v__ast__Type field_unwrap_typ = v__gen__c__Gen_unwrap_generic(g, sfield.typ); v__ast__TypeSymbol* field_unwrap_sym = v__ast__Table_final_sym(g->table, field_unwrap_typ); bool is_auto_deref_var = v__ast__Expr_is_auto_deref_var(sfield.expr); if ((field_unwrap_sym->info)._typ == 549 /* v.ast.ArrayFixed */ && !v__ast__Type_has_flag(sfield.expected_type, v__ast__TypeFlag__option)) { if (sfield.expr._typ == 358 /* v.ast.Ident */) { v__gen__c__Gen_fixed_array_var_init(g, v__gen__c__Gen_expr_string(g, sfield.expr), is_auto_deref_var, (*field_unwrap_sym->info._v__ast__ArrayFixed).elem_type, (*field_unwrap_sym->info._v__ast__ArrayFixed).size); } else if (sfield.expr._typ == 379 /* v.ast.SelectorExpr */) { v__gen__c__Gen_fixed_array_var_init(g, v__gen__c__Gen_expr_string(g, sfield.expr), is_auto_deref_var, (*field_unwrap_sym->info._v__ast__ArrayFixed).elem_type, (*field_unwrap_sym->info._v__ast__ArrayFixed).size); } else if (sfield.expr._typ == 345 /* v.ast.CastExpr */) { string tmp_var = v__gen__c__Gen_expr_with_var(g, sfield.expr, sfield.expected_type, false); v__gen__c__Gen_fixed_array_var_init(g, tmp_var, false, (*field_unwrap_sym->info._v__ast__ArrayFixed).elem_type, (*field_unwrap_sym->info._v__ast__ArrayFixed).size); } else if (sfield.expr._typ == 344 /* v.ast.CallExpr */) { string tmp_var = v__gen__c__Gen_expr_with_var(g, sfield.expr, sfield.expected_type, false); v__gen__c__Gen_fixed_array_var_init(g, tmp_var, false, (*field_unwrap_sym->info._v__ast__ArrayFixed).elem_type, (*field_unwrap_sym->info._v__ast__ArrayFixed).size); } else if (sfield.expr._typ == 338 /* v.ast.ArrayInit */) { if ((*sfield.expr._v__ast__ArrayInit).has_index) { string tmp_var = v__gen__c__Gen_expr_with_var(g, sfield.expr, sfield.expected_type, false); v__gen__c__Gen_fixed_array_var_init(g, tmp_var, false, (*field_unwrap_sym->info._v__ast__ArrayFixed).elem_type, (*field_unwrap_sym->info._v__ast__ArrayFixed).size); } else if ((*sfield.expr._v__ast__ArrayInit).has_callexpr) { string tmp_var = v__gen__c__Gen_expr_with_fixed_array(g, sfield.expr, sfield.typ, sfield.expected_type); v__gen__c__Gen_fixed_array_var_init(g, tmp_var, false, (*field_unwrap_sym->info._v__ast__ArrayFixed).elem_type, (*field_unwrap_sym->info._v__ast__ArrayFixed).size); } else { v__gen__c__Gen_struct_init_field_default(g, field_unwrap_typ, (voidptr)&sfield, *field_unwrap_sym); } } else { v__gen__c__Gen_struct_init_field_default(g, field_unwrap_typ, (voidptr)&sfield, *field_unwrap_sym); } } else { v__gen__c__Gen_struct_init_field_default(g, field_unwrap_typ, (voidptr)&sfield, *field_unwrap_sym); } g->inside_cast_in_heap = inside_cast_in_heap; } } VV_LOC void v__gen__c__Gen_struct_init_field_default(v__gen__c__Gen* g, v__ast__Type field_unwrap_typ, v__ast__StructInitField* sfield, v__ast__TypeSymbol field_unwrap_sym) { if (field_unwrap_typ != _const_v__ast__voidptr_type && field_unwrap_typ != _const_v__ast__nil_type && (v__ast__Type_is_ptr(sfield->expected_type) && !v__ast__Type_has_flag(sfield->expected_type, v__ast__TypeFlag__shared_f)) && !v__ast__Type_has_flag(sfield->expected_type, v__ast__TypeFlag__option) && !v__ast__Type_is_any_kind_of_pointer(field_unwrap_typ) && !v__ast__Type_is_number(field_unwrap_typ)) { v__gen__c__Gen_write(g, _S("/* autoref */&")); } if ((v__ast__Type_has_flag(sfield->expected_type, v__ast__TypeFlag__option) && !v__ast__Type_has_flag(field_unwrap_typ, v__ast__TypeFlag__option)) || (v__ast__Type_has_flag(sfield->expected_type, v__ast__TypeFlag__result) && !v__ast__Type_has_flag(field_unwrap_typ, v__ast__TypeFlag__result))) { v__gen__c__Gen_expr_with_opt(g, sfield->expr, field_unwrap_typ, sfield->expected_type); } else if ((sfield->expr)._typ == 365 /* v.ast.LambdaExpr */ && v__ast__Type_has_flag(sfield->expected_type, v__ast__TypeFlag__option)) { v__gen__c__Gen_expr_opt_with_cast(g, sfield->expr, field_unwrap_typ, sfield->expected_type); } else if (field_unwrap_sym.kind == v__ast__Kind__function && v__ast__Type_has_flag(sfield->expected_type, v__ast__TypeFlag__option)) { string tmp_out_var = v__gen__c__Gen_new_tmp_var(g); v__gen__c__Gen_expr_with_tmp_var(g, sfield->expr, field_unwrap_typ, sfield->expected_type, tmp_out_var); } else { g->left_is_opt = true; v__gen__c__Gen_expr_with_cast(g, sfield->expr, field_unwrap_typ, sfield->expected_type); } } VV_LOC void v__gen__c__Gen_write(v__gen__c__Gen* g, string s) { ; ; if (g->indent > 0 && g->empty_line) { strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); } strings__Builder_write_string(&g->out, s); g->empty_line = false; } VV_LOC void v__gen__c__Gen_write2(v__gen__c__Gen* g, string s1, string s2) { ; ; if (g->indent > 0 && g->empty_line) { strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); } strings__Builder_write_string(&g->out, s1); g->empty_line = false; ; if (g->indent > 0 && g->empty_line) { strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); } strings__Builder_write_string(&g->out, s2); g->empty_line = false; } VV_LOC void v__gen__c__Gen_write_decimal(v__gen__c__Gen* g, i64 x) { ; if (g->indent > 0 && g->empty_line) { strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); } strings__Builder_write_decimal(&g->out, x); g->empty_line = false; } VV_LOC void v__gen__c__Gen_writeln(v__gen__c__Gen* g, string s) { ; ; if (g->indent > 0 && g->empty_line) { strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); } strings__Builder_writeln(&g->out, s); g->empty_line = true; } VV_LOC void v__gen__c__Gen_writeln2(v__gen__c__Gen* g, string s1, string s2) { ; ; if (g->indent > 0 && g->empty_line) { strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); } strings__Builder_writeln(&g->out, s1); g->empty_line = true; ; if (g->indent > 0 && g->empty_line) { strings__Builder_write_string(&g->out, v__util__tabs(g->indent)); } strings__Builder_writeln(&g->out, s2); g->empty_line = true; } VV_LOC void v__gen__c__Gen_go_back(v__gen__c__Gen* g, int n) { strings__Builder_go_back(&g->out, n); } VV_LOC void v__gen__c__Gen_go_back_to(v__gen__c__Gen* g, int n) { strings__Builder_go_back_to(&g->out, n); } inline VV_LOC int v__gen__c__Gen_nth_stmt_pos(v__gen__c__Gen* g, int n) { return (*(int*)array_get(g->stmt_path_pos, (int)(g->stmt_path_pos.len - ((int)(1 + n))))); } inline VV_LOC void v__gen__c__Gen_set_current_pos_as_last_stmt_pos(v__gen__c__Gen* g) { array_push((array*)&g->stmt_path_pos, _MOV((int[]){ g->out.len })); } inline VV_LOC string v__gen__c__Gen_go_before_last_stmt(v__gen__c__Gen* g) { return strings__Builder_cut_to(&g->out, v__gen__c__Gen_nth_stmt_pos(g, 0)); } inline VV_LOC string v__gen__c__Gen_go_before_ternary(v__gen__c__Gen* g) { return strings__Builder_cut_to(&g->out, v__gen__c__Gen_nth_stmt_pos(g, g->inside_ternary)); } VV_LOC void v__gen__c__Gen_insert_before_stmt(v__gen__c__Gen* g, string s) { string cur_line = strings__Builder_cut_to(&g->out, v__gen__c__Gen_nth_stmt_pos(g, g->inside_ternary)); v__gen__c__Gen_writeln(g, s); v__gen__c__Gen_write(g, cur_line); } VV_LOC void v__gen__c__Gen_insert_at(v__gen__c__Gen* g, int pos, string s) { string cur_line = strings__Builder_cut_to(&g->out, pos); v__gen__c__Gen_writeln(g, s); v__gen__c__Gen_write(g, cur_line); for (int index = 0; index < g->stmt_path_pos.len; ++index) { int stmt_pos = ((int*)g->stmt_path_pos.data)[index]; if (stmt_pos >= pos) { (*(int*)array_get(g->stmt_path_pos, index)) += (int)(s.len + 1); } } } VV_LOC v__ast__Type v__gen__c__Gen_unwrap_generic(v__gen__c__Gen* g, v__ast__Type typ) { if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__generic)) { if (g->cur_fn != ((void*)0) && g->cur_fn->generic_names.len > 0) { _option_v__ast__Type _t1; if (_t1 = v__ast__Table_convert_generic_type(g->table, typ, g->cur_fn->generic_names, g->cur_concrete_types), _t1.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t1.data; return t_typ; } } else if (g->inside_struct_init) { if (g->cur_struct_init_typ != 0) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, g->cur_struct_init_typ); if ((sym->info)._typ == 518 /* v.ast.Struct */) { if ((*sym->info._v__ast__Struct).generic_types.len > 0) { Array_string _t3 = {0}; Array_v__ast__Type _t3_orig = (*sym->info._v__ast__Struct).generic_types; int _t3_len = _t3_orig.len; _t3 = __new_array(0, _t3_len, sizeof(string)); for (int _t5 = 0; _t5 < _t3_len; ++_t5) { v__ast__Type it = ((v__ast__Type*) _t3_orig.data)[_t5]; string _t4 = v__ast__Table_sym(g->table, it)->name; array_push((array*)&_t3, &_t4); } Array_string generic_names =_t3; _option_v__ast__Type _t6; if (_t6 = v__ast__Table_convert_generic_type(g->table, typ, generic_names, (*sym->info._v__ast__Struct).concrete_types), _t6.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t6.data; return t_typ; } } } } } else if (v__ast__Table_sym(g->table, typ)->kind == v__ast__Kind__struct) { v__ast__TypeSymbol* sym = v__ast__Table_sym(g->table, typ); if ((sym->info)._typ == 518 /* v.ast.Struct */) { if ((*sym->info._v__ast__Struct).generic_types.len > 0) { Array_string _t8 = {0}; Array_v__ast__Type _t8_orig = (*sym->info._v__ast__Struct).generic_types; int _t8_len = _t8_orig.len; _t8 = __new_array(0, _t8_len, sizeof(string)); for (int _t10 = 0; _t10 < _t8_len; ++_t10) { v__ast__Type it = ((v__ast__Type*) _t8_orig.data)[_t10]; string _t9 = v__ast__Table_sym(g->table, it)->name; array_push((array*)&_t8, &_t9); } Array_string generic_names =_t8; _option_v__ast__Type _t11; if (_t11 = v__ast__Table_convert_generic_type(g->table, typ, generic_names, (*sym->info._v__ast__Struct).concrete_types), _t11.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t11.data; return t_typ; } _option_v__ast__Type _t13; if (_t13 = v__ast__Table_convert_generic_type(g->table, typ, generic_names, g->cur_concrete_types), _t13.state == 0) { v__ast__Type t_typ = *(v__ast__Type*)_t13.data; return t_typ; } } } } } return typ; } VV_LOC v__gen__c__Type v__gen__c__Gen_unwrap(v__gen__c__Gen* g, v__ast__Type typ) { v__ast__Type no_generic = v__gen__c__Gen_unwrap_generic(g, typ); v__ast__TypeSymbol* no_generic_sym = v__ast__Table_sym(g->table, no_generic); if (no_generic_sym->kind != v__ast__Kind__alias) { return ((v__gen__c__Type){.typ = no_generic,.sym = no_generic_sym,.unaliased = no_generic,.unaliased_sym = no_generic_sym,}); } return ((v__gen__c__Type){.typ = no_generic,.sym = no_generic_sym,.unaliased = no_generic_sym->parent_idx,.unaliased_sym = v__ast__Table_sym(g->table, v__ast__idx_to_type(no_generic_sym->parent_idx)),}); } VV_LOC string v__gen__c__Gen_fn_var_signature(v__gen__c__Gen* g, v__ast__Type return_type, Array_v__ast__Type arg_types, string var_name) { string ret_styp = v__gen__c__Gen_styp(g, return_type); string sig = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ret_styp}}, {_S(" (*"), 0xfe10, {.d_s = v__gen__c__c_name(var_name)}}, {_S(") ("), 0, { .d_c = 0 }}})); for (int j = 0; j < arg_types.len; ++j) { v__ast__Type arg_typ = ((v__ast__Type*)arg_types.data)[j]; v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(g->table, arg_typ); if ((arg_sym->info)._typ == 553 /* v.ast.FnType */) { v__ast__Fn func = (*arg_sym->info._v__ast__FnType).func; Array_v__ast__Type _t1 = {0}; Array_v__ast__Param _t1_orig = func.params; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Param it = ((v__ast__Param*) _t1_orig.data)[_t3]; v__ast__Type _t2 = it.typ; array_push((array*)&_t1, &_t2); } string arg_sig = v__gen__c__Gen_fn_var_signature(g, func.return_type,_t1, _S("")); sig = string__plus(sig, arg_sig); } else { string arg_styp = v__gen__c__Gen_styp(g, arg_typ); sig = string__plus(sig, arg_styp); } if (j < (int)(arg_types.len - 1)) { sig = string__plus(sig, _S(", ")); } } sig = string__plus(sig, _S(")")); return sig; } VV_LOC string v__gen__c__Gen_anon_fn_cname(v__gen__c__Gen* g, v__ast__Type return_type, Array_v__ast__Type arg_types) { string ret_styp = string_replace(v__gen__c__Gen_styp(g, return_type), _S("*"), _S("_ptr")); string sig = str_intp(2, _MOV((StrIntpData[]){{_S("anon_fn_"), 0xfe10, {.d_s = ret_styp}}, {_S("_"), 0, { .d_c = 0 }}})); for (int j = 0; j < arg_types.len; ++j) { v__ast__Type arg_typ = ((v__ast__Type*)arg_types.data)[j]; v__ast__TypeSymbol* arg_sym = v__ast__Table_sym(g->table, arg_typ); if ((arg_sym->info)._typ == 553 /* v.ast.FnType */) { Array_v__ast__Type _t1 = {0}; Array_v__ast__Param _t1_orig = (*arg_sym->info._v__ast__FnType).func.params; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(v__ast__Type)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__Param it = ((v__ast__Param*) _t1_orig.data)[_t3]; v__ast__Type _t2 = it.typ; array_push((array*)&_t1, &_t2); } sig = string__plus(sig, v__gen__c__Gen_anon_fn_cname(g, (*arg_sym->info._v__ast__FnType).func.return_type,_t1)); } else { sig = string__plus(sig, string_replace(v__gen__c__Gen_styp(g, arg_typ), _S("*"), _S("_ptr"))); } if (j < (int)(arg_types.len - 1)) { sig = string__plus(sig, _S("_")); } } return sig; } VV_LOC string v__gen__c__escape_quotes(string val) { string bs = _S("\\"); string unescaped_val = string_replace_each(string_replace(val, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = bs}}, {_SLIT0, 0xfe10, {.d_s = bs}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("\001")), new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = bs}}, {_S("'"), 0, { .d_c = 0 }}})), _S("'"), str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = bs}}, {_S("\""), 0, { .d_c = 0 }}})), _S("\"")}))); return string_replace_each(unescaped_val, new_array_from_c_array(6, 6, sizeof(string), _MOV((string[6]){_S("\001"), str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = bs}}, {_SLIT0, 0xfe10, {.d_s = bs}}, {_SLIT0, 0, { .d_c = 0 }}})), _S("'"), str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = bs}}, {_S("'"), 0, { .d_c = 0 }}})), _S("\""), str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = bs}}, {_S("\""), 0, { .d_c = 0 }}}))}))); } inline VV_LOC string v__gen__c__Gen_dot_or_ptr(v__gen__c__Gen* g, v__ast__Type val_type) { return (v__ast__Type_has_flag(val_type, v__ast__TypeFlag__shared_f) ? (_S("->val.")) : v__ast__Type_is_ptr(val_type) ? (_S("->")) : (_S("."))); } VV_LOC void v__gen__c__Gen_unwrap_option_type(v__gen__c__Gen* g, v__ast__Type typ, string name, bool is_auto_heap) { string styp = v__gen__c__Gen_base_type(g, typ); if (is_auto_heap) { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S("->data)")); } } else { v__ast__TypeSymbol* type_sym = v__ast__Table_sym(g->table, typ); if (type_sym->kind == v__ast__Kind__alias) { v__ast__Type parent_typ = (*(v__ast__Alias*)__as_cast((type_sym->info)._v__ast__Alias,(type_sym->info)._typ, 539)).parent_type; if (v__ast__Type_has_flag(parent_typ, v__ast__TypeFlag__option)) { { v__gen__c__Gen_write(g, _S("*((")); v__gen__c__Gen_write(g, v__gen__c__Gen_base_type(g, parent_typ)); v__gen__c__Gen_write(g, _S("*)")); } } { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S(".data)")); } if (v__ast__Type_has_flag(parent_typ, v__ast__TypeFlag__option)) { v__gen__c__Gen_write(g, _S(".data)")); } } else if (v__ast__Type_has_flag(typ, v__ast__TypeFlag__option_mut_param_t)) { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S("->data)")); } } else { { v__gen__c__Gen_write(g, _S("(*(")); v__gen__c__Gen_write(g, styp); v__gen__c__Gen_write(g, _S("*)")); v__gen__c__Gen_write(g, name); v__gen__c__Gen_write(g, _S(".data)")); } } } } v__builder__Builder v__builder__new_builder(v__pref__Preferences* pref_) { string rdir = os__real_path(pref_->path); string compiled_dir = (os__is_dir(rdir) ? (rdir) : (os__dir(rdir))); v__ast__Table* table = v__ast__new_table(); table->is_fmt = false; if (pref_->use_color == v__pref__ColorOutput__always) { v__util__EManager_set_support_color(_const_v__util__emanager, true); } if (pref_->use_color == v__pref__ColorOutput__never) { v__util__EManager_set_support_color(_const_v__util__emanager, false); } table->pointer_size = (pref_->m64 ? (8) : (4)); v__builder__MsvcResult msvc = ((v__builder__MsvcResult){.full_cl_exe_path = (string){.str=(byteptr)"", .is_lit=1},.exe_path = (string){.str=(byteptr)"", .is_lit=1},.um_lib_path = (string){.str=(byteptr)"", .is_lit=1},.ucrt_lib_path = (string){.str=(byteptr)"", .is_lit=1},.vs_lib_path = (string){.str=(byteptr)"", .is_lit=1},.um_include_path = (string){.str=(byteptr)"", .is_lit=1},.ucrt_include_path = (string){.str=(byteptr)"", .is_lit=1},.vs_include_path = (string){.str=(byteptr)"", .is_lit=1},.shared_include_path = (string){.str=(byteptr)"", .is_lit=1},.valid = 0,}); if (fast_string_eq(pref_->ccompiler, _S("msvc"))) { #if defined(_WIN32) { _result_v__builder__MsvcResult _t2 = v__builder__find_msvc(pref_->m64); if (_t2.is_error) { IError err = _t2.err; *(v__builder__MsvcResult*) _t2.data = ((v__builder__MsvcResult){.full_cl_exe_path = (string){.str=(byteptr)"", .is_lit=1},.exe_path = (string){.str=(byteptr)"", .is_lit=1},.um_lib_path = (string){.str=(byteptr)"", .is_lit=1},.ucrt_lib_path = (string){.str=(byteptr)"", .is_lit=1},.vs_lib_path = (string){.str=(byteptr)"", .is_lit=1},.um_include_path = (string){.str=(byteptr)"", .is_lit=1},.ucrt_include_path = (string){.str=(byteptr)"", .is_lit=1},.vs_include_path = (string){.str=(byteptr)"", .is_lit=1},.shared_include_path = (string){.str=(byteptr)"", .is_lit=1},.valid = false,}); } msvc = (*(v__builder__MsvcResult*)_t2.data); } #endif } v__util__timing_set_should_print(pref_->show_timings || pref_->is_verbose); if (pref_->show_callgraph || pref_->show_depgraph) { v__dotgraph__start_digraph(); } string executable_name = pref_->out_name; #if defined(_WIN32) { executable_name = string__plus(executable_name, _S(".exe")); } #endif return ((v__builder__Builder){ .compiled_dir = compiled_dir, .module_path = (string){.str=(byteptr)"", .is_lit=1}, .checker = v__checker__new_checker(table, pref_), .transformer = v__transformer__new_transformer_with_table(table, pref_), .out_name_c = (string){.str=(byteptr)"", .is_lit=1}, .out_name_js = (string){.str=(byteptr)"", .is_lit=1}, .stats_lines = 0, .stats_bytes = 0, .nr_errors = 0, .nr_warnings = 0, .nr_notices = 0, .pref = pref_, .module_search_paths = __new_array(0, 0, sizeof(string)), .parsed_files = __new_array(0, 0, sizeof(v__ast__File*)), .cached_msvc = msvc, .table = table, .ccoptions = ((v__builder__CcompilerOptions){.guessed_compiler = (string){.str=(byteptr)"", .is_lit=1},.shared_postfix = (string){.str=(byteptr)"", .is_lit=1},.debug_mode = 0,.cc = 0,.env_cflags = (string){.str=(byteptr)"", .is_lit=1},.env_ldflags = (string){.str=(byteptr)"", .is_lit=1},.args = __new_array(0, 0, sizeof(string)),.wargs = __new_array(0, 0, sizeof(string)),.pre_args = __new_array(0, 0, sizeof(string)),.o_args = __new_array(0, 0, sizeof(string)),.source_args = __new_array(0, 0, sizeof(string)),.post_args = __new_array(0, 0, sizeof(string)),.linker_flags = __new_array(0, 0, sizeof(string)),.ldflags = __new_array(0, 0, sizeof(string)),}), .mod_invalidates_paths = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .mod_invalidates_mods = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .path_invalidates_mods = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string), .crun_cache_keys = __new_array(0, 0, sizeof(string)), .executable_exists = os__is_file(executable_name), .str_args = (string){.str=(byteptr)"", .is_lit=1}, }); } _result_void v__builder__Builder_front_stages(v__builder__Builder* b, Array_string v_files) { bool v__builder__Builder_front_stages_defer_0 = false; v__util__Timers* timers; timers = v__util__get_timers(); v__util__timing_start(_S("ALL_FRONT_STAGES")); v__builder__Builder_front_stages_defer_0 = true; v__util__timing_start(_S("PARSE")); v__util__timing_start(_S("Builder.front_stages.parse_files")); b->parsed_files = v__parser__parse_files(v_files, b->table, b->pref); v__util__Timers_show(timers, _S("Builder.front_stages.parse_files")); v__builder__Builder_parse_imports(b); v__util__Timers_show(timers, _S("SCAN")); v__util__Timers_show(timers, _S("PARSE")); v__util__Timers_show_if_exists(timers, _S("PARSE stmt")); if (b->pref->only_check_syntax) { _result_void _t1 = (_result_void){ .is_error=true, .err=error_with_code(_S("stop_after_parser"), 7001), .data={E_STRUCT} }; // Defer begin if (v__builder__Builder_front_stages_defer_0) { v__util__Timers_show(timers, _S("ALL_FRONT_STAGES")); } // Defer end return _t1; } // Defer begin if (v__builder__Builder_front_stages_defer_0) { v__util__Timers_show(timers, _S("ALL_FRONT_STAGES")); } // Defer end return (_result_void){0}; } _result_void v__builder__Builder_middle_stages(v__builder__Builder* b) { v__util__timing_start(_S("CHECK")); v__util__timing_start(_S("Checker.generic_insts_to_concrete")); v__ast__Table_generic_insts_to_concrete(b->table); v__util__timing_measure(_S("Checker.generic_insts_to_concrete")); v__checker__Checker_check_files(b->checker, b->parsed_files); v__util__timing_measure(_S("CHECK")); if ((b->pref->dump_defines).len != 0) { v__builder__Builder_dump_defines(b); } v__vmod__ModFileCacher* mcache = v__vmod__get_cache(); ; v__builder__Builder_print_warnings_and_errors(b); if (b->checker->should_abort) { return (_result_void){ .is_error=true, .err=_v_error(_S("too many errors/warnings/notices")), .data={E_STRUCT} }; } if (b->checker->unresolved_fixed_sizes.len > 0) { v__util__timing_start(_S("Checker.update_unresolved_fixed_sizes")); v__checker__Checker_update_unresolved_fixed_sizes(b->checker); v__util__timing_measure(_S("Checker.update_unresolved_fixed_sizes")); } if (b->pref->check_only) { return (_result_void){ .is_error=true, .err=error_with_code(_S("stop_after_checker"), 8001), .data={E_STRUCT} }; } v__util__timing_start(_S("TRANSFORM")); v__transformer__Transformer_transform_files(b->transformer, b->parsed_files); v__util__timing_measure(_S("TRANSFORM")); v__ast__Table_complete_interface_check(b->table); if (b->pref->skip_unused) { v__markused__mark_used(b->table, b->pref, b->parsed_files); } if (b->pref->show_callgraph) { v__callgraph__show(b->table, b->pref, b->parsed_files); } return (_result_void){0}; } _result_void v__builder__Builder_front_and_middle_stages(v__builder__Builder* b, Array_string v_files) { _result_void _t1 = v__builder__Builder_front_stages(b, v_files); if (_t1.is_error) { _result_void _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } ; _result_void _t3 = v__builder__Builder_middle_stages(b); if (_t3.is_error) { _result_void _t4 = {0}; _t4.is_error = true; _t4.err = _t3.err; return _t4; } ; return (_result_void){0}; } void v__builder__Builder_parse_imports(v__builder__Builder* b) { bool v__builder__Builder_parse_imports_defer_0 = false; v__util__timing_start(_S("Builder.parse_imports")); v__builder__Builder_parse_imports_defer_0 = true; Array_string done_imports = __new_array_with_default(0, 0, sizeof(string), 0); if (b->pref->is_vsh) { array_push((array*)&done_imports, _MOV((string[]){ _S("os") })); } for (int _t2 = 0; _t2 < b->parsed_files.len; ++_t2) { v__ast__File* file = ((v__ast__File**)b->parsed_files.data)[_t2]; if (!fast_string_eq(file->mod.name, _S("main")) && !(Array_string_contains(done_imports, file->mod.name))) { array_push((array*)&done_imports, _MOV((string[]){ string_clone(file->mod.name) })); } } for (int i = 0; i < b->parsed_files.len; i++) { v__ast__File* ast_file = (*(v__ast__File**)array_get(b->parsed_files, i)); array_push((array*)&(*(Array_string*)map_get_and_set((map*)&b->path_invalidates_mods, &(string[]){ast_file->path}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })), _MOV((string[]){ string_clone(ast_file->mod.name) })); if (!fast_string_eq(ast_file->mod.name, _S("builtin"))) { array_push((array*)&(*(Array_string*)map_get_and_set((map*)&b->mod_invalidates_paths, &(string[]){_S("builtin")}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })), _MOV((string[]){ string_clone(ast_file->path) })); array_push((array*)&(*(Array_string*)map_get_and_set((map*)&b->mod_invalidates_mods, &(string[]){_S("builtin")}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })), _MOV((string[]){ string_clone(ast_file->mod.name) })); } for (int _t7 = 0; _t7 < ast_file->imports.len; ++_t7) { v__ast__Import imp = ((v__ast__Import*)ast_file->imports.data)[_t7]; string mod = imp.mod; array_push((array*)&(*(Array_string*)map_get_and_set((map*)&b->mod_invalidates_paths, &(string[]){mod}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })), _MOV((string[]){ string_clone(ast_file->path) })); array_push((array*)&(*(Array_string*)map_get_and_set((map*)&b->mod_invalidates_mods, &(string[]){mod}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })), _MOV((string[]){ string_clone(ast_file->mod.name) })); if (_SLIT_EQ(mod.str, mod.len, "builtin")) { array_push((array*)&(*(v__ast__File**)array_get(b->parsed_files, i))->errors, _MOV((v__errors__Error[]){ v__builder__Builder_error_with_pos(b, _S("cannot import module \"builtin\""), ast_file->path, imp.pos) })); break; } if ((Array_string_contains(done_imports, mod))) { continue; } _result_string _t11 = v__builder__Builder_find_module_path(b, mod, ast_file->path); if (_t11.is_error) { IError err = _t11.err; array_push((array*)&(*(v__ast__File**)array_get(b->parsed_files, i))->errors, _MOV((v__errors__Error[]){ v__builder__Builder_error_with_pos(b, str_intp(2, _MOV((StrIntpData[]){{_S("cannot import module \""), 0xfe10, {.d_s = mod}}, {_S("\" (not found)"), 0, { .d_c = 0 }}})), ast_file->path, imp.pos) })); break; } string import_path = (*(string*)_t11.data); Array_string v_files = v__builder__Builder_v_files_from_dir(b, import_path); if (v_files.len == 0) { array_push((array*)&(*(v__ast__File**)array_get(b->parsed_files, i))->errors, _MOV((v__errors__Error[]){ v__builder__Builder_error_with_pos(b, str_intp(3, _MOV((StrIntpData[]){{_S("cannot import module \""), 0xfe10, {.d_s = mod}}, {_S("\" (no .v files in \""), 0xfe10, {.d_s = import_path}}, {_S("\")"), 0, { .d_c = 0 }}})), ast_file->path, imp.pos) })); continue; } Array_v__ast__File_ptr parsed_files = v__parser__parse_files(v_files, b->table, b->pref); for (int _t14 = 0; _t14 < parsed_files.len; ++_t14) { v__ast__File* file = ((v__ast__File**)parsed_files.data)[_t14]; string name = file->mod.name; if ((name).len == 0) { name = file->mod.short_name; } string sname = string_all_after_last(name, _S(".")); string smod = string_all_after_last(mod, _S(".")); if (!string__eq(sname, smod)) { string msg = str_intp(5, _MOV((StrIntpData[]){{_S("bad module definition: "), 0xfe10, {.d_s = ast_file->path}}, {_S(" imports module \""), 0xfe10, {.d_s = mod}}, {_S("\" but "), 0xfe10, {.d_s = file->path}}, {_S(" is defined as module `"), 0xfe10, {.d_s = name}}, {_S("`"), 0, { .d_c = 0 }}})); array_push((array*)&(*(v__ast__File**)array_get(b->parsed_files, i))->errors, _MOV((v__errors__Error[]){ v__builder__Builder_error_with_pos(b, msg, ast_file->path, imp.pos) })); } } _PUSH_MANY(&b->parsed_files, (parsed_files), _t16, Array_v__ast__File_ptr); array_push((array*)&done_imports, _MOV((string[]){ string_clone(mod) })); } } v__builder__Builder_resolve_deps(b); #if defined(CUSTOM_DEFINE_trace_parsed_files) { v__builder__Builder_show_parsed_files(b); } #endif if (b->pref->print_v_files) { v__builder__Builder_show_parsed_files(b); _v_exit(0); VUNREACHABLE(); } if (b->pref->print_watched_files) { for (int _t19 = 0; _t19 < b->parsed_files.len; ++_t19) { v__ast__File* p = ((v__ast__File**)b->parsed_files.data)[_t19]; if (p->is_parse_text) { continue; } println(p->path); for (int _t20 = 0; _t20 < p->template_paths.len; ++_t20) { string tp = ((string*)p->template_paths.data)[_t20]; println(tp); } } _v_exit(0); VUNREACHABLE(); } if ((b->pref->dump_files).len != 0) { Array_string _t21 = {0}; Array_v__ast__File_ptr _t21_orig = b->parsed_files; int _t21_len = _t21_orig.len; _t21 = __new_array(0, _t21_len, sizeof(string)); for (int _t23 = 0; _t23 < _t21_len; ++_t23) { v__ast__File* it = ((v__ast__File**) _t21_orig.data)[_t23]; string _t22 = it->path; array_push((array*)&_t21, &_t22); } v__builder__Builder_dump_files(b,_t21); } v__builder__Builder_rebuild_modules(b); // Defer begin if (v__builder__Builder_parse_imports_defer_0) { v__util__timing_measure(_S("Builder.parse_imports")); } // Defer end } void v__builder__Builder_resolve_deps(v__builder__Builder* b) { bool v__builder__Builder_resolve_deps_defer_0 = false; v__util__timing_start(_S("Builder.resolve_deps")); v__builder__Builder_resolve_deps_defer_0 = true; v__depgraph__DepGraph* graph = v__builder__Builder_import_graph(b); v__depgraph__DepGraph* deps_resolved = v__depgraph__DepGraph_resolve(graph); if (b->pref->is_verbose) { eprintln(_S("------ resolved dependencies graph: ------")); eprintln(v__depgraph__DepGraph_display(deps_resolved)); eprintln(_S("------------------------------------------")); } if (b->pref->show_depgraph) { v__depgraph__show(deps_resolved, b->pref->path); } string cycles = v__depgraph__DepGraph_display_cycles(deps_resolved); if (cycles.len > 1) { v__builder__verror(string__plus(_S("error: import cycle detected between the following modules: \n"), cycles)); VUNREACHABLE(); } Array_string mods = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < deps_resolved->nodes.len; ++_t1) { v__depgraph__DepGraphNode node = ((v__depgraph__DepGraphNode*)deps_resolved->nodes.data)[_t1]; array_push((array*)&mods, _MOV((string[]){ string_clone(node.name) })); } v__builder__Builder_dump_modules(b, mods); if (b->pref->is_verbose) { eprintln(_S("------ imported modules: ------")); eprintln(Array_string_str(mods)); eprintln(_S("-------------------------------")); } { // Unsafe block Array_v__ast__File_ptr reordered_parsed_files = __new_array_with_default(0, 0, sizeof(v__ast__File*), 0); for (int _t3 = 0; _t3 < mods.len; ++_t3) { string m = ((string*)mods.data)[_t3]; for (int _t4 = 0; _t4 < b->parsed_files.len; ++_t4) { v__ast__File* pf = ((v__ast__File**)b->parsed_files.data)[_t4]; if (string__eq(m, pf->mod.name)) { array_push((array*)&reordered_parsed_files, _MOV((v__ast__File*[]){ pf })); } } } b->table->modules = mods; b->parsed_files = reordered_parsed_files; } // Defer begin if (v__builder__Builder_resolve_deps_defer_0) { v__util__timing_measure(_S("Builder.resolve_deps")); } // Defer end } v__depgraph__DepGraph* v__builder__Builder_import_graph(v__builder__Builder* b) { Array_string builtins = array_clone_to_depth(&_const_v__util__builtin_module_parts, 0); v__depgraph__DepGraph* graph = v__depgraph__new_dep_graph(); for (int _t1 = 0; _t1 < b->parsed_files.len; ++_t1) { v__ast__File* p = ((v__ast__File**)b->parsed_files.data)[_t1]; Array_string deps = __new_array_with_default(0, 0, sizeof(string), 0); if (!(Array_string_contains(builtins, p->mod.name))) { array_push((array*)&deps, _MOV((string[]){ _S("builtin") })); if (b->pref->backend == v__pref__Backend__c) { if (b->pref->is_vsh && !(fast_string_eq(p->mod.name, _S("os")) || fast_string_eq(p->mod.name, _S("dl")) || fast_string_eq(p->mod.name, _S("strings.textscanner")) || fast_string_eq(p->mod.name, _S("term.termios")))) { array_push((array*)&deps, _MOV((string[]){ _S("os") })); } } } for (int _t4 = 0; _t4 < p->imports.len; ++_t4) { v__ast__Import m = ((v__ast__Import*)p->imports.data)[_t4]; if (string__eq(m.mod, p->mod.name)) { continue; } array_push((array*)&deps, _MOV((string[]){ string_clone(m.mod) })); } v__depgraph__DepGraph_add(graph, p->mod.name, deps); } #if defined(CUSTOM_DEFINE_trace_import_graph) { eprintln(v__depgraph__DepGraph_display(graph)); } #endif return graph; } Array_string v__builder__Builder_v_files_from_dir(v__builder__Builder* b, string dir) { if (!os__exists(dir)) { if (_SLIT_EQ(dir.str, dir.len, "compiler") && os__is_dir(_S("vlib"))) { println(_S("looks like you are trying to build V with an old command")); println(_S("use `v -o v cmd/v` instead of `v -o v compiler`")); } v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = dir}}, {_S(" doesn't exist"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } else if (!os__is_dir(dir)) { v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = dir}}, {_S(" isn't a directory!"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } _result_Array_string _t1 = os__ls(dir); if (_t1.is_error) { IError err = _t1.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } Array_string files = (*(Array_string*)_t1.data); if (b->pref->is_verbose) { println(str_intp(2, _MOV((StrIntpData[]){{_S("v_files_from_dir (\""), 0xfe10, {.d_s = dir}}, {_S("\")"), 0, { .d_c = 0 }}}))); } Array_string res = v__pref__Preferences_should_compile_filtered_files(b->pref, dir, files); if (res.len == 0) { string src_path = os__join_path(dir, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("src")}))); if (os__is_dir(src_path)) { if (b->pref->is_verbose) { println(str_intp(2, _MOV((StrIntpData[]){{_S("v_files_from_dir (\""), 0xfe10, {.d_s = src_path}}, {_S("\") (/src/)"), 0, { .d_c = 0 }}}))); } _result_Array_string _t2 = os__ls(src_path); if (_t2.is_error) { IError err = _t2.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } files = (*(Array_string*)_t2.data); return v__pref__Preferences_should_compile_filtered_files(b->pref, src_path, files); } } return res; } void v__builder__Builder_log(v__builder__Builder* b, string s) { if (b->pref->is_verbose) { println(s); } } void v__builder__Builder_info(v__builder__Builder* b, string s) { if (b->pref->is_verbose) { println(s); } } inline string v__builder__module_path(string mod) { return string_replace(mod, _S("."), _const_os__path_separator); } _result_string v__builder__Builder_find_module_path(v__builder__Builder* b, string mod, string fpath) { v__vmod__ModFileCacher* mcache = v__vmod__get_cache(); v__vmod__ModFileAndFolder vmod_file_location = v__vmod__ModFileCacher_get_by_file(mcache, fpath); string mod_path = v__builder__module_path(mod); Array_string module_lookup_paths = __new_array_with_default(0, 0, sizeof(string), 0); if (vmod_file_location.vmod_file.len != 0 && !(Array_string_contains(b->module_search_paths, vmod_file_location.vmod_folder))) { array_push((array*)&module_lookup_paths, _MOV((string[]){ string_clone(vmod_file_location.vmod_folder) })); } _PUSH_MANY(&module_lookup_paths, (b->module_search_paths), _t2, Array_string); array_push((array*)&module_lookup_paths, _MOV((string[]){ os__getwd() })); if (string_contains(fpath, _S("/modules/"))) { Array_string parts = string_split(fpath, _const_os__path_separator); for (int i = (int)(parts.len - 2); i >= 0; i--) { if (string__eq((*(string*)array_get(parts, i)), _S("modules"))) { array_push((array*)&module_lookup_paths, _MOV((string[]){ Array_string_join(array_slice(parts, 0, (int)(i + 1)), _const_os__path_separator) })); break; } } } for (int _t5 = 0; _t5 < module_lookup_paths.len; ++_t5) { string search_path = ((string*)module_lookup_paths.data)[_t5]; string try_path = os__join_path(search_path, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){mod_path}))); if (b->pref->is_verbose) { println(str_intp(3, _MOV((StrIntpData[]){{_S(" >> trying to find "), 0xfe10, {.d_s = mod}}, {_S(" in "), 0xfe10, {.d_s = try_path}}, {_S(" .."), 0, { .d_c = 0 }}}))); } if (os__is_dir(try_path)) { if (b->pref->is_verbose) { println(str_intp(2, _MOV((StrIntpData[]){{_S(" << found "), 0xfe10, {.d_s = try_path}}, {_S(" ."), 0, { .d_c = 0 }}}))); } _result_string _t6 = {0}; _result_ok(&(string[]) { try_path }, (_result*)(&_t6), sizeof(string)); return _t6; } } Array_string path_parts = string_split(fpath, _const_os__path_separator); for (int i = (int)(path_parts.len - 2); i > 0; i--) { string p1 = Array_string_join(array_slice(path_parts, 0, i), _const_os__path_separator); string try_path = os__join_path(p1, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){mod_path}))); if (b->pref->is_verbose) { println(str_intp(3, _MOV((StrIntpData[]){{_S(" >> trying to find "), 0xfe10, {.d_s = mod}}, {_S(" in "), 0xfe10, {.d_s = try_path}}, {_S(" .."), 0, { .d_c = 0 }}}))); } if (os__is_dir(try_path)) { _result_string _t7 = {0}; _result_ok(&(string[]) { try_path }, (_result*)(&_t7), sizeof(string)); return _t7; } } string smodule_lookup_paths = Array_string_join(module_lookup_paths, _S(", ")); return (_result_string){ .is_error=true, .err=_v_error(str_intp(3, _MOV((StrIntpData[]){{_S("module \""), 0xfe10, {.d_s = mod}}, {_S("\" not found in:\n"), 0xfe10, {.d_s = smodule_lookup_paths}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={E_STRUCT} }; } void v__builder__Builder_show_total_warns_and_errors_stats(v__builder__Builder* b) { if (b->nr_errors == 0 && b->nr_warnings == 0 && b->nr_notices == 0) { return; } if (b->pref->is_stats) { int nr_errors = b->checker->errors.len; int nr_warnings = b->checker->warnings.len; int nr_notices = b->checker->notices.len; if (b->pref->check_only) { nr_errors = b->nr_errors; nr_warnings = b->nr_warnings; nr_notices = b->nr_notices; } string estring = v__util__bold(int_str(nr_errors)); string wstring = v__util__bold(int_str(nr_warnings)); string nstring = v__util__bold(int_str(nr_notices)); if (b->pref->check_only) { println(str_intp(4, _MOV((StrIntpData[]){{_S("summary: "), 0xfe10, {.d_s = estring}}, {_S(" V errors, "), 0xfe10, {.d_s = wstring}}, {_S(" V warnings, "), 0xfe10, {.d_s = nstring}}, {_S(" V notices"), 0, { .d_c = 0 }}}))); } else { println(str_intp(4, _MOV((StrIntpData[]){{_S("checker summary: "), 0xfe10, {.d_s = estring}}, {_S(" V errors, "), 0xfe10, {.d_s = wstring}}, {_S(" V warnings, "), 0xfe10, {.d_s = nstring}}, {_S(" V notices"), 0, { .d_c = 0 }}}))); } } if (b->checker->nr_errors > 0 && string_ends_with(b->pref->path, _S(".v")) && os__is_file(b->pref->path)) { bool _t1 = false; Array_v__errors__Error _t1_orig = b->checker->errors; int _t1_len = _t1_orig.len; for (int _t2 = 0; _t2 < _t1_len; ++_t2) { v__errors__Error it = ((v__errors__Error*) _t1_orig.data)[_t2]; if (string_starts_with(it.CompilerMessage.message, _S("unknown "))) { _t1 = true; break; } } if (_t1) { string old_cmd = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_S("v "), 0xfe10, {.d_s = b->pref->path}}, {_SLIT0, 0, { .d_c = 0 }}}))); string new_cmd = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_S("v "), 0xfe10, {.d_s = os__dir(b->pref->path)}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(v__util__color(_S("notice"), str_intp(3, _MOV((StrIntpData[]){{_S("If the code of your project is in multiple files, try with `"), 0xfe10, {.d_s = new_cmd}}, {_S("` instead of `"), 0xfe10, {.d_s = old_cmd}}, {_S("`"), 0, { .d_c = 0 }}})))); } } } void v__builder__Builder_print_warnings_and_errors(v__builder__Builder* b) { bool v__builder__Builder_print_warnings_and_errors_defer_0 = false; v__builder__Builder_print_warnings_and_errors_defer_0 = true; for (int _t1 = 0; _t1 < b->parsed_files.len; ++_t1) { v__ast__File* file = ((v__ast__File**)b->parsed_files.data)[_t1]; b->nr_errors += file->errors.len; b->nr_warnings += file->warnings.len; b->nr_notices += file->notices.len; } if (b->pref->output_mode == v__pref__OutputMode__silent) { if (b->nr_errors > 0) { _v_exit(1); VUNREACHABLE(); } // Defer begin if (v__builder__Builder_print_warnings_and_errors_defer_0) { v__builder__Builder_show_total_warns_and_errors_stats(b); } // Defer end return; } if (b->pref->check_only) { if (!b->pref->skip_notes) { for (int _t2 = 0; _t2 < b->parsed_files.len; ++_t2) { v__ast__File* file = ((v__ast__File**)b->parsed_files.data)[_t2]; for (int _t3 = 0; _t3 < file->notices.len; ++_t3) { v__errors__Notice err = ((v__errors__Notice*)file->notices.data)[_t3]; string kind = (b->pref->is_verbose ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__errors__Reporter_str(err.CompilerMessage.reporter)}}, {_S(" notice #"), 0xfe07, {.d_i32 = b->nr_notices}}, {_S(":"), 0, { .d_c = 0 }}}))) : (_S("notice:"))); v__util__show_compiler_message(kind, err.CompilerMessage); } } } for (int _t4 = 0; _t4 < b->parsed_files.len; ++_t4) { v__ast__File* file = ((v__ast__File**)b->parsed_files.data)[_t4]; for (int _t5 = 0; _t5 < file->errors.len; ++_t5) { v__errors__Error err = ((v__errors__Error*)file->errors.data)[_t5]; string kind = (b->pref->is_verbose ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__errors__Reporter_str(err.CompilerMessage.reporter)}}, {_S(" error #"), 0xfe07, {.d_i32 = b->nr_errors}}, {_S(":"), 0, { .d_c = 0 }}}))) : (_S("error:"))); v__util__show_compiler_message(kind, err.CompilerMessage); } } if (!b->pref->skip_warnings) { for (int _t6 = 0; _t6 < b->parsed_files.len; ++_t6) { v__ast__File* file = ((v__ast__File**)b->parsed_files.data)[_t6]; for (int _t7 = 0; _t7 < file->warnings.len; ++_t7) { v__errors__Warning err = ((v__errors__Warning*)file->warnings.data)[_t7]; string kind = (b->pref->is_verbose ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__errors__Reporter_str(err.CompilerMessage.reporter)}}, {_S(" warning #"), 0xfe07, {.d_i32 = b->nr_warnings}}, {_S(":"), 0, { .d_c = 0 }}}))) : (_S("warning:"))); v__util__show_compiler_message(kind, err.CompilerMessage); } } } v__builder__Builder_show_total_warns_and_errors_stats(b); if (b->nr_errors > 0) { _v_exit(1); VUNREACHABLE(); } } if (b->pref->is_verbose && b->checker->nr_warnings > 1) { println(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = b->checker->nr_warnings}}, {_S(" warnings"), 0, { .d_c = 0 }}}))); } if (b->pref->is_verbose && b->checker->nr_notices > 1) { println(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = b->checker->nr_notices}}, {_S(" notices"), 0, { .d_c = 0 }}}))); } if (b->checker->nr_notices > 0 && !b->pref->skip_notes) { for (int _t8 = 0; _t8 < b->checker->notices.len; ++_t8) { v__errors__Notice err = ((v__errors__Notice*)b->checker->notices.data)[_t8]; string kind = (b->pref->is_verbose ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__errors__Reporter_str(err.CompilerMessage.reporter)}}, {_S(" notice #"), 0xfe07, {.d_i32 = b->checker->nr_notices}}, {_S(":"), 0, { .d_c = 0 }}}))) : (_S("notice:"))); v__util__show_compiler_message(kind, err.CompilerMessage); } } if (b->checker->nr_warnings > 0 && !b->pref->skip_warnings) { for (int _t9 = 0; _t9 < b->checker->warnings.len; ++_t9) { v__errors__Warning err = ((v__errors__Warning*)b->checker->warnings.data)[_t9]; string kind = (b->pref->is_verbose ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__errors__Reporter_str(err.CompilerMessage.reporter)}}, {_S(" warning #"), 0xfe07, {.d_i32 = b->checker->nr_warnings}}, {_S(":"), 0, { .d_c = 0 }}}))) : (_S("warning:"))); v__util__show_compiler_message(kind, err.CompilerMessage); } } if (b->pref->is_verbose && b->checker->nr_errors > 1) { println(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe07, {.d_i32 = b->checker->nr_errors}}, {_S(" errors"), 0, { .d_c = 0 }}}))); } if (b->checker->nr_errors > 0) { for (int _t10 = 0; _t10 < b->checker->errors.len; ++_t10) { v__errors__Error err = ((v__errors__Error*)b->checker->errors.data)[_t10]; string kind = (b->pref->is_verbose ? (str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__errors__Reporter_str(err.CompilerMessage.reporter)}}, {_S(" error #"), 0xfe07, {.d_i32 = b->checker->nr_errors}}, {_S(":"), 0, { .d_c = 0 }}}))) : (_S("error:"))); v__util__show_compiler_message(kind, err.CompilerMessage); } v__builder__Builder_show_total_warns_and_errors_stats(b); _v_exit(1); VUNREACHABLE(); } if (b->table->redefined_fns.len > 0) { int total_conflicts = 0; for (int _t11 = 0; _t11 < b->table->redefined_fns.len; ++_t11) { string fn_name = ((string*)b->table->redefined_fns.data)[_t11]; Array_v__builder__FunctionRedefinition redefines = __new_array_with_default(0, 0, sizeof(v__builder__FunctionRedefinition), 0); Map_string_int redefine_conflicts = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; for (int _t12 = 0; _t12 < b->parsed_files.len; ++_t12) { v__ast__File* file = ((v__ast__File**)b->parsed_files.data)[_t12]; for (int _t13 = 0; _t13 < file->stmts.len; ++_t13) { v__ast__Stmt stmt = ((v__ast__Stmt*)file->stmts.data)[_t13]; if ((stmt)._typ == 237 /* v.ast.FnDecl */) { if (string__eq((*stmt._v__ast__FnDecl).name, fn_name)) { string fheader = v__ast__Table_stringify_fn_decl(b->table, &(*stmt._v__ast__FnDecl), _S("main"), new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) , false); array_push((array*)&redefines, _MOV((v__builder__FunctionRedefinition[]){ ((v__builder__FunctionRedefinition){.fpath = file->path,.fline = (*stmt._v__ast__FnDecl).pos.line_nr,.fheader = fheader,.f = (*stmt._v__ast__FnDecl),}) })); (*(int*)map_get_and_set((map*)&redefine_conflicts, &(string[]){fheader}, &(int[]){ 0 }))++; } } } } if (redefines.len > 0) { v__util__show_compiler_message(_S("builder error:"), ((v__errors__CompilerMessage){.message = str_intp(2, _MOV((StrIntpData[]){{_S("redefinition of function `"), 0xfe10, {.d_s = fn_name}}, {_S("`"), 0, { .d_c = 0 }}})),.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = (string){.str=(byteptr)"", .is_lit=1},.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),.reporter = 0,})); for (int _t15 = 0; _t15 < redefines.len; ++_t15) { v__builder__FunctionRedefinition redefine = ((v__builder__FunctionRedefinition*)redefines.data)[_t15]; v__util__show_compiler_message(_S("conflicting declaration:"), ((v__errors__CompilerMessage){.message = redefine.fheader,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = redefine.fpath,.pos = redefine.f.pos,.reporter = 0,})); } total_conflicts++; } } if (total_conflicts > 0) { v__builder__Builder_show_total_warns_and_errors_stats(b); _v_exit(1); VUNREACHABLE(); } } // Defer begin if (v__builder__Builder_print_warnings_and_errors_defer_0) { v__builder__Builder_show_total_warns_and_errors_stats(b); } // Defer end } v__errors__Error v__builder__Builder_error_with_pos(v__builder__Builder* b, string s, string fpath, v__token__Pos pos) { if (!b->pref->check_only) { v__util__show_compiler_message(_S("builder error:"), ((v__errors__CompilerMessage){.message = s,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = fpath,.pos = pos,.reporter = 0,})); _v_exit(1); VUNREACHABLE(); } return ((v__errors__Error){.CompilerMessage = ((v__errors__CompilerMessage){.message = s,.details = (string){.str=(byteptr)"", .is_lit=1},.file_path = fpath,.pos = pos,.reporter = v__errors__Reporter__builder,}),}); } VNORETURN void v__builder__verror(string s) { v__util__verror(_S("builder error"), s); VUNREACHABLE(); while(1); } void v__builder__Builder_show_parsed_files(v__builder__Builder* b) { for (int _t1 = 0; _t1 < b->parsed_files.len; ++_t1) { v__ast__File* p = ((v__ast__File**)b->parsed_files.data)[_t1]; if (p->is_parse_text) { println(string__plus(p->path, _S(":parse_text"))); } println(p->path); } } VV_LOC void v__builder__Builder_show_c_compiler_output(v__builder__Builder* v, string ccompiler, os__Result res) { string header = str_intp(2, _MOV((StrIntpData[]){{_S("======== Output of the C Compiler ("), 0xfe10, {.d_s = ccompiler}}, {_S(") ========"), 0, { .d_c = 0 }}})); println(header); println(string_trim_space(res.output)); println(string_repeat(_S("="), header.len)); } VV_LOC void v__builder__Builder_post_process_c_compiler_output(v__builder__Builder* v, string ccompiler, os__Result res) { if (res.exit_code == 0) { if (v->pref->reuse_tmpc) { return; } for (int _t1 = 0; _t1 < v->pref->cleanup_files.len; ++_t1) { string tmpfile = ((string*)v->pref->cleanup_files.data)[_t1]; if (os__is_file(tmpfile)) { if (v->pref->is_verbose) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(">> remove tmp file: "), 0xfe10, {.d_s = tmpfile}}, {_SLIT0, 0, { .d_c = 0 }}}))); } _result_void _t2 = os__rm(tmpfile); (void)_t2; ; } } return; } Array_string _t3 = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){string_clone(_const_v__builder__c_verror_message_marker), _S("error: include file ")})); for (int _t4 = 0; _t4 < _t3.len; ++_t4) { string emsg_marker = ((string*)_t3.data)[_t4]; if (string_contains(res.output, emsg_marker)) { string emessage = string_trim_right(string_all_before(string_all_before(string_all_after(res.output, emsg_marker), _S("\n")), _S("\r")), _S("\r\n")); v__builder__verror(emessage); VUNREACHABLE(); } } if (v->pref->is_debug) { string eword = _S("error:"); string khighlight = v__builder__highlight_word(eword); println(string_replace(string_trim_right(res.output, _S("\r\n")), eword, khighlight)); } else { if (res.output.len < 30) { println(res.output); } else { string trimmed_output = string_trim_space(res.output); Array_string original_elines = string_split_into_lines(trimmed_output); int mlines = 12; int cut_off_limit = (original_elines.len > (int)(mlines + 3) ? (mlines) : ((int)(mlines + 3))); Array_string elines = v__builder__error_context_lines(trimmed_output, _S("error:"), 1, cut_off_limit); string header = str_intp(3, _MOV((StrIntpData[]){{_S("================== "), 0xfe10, {.d_s = _const_v__builder__c_compilation_error_title}}, {_S(" (from "), 0xfe10, {.d_s = ccompiler}}, {_S("): =============="), 0, { .d_c = 0 }}})); println(header); for (int _t5 = 0; _t5 < elines.len; ++_t5) { string eline = ((string*)elines.data)[_t5]; println(str_intp(2, _MOV((StrIntpData[]){{_S("cc: "), 0xfe10, {.d_s = eline}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (original_elines.len != elines.len) { println(_S("...")); println(str_intp(2, _MOV((StrIntpData[]){{_S("cc: "), 0xfe10, {.d_s = (*(string*)array_get(array_slice_ni(original_elines, -1, 2147483647), 0))}}, {_SLIT0, 0, { .d_c = 0 }}}))); println(str_intp(3, _MOV((StrIntpData[]){{_S("(note: the original output was "), 0xfe07, {.d_i32 = original_elines.len}}, {_S(" lines long; it was truncated to its first "), 0xfe07, {.d_i32 = elines.len}}, {_S(" lines + the last line)"), 0, { .d_c = 0 }}}))); } println(string_repeat(_S("="), header.len)); println(_S("(You can pass `-cg`, or `-show-c-output` as well, to print all the C error messages).")); } } if ((os__getenv(_S("V_NO_C_ERROR_INFO"))).len != 0) { eprintln(_S("> V_NO_C_ERROR_INFO is obsoleted by either setting VQUIET to 1, or by passing `-q` on the command line")); _v_exit(1); VUNREACHABLE(); } if (v->pref->is_quiet) { _v_exit(1); VUNREACHABLE(); } string more_suggestions = _S(""); if (string_contains(res.output, _S("o: unrecognized file type")) || string_contains(res.output, _S(".o: file not recognized"))) { more_suggestions = string__plus(more_suggestions, str_intp(2, _MOV((StrIntpData[]){{_S("\n"), 0xfe10, {.d_s = v__builder__highlight_word(_S("Suggestion"))}}, {_S(": try `v wipe-cache`, then repeat your compilation."), 0, { .d_c = 0 }}}))); } v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_S("\n==================\nC error found. It should never happen, when compiling pure V code.\nThis is a V compiler bug, please report it using `v bug file.v`,\nor goto https://github.com/vlang/v/issues/new/choose .\nYou can also use #help on Discord: https://discord.gg/vlang ."), 0xfe10, {.d_s = more_suggestions}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } VV_LOC void v__builder__Builder_show_cc(v__builder__Builder* v, string cmd, string response_file, string response_file_content) { if (v->pref->is_verbose || v->pref->show_cc) { println(str_intp(2, _MOV((StrIntpData[]){{_S("> C compiler cmd: "), 0xfe10, {.d_s = cmd}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (v->pref->show_cc && !v->pref->no_rsp) { println(str_intp(2, _MOV((StrIntpData[]){{_S("> C compiler response file \""), 0xfe10, {.d_s = response_file}}, {_S("\":"), 0, { .d_c = 0 }}}))); println(response_file_content); } } } VV_LOC void v__builder__Builder_setup_ccompiler_options(v__builder__Builder* v, string ccompiler) { v__builder__CcompilerOptions ccoptions = ((v__builder__CcompilerOptions){.guessed_compiler = (string){.str=(byteptr)"", .is_lit=1},.shared_postfix = (string){.str=(byteptr)"", .is_lit=1},.debug_mode = 0,.cc = 0,.env_cflags = (string){.str=(byteptr)"", .is_lit=1},.env_ldflags = (string){.str=(byteptr)"", .is_lit=1},.args = __new_array(0, 0, sizeof(string)),.wargs = __new_array(0, 0, sizeof(string)),.pre_args = __new_array(0, 0, sizeof(string)),.o_args = __new_array(0, 0, sizeof(string)),.source_args = __new_array(0, 0, sizeof(string)),.post_args = __new_array(0, 0, sizeof(string)),.linker_flags = __new_array(0, 0, sizeof(string)),.ldflags = __new_array(0, 0, sizeof(string)),}); Array_string debug_options = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("-g")})); Array_string optimization_options = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("-O2")})); ccoptions.args = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){string_clone(v->pref->cflags)})); ccoptions.ldflags = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){string_clone(v->pref->ldflags)})); ccoptions.wargs = new_array_from_c_array(28, 28, sizeof(string), _MOV((string[28]){ _S("-Wall"), _S("-Wextra"), _S("-Werror"), _S("-Wno-unused-parameter"), _S("-Wno-unused"), _S("-Wno-type-limits"), _S("-Wno-tautological-compare"), _S("-Wno-shadow"), _S("-Wno-int-to-pointer-cast"), _S("-Wno-trigraphs"), _S("-Wno-missing-braces"), _S("-Wno-enum-conversion"), _S("-Wno-enum-compare"), _S("-Wno-unknown-warning"), _S("-Wno-unknown-warning-option"), _S("-Wno-excess-initializers"), _S("-Wdate-time"), _S("-Wduplicated-branches"), _S("-Wduplicated-cond"), _S("-Winit-self"), _S("-Winvalid-pch"), _S("-Wjump-misses-init"), _S("-Wlogical-op"), _S("-Wmultichar"), _S("-Wnested-externs"), _S("-Wnull-dereference"), _S("-Wpacked"), _S("-Wpointer-arith")})); if (v->pref->os == v__pref__OS__ios) { array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-fobjc-arc") })); } if (v->pref->os == v__pref__OS__macos && os__exists(_S("/opt/procursus"))) { array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-Wl,-rpath,/opt/procursus/lib") })); } int user_darwin_version = 999999; bool user_darwin_ppc = false; #if defined(__APPLE__) { user_darwin_version = string_int((*(string*)array_get(string_split(os__uname().release, _S(".")), 0))); if (fast_string_eq(os__uname().machine, _S("Power Macintosh"))) { user_darwin_ppc = true; } } #endif ccoptions.debug_mode = v->pref->is_debug; ccoptions.guessed_compiler = v->pref->ccompiler; if (fast_string_eq(ccoptions.guessed_compiler, _S("cc"))) { string cc_ver = os__execute(_S("cc --version")).output; if (string_contains(string_replace(cc_ver, _S("\n"), _S("")), _S("Free Software Foundation, Inc.This is free software;"))) { ccoptions.cc = v__builder__CC__gcc; } else if (string_contains(cc_ver, _S("clang version "))) { ccoptions.cc = v__builder__CC__clang; } else { if (v->pref->is_verbose) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("failed to detect C compiler from version info `"), 0xfe10, {.d_s = cc_ver}}, {_S("`"), 0, { .d_c = 0 }}}))); } eprintln(_S("Compilation with unknown C compiler")); ccoptions.cc = v__builder__CC__unknown; } } else { string cc_file_name = os__file_name(ccompiler); bool _t4 = true; ccoptions.cc = ((_t4 == (string_contains(cc_file_name, _S("tcc")) || fast_string_eq(ccoptions.guessed_compiler, _S("tcc"))))? (v__builder__CC__tcc) : (_t4 == (string_contains(cc_file_name, _S("gcc")) || string_contains(cc_file_name, _S("g++")) || fast_string_eq(ccoptions.guessed_compiler, _S("gcc"))))? (v__builder__CC__gcc) : (_t4 == (string_contains(cc_file_name, _S("clang")) || fast_string_eq(ccoptions.guessed_compiler, _S("clang"))))? (v__builder__CC__clang) : (_t4 == (string_contains(cc_file_name, _S("msvc")) || fast_string_eq(ccoptions.guessed_compiler, _S("msvc"))))? (v__builder__CC__msvc) : (_t4 == (string_contains(cc_file_name, _S("icc")) || fast_string_eq(ccoptions.guessed_compiler, _S("icc"))))? (v__builder__CC__icc) : (_t4 == (string_contains(cc_file_name, _S("emcc")) || fast_string_eq(ccoptions.guessed_compiler, _S("emcc"))))? (v__builder__CC__emcc) : (v__builder__CC__unknown)); if (ccoptions.cc == v__builder__CC__unknown) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("Compilation with unknown C compiler `"), 0xfe10, {.d_s = cc_file_name}}, {_S("`"), 0, { .d_c = 0 }}}))); } } if ((ccoptions.cc == v__builder__CC__gcc || ccoptions.cc == v__builder__CC__clang || ccoptions.cc == v__builder__CC__tcc) && (v->pref->os == v__pref__OS__macos || v->pref->os == v__pref__OS__linux || v->pref->os == v__pref__OS__openbsd || v->pref->os == v__pref__OS__windows)) { array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-fwrapv") })); } if (string_contains(ccoptions.guessed_compiler, _S("++"))) { array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-fpermissive") })); array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-w") })); } if (ccoptions.cc == v__builder__CC__clang) { if (ccoptions.debug_mode) { debug_options = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("-g"), _S("-O0")})); } optimization_options = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("-O3")})); bool have_flto = true; #if defined(_WIN32) { have_flto = false; } #endif if (v->pref->parallel_cc) { have_flto = false; } if (have_flto) { array_push((array*)&optimization_options, _MOV((string[]){ _S("-flto") })); } _PUSH_MANY(&ccoptions.wargs, (new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S("-Wno-tautological-bitwise-compare"), _S("-Wno-enum-conversion"), _S("-Wno-sometimes-uninitialized"), _S("-Wno-int-to-void-pointer-cast")}))), _t10, Array_string); } if (ccoptions.cc == v__builder__CC__gcc) { if (ccoptions.debug_mode) { debug_options = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("-g")})); if (user_darwin_version > 9) { array_push((array*)&debug_options, _MOV((string[]){ _S("-no-pie") })); } } optimization_options = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("-O3")})); bool have_flto = true; if (v->pref->parallel_cc) { have_flto = false; } if (have_flto) { array_push((array*)&optimization_options, _MOV((string[]){ _S("-flto") })); } } if (ccoptions.cc == v__builder__CC__icc) { if (ccoptions.debug_mode) { debug_options = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("-g")})); if (user_darwin_version > 9) { array_push((array*)&debug_options, _MOV((string[]){ _S("-no-pie") })); } } optimization_options = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("-Ofast")})); } if (ccoptions.debug_mode) { _PUSH_MANY(&ccoptions.args, (debug_options), _t14, Array_string); } if (v->pref->is_prod) { bool _t15 = (ccoptions.cc == v__builder__CC__tcc); bool _t16 = (v->parsed_files.len > 0); if ( _t15 && !( _t16 && string_contains((*(v__ast__File**)array_last(v->parsed_files))->path, _S("vlib")))) { eprintln(_S("Note: tcc is not recommended for -prod builds")); } if (!v->pref->no_prod_options) { _PUSH_MANY(&ccoptions.args, (optimization_options), _t17, Array_string); } } if (v->pref->is_prod && !ccoptions.debug_mode) { array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-DNDEBUG") })); } if (v->pref->sanitize) { array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-fsanitize=leak") })); } if (v->pref->is_o) { array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-c") })); } ccoptions.shared_postfix = _S(".so"); if (v->pref->os == v__pref__OS__macos) { ccoptions.shared_postfix = _S(".dylib"); } if (v->pref->os == v__pref__OS__windows) { ccoptions.shared_postfix = _S(".dll"); } if (v->pref->is_shared) { array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-shared") })); #if !defined(_WIN32) { array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-fPIC") })); } #endif } if (v->pref->is_bare && v->pref->os != v__pref__OS__wasm32) { array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-fno-stack-protector") })); array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-ffreestanding") })); array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-static") })); array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-nostdlib") })); } else if (v->pref->os == v__pref__OS__wasm32) { array_push((array*)&ccoptions.args, _MOV((string[]){ _S("--no-standard-libraries") })); array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-target wasm32-unknown-unknown") })); array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-static") })); array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-nostdlib") })); array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-ffreestanding") })); array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-Wl,--export-all") })); array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-Wl,--no-entry") })); } if (ccoptions.debug_mode && _SLIT_NE(_const_v__builder__current_os.str, _const_v__builder__current_os.len, "windows") && v->pref->build_mode != v__pref__BuildMode__build_module) { if (ccoptions.cc != v__builder__CC__tcc && _SLIT_EQ(_const_v__builder__current_os.str, _const_v__builder__current_os.len, "macos")) { array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-Wl,-export_dynamic") })); } else { if (!fast_string_eq(v->pref->ccompiler, _S("x86_64-w64-mingw32-gcc"))) { array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-rdynamic") })); } } } if (v->pref->os == v__pref__OS__freebsd) { if (ccoptions.cc != v__builder__CC__tcc) { array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-Wl,--allow-multiple-definition") })); } else { array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-D__RUNETYPE_INTERNAL") })); } } if (v->pref->os == v__pref__OS__openbsd && ccoptions.cc == v__builder__CC__clang) { array_push((array*)&ccoptions.wargs, _MOV((string[]){ _S("-Wno-braced-scalar-init") })); } if (_SLIT_NE(ccompiler.str, ccompiler.len, "msvc") && v->pref->os != v__pref__OS__freebsd) { array_push((array*)&ccoptions.wargs, _MOV((string[]){ _S("-Werror=implicit-function-declaration") })); } if (ccoptions.cc == v__builder__CC__tcc) { array_push((array*)&ccoptions.wargs, _MOV((string[]){ _S("-Wno-write-strings") })); } if (v->pref->is_liveshared || v->pref->is_livemain) { if (v->pref->os == v__pref__OS__linux && v->pref->build_mode != v__pref__BuildMode__build_module) { array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-rdynamic") })); } if (v->pref->os == v__pref__OS__macos) { array_push((array*)&ccoptions.args, _MOV((string[]){ _S("-flat_namespace") })); } } if (v->pref->os == v__pref__OS__macos || v->pref->os == v__pref__OS__ios) { if (ccoptions.cc != v__builder__CC__tcc && !user_darwin_ppc && !v->pref->is_bare && _SLIT_NE(ccompiler.str, ccompiler.len, "musl-gcc")) { array_push((array*)&ccoptions.source_args, _MOV((string[]){ _S("-x objective-c") })); } } if (!v->pref->parallel_cc) { array_push((array*)&ccoptions.source_args, _MOV((string[]){ v__builder__Builder_tcc_quoted_path(v, v->out_name_c) })); } if (v->pref->os == v__pref__OS__macos) { if (!fast_string_eq(v->pref->macosx_version_min, _S("0"))) { array_push((array*)&ccoptions.post_args, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-mmacosx-version-min="), 0xfe10, {.d_s = v->pref->macosx_version_min}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } if (v->pref->os == v__pref__OS__ios) { if (v->pref->is_ios_simulator) { array_push((array*)&ccoptions.post_args, _MOV((string[]){ _S("-miphonesimulator-version-min=10.0") })); } else { array_push((array*)&ccoptions.post_args, _MOV((string[]){ _S("-miphoneos-version-min=10.0") })); } } if (v->pref->os == v__pref__OS__windows) { array_push((array*)&ccoptions.post_args, _MOV((string[]){ v__builder__Builder_get_subsystem_flag(v) })); } Array_v__cflag__CFlag cflags = v__builder__Builder_get_os_cflags(v); if (v->pref->build_mode != v__pref__BuildMode__build_module) { Array_string only_o_files = Array_v__cflag__CFlag_c_options_only_object_files(cflags); _PUSH_MANY(&ccoptions.o_args, (only_o_files), _t50, Array_string); } multi_return_Array_string_Array_string_Array_string mr_13303 = Array_v__cflag__CFlag_defines_others_libs(cflags); Array_string defines = mr_13303.arg0; Array_string others = mr_13303.arg1; Array_string libs = mr_13303.arg2; _PUSH_MANY(&ccoptions.pre_args, (defines), _t51, Array_string); _PUSH_MANY(&ccoptions.pre_args, (others), _t52, Array_string); _PUSH_MANY(&ccoptions.linker_flags, (libs), _t53, Array_string); if (v->pref->use_cache && v->pref->build_mode != v__pref__BuildMode__build_module) { if (ccoptions.cc != v__builder__CC__tcc) { #if defined(__linux__) { array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-Xlinker -z") })); array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-Xlinker muldefs") })); } #endif } } if (ccoptions.cc == v__builder__CC__tcc && !(Array_string_contains(v->pref->compile_defines, _S("no_backtrace")))) { array_push((array*)&ccoptions.post_args, _MOV((string[]){ _S("-bt25") })); } if (!v->pref->is_bare && v->pref->build_mode != v__pref__BuildMode__build_module && (v->pref->os == v__pref__OS__linux || v->pref->os == v__pref__OS__freebsd || v->pref->os == v__pref__OS__openbsd || v->pref->os == v__pref__OS__netbsd || v->pref->os == v__pref__OS__dragonfly || v->pref->os == v__pref__OS__solaris || v->pref->os == v__pref__OS__haiku)) { if (v->pref->os == v__pref__OS__freebsd || v->pref->os == v__pref__OS__netbsd) { array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-lexecinfo") })); array_push((array*)&ccoptions.linker_flags, _MOV((string[]){ _S("-lelf") })); } } ccoptions.env_cflags = os__getenv(_S("CFLAGS")); ccoptions.env_ldflags = os__getenv(_S("LDFLAGS")); if (v->pref->os == v__pref__OS__macos) { if (v->pref->use_cache) { array_push((array*)&ccoptions.source_args, _MOV((string[]){ _S("-x none") })); } else { for (int _t61 = 0; _t61 < ccoptions.linker_flags.len; ++_t61) { string flag = ((string*)ccoptions.linker_flags.data)[_t61]; if (string_starts_with(flag, _S("-"))) { continue; } if (os__is_file(flag)) { array_push((array*)&ccoptions.source_args, _MOV((string[]){ _S("-x none") })); break; } string path = (string_starts_with(flag, _S("\"")) && string_ends_with(flag, _S("\"")) ? (string_substr(flag, 1, (int)(flag.len - 1))) : (flag)); if (os__is_dir(os__dir(path))) { array_push((array*)&ccoptions.source_args, _MOV((string[]){ _S("-x none") })); break; } } } } if (!v->pref->no_std) { if (v->pref->os == v__pref__OS__linux) { array_push((array*)&ccoptions.source_args, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-std="), 0xfe10, {.d_s = _const_v__builder__c_std_gnu}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else { array_push((array*)&ccoptions.source_args, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-std="), 0xfe10, {.d_s = _const_v__builder__c_std}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } array_push((array*)&ccoptions.source_args, _MOV((string[]){ _S("-D_DEFAULT_SOURCE") })); } #if defined(CUSTOM_DEFINE_trace_ccoptions) { println(str_intp(2, _MOV((StrIntpData[]){{_S(">>> setup_ccompiler_options ccompiler: "), 0xfe10, {.d_s = ccompiler}}, {_SLIT0, 0, { .d_c = 0 }}}))); println(str_intp(2, _MOV((StrIntpData[]){{_S(">>> setup_ccompiler_options ccoptions: "), 0xfe10, {.d_s = v__builder__CcompilerOptions_str(ccoptions)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif v->ccoptions = ccoptions; v__vcache__CacheManager_set_temporary_options(&v->pref->cache_manager, v__builder__Builder_thirdparty_object_args(v, v->ccoptions, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){string_clone(ccoptions.guessed_compiler)})), false)); } VV_LOC Array_string v__builder__Builder_all_args(v__builder__Builder* v, v__builder__CcompilerOptions ccoptions) { Array_string all = __new_array_with_default(0, 0, sizeof(string), 0); _PUSH_MANY(&all, (v__builder__Builder_only_compile_args(v, ccoptions)), _t1, Array_string); _PUSH_MANY(&all, (v__builder__Builder_only_linker_args(v, ccoptions)), _t2, Array_string); return all; } Array_string v__builder__Builder_get_compile_args(v__builder__Builder* v) { return v__builder__Builder_only_compile_args(v, v->ccoptions); } VV_LOC Array_string v__builder__Builder_only_compile_args(v__builder__Builder* v, v__builder__CcompilerOptions ccoptions) { Array_string all = __new_array_with_default(0, 0, sizeof(string), 0); array_push((array*)&all, _MOV((string[]){ string_clone(ccoptions.env_cflags) })); if (v->pref->is_cstrict) { _PUSH_MANY(&all, (ccoptions.wargs), _t2, Array_string); } _PUSH_MANY(&all, (ccoptions.args), _t3, Array_string); _PUSH_MANY(&all, (ccoptions.o_args), _t4, Array_string); #if defined(_WIN32) { if (ccoptions.cc != v__builder__CC__msvc) { if (v->pref->os != v__pref__OS__wasm32_emscripten) { array_push((array*)&all, _MOV((string[]){ _S("-Wl,-stack=16777216") })); } if (!v->pref->is_cstrict) { array_push((array*)&all, _MOV((string[]){ _S("-Werror=implicit-function-declaration") })); } } } #endif _PUSH_MANY(&all, (ccoptions.pre_args), _t8, Array_string); _PUSH_MANY(&all, (ccoptions.source_args), _t9, Array_string); _PUSH_MANY(&all, (ccoptions.post_args), _t10, Array_string); return all; } Array_string v__builder__Builder_get_linker_args(v__builder__Builder* v) { return v__builder__Builder_only_linker_args(v, v->ccoptions); } VV_LOC Array_string v__builder__Builder_only_linker_args(v__builder__Builder* v, v__builder__CcompilerOptions ccoptions) { Array_string all = __new_array_with_default(0, 0, sizeof(string), 0); if (v->pref->build_mode != v__pref__BuildMode__build_module) { _PUSH_MANY(&all, (ccoptions.linker_flags), _t1, Array_string); array_push((array*)&all, _MOV((string[]){ string_clone(ccoptions.env_ldflags) })); _PUSH_MANY(&all, (ccoptions.ldflags), _t3, Array_string); } return all; } VV_LOC Array_string v__builder__Builder_thirdparty_object_args(v__builder__Builder* v, v__builder__CcompilerOptions ccoptions, Array_string middle, bool cpp_file) { Array_string all = __new_array_with_default(0, 0, sizeof(string), 0); if (!v->pref->no_std) { if (v->pref->os == v__pref__OS__linux) { if (cpp_file) { array_push((array*)&all, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-std="), 0xfe10, {.d_s = _const_v__builder__cpp_std_gnu}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else { array_push((array*)&all, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-std="), 0xfe10, {.d_s = _const_v__builder__c_std_gnu}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } else { if (cpp_file) { array_push((array*)&all, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-std="), 0xfe10, {.d_s = _const_v__builder__cpp_std}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else { array_push((array*)&all, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-std="), 0xfe10, {.d_s = _const_v__builder__c_std}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } array_push((array*)&all, _MOV((string[]){ _S("-D_DEFAULT_SOURCE") })); } string sysroot = os__join_path(os__vmodules_dir(), new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("linuxroot")}))); bool cross_compiling_from_macos_to_linux = false; if (v->pref->os == v__pref__OS__linux && v->pref->arch == v__pref__Arch__amd64) { #if defined(__APPLE__) { cross_compiling_from_macos_to_linux = true; } #endif } if (cross_compiling_from_macos_to_linux) { v__builder__Builder_ensure_linuxroot_exists(v, sysroot); array_push((array*)&all, _MOV((string[]){ _S("-target x86_64-linux-gnu") })); } array_push((array*)&all, _MOV((string[]){ string_clone(ccoptions.env_cflags) })); _PUSH_MANY(&all, (ccoptions.args), _t9, Array_string); _PUSH_MANY(&all, (middle), _t10, Array_string); if (cross_compiling_from_macos_to_linux) { array_push((array*)&all, _MOV((string[]){ _S("-I") })); array_push((array*)&all, _MOV((string[]){ os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/include"), 0, { .d_c = 0 }}}))) })); } return all; } VV_LOC void v__builder__Builder_setup_output_name(v__builder__Builder* v) { if (!v->pref->is_shared && v->pref->build_mode != v__pref__BuildMode__build_module && v->pref->os == v__pref__OS__windows && !string_ends_with(v->pref->out_name, _S(".exe"))) { v->pref->out_name = string__plus(v->pref->out_name, _S(".exe")); } v__builder__Builder_log(v, str_intp(3, _MOV((StrIntpData[]){{_S("cc() isprod="), 0xfe10, {.d_s = v->pref->is_prod ? _S("true") : _S("false")}}, {_S(" outname="), 0xfe10, {.d_s = v->pref->out_name}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (v->pref->is_shared) { if (!string_ends_with(v->pref->out_name, v->ccoptions.shared_postfix)) { v->pref->out_name = string__plus(v->pref->out_name, v->ccoptions.shared_postfix); } } if (v->pref->build_mode == v__pref__BuildMode__build_module) { v->pref->out_name = v__vcache__CacheManager_mod_postfix_with_key2cpath(&v->pref->cache_manager, v->pref->path, _S(".o"), v->pref->path); if (v->pref->is_verbose) { println(str_intp(3, _MOV((StrIntpData[]){{_S("Building "), 0xfe10, {.d_s = v->pref->path}}, {_S(" to "), 0xfe10, {.d_s = v->pref->out_name}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } _result_string _t1 = v__vcache__CacheManager_mod_save(&v->pref->cache_manager, v->pref->path, _S(".description.txt"), v->pref->path, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0x3cfe10, {.d_s = v->pref->path}}, {_S(" @ "), 0xfe10, {.d_s = v->pref->cache_manager.vopts}}, {_S("\n"), 0, { .d_c = 0 }}}))); if (_t1.is_error) { IError err = _t1.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; } if (os__is_dir(v->pref->out_name)) { v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(v->pref->out_name)}}, {_S(" is a directory"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } if (!v->pref->parallel_cc) { array_push((array*)&v->ccoptions.o_args, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-o "), 0xfe10, {.d_s = v__builder__Builder_tcc_quoted_path(v, v->pref->out_name)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } } string v__builder__Builder_tcc_quoted_path(v__builder__Builder* v, string p) { if (v->ccoptions.cc == v__builder__CC__tcc && !v->pref->no_rsp) { return str_intp(2, _MOV((StrIntpData[]){{_S("\""), 0xfe10, {.d_s = p}}, {_S("\""), 0, { .d_c = 0 }}})); } return os__quoted_path(p); } void v__builder__Builder_cc(v__builder__Builder* v) { if (string_contains(os__executable(), _S("vfmt"))) { return; } if (v->pref->is_verbose) { println(str_intp(2, _MOV((StrIntpData[]){{_S("builder.cc() pref.out_name="), 0xfe10, {.d_s = os__quoted_path(v->pref->out_name)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (v->pref->only_check_syntax) { if (v->pref->is_verbose) { println(_S("builder.cc returning early, since pref.only_check_syntax is true")); } return; } if (v->pref->check_only) { if (v->pref->is_verbose) { println(_S("builder.cc returning early, since pref.check_only is true")); } return; } if (v__pref__Preferences_should_output_to_stdout(v->pref)) { _result_string _t1 = os__read_file(v->out_name_c); if (_t1.is_error) { IError err = _t1.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } string content = (*(string*)_t1.data); println(content); _result_void _t2 = os__rm(v->out_name_c); (void)_t2; ; return; } bool ends_with_c = string_ends_with(v->pref->out_name, _S(".c")); bool ends_with_js = string_ends_with(v->pref->out_name, _S(".js")); if (ends_with_c || (ends_with_js && v->pref->os != v__pref__OS__wasm32_emscripten)) { v->pref->skip_running = true; string msg_mv = str_intp(3, _MOV((StrIntpData[]){{_S("os.mv_by_cp "), 0xfe10, {.d_s = os__quoted_path(v->out_name_c)}}, {_S(" => "), 0xfe10, {.d_s = os__quoted_path(v->pref->out_name)}}, {_SLIT0, 0, { .d_c = 0 }}})); v__util__timing_start(msg_mv); _result_void _t3 = os__mv_by_cp(v->out_name_c, v->pref->out_name, ((os__MvParams){.overwrite = true,})); if (_t3.is_error) { IError err = _t3.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; v__util__timing_measure(msg_mv); return; } if (v->pref->os == v__pref__OS__windows && !fast_string_eq(v->pref->ccompiler, _S("msvc"))) { #if !defined(_WIN32) { v__builder__Builder_cc_windows_cross(v); return; } #endif } if (v->pref->os == v__pref__OS__linux) { #if !defined(__linux__) { v__builder__Builder_cc_linux_cross(v); return; } #endif } if (v->pref->os == v__pref__OS__freebsd) { #if !defined(__FreeBSD__) { v__builder__Builder_cc_freebsd_cross(v); return; } #endif } string vexe = v__pref__vexe_path(); string vdir = os__dir(vexe); Array_string tried_compilation_commands = __new_array_with_default(0, 0, sizeof(string), 0); os__Result tcc_output = ((os__Result){.exit_code = 0,.output = (string){.str=(byteptr)"", .is_lit=1},}); string original_pwd = os__getwd(); for (;;) { string ccompiler = v->pref->ccompiler; if (v->pref->os == v__pref__OS__wasm32) { ccompiler = _S("clang"); } v__builder__Builder_setup_ccompiler_options(v, ccompiler); v__builder__Builder_build_thirdparty_obj_files(v); v__builder__Builder_setup_output_name(v); if (v->pref->os != v__pref__OS__windows && string_contains(ccompiler, _S("++"))) { string cpp_atomic_h_path = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _S("/home/runner/work/v/v")}}, {_S("/thirdparty/stdatomic/nix/cpp/atomic.h"), 0, { .d_c = 0 }}})); if (!os__exists(cpp_atomic_h_path)) { for (int _t7 = 0; _t7 < v->parsed_files.len; ++_t7) { v__ast__File* file = ((v__ast__File**)v->parsed_files.data)[_t7]; bool _t8 = false; Array_v__ast__Import _t8_orig = file->imports; int _t8_len = _t8_orig.len; for (int _t9 = 0; _t9 < _t8_len; ++_t9) { v__ast__Import it = ((v__ast__Import*) _t8_orig.data)[_t9]; if (string_contains(it.mod, _S("sync"))) { _t8 = true; break; } } if (_t8) { #if defined(CUSTOM_DEFINE_trace_stdatomic_gen) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> creating "), 0xfe10, {.d_s = cpp_atomic_h_path}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } #endif string cppgenv = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _S("/home/runner/work/v/v")}}, {_S("/thirdparty/stdatomic/nix/cpp/gen.v"), 0, { .d_c = 0 }}})); os__execute(str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(vexe)}}, {_S(" run "), 0xfe10, {.d_s = os__quoted_path(cppgenv)}}, {_S(" "), 0xfe10, {.d_s = os__quoted_path(ccompiler)}}, {_SLIT0, 0, { .d_c = 0 }}}))); break; } } } } if (v->pref->build_mode == v__pref__BuildMode__build_module) { array_push((array*)&v->ccoptions.pre_args, _MOV((string[]){ _S("-c") })); } v__builder__Builder_handle_usecache(v, vexe); #if defined(_WIN32) { if (_SLIT_EQ(ccompiler.str, ccompiler.len, "msvc")) { v__builder__Builder_cc_msvc(v); return; } } #endif Array_string all_args = v__builder__Builder_all_args(v, v->ccoptions); v__builder__Builder_dump_c_options(v, all_args); string _t13; /* if prepend */ if (v->pref->no_rsp) { _t13 = string_replace(Array_string_join(all_args, _S(" ")), _S("\n"), _S(" ")); } else { _t13 = Array_string_join(all_args, _S(" ")); } string str_args = _t13; string cmd = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__builder__Builder_quote_compiler_name(v, ccompiler)}}, {_S(" "), 0xfe10, {.d_s = str_args}}, {_SLIT0, 0, { .d_c = 0 }}})); if (v->pref->parallel_cc) { v->str_args = str_args; return; } string response_file = _S(""); string response_file_content = str_args; if (!v->pref->no_rsp) { response_file = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v->out_name_c}}, {_S(".rsp"), 0, { .d_c = 0 }}})); response_file_content = string_replace(str_args, _S("\\"), _S("\\\\")); string rspexpr = str_intp(2, _MOV((StrIntpData[]){{_S("@"), 0xfe10, {.d_s = response_file}}, {_SLIT0, 0, { .d_c = 0 }}})); cmd = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__builder__Builder_quote_compiler_name(v, ccompiler)}}, {_S(" "), 0xfe10, {.d_s = os__quoted_path(rspexpr)}}, {_SLIT0, 0, { .d_c = 0 }}})); v__builder__write_response_file(response_file, response_file_content); if (!v->ccoptions.debug_mode) { array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ string_clone(response_file) })); } } if (!v->ccoptions.debug_mode) { array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ string_clone(v->out_name_c) })); } #if defined(_WIN32) { if (v->ccoptions.cc == v__builder__CC__tcc) { string def_name = string_substr(v->pref->out_name, 0, (int)(v->pref->out_name.len - 4)); array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = def_name}}, {_S(".def"), 0, { .d_c = 0 }}})) })); } } #endif _result_void _t18 = os__chdir(vdir); (void)_t18; ; array_push((array*)&tried_compilation_commands, _MOV((string[]){ string_clone(cmd) })); v__builder__Builder_show_cc(v, cmd, response_file, response_file_content); string ccompiler_label = str_intp(2, _MOV((StrIntpData[]){{_S("C "), 0x6fe30, {.d_s = os__file_name(ccompiler)}}, {_SLIT0, 0, { .d_c = 0 }}})); v__util__timing_start(ccompiler_label); os__Result res = os__execute(cmd); v__util__timing_measure(ccompiler_label); if (v->pref->show_c_output) { v__builder__Builder_show_c_compiler_output(v, ccompiler, res); } _result_void _t20 = os__chdir(original_pwd); (void)_t20; ; ; ; ; if (res.exit_code != 0) { if (string_contains(ccompiler, _S("tcc.exe"))) { if (tried_compilation_commands.len > 1) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("Recompilation loop detected (ccompiler: "), 0xfe10, {.d_s = ccompiler}}, {_S("):"), 0, { .d_c = 0 }}}))); for (int _t21 = 0; _t21 < tried_compilation_commands.len; ++_t21) { string recompile_command = ((string*)tried_compilation_commands.data)[_t21]; eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = recompile_command}}, {_SLIT0, 0, { .d_c = 0 }}}))); } _v_exit(101); VUNREACHABLE(); } if (v->pref->retry_compilation) { tcc_output = res; v__pref__Preferences_default_c_compiler(v->pref); if (v->pref->is_verbose) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("Compilation with tcc failed. Retrying with "), 0xfe10, {.d_s = v->pref->ccompiler}}, {_S(" ..."), 0, { .d_c = 0 }}}))); } continue; } } if (res.exit_code == 127) { v__builder__verror(string__plus(string__plus(string__plus(string__plus(string__plus(_S("C compiler error, while attempting to run: \n-----------------------------------------------------------\n"), str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = cmd}}, {_S("\n"), 0, { .d_c = 0 }}}))), _S("-----------------------------------------------------------\n")), _S("Probably your C compiler is missing. \n")), _S("Please reinstall it, or make it available in your PATH.\n\n")), v__builder__missing_compiler_info())); VUNREACHABLE(); } } if (!v->pref->show_c_output) { if (res.exit_code != 0 && (tcc_output.output).len != 0) { v__builder__Builder_post_process_c_compiler_output(v, _S("tcc"), tcc_output); } else { v__builder__Builder_post_process_c_compiler_output(v, ccompiler, res); } } if (v->pref->is_verbose) { println(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = ccompiler}}, {_SLIT0, 0, { .d_c = 0 }}}))); println(_S("=========\n")); } break; } if (v->pref->compress) { int ret = os__system(str_intp(2, _MOV((StrIntpData[]){{_S("strip "), 0xfe10, {.d_s = os__quoted_path(v->pref->out_name)}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (ret != 0) { println(_S("strip failed")); return; } int ret2 = os__system(str_intp(2, _MOV((StrIntpData[]){{_S("upx --lzma -qqq "), 0xfe10, {.d_s = os__quoted_path(v->pref->out_name)}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (ret2 != 0) { ret2 = os__system(str_intp(2, _MOV((StrIntpData[]){{_S("upx -qqq "), 0xfe10, {.d_s = os__quoted_path(v->pref->out_name)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (ret2 != 0) { println(_S("upx failed")); #if defined(__APPLE__) { println(_S("install upx with `brew install upx`")); } #endif #if defined(__linux__) { println(string__plus(_S("install upx\n"), _S("for example, on Debian/Ubuntu run `sudo apt install upx`"))); } #endif #if defined(_WIN32) { println(_S("install upx")); } #endif } } } VV_LOC void v__builder__Builder_ensure_linuxroot_exists(v__builder__Builder* b, string sysroot) { string crossrepo_url = _S("https://github.com/vlang/linuxroot"); string sysroot_git_config_path = os__join_path(sysroot, new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S(".git"), _S("config")}))); if (os__is_dir(sysroot) && !os__exists(sysroot_git_config_path)) { _result_void _t1 = os__rmdir_all(sysroot); (void)_t1; ; } if (!os__is_dir(sysroot)) { println(_S("Downloading files for Linux cross compilation (~77MB) ...")); os__system(str_intp(3, _MOV((StrIntpData[]){{_S("git clone \""), 0xfe10, {.d_s = crossrepo_url}}, {_S("\" "), 0xfe10, {.d_s = os__quoted_path(sysroot)}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (!os__exists(sysroot_git_config_path)) { v__builder__verror(str_intp(3, _MOV((StrIntpData[]){{_S("Failed to clone `"), 0xfe10, {.d_s = crossrepo_url}}, {_S("` to `"), 0xfe10, {.d_s = sysroot}}, {_S("`"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } _result_void _t2 = os__chmod(os__join_path(sysroot, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("ld.lld")}))), 0755); if (_t2.is_error) { IError err = _t2.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; } } VV_LOC void v__builder__Builder_ensure_freebsdroot_exists(v__builder__Builder* b, string sysroot) { string crossrepo_url = _S("https://github.com/spytheman/freebsd_base13.2"); string sysroot_git_config_path = os__join_path(sysroot, new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S(".git"), _S("config")}))); if (os__is_dir(sysroot) && !os__exists(sysroot_git_config_path)) { _result_void _t1 = os__rmdir_all(sysroot); (void)_t1; ; } if (!os__is_dir(sysroot)) { println(_S("Downloading files for FreeBSD cross compilation (~458MB) ...")); os__system(str_intp(3, _MOV((StrIntpData[]){{_S("git clone \""), 0xfe10, {.d_s = crossrepo_url}}, {_S("\" "), 0xfe10, {.d_s = os__quoted_path(sysroot)}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (!os__exists(sysroot_git_config_path)) { v__builder__verror(str_intp(3, _MOV((StrIntpData[]){{_S("Failed to clone `"), 0xfe10, {.d_s = crossrepo_url}}, {_S("` to `"), 0xfe10, {.d_s = sysroot}}, {_S("`"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } } } VV_LOC string v__builder__Builder_get_subsystem_flag(v__builder__Builder* b) { return ((b->pref->subsystem == (v__pref__Subsystem__auto))? (_S("-municode")) : (b->pref->subsystem == (v__pref__Subsystem__console))? (_S("-municode -mconsole")) : (_S("-municode -mwindows"))); } VV_LOC void v__builder__Builder_cc_linux_cross(v__builder__Builder* b) { v__builder__Builder_setup_ccompiler_options(b, b->pref->ccompiler); v__builder__Builder_build_thirdparty_obj_files(b); v__builder__Builder_setup_output_name(b); string parent_dir = os__vmodules_dir(); if (!os__exists(parent_dir)) { _result_void _t1 = os__mkdir(parent_dir, ((os__MkdirParams){.mode = 0777,})); if (_t1.is_error) { IError err = _t1.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; } string sysroot = os__join_path(os__vmodules_dir(), new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("linuxroot")}))); v__builder__Builder_ensure_linuxroot_exists(b, sysroot); string obj_file = string__plus(b->out_name_c, _S(".o")); Array_v__cflag__CFlag cflags = v__builder__Builder_get_os_cflags(b); multi_return_Array_string_Array_string_Array_string mr_28715 = Array_v__cflag__CFlag_defines_others_libs(cflags); Array_string defines = mr_28715.arg0; Array_string others = mr_28715.arg1; Array_string libs = mr_28715.arg2; Array_string cc_args = __new_array_with_default(0, 20, sizeof(string), 0); array_push((array*)&cc_args, _MOV((string[]){ _S("-w") })); array_push((array*)&cc_args, _MOV((string[]){ _S("-fPIC") })); array_push((array*)&cc_args, _MOV((string[]){ _S("-target x86_64-linux-gnu") })); _PUSH_MANY(&cc_args, (defines), _t5, Array_string); array_push((array*)&cc_args, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-I "), 0xfe10, {.d_s = os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/include"), 0, { .d_c = 0 }}})))}}, {_S(" "), 0, { .d_c = 0 }}})) })); _PUSH_MANY(&cc_args, (others), _t7, Array_string); array_push((array*)&cc_args, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-o "), 0xfe10, {.d_s = os__quoted_path(obj_file)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); array_push((array*)&cc_args, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-c "), 0xfe10, {.d_s = os__quoted_path(b->out_name_c)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); _PUSH_MANY(&cc_args, (libs), _t10, Array_string); v__builder__Builder_dump_c_options(b, cc_args); string cc_name = _S("cc"); string out_name = b->pref->out_name; #if defined(_WIN32) { cc_name = _S("clang.exe"); out_name = string_trim_string_right(out_name, _S(".exe")); } #endif string cc_cmd = string__plus(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__builder__Builder_quote_compiler_name(b, cc_name)}}, {_S(" "), 0, { .d_c = 0 }}})), Array_string_join(cc_args, _S(" "))); if (b->pref->show_cc) { println(cc_cmd); } os__Result cc_res = os__execute(cc_cmd); if (cc_res.exit_code != 0) { println(_S("Cross compilation for Linux failed (first step, cc). Make sure you have clang installed.")); v__builder__verror(cc_res.output); VUNREACHABLE(); return; } Array_string linker_args = new_array_from_c_array(21, 21, sizeof(string), _MOV((string[21]){ _S("-L"), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/usr/lib/x86_64-linux-gnu/"), 0, { .d_c = 0 }}}))), _S("-L"), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/lib/x86_64-linux-gnu"), 0, { .d_c = 0 }}}))), string__plus(_S("--sysroot="), os__quoted_path(sysroot)), _S("-v"), _S("-o"), os__quoted_path(out_name), _S("-m elf_x86_64"), _S("-dynamic-linker"), os__quoted_path(_S("/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2")), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/crt1.o"), 0, { .d_c = 0 }}}))), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/crti.o"), 0, { .d_c = 0 }}}))), os__quoted_path(obj_file), _S("-lc"), _S("-lcrypto"), _S("-lssl"), _S("-lpthread"), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/crtn.o"), 0, { .d_c = 0 }}}))), _S("-lm"), _S("-ldl")})); _PUSH_MANY(&linker_args, (Array_v__cflag__CFlag_c_options_only_object_files(cflags)), _t12, Array_string); v__builder__Builder_dump_c_options(b, linker_args); string ldlld = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/ld.lld"), 0, { .d_c = 0 }}})); #if defined(_WIN32) { ldlld = _S("ld.lld.exe"); } #endif string linker_cmd = string__plus(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__builder__Builder_quote_compiler_name(b, ldlld)}}, {_S(" "), 0, { .d_c = 0 }}})), Array_string_join(linker_args, _S(" "))); if (b->pref->show_cc) { println(linker_cmd); } os__Result res = os__execute(linker_cmd); if (res.exit_code != 0) { println(_S("Cross compilation for Linux failed (second step, lld).")); v__builder__verror(res.output); VUNREACHABLE(); return; } println(string__plus(out_name, _S(" has been successfully cross compiled for linux."))); } VV_LOC void v__builder__Builder_cc_freebsd_cross(v__builder__Builder* b) { v__builder__Builder_setup_ccompiler_options(b, b->pref->ccompiler); v__builder__Builder_build_thirdparty_obj_files(b); v__builder__Builder_setup_output_name(b); string parent_dir = os__vmodules_dir(); if (!os__exists(parent_dir)) { _result_void _t1 = os__mkdir(parent_dir, ((os__MkdirParams){.mode = 0777,})); if (_t1.is_error) { IError err = _t1.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; } string sysroot = os__join_path(os__vmodules_dir(), new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("freebsdroot")}))); v__builder__Builder_ensure_freebsdroot_exists(b, sysroot); string obj_file = string__plus(b->out_name_c, _S(".o")); Array_v__cflag__CFlag cflags = v__builder__Builder_get_os_cflags(b); multi_return_Array_string_Array_string_Array_string mr_31045 = Array_v__cflag__CFlag_defines_others_libs(cflags); Array_string defines = mr_31045.arg0; Array_string others = mr_31045.arg1; Array_string libs = mr_31045.arg2; Array_string cc_args = __new_array_with_default(0, 20, sizeof(string), 0); array_push((array*)&cc_args, _MOV((string[]){ _S("-w") })); array_push((array*)&cc_args, _MOV((string[]){ _S("-fPIC") })); array_push((array*)&cc_args, _MOV((string[]){ _S("-target x86_64-unknown-freebsd14.0") })); _PUSH_MANY(&cc_args, (defines), _t5, Array_string); array_push((array*)&cc_args, _MOV((string[]){ _S("-I") })); array_push((array*)&cc_args, _MOV((string[]){ os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/include"), 0, { .d_c = 0 }}}))) })); array_push((array*)&cc_args, _MOV((string[]){ _S("-I") })); array_push((array*)&cc_args, _MOV((string[]){ os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/usr/include"), 0, { .d_c = 0 }}}))) })); _PUSH_MANY(&cc_args, (others), _t10, Array_string); array_push((array*)&cc_args, _MOV((string[]){ _S("-o") })); array_push((array*)&cc_args, _MOV((string[]){ os__quoted_path(obj_file) })); array_push((array*)&cc_args, _MOV((string[]){ _S("-c") })); array_push((array*)&cc_args, _MOV((string[]){ os__quoted_path(b->out_name_c) })); _PUSH_MANY(&cc_args, (libs), _t15, Array_string); v__builder__Builder_dump_c_options(b, cc_args); string cc_name = v__pref__Preferences_vcross_compiler_name(b->pref); string out_name = b->pref->out_name; #if defined(_WIN32) { cc_name = _S("clang.exe"); out_name = string_trim_string_right(out_name, _S(".exe")); } #endif string cc_cmd = string__plus(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__builder__Builder_quote_compiler_name(b, cc_name)}}, {_S(" "), 0, { .d_c = 0 }}})), Array_string_join(cc_args, _S(" "))); if (b->pref->show_cc) { println(cc_cmd); } os__Result cc_res = os__execute(cc_cmd); if (cc_res.exit_code != 0) { println(_S("Cross compilation for FreeBSD failed (first step, cc). Make sure you have clang installed.")); v__builder__verror(cc_res.output); VUNREACHABLE(); return; } Array_string linker_args = new_array_from_c_array(14, 14, sizeof(string), _MOV((string[14]){ _S("-L"), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/lib/"), 0, { .d_c = 0 }}}))), _S("-L"), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/usr/lib/"), 0, { .d_c = 0 }}}))), string__plus(_S("--sysroot="), os__quoted_path(sysroot)), _S("-v"), _S("-o"), os__quoted_path(out_name), _S("-m elf_x86_64"), _S("-dynamic-linker /libexec/ld-elf.so.1"), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/usr/lib/crt1.o"), 0, { .d_c = 0 }}}))), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/usr/lib/crti.o"), 0, { .d_c = 0 }}}))), os__quoted_path(obj_file), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = sysroot}}, {_S("/usr/lib/crtn.o"), 0, { .d_c = 0 }}})))})); array_push((array*)&linker_args, _MOV((string[]){ _S("-lc") })); array_push((array*)&linker_args, _MOV((string[]){ _S("-lexecinfo") })); _PUSH_MANY(&linker_args, (Array_v__cflag__CFlag_c_options_only_object_files(cflags)), _t19, Array_string); _PUSH_MANY(&linker_args, (libs), _t20, Array_string); v__builder__Builder_dump_c_options(b, linker_args); string ldlld = v__pref__Preferences_vcross_linker_name(b->pref); string linker_cmd = string__plus(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__builder__Builder_quote_compiler_name(b, ldlld)}}, {_S(" "), 0, { .d_c = 0 }}})), Array_string_join(linker_args, _S(" "))); if (b->pref->show_cc) { println(linker_cmd); } os__Result res = os__execute(linker_cmd); if (res.exit_code != 0) { println(_S("Cross compilation for FreeBSD failed (second step, lld).")); v__builder__verror(res.output); VUNREACHABLE(); return; } println(string__plus(out_name, _S(" has been successfully cross compiled for FreeBSD."))); } VV_LOC void v__builder__Builder_cc_windows_cross(v__builder__Builder* c) { println(_S("Cross compiling for Windows...")); string cross_compiler_name = v__pref__Preferences_vcross_compiler_name(c->pref); _result_string _t1 = os__find_abs_path_of_executable(cross_compiler_name); if (_t1.is_error) { IError err = _t1.err; eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("Could not find `"), 0xfe10, {.d_s = cross_compiler_name}}, {_S("` in your PATH."), 0, { .d_c = 0 }}}))); eprintln(_S("See https://github.com/vlang/v/blob/master/doc/docs.md#cross-compilation for instructions on how to fix that.")); _v_exit(1); VUNREACHABLE(); ; } string cross_compiler_name_path = (*(string*)_t1.data); v__builder__Builder_setup_ccompiler_options(c, c->pref->ccompiler); v__builder__Builder_build_thirdparty_obj_files(c); v__builder__Builder_setup_output_name(c); Array_string args = __new_array_with_default(0, 0, sizeof(string), 0); array_push((array*)&args, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = c->pref->cflags}}, {_SLIT0, 0, { .d_c = 0 }}})) })); array_push((array*)&args, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-o "), 0xfe10, {.d_s = os__quoted_path(c->pref->out_name)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); array_push((array*)&args, _MOV((string[]){ _S("-w -L.") })); Array_v__cflag__CFlag cflags = v__builder__Builder_get_os_cflags(c); if (fast_string_eq(c->pref->ccompiler, _S("msvc"))) { _PUSH_MANY(&args, (Array_v__cflag__CFlag_c_options_before_target_msvc(cflags)), _t5, Array_string); } else { _PUSH_MANY(&args, (Array_v__cflag__CFlag_c_options_before_target(cflags)), _t6, Array_string); } Array_string optimization_options = __new_array_with_default(0, 0, sizeof(string), 0); Array_string debug_options = __new_array_with_default(0, 0, sizeof(string), 0); if (c->pref->is_prod) { if (!fast_string_eq(c->pref->ccompiler, _S("msvc"))) { optimization_options = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("-O3")})); bool have_flto = true; if (c->pref->parallel_cc) { have_flto = false; } if (have_flto) { array_push((array*)&optimization_options, _MOV((string[]){ _S("-flto") })); } } } if (c->pref->is_debug) { if (!fast_string_eq(c->pref->ccompiler, _S("msvc"))) { debug_options = new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("-O0"), _S("-g"), _S("-gdwarf-2")})); } } Array_string libs = __new_array_with_default(0, 0, sizeof(string), 0); if (false && c->pref->build_mode == v__pref__BuildMode__default_mode) { string builtin_o = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__pref__default_module_path}}, {_S("/vlib/builtin.o"), 0, { .d_c = 0 }}})); array_push((array*)&libs, _MOV((string[]){ os__quoted_path(builtin_o) })); if (!os__exists(builtin_o)) { v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = builtin_o}}, {_S(" not found"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } for (int _t9 = 0; _t9 < c->table->imports.len; ++_t9) { string imp = ((string*)c->table->imports.data)[_t9]; array_push((array*)&libs, _MOV((string[]){ os__quoted_path(str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _const_v__pref__default_module_path}}, {_S("/vlib/"), 0xfe10, {.d_s = imp}}, {_S(".o"), 0, { .d_c = 0 }}}))) })); } } _PUSH_MANY(&args, (Array_v__cflag__CFlag_c_options_only_object_files(cflags)), _t11, Array_string); array_push((array*)&args, _MOV((string[]){ os__quoted_path(c->out_name_c) })); Array_string c_options_after_target = __new_array_with_default(0, 0, sizeof(string), 0); if (fast_string_eq(c->pref->ccompiler, _S("msvc"))) { _PUSH_MANY(&c_options_after_target, (Array_v__cflag__CFlag_c_options_after_target_msvc(cflags)), _t13, Array_string); } else { _PUSH_MANY(&c_options_after_target, (Array_v__cflag__CFlag_c_options_after_target(cflags)), _t14, Array_string); } for (int _t15 = 0; _t15 < c->ccoptions.linker_flags.len; ++_t15) { string lf = ((string*)c->ccoptions.linker_flags.data)[_t15]; if ((Array_string_contains(c_options_after_target, lf))) { continue; } array_push((array*)&c_options_after_target, _MOV((string[]){ string_clone(lf) })); } _PUSH_MANY(&args, (c_options_after_target), _t17, Array_string); if (!(_SLIT_EQ(_const_v__builder__current_os.str, _const_v__builder__current_os.len, "macos") || _SLIT_EQ(_const_v__builder__current_os.str, _const_v__builder__current_os.len, "linux") || _SLIT_EQ(_const_v__builder__current_os.str, _const_v__builder__current_os.len, "termux"))) { println(_const_v__builder__current_os); _v_panic(_S("your platform is not supported yet")); VUNREACHABLE(); } Array_string all_args = __new_array_with_default(0, 0, sizeof(string), 0); array_push((array*)&all_args, _MOV((string[]){ _S("-std=gnu11") })); if (!c->pref->no_prod_options) { _PUSH_MANY(&all_args, (optimization_options), _t19, Array_string); } _PUSH_MANY(&all_args, (debug_options), _t20, Array_string); _PUSH_MANY(&all_args, (args), _t21, Array_string); array_push((array*)&all_args, _MOV((string[]){ v__builder__Builder_get_subsystem_flag(c) })); array_push((array*)&all_args, _MOV((string[]){ string_clone(c->pref->ldflags) })); v__builder__Builder_dump_c_options(c, all_args); string cmd = string__plus(string__plus(cross_compiler_name_path, _S(" ")), Array_string_join(all_args, _S(" "))); if (c->pref->is_verbose || c->pref->show_cc) { println(cmd); } if (os__system(cmd) != 0) { println(_S("Cross compilation for Windows failed. Make sure you have mingw-w64 installed.")); #if defined(__APPLE__) { println(_S("brew install mingw-w64")); } #endif #if defined(__linux__) { println(_S("Try `sudo apt install -y mingw-w64` on Debian based distros, or `sudo pacman -S mingw-w64-gcc` on Arch, etc...")); } #endif _v_exit(1); VUNREACHABLE(); } println(string__plus(c->pref->out_name, _S(" has been successfully cross compiled for windows."))); } VV_LOC void v__builder__Builder_build_thirdparty_obj_files(v__builder__Builder* b) { v__builder__Builder_log(b, str_intp(2, _MOV((StrIntpData[]){{_S("build_thirdparty_obj_files: v.ast.cflags: "), 0xfe10, {.d_s = Array_v__cflag__CFlag_str(b->table->cflags)}}, {_SLIT0, 0, { .d_c = 0 }}}))); Array_v__cflag__CFlag _t1 = v__builder__Builder_get_os_cflags(b); for (int _t2 = 0; _t2 < _t1.len; ++_t2) { v__cflag__CFlag flag = ((v__cflag__CFlag*)_t1.data)[_t2]; if (string_ends_with(flag.value, _S(".o"))) { Array_v__cflag__CFlag rest_of_module_flags = v__builder__Builder_get_rest_of_module_cflags(b, (voidptr)&flag); #if defined(_WIN32) { if (fast_string_eq(b->pref->ccompiler, _S("msvc"))) { v__builder__Builder_build_thirdparty_obj_file_with_msvc(b, flag.mod, flag.value, rest_of_module_flags); continue; } } #endif v__builder__Builder_build_thirdparty_obj_file(b, flag.mod, flag.value, rest_of_module_flags); } } } VV_LOC void v__builder__Builder_build_thirdparty_obj_file(v__builder__Builder* v, string mod, string path, Array_v__cflag__CFlag moduleflags) { string obj_path = os__real_path(path); string cfile = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = string_substr(obj_path, 0, (int)(obj_path.len - 2))}}, {_S(".c"), 0, { .d_c = 0 }}})); bool cpp_file = false; if (!os__exists(cfile)) { cfile = string__plus(cfile, _S("pp")); cpp_file = true; } string opath = v__vcache__CacheManager_mod_postfix_with_key2cpath(&v->pref->cache_manager, mod, _S(".o"), obj_path); string rebuild_reason_message = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(obj_path)}}, {_S(" not found, building it in "), 0xfe10, {.d_s = os__quoted_path(opath)}}, {_S(" ..."), 0, { .d_c = 0 }}})); if (os__exists(opath)) { if (os__exists(cfile) && os__file_last_mod_unix(opath) < os__file_last_mod_unix(cfile)) { rebuild_reason_message = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(opath)}}, {_S(" is older than "), 0xfe10, {.d_s = os__quoted_path(cfile)}}, {_S(", rebuilding ..."), 0, { .d_c = 0 }}})); } else { return; } } if (os__exists(obj_path)) { _result_void _t1 = os__cp(obj_path, opath); if (_t1.is_error) { IError err = _t1.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; return; } if (v->pref->is_verbose) { println(rebuild_reason_message); } string current_folder = os__getwd(); _result_void _t2 = os__chdir(v->pref->vroot); (void)_t2; ; Array_string all_options = __new_array_with_default(0, 0, sizeof(string), 0); array_push((array*)&all_options, _MOV((string[]){ string_clone(v->pref->third_party_option) })); _PUSH_MANY(&all_options, (Array_v__cflag__CFlag_c_options_before_target(moduleflags)), _t4, Array_string); array_push((array*)&all_options, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-o "), 0xfe10, {.d_s = v__builder__Builder_tcc_quoted_path(v, opath)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); array_push((array*)&all_options, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-c "), 0xfe10, {.d_s = v__builder__Builder_tcc_quoted_path(v, cfile)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); string cc_options = Array_string_join(v__builder__Builder_thirdparty_object_args(v, v->ccoptions, all_options, cpp_file), _S(" ")); string ccompiler = v->pref->ccompiler; if (cpp_file) { #if defined(CUSTOM_DEFINE_trace_thirdparty_obj_files) { println(str_intp(3, _MOV((StrIntpData[]){{_S(">>> build_thirdparty_obj_files switched from compiler \""), 0xfe10, {.d_s = ccompiler}}, {_S("\" to \""), 0xfe10, {.d_s = v->pref->cppcompiler}}, {_S("\""), 0, { .d_c = 0 }}}))); } #endif ccompiler = v->pref->cppcompiler; } string cmd = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__builder__Builder_quote_compiler_name(v, ccompiler)}}, {_S(" "), 0xfe10, {.d_s = cc_options}}, {_SLIT0, 0, { .d_c = 0 }}})); #if defined(CUSTOM_DEFINE_trace_thirdparty_obj_files) { println(str_intp(2, _MOV((StrIntpData[]){{_S(">>> build_thirdparty_obj_files cmd: "), 0xfe10, {.d_s = cmd}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif os__Result res = os__execute(cmd); _result_void _t9 = os__chdir(current_folder); (void)_t9; ; if (res.exit_code != 0) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("failed thirdparty object build cmd:\n"), 0xfe10, {.d_s = cmd}}, {_SLIT0, 0, { .d_c = 0 }}}))); v__builder__verror(res.output); VUNREACHABLE(); return; } _result_string _t10 = v__vcache__CacheManager_mod_save(&v->pref->cache_manager, mod, _S(".description.txt"), obj_path, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0x3cfe10, {.d_s = obj_path}}, {_S(" @ "), 0xfe10, {.d_s = cmd}}, {_S("\n"), 0, { .d_c = 0 }}}))); if (_t10.is_error) { IError err = _t10.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; if (v->pref->show_cc) { println(str_intp(2, _MOV((StrIntpData[]){{_S(">> OBJECT FILE compilation cmd: "), 0xfe10, {.d_s = cmd}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #if defined(CUSTOM_DEFINE_trace_thirdparty_obj_files) { if ((res.output).len != 0) { println(res.output); } println(_S(">>> build_thirdparty_obj_files done")); } #endif } VV_LOC string v__builder__missing_compiler_info(void) { #if defined(_WIN32) { return _S("https://github.com/vlang/v/wiki/Installing-a-C-compiler-on-Windows"); } #endif #if defined(__linux__) { return _S("On Debian/Ubuntu, run `sudo apt install build-essential`"); } #endif #if defined(__APPLE__) { return _S("Install command line XCode tools with `xcode-select --install`"); } #endif return _S("Install a C compiler, like gcc or clang"); } VV_LOC string v__builder__highlight_word(string keyword) { return (term__can_show_color_on_stdout() ? (term__red(keyword)) : (keyword)); } VV_LOC Array_string v__builder__error_context_lines(string text, string keyword, int before, int after) { string khighlight = v__builder__highlight_word(keyword); int eline_idx = -1; Array_string lines = string_split_into_lines(text); for (int idx = 0; idx < lines.len; ++idx) { string eline = ((string*)lines.data)[idx]; if (string_contains(eline, keyword)) { array_set(&lines, idx, &(string[]) { string_replace((*(string*)array_get(lines, idx)), keyword, khighlight) }); if (eline_idx == -1) { eline_idx = idx; } } } int idx_s = ((int)(eline_idx - before) >= 0 ? ((int)(eline_idx - before)) : (0)); int idx_e = ((int)(idx_s + after) < lines.len ? ((int)(idx_s + after)) : (lines.len)); return array_slice(lines, idx_s, idx_e); } string v__builder__Builder_quote_compiler_name(v__builder__Builder* v, string name) { #if defined(_WIN32) { if (string_contains(name, _S("/")) || string_contains(name, _S("\\"))) { return os__quoted_path(name); } return name; } #endif return os__quoted_path(name); } VV_LOC void v__builder__write_response_file(string response_file, string response_file_content) { #if defined(_WIN32) { _result_void _t2 = os__write_file_array(response_file, string_to_ansi_not_null_terminated(response_file_content)); if (_t2.is_error) { IError err = _t2.err; v__builder__write_response_file_error(response_file_content, err); ; } ; } #else { _result_void _t3 = os__write_file(response_file, response_file_content); if (_t3.is_error) { IError err = _t3.err; v__builder__write_response_file_error(response_file_content, err); ; } ; } #endif } VV_LOC void v__builder__write_response_file_error(string response_file, IError err) { v__builder__verror(str_intp(3, _MOV((StrIntpData[]){{_S("Unable to write to C response file \""), 0xfe10, {.d_s = response_file}}, {_S("\", error: "), 0xfe10, {.d_s = IError_str(err)}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } _result_void v__builder__Builder_find_win_cc(v__builder__Builder* v) { #if !defined(_WIN32) { return (_result_void){0}; } #endif string cmd_version = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v__builder__Builder_quote_compiler_name(v, v->pref->ccompiler)}}, {_S(" -v"), 0, { .d_c = 0 }}})); os__Result ccompiler_version_res = os__execute(cmd_version); if (ccompiler_version_res.exit_code != 0) { if (v->pref->is_verbose) { println(str_intp(2, _MOV((StrIntpData[]){{_S("failed command: `"), 0xfe10, {.d_s = cmd_version}}, {_S("`"), 0, { .d_c = 0 }}}))); println(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = v->pref->ccompiler}}, {_S(" not found, looking for msvc..."), 0, { .d_c = 0 }}}))); } if (!v->cached_msvc.valid) { _result_v__builder__MsvcResult _t2 = v__builder__find_msvc(v->pref->m64); if (_t2.is_error) { IError err = _t2.err; if (v->pref->is_verbose) { println(_S("msvc not found, looking for thirdparty/tcc...")); } string thirdparty_tcc = os__join_path(v->pref->vroot, new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("thirdparty"), _S("tcc"), _S("tcc.exe")}))); os__Result tcc_version_res = os__execute(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(thirdparty_tcc)}}, {_S(" -v"), 0, { .d_c = 0 }}}))); if (tcc_version_res.exit_code != 0) { if (v->pref->is_verbose) { println(_S("tcc not found")); } return (_result_void){ .is_error=true, .err=_v_error(_S("tcc not found")), .data={E_STRUCT} }; } v->pref->ccompiler = thirdparty_tcc; v->pref->ccompiler_type = v__pref__CompilerType__tinyc; return (_result_void){0}; } v__builder__MsvcResult msvc = (*(v__builder__MsvcResult*)_t2.data); v->cached_msvc = msvc; } v->pref->ccompiler = _S("msvc"); v->pref->ccompiler_type = v__pref__CompilerType__msvc; return (_result_void){0}; } v->pref->ccompiler_type = v__pref__cc_from_string(v->pref->ccompiler); return (_result_void){0}; } VV_LOC Array_v__cflag__CFlag v__builder__Builder_get_os_cflags(v__builder__Builder* v) { Array_v__cflag__CFlag flags = __new_array_with_default(0, 0, sizeof(v__cflag__CFlag), 0); Array_string ctimedefines = __new_array_with_default(0, 0, sizeof(string), 0); if (v->pref->compile_defines.len > 0) { _PUSH_MANY(&ctimedefines, (v->pref->compile_defines), _t1, Array_string); } for (int _t2 = 0; _t2 < v->table->cflags.len; ++_t2) { v__cflag__CFlag* flag = ((v__cflag__CFlag*)v->table->cflags.data) + _t2; if (string_ends_with(flag->value, _S(".o"))) { flag->cached = v__vcache__CacheManager_mod_postfix_with_key2cpath(&v->pref->cache_manager, flag->mod, _S(".o"), os__real_path(flag->value)); } if ((flag->os).len == 0 || (Array_string_contains(ctimedefines, flag->os))) { array_push((array*)&flags, _MOV((v__cflag__CFlag[]){ *flag })); continue; } _result_v__pref__OS _t4 = v__pref__os_from_string(flag->os); if (_t4.is_error) { IError err = _t4.err; *(v__pref__OS*) _t4.data = v__pref__OS__all; } v__pref__OS fos = (*(v__pref__OS*)_t4.data); if (fos != v__pref__OS__all && fos == v->pref->os) { array_push((array*)&flags, _MOV((v__cflag__CFlag[]){ *flag })); continue; } if (v->pref->os == v__pref__OS__windows && fast_string_eq(flag->os, _S("mingw")) && !fast_string_eq(v->pref->ccompiler, _S("msvc"))) { array_push((array*)&flags, _MOV((v__cflag__CFlag[]){ *flag })); continue; } } return flags; } VV_LOC Array_v__cflag__CFlag v__builder__Builder_get_rest_of_module_cflags(v__builder__Builder* v, v__cflag__CFlag* c) { Array_v__cflag__CFlag flags = __new_array_with_default(0, 0, sizeof(v__cflag__CFlag), 0); Array_v__cflag__CFlag cflags = v__builder__Builder_get_os_cflags(v); for (int _t1 = 0; _t1 < cflags.len; ++_t1) { v__cflag__CFlag flag = ((v__cflag__CFlag*)cflags.data)[_t1]; if (string__eq(c->mod, flag.mod)) { if (string__eq(c->name, flag.name) && string__eq(c->value, flag.value) && string__eq(c->os, flag.os)) { continue; } array_push((array*)&flags, _MOV((v__cflag__CFlag[]){ flag })); } } return flags; } void v__builder__compile(string command, v__pref__Preferences* pref_, void (*backend_cb)(v__builder__Builder* b)) { v__builder__check_if_output_folder_is_writable(pref_); v__builder__Builder b = v__builder__new_builder(pref_); if (v__builder__Builder_should_rebuild(&b)) { v__builder__Builder_rebuild(&b, (voidptr)backend_cb); } v__builder__Builder_exit_on_invalid_syntax(&b); v__builder__Builder_myfree(&b); v__builder__Builder_run_compiled_executable_and_exit(&b); } VV_LOC void v__builder__check_if_output_folder_is_writable(v__pref__Preferences* pref_) { string odir = os__dir(pref_->out_name); string output_folder = odir; if (odir.len == pref_->out_name.len) { output_folder = os__getwd(); } _result_void _t1 = os__ensure_folder_is_writable(output_folder); if (_t1.is_error) { IError err = _t1.err; v__builder__verror(IError_name_table[err._typ]._method_msg(err._object)); VUNREACHABLE(); ; } ; } VV_LOC void v__builder__Builder_myfree(v__builder__Builder* b) { array_free(&b->parsed_files); v__util__free_caches(); } VV_LOC void v__builder__Builder_exit_on_invalid_syntax(v__builder__Builder* b) { v__util__free_caches(); if (b->pref->only_check_syntax) { for (int _t1 = 0; _t1 < b->parsed_files.len; ++_t1) { v__ast__File* pf = ((v__ast__File**)b->parsed_files.data)[_t1]; if (pf->errors.len > 0) { _v_exit(1); VUNREACHABLE(); } } if (b->checker->nr_errors > 0) { _v_exit(1); VUNREACHABLE(); } } } VV_LOC void v__builder__Builder_run_compiled_executable_and_exit(v__builder__Builder* b) { if (b->pref->backend == v__pref__Backend__interpret) { return; } if (b->pref->skip_running) { return; } if (b->pref->only_check_syntax || b->pref->check_only) { return; } if (v__pref__Preferences_should_output_to_stdout(b->pref)) { return; } if (b->pref->os == v__pref__OS__ios) { _v_panic(_S("Running iOS apps is not supported yet.")); VUNREACHABLE(); } if (!(b->pref->is_test || b->pref->is_run || b->pref->is_crun)) { _v_exit(0); VUNREACHABLE(); } string compiled_file = b->pref->out_name; if (b->pref->backend == v__pref__Backend__wasm && !string_ends_with(compiled_file, _S(".wasm"))) { compiled_file = string__plus(compiled_file, _S(".wasm")); } compiled_file = os__real_path(compiled_file); Array_string run_args = __new_array_with_default(0, (int)(b->pref->run_args.len + 1), sizeof(string), 0); string _t1; /* if prepend */ if (v__pref__Backend_is_js(b->pref->backend)) { string _t2; #if defined(_WIN32) _t2 = _S("node.exe"); ; #else _t2 = _S("node"); ; #endif string node_basename = _t2; _result_string _t3 = os__find_abs_path_of_executable(node_basename); if (_t3.is_error) { IError err = _t3.err; _v_panic(str_intp(2, _MOV((StrIntpData[]){{_S("Could not find `"), 0xfe10, {.d_s = node_basename}}, {_S("` in system path. Do you have Node.js installed?"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } _t1 = (*(string*)_t3.data); } else if (b->pref->backend == v__pref__Backend__wasm) { Array_string actual_run = new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S("wasmer"), _S("wasmtime"), _S("wavm"), _S("wasm3")})); string actual_rf = _S(""); for (int _t4 = 0; _t4 < actual_run.len; ++_t4) { string runtime = ((string*)actual_run.data)[_t4]; string _t5; #if defined(_WIN32) _t5 = string__plus(runtime, _S(".exe")); ; #else _t5 = runtime; ; #endif string basename = _t5; _result_string _t6; if (_t6 = os__find_abs_path_of_executable(basename), !_t6.is_error) { string rf = *(string*)_t6.data; if (_SLIT_EQ(basename.str, basename.len, "wavm")) { array_push((array*)&run_args, _MOV((string[]){ _S("run") })); } actual_rf = rf; break; } } if ((actual_rf).len == 0) { _v_panic(_S("Could not find `wasmer`, `wasmtime`, `wavm`, or `wasm3` in system path. Do you have any installed?")); VUNREACHABLE(); } _t1 = actual_rf; } else if (b->pref->backend == v__pref__Backend__golang) { string _t8; #if defined(_WIN32) _t8 = _S("go.exe"); ; #else _t8 = _S("go"); ; #endif string go_basename = _t8; _result_string _t9 = os__find_abs_path_of_executable(go_basename); if (_t9.is_error) { IError err = _t9.err; _v_panic(str_intp(2, _MOV((StrIntpData[]){{_S("Could not find `"), 0xfe10, {.d_s = go_basename}}, {_S("` in system path. Do you have Go installed?"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } _t1 = (*(string*)_t9.data); } else { _t1 = compiled_file; } string run_file = _t1; if (v__pref__Backend_is_js(b->pref->backend) || b->pref->backend == v__pref__Backend__wasm) { array_push((array*)&run_args, _MOV((string[]){ string_clone(compiled_file) })); } else if (b->pref->backend == v__pref__Backend__golang) { _PUSH_MANY(&run_args, (new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("run"), string_clone(compiled_file)}))), _t11, Array_string); } _PUSH_MANY(&run_args, (b->pref->run_args), _t12, Array_string); if (b->pref->is_verbose) { println(str_intp(3, _MOV((StrIntpData[]){{_S("running "), 0xfe10, {.d_s = run_file}}, {_S(" with arguments "), 0xfe10, {.d_s = Array_string_join(run_args, _S(" "))}}, {_SLIT0, 0, { .d_c = 0 }}}))); } if (b->pref->is_shared) { v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_S("can not run shared library "), 0xfe10, {.d_s = run_file}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } int ret = 0; if (b->pref->use_os_system_to_run) { string command_to_run = string__plus(string__plus(os__quoted_path(run_file), _S(" ")), Array_string_join(run_args, _S(" "))); ret = os__system(command_to_run); } else { os__Process* run_process = os__new_process(run_file); os__Process_set_args(run_process, run_args); _result_anon_fn_os__signal _t13 = os__signal_opt(os__Signal__int, (voidptr)v__builder__eshcb); if (_t13.is_error) { IError err = _t13.err; v__builder__serror(_S("set .int"), err); VUNREACHABLE(); ; } void (*prev_int_handler) (os__Signal ) = (*(os__SignalHandler*)_t13.data); void (*prev_quit_handler) (os__Signal ) = ((os__SignalHandler)(v__builder__eshcb)); #if !defined(_WIN32) { _result_anon_fn_os__signal _t15 = os__signal_opt(os__Signal__quit, (voidptr)v__builder__eshcb); if (_t15.is_error) { IError err = _t15.err; v__builder__serror(_S("set .quit"), err); VUNREACHABLE(); ; } prev_quit_handler = (voidptr)(*(os__SignalHandler*)_t15.data); } #endif os__Process_wait(run_process); _result_anon_fn_os__signal _t16 = os__signal_opt(os__Signal__int, (voidptr)prev_int_handler); if (_t16.is_error) { IError err = _t16.err; v__builder__serror(_S("restore .int"), err); VUNREACHABLE(); ; } ; #if !defined(_WIN32) { _result_anon_fn_os__signal _t18 = os__signal_opt(os__Signal__quit, (voidptr)prev_quit_handler); if (_t18.is_error) { IError err = _t18.err; v__builder__serror(_S("restore .quit"), err); VUNREACHABLE(); ; } ; } #endif ret = run_process->code; if ((run_process->err).len != 0) { eprintln(run_process->err); } os__Process_close(run_process); } v__builder__Builder_cleanup_run_executable_after_exit(b, compiled_file); _v_exit(ret); VUNREACHABLE(); } VV_LOC void v__builder__eshcb(os__Signal _d1) { } VNORETURN VV_LOC void v__builder__serror(string reason, IError e) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("could not "), 0xfe10, {.d_s = reason}}, {_S(" handler"), 0, { .d_c = 0 }}}))); _v_panic(IError_str(e)); VUNREACHABLE(); while(1); } VV_LOC void v__builder__Builder_cleanup_run_executable_after_exit(v__builder__Builder* v, string exefile) { if (v->pref->is_crun) { return; } if (v->pref->reuse_tmpc) { v__pref__Preferences_vrun_elog(v->pref, str_intp(2, _MOV((StrIntpData[]){{_S("keeping executable: "), 0xfe10, {.d_s = exefile}}, {_S(" , because -keepc was passed"), 0, { .d_c = 0 }}}))); return; } if (!v->executable_exists) { v__pref__Preferences_vrun_elog(v->pref, str_intp(2, _MOV((StrIntpData[]){{_S("remove run executable: "), 0xfe10, {.d_s = exefile}}, {_SLIT0, 0, { .d_c = 0 }}}))); _result_void _t1 = os__rm(exefile); (void)_t1; ; } } void v__builder__Builder_set_module_lookup_paths(v__builder__Builder* v) { v->module_search_paths = __new_array_with_default(0, 0, sizeof(string), 0); if (v->pref->is_test) { array_push((array*)&v->module_search_paths, _MOV((string[]){ os__dir(v->compiled_dir) })); } array_push((array*)&v->module_search_paths, _MOV((string[]){ string_clone(v->compiled_dir) })); string x = os__join_path(v->compiled_dir, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("modules")}))); if (v->pref->is_verbose) { println(str_intp(2, _MOV((StrIntpData[]){{_S("x: \""), 0xfe10, {.d_s = x}}, {_S("\""), 0, { .d_c = 0 }}}))); } if (os__exists(os__join_path(v->compiled_dir, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("src/modules")}))))) { array_push((array*)&v->module_search_paths, _MOV((string[]){ os__join_path(v->compiled_dir, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("src/modules")}))) })); } if (os__exists(os__join_path(v->compiled_dir, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("modules")}))))) { array_push((array*)&v->module_search_paths, _MOV((string[]){ os__join_path(v->compiled_dir, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("modules")}))) })); } _PUSH_MANY(&v->module_search_paths, (v->pref->lookup_path), _t5, Array_string); if (v->pref->is_verbose) { v__builder__Builder_log(v, _S("v.module_search_paths:")); println(Array_string_str(v->module_search_paths)); } } Array_string v__builder__Builder_get_builtin_files(v__builder__Builder v) { if (v.pref->no_builtin) { v__builder__Builder_log(&v, _S("v.pref.no_builtin is true, get_builtin_files == []")); return __new_array_with_default(0, 0, sizeof(string), 0); } v__builder__Builder_log(&v, str_intp(2, _MOV((StrIntpData[]){{_S("v.pref.lookup_path: "), 0xfe10, {.d_s = Array_string_str(v.pref->lookup_path)}}, {_SLIT0, 0, { .d_c = 0 }}}))); for (int _t2 = 0; _t2 < v.pref->lookup_path.len; ++_t2) { string location = ((string*)v.pref->lookup_path.data)[_t2]; if (os__exists(os__join_path(location, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("builtin")}))))) { Array_string builtin_files = __new_array_with_default(0, 0, sizeof(string), 0); if (v__pref__Backend_is_js(v.pref->backend)) { _PUSH_MANY(&builtin_files, (v__builder__Builder_v_files_from_dir(&v, os__join_path(location, new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("builtin"), _S("js")}))))), _t3, Array_string); } else if (v.pref->backend == v__pref__Backend__wasm) { _PUSH_MANY(&builtin_files, (v__builder__Builder_v_files_from_dir(&v, os__join_path(location, new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("builtin"), _S("wasm")}))))), _t4, Array_string); if (v.pref->os == v__pref__OS__browser) { _PUSH_MANY(&builtin_files, (v__builder__Builder_v_files_from_dir(&v, os__join_path(location, new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("builtin"), _S("wasm"), _S("browser")}))))), _t5, Array_string); } else { _PUSH_MANY(&builtin_files, (v__builder__Builder_v_files_from_dir(&v, os__join_path(location, new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("builtin"), _S("wasm"), _S("wasi")}))))), _t6, Array_string); } } else { _PUSH_MANY(&builtin_files, (v__builder__Builder_v_files_from_dir(&v, os__join_path(location, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("builtin")}))))), _t7, Array_string); } if (v.pref->is_bare) { _PUSH_MANY(&builtin_files, (v__builder__Builder_v_files_from_dir(&v, v.pref->bare_builtin_dir)), _t8, Array_string); } if (v.pref->backend == v__pref__Backend__c) { if (v.pref->is_vsh && os__exists(os__join_path(location, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("os")}))))) { _PUSH_MANY(&builtin_files, (v__builder__Builder_v_files_from_dir(&v, os__join_path(location, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("os")}))))), _t9, Array_string); } } return builtin_files; } } v__builder__verror(_S("`builtin/` not included on module lookup path.\nDid you forget to add vlib to the path? (Use @vlib for default vlib)")); VUNREACHABLE(); return __new_array(0, 0, sizeof(string)); } Array_string v__builder__Builder_get_user_files(v__builder__Builder* v) { if ((fast_string_eq(v->pref->path, _S("vlib/builtin")) || fast_string_eq(v->pref->path, _S("vlib/strconv")) || fast_string_eq(v->pref->path, _S("vlib/strings")) || fast_string_eq(v->pref->path, _S("vlib/hash"))) || string_ends_with(v->pref->path, _S("vlib/builtin"))) { v__builder__Builder_log(v, _S("Skipping user files.")); return __new_array_with_default(0, 0, sizeof(string), 0); } string dir = v->pref->path; v__builder__Builder_log(v, str_intp(2, _MOV((StrIntpData[]){{_S("get_v_files("), 0xfe10, {.d_s = dir}}, {_S(")"), 0, { .d_c = 0 }}}))); Array_string user_files = __new_array_with_default(0, 0, sizeof(string), 0); string preludes_path = os__join_path(v->pref->vroot, new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("vlib"), _S("v"), _S("preludes")}))); if (v->pref->backend == v__pref__Backend__js_node) { preludes_path = os__join_path(v->pref->vroot, new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("vlib"), _S("v"), _S("preludes_js")}))); } if (v->pref->trace_calls) { array_push((array*)&user_files, _MOV((string[]){ os__join_path(preludes_path, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("trace_calls.v")}))) })); } if (v->pref->is_livemain || v->pref->is_liveshared) { array_push((array*)&user_files, _MOV((string[]){ os__join_path(preludes_path, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("live.v")}))) })); } if (v->pref->is_livemain) { array_push((array*)&user_files, _MOV((string[]){ os__join_path(preludes_path, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("live_main.v")}))) })); } if (v->pref->is_liveshared) { array_push((array*)&user_files, _MOV((string[]){ os__join_path(preludes_path, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("live_shared.v")}))) })); } if (v->pref->is_test) { if (v->pref->backend == v__pref__Backend__js_node) { array_push((array*)&user_files, _MOV((string[]){ os__join_path(preludes_path, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("test_runner.v")}))) })); } else { array_push((array*)&user_files, _MOV((string[]){ os__join_path(preludes_path, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("test_runner.c.v")}))) })); } string v_test_runner_prelude = os__getenv(_S("VTEST_RUNNER")); if ((v->pref->test_runner).len != 0) { v_test_runner_prelude = v->pref->test_runner; } if ((v_test_runner_prelude).len == 0) { v_test_runner_prelude = _S("normal"); } if (!string_contains(v_test_runner_prelude, _S("/")) && !string_contains(v_test_runner_prelude, _S("\\")) && !string_ends_with(v_test_runner_prelude, _S(".v"))) { v_test_runner_prelude = os__join_path(preludes_path, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){str_intp(2, _MOV((StrIntpData[]){{_S("test_runner_"), 0xfe10, {.d_s = v_test_runner_prelude}}, {_S(".v"), 0, { .d_c = 0 }}}))}))); } if (!os__is_file(v_test_runner_prelude) || !os__is_readable(v_test_runner_prelude)) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("test runner error: File "), 0xfe10, {.d_s = v_test_runner_prelude}}, {_S(" should be readable."), 0, { .d_c = 0 }}}))); v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_S("the supported test runners are: "), 0xfe10, {.d_s = v__pref__supported_test_runners_list()}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } array_push((array*)&user_files, _MOV((string[]){ string_clone(v_test_runner_prelude) })); } if (v->pref->is_test && v->pref->show_asserts) { array_push((array*)&user_files, _MOV((string[]){ os__join_path(preludes_path, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("tests_with_stats.v")}))) })); if (v__pref__Backend_is_js(v->pref->backend)) { array_push((array*)&user_files, _MOV((string[]){ os__join_path(preludes_path, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("stats_import.js.v")}))) })); } } if (v->pref->is_prof) { array_push((array*)&user_files, _MOV((string[]){ os__join_path(preludes_path, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("profiled_program.v")}))) })); } bool is_test = v->pref->is_test; bool is_internal_module_test = false; if (is_test) { _result_string _t12 = v__util__read_file(dir); if (_t12.is_error) { IError err = _t12.err; v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = dir}}, {_S(" does not exist"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } string tcontent = (*(string*)_t12.data); Array_string slines = string_split_into_lines(tcontent); for (int _t13 = 0; _t13 < slines.len; ++_t13) { string sline = ((string*)slines.data)[_t13]; string line = string_trim_space(sline); if (line.len > 2) { if (string_at(line, 0) == '/' && string_at(line, 1) == '/') { continue; } if (string_starts_with(line, _S("module "))) { is_internal_module_test = true; break; } } } } if (is_internal_module_test) { string single_test_v_file = os__real_path(dir); if (v->pref->is_verbose) { v__builder__Builder_log(v, str_intp(2, _MOV((StrIntpData[]){{_S("> Compiling an internal module _test.v file "), 0xfe10, {.d_s = single_test_v_file}}, {_S(" ."), 0, { .d_c = 0 }}}))); v__builder__Builder_log(v, _S("> That brings in all other ordinary .v files in the same module too .")); } array_push((array*)&user_files, _MOV((string[]){ string_clone(single_test_v_file) })); dir = os__dir(single_test_v_file); } bool does_exist = os__exists(dir); if (!does_exist) { v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = dir}}, {_S(" doesn't exist"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } bool is_real_file = does_exist && !os__is_dir(dir); string resolved_link = (is_real_file && os__is_link(dir) ? (os__real_path(dir)) : (dir)); if (is_real_file && (string_ends_with(dir, _S(".v")) || string_ends_with(resolved_link, _S(".vsh")) || (v->pref->raw_vsh_tmp_prefix).len != 0 || string_ends_with(dir, _S(".vv")))) { string single_v_file = (string_ends_with(resolved_link, _S(".vsh")) ? (resolved_link) : (dir)); array_push((array*)&user_files, _MOV((string[]){ string_clone(single_v_file) })); if (v->pref->is_verbose) { v__builder__Builder_log(v, str_intp(2, _MOV((StrIntpData[]){{_S("> just compile one file: \""), 0xfe10, {.d_s = single_v_file}}, {_S("\""), 0, { .d_c = 0 }}}))); } } else if (os__is_dir(dir)) { if (v->pref->is_verbose) { v__builder__Builder_log(v, str_intp(2, _MOV((StrIntpData[]){{_S("> add all .v files from directory \""), 0xfe10, {.d_s = dir}}, {_S("\" ..."), 0, { .d_c = 0 }}}))); } _PUSH_MANY(&user_files, (v__builder__Builder_v_files_from_dir(v, dir)), _t16, Array_string); } else { println(_S("usage: `v file.v` or `v directory`")); string ext = os__file_ext(dir); println(str_intp(2, _MOV((StrIntpData[]){{_S("unknown file extension `"), 0xfe10, {.d_s = ext}}, {_S("`"), 0, { .d_c = 0 }}}))); _v_exit(1); VUNREACHABLE(); } if (user_files.len == 0) { println(_S("No input .v files")); _v_exit(1); VUNREACHABLE(); } if (v->pref->is_verbose) { v__builder__Builder_log(v, str_intp(2, _MOV((StrIntpData[]){{_S("user_files: "), 0xfe10, {.d_s = Array_string_str(user_files)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } return user_files; } void v__builder__Builder_dump_c_options(v__builder__Builder* b, Array_string all_args) { v__builder__dump_list(b->pref->dump_c_flags, all_args); } void v__builder__Builder_dump_modules(v__builder__Builder* b, Array_string mods) { v__builder__dump_list(b->pref->dump_modules, mods); } void v__builder__Builder_dump_files(v__builder__Builder* b, Array_string files) { v__builder__dump_list(b->pref->dump_files, files); } VV_LOC void v__builder__dump_list(string file_path, Array_string list) { if ((file_path).len != 0) { Array_string _t1 = {0}; Array_string _t1_orig = list; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t2 = 0; _t2 < _t1_len; ++_t2) { string it = ((string*) _t1_orig.data)[_t2]; if ((it).len != 0) { array_push((array*)&_t1, &it); } } string content = string__plus(Array_string_join(_t1, _S("\n")), _S("\n")); if (_SLIT_EQ(file_path.str, file_path.len, "-")) { print(content); } else { _result_void _t3 = os__write_file(file_path, content); if (_t3.is_error) { IError err = _t3.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; } } } void v__builder__Builder_dump_defines(v__builder__Builder* b) { Array_string res = __new_array_with_default(0, 0, sizeof(string), 0); Map_string_v__checker__ComptimeBranchSkipState _t1 = b->checker->ct_system_defines; int _t3 = _t1.key_values.len; for (int _t2 = 0; _t2 < _t3; ++_t2 ) { int _t4 = _t1.key_values.len - _t3; _t3 = _t1.key_values.len; if (_t4 < 0) { _t2 = -1; continue; } if (!DenseArray_has_index(&_t1.key_values, _t2)) {continue;} string k = *(string*)DenseArray_key(&_t1.key_values, _t2); k = string_clone(k); v__checker__ComptimeBranchSkipState v = (*(v__checker__ComptimeBranchSkipState*)DenseArray_value(&_t1.key_values, _t2)); array_push((array*)&res, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_S("system,"), 0xfe10, {.d_s = k}}, {_S(","), 0xfe10, {.d_s = v__checker__ComptimeBranchSkipState_str(v)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } Map_string_v__checker__ComptimeBranchSkipState _t6 = b->checker->ct_user_defines; int _t8 = _t6.key_values.len; for (int _t7 = 0; _t7 < _t8; ++_t7 ) { int _t9 = _t6.key_values.len - _t8; _t8 = _t6.key_values.len; if (_t9 < 0) { _t7 = -1; continue; } if (!DenseArray_has_index(&_t6.key_values, _t7)) {continue;} string k = *(string*)DenseArray_key(&_t6.key_values, _t7); k = string_clone(k); v__checker__ComptimeBranchSkipState v = (*(v__checker__ComptimeBranchSkipState*)DenseArray_value(&_t6.key_values, _t7)); array_push((array*)&res, _MOV((string[]){ str_intp(3, _MOV((StrIntpData[]){{_S("user,"), 0xfe10, {.d_s = k}}, {_S(","), 0xfe10, {.d_s = v__checker__ComptimeBranchSkipState_str(v)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } v__builder__dump_list(b->pref->dump_defines, res); } VV_LOC _result_string v__builder__find_windows_kit_internal(v__builder__RegKey key, Array_string versions) { #if defined(_WIN32) { { // Unsafe block for (int _t2 = 0; _t2 < versions.len; ++_t2) { string version = ((string*)versions.data)[_t2]; u32 required_bytes = ((u32)(0U)); int result = RegQueryValueEx(key, string_to_wide(version), 0, 0, 0, ((voidptr)(&required_bytes))); u32 length = (u32)(required_bytes / 2U); if (result != 0) { continue; } u32 alloc_length = ((u32)(required_bytes + 2U)); u16* value = ((u16*)(malloc_noscan(((int)(alloc_length))))); if (value == ((void*)0)) { continue; } else { } int result2 = RegQueryValueEx(key, string_to_wide(version), 0, 0, ((voidptr)(value)), ((voidptr)(&alloc_length))); if (result2 != 0) { continue; } if (value[(u32)(length - 1U)] != ((u16)(0U))) { value[length] = ((u16)(0U)); } string res = string_from_wide(value); _result_string _t3 = {0}; _result_ok(&(string[]) { res }, (_result*)(&_t3), sizeof(string)); return _t3; } } } #endif return (_result_string){ .is_error=true, .err=_v_error(_S("windows kit not found")), .data={E_STRUCT} }; } VV_LOC _result_v__builder__WindowsKit v__builder__find_windows_kit_root(string target_arch) { #if defined(_WIN32) { _result_v__builder__WindowsKit _t2 = v__builder__find_windows_kit_root_by_reg(target_arch); if (_t2.is_error) { IError err = _t2.err; _result_v__builder__WindowsKit _t3; if (_t3 = v__builder__find_windows_kit_root_by_env(target_arch), !_t3.is_error) { v__builder__WindowsKit wkroot = *(v__builder__WindowsKit*)_t3.data; _result_v__builder__WindowsKit _t4 = {0}; _result_ok(&(v__builder__WindowsKit[]) { wkroot }, (_result*)(&_t4), sizeof(v__builder__WindowsKit)); return _t4; } return (_result_v__builder__WindowsKit){ .is_error=true, .err=err, .data={E_STRUCT} }; } v__builder__WindowsKit wkroot = (*(v__builder__WindowsKit*)_t2.data); _result_v__builder__WindowsKit _t6 = {0}; _result_ok(&(v__builder__WindowsKit[]) { wkroot }, (_result*)(&_t6), sizeof(v__builder__WindowsKit)); return _t6; } #else { return (_result_v__builder__WindowsKit){ .is_error=true, .err=_v_error(_S("Host OS does not support finding a windows kit")), .data={E_STRUCT} }; } #endif return (_result_v__builder__WindowsKit){0}; } VV_LOC _result_v__builder__WindowsKit v__builder__find_windows_kit_root_by_reg(string target_arch) { #if defined(_WIN32) { v__builder__RegKey root_key = ((v__builder__RegKey)(0)); string path = _S("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots"); int rc = RegOpenKeyEx(_const_v__builder__hkey_local_machine, string_to_wide(path), 0U, ((_const_v__builder__key_query_value | _const_v__builder__key_wow64_32key) | _const_v__builder__key_enumerate_sub_keys), ((voidptr)(&root_key))); if (rc != 0) { return (_result_v__builder__WindowsKit){ .is_error=true, .err=_v_error(_S("Unable to open root key")), .data={E_STRUCT} }; } _result_string _t3 = v__builder__find_windows_kit_internal(root_key, new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("KitsRoot10"), _S("KitsRoot81")}))); if (_t3.is_error) { IError err = _t3.err; RegCloseKey(root_key); return (_result_v__builder__WindowsKit){ .is_error=true, .err=_v_error(_S("Unable to find a windows kit")), .data={E_STRUCT} }; } string kit_root = (*(string*)_t3.data); RegCloseKey(root_key); return v__builder__new_windows_kit(kit_root, target_arch); } #else { return (_result_v__builder__WindowsKit){ .is_error=true, .err=_v_error(_S("Host OS does not support finding a windows kit")), .data={E_STRUCT} }; } #endif return (_result_v__builder__WindowsKit){0}; } VV_LOC _result_v__builder__WindowsKit v__builder__new_windows_kit(string kit_root, string target_arch) { string kit_lib = string__plus(kit_root, _S("Lib")); _result_Array_string _t1 = os__ls(kit_lib); if (_t1.is_error) { _result_v__builder__WindowsKit _t2 = {0}; _t2.is_error = true; _t2.err = _t1.err; return _t2; } Array_string files = (*(Array_string*)_t1.data); string highest_path = _S(""); int highest_int = 0; for (int _t3 = 0; _t3 < files.len; ++_t3) { string f = ((string*)files.data)[_t3]; string no_dot = string_replace(f, _S("."), _S("")); int v_int = string_int(no_dot); if (v_int > highest_int) { highest_int = v_int; highest_path = f; } } string kit_lib_highest = string__plus(kit_lib, str_intp(2, _MOV((StrIntpData[]){{_S("\\"), 0xfe10, {.d_s = highest_path}}, {_SLIT0, 0, { .d_c = 0 }}}))); string kit_include_highest = string_replace(kit_lib_highest, _S("Lib"), _S("Include")); _result_v__builder__WindowsKit _t4 = {0}; _result_ok(&(v__builder__WindowsKit[]) { ((v__builder__WindowsKit){.um_lib_path = string__plus(kit_lib_highest, str_intp(2, _MOV((StrIntpData[]){{_S("\\um\\"), 0xfe10, {.d_s = target_arch}}, {_SLIT0, 0, { .d_c = 0 }}}))),.ucrt_lib_path = string__plus(kit_lib_highest, str_intp(2, _MOV((StrIntpData[]){{_S("\\ucrt\\"), 0xfe10, {.d_s = target_arch}}, {_SLIT0, 0, { .d_c = 0 }}}))),.um_include_path = string__plus(kit_include_highest, _S("\\um")),.ucrt_include_path = string__plus(kit_include_highest, _S("\\ucrt")),.shared_include_path = string__plus(kit_include_highest, _S("\\shared")),}) }, (_result*)(&_t4), sizeof(v__builder__WindowsKit)); return _t4; } VV_LOC _result_v__builder__WindowsKit v__builder__find_windows_kit_root_by_env(string target_arch) { string kit_root = os__getenv(_S("WindowsSdkDir")); if ((kit_root).len == 0) { return (_result_v__builder__WindowsKit){ .is_error=true, .err=_v_error(_S("empty WindowsSdkDir")), .data={E_STRUCT} }; } return v__builder__new_windows_kit(kit_root, target_arch); } VV_LOC _result_v__builder__VsInstallation v__builder__find_vs(string vswhere_dir, string host_arch, string target_arch) { #if defined(_WIN32) { _result_v__builder__VsInstallation _t2 = v__builder__find_vs_by_reg(vswhere_dir, host_arch, target_arch); if (_t2.is_error) { IError err = _t2.err; _result_v__builder__VsInstallation _t3; if (_t3 = v__builder__find_vs_by_env(host_arch, target_arch), !_t3.is_error) { v__builder__VsInstallation vsinst = *(v__builder__VsInstallation*)_t3.data; _result_v__builder__VsInstallation _t4 = {0}; _result_ok(&(v__builder__VsInstallation[]) { vsinst }, (_result*)(&_t4), sizeof(v__builder__VsInstallation)); return _t4; } return (_result_v__builder__VsInstallation){ .is_error=true, .err=err, .data={E_STRUCT} }; } v__builder__VsInstallation vsinst = (*(v__builder__VsInstallation*)_t2.data); _result_v__builder__VsInstallation _t6 = {0}; _result_ok(&(v__builder__VsInstallation[]) { vsinst }, (_result*)(&_t6), sizeof(v__builder__VsInstallation)); return _t6; } #else { return (_result_v__builder__VsInstallation){ .is_error=true, .err=_v_error(_S("Host OS does not support finding a Visual Studio installation")), .data={E_STRUCT} }; } #endif return (_result_v__builder__VsInstallation){0}; } VV_LOC _result_v__builder__VsInstallation v__builder__find_vs_by_reg(string vswhere_dir, string host_arch, string target_arch) { #if defined(_WIN32) { os__Result res = os__execute(str_intp(2, _MOV((StrIntpData[]){{_S("\""), 0xfe10, {.d_s = vswhere_dir}}, {_S("\\Microsoft Visual Studio\\Installer\\vswhere.exe\" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath"), 0, { .d_c = 0 }}}))); if (res.exit_code != 0) { return (_result_v__builder__VsInstallation){ .is_error=true, .err=error_with_code(res.output, res.exit_code), .data={E_STRUCT} }; } string res_output = string_trim_space(res.output); _result_string _t3 = os__read_file(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = res_output}}, {_S("\\VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt"), 0, { .d_c = 0 }}}))); if (_t3.is_error) { IError err = _t3.err; return (_result_v__builder__VsInstallation){ .is_error=true, .err=_v_error(_S("Unable to find vs installation")), .data={E_STRUCT} }; } string version = (*(string*)_t3.data); string v = string_trim_space(version); string lib_path = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = res_output}}, {_S("\\VC\\Tools\\MSVC\\"), 0xfe10, {.d_s = v}}, {_S("\\lib\\"), 0xfe10, {.d_s = target_arch}}, {_SLIT0, 0, { .d_c = 0 }}})); string include_path = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = res_output}}, {_S("\\VC\\Tools\\MSVC\\"), 0xfe10, {.d_s = v}}, {_S("\\include"), 0, { .d_c = 0 }}})); if (os__exists(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = lib_path}}, {_S("\\vcruntime.lib"), 0, { .d_c = 0 }}})))) { string p = str_intp(5, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = res_output}}, {_S("\\VC\\Tools\\MSVC\\"), 0xfe10, {.d_s = v}}, {_S("\\bin\\Host"), 0xfe10, {.d_s = host_arch}}, {_S("\\"), 0xfe10, {.d_s = target_arch}}, {_SLIT0, 0, { .d_c = 0 }}})); _result_v__builder__VsInstallation _t5 = {0}; _result_ok(&(v__builder__VsInstallation[]) { ((v__builder__VsInstallation){.include_path = include_path,.lib_path = lib_path,.exe_path = p,}) }, (_result*)(&_t5), sizeof(v__builder__VsInstallation)); return _t5; } println(str_intp(2, _MOV((StrIntpData[]){{_S("Unable to find vs installation (attempted to use lib path \""), 0xfe10, {.d_s = lib_path}}, {_S("\")"), 0, { .d_c = 0 }}}))); return (_result_v__builder__VsInstallation){ .is_error=true, .err=_v_error(_S("Unable to find vs exe folder")), .data={E_STRUCT} }; } #else { return (_result_v__builder__VsInstallation){ .is_error=true, .err=_v_error(_S("Host OS does not support finding a Visual Studio installation")), .data={E_STRUCT} }; } #endif return (_result_v__builder__VsInstallation){0}; } VV_LOC _result_v__builder__VsInstallation v__builder__find_vs_by_env(string host_arch, string target_arch) { string vs_dir = os__getenv(_S("VSINSTALLDIR")); if ((vs_dir).len == 0) { return (_result_v__builder__VsInstallation){ .is_error=true, .err=_v_error(_S("empty VSINSTALLDIR")), .data={E_STRUCT} }; } string vc_tools_dir = os__getenv(_S("VCToolsInstallDir")); if ((vc_tools_dir).len == 0) { return (_result_v__builder__VsInstallation){ .is_error=true, .err=_v_error(_S("empty VCToolsInstallDir")), .data={E_STRUCT} }; } string bin_dir = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = vc_tools_dir}}, {_S("bin\\Host"), 0xfe10, {.d_s = host_arch}}, {_S("\\"), 0xfe10, {.d_s = target_arch}}, {_SLIT0, 0, { .d_c = 0 }}})); string lib_path = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = vc_tools_dir}}, {_S("lib\\"), 0xfe10, {.d_s = target_arch}}, {_SLIT0, 0, { .d_c = 0 }}})); string include_path = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = vc_tools_dir}}, {_S("include"), 0, { .d_c = 0 }}})); _result_v__builder__VsInstallation _t3 = {0}; _result_ok(&(v__builder__VsInstallation[]) { ((v__builder__VsInstallation){.include_path = include_path,.lib_path = lib_path,.exe_path = bin_dir,}) }, (_result*)(&_t3), sizeof(v__builder__VsInstallation)); return _t3; } VV_LOC _result_v__builder__MsvcResult v__builder__find_msvc(bool m64_target) { #if defined(_WIN32) { string processor_architecture = os__getenv(_S("PROCESSOR_ARCHITECTURE")); string vswhere_dir = (_SLIT_EQ(processor_architecture.str, processor_architecture.len, "x86") ? (_S("%ProgramFiles%")) : (_S("%ProgramFiles(x86)%"))); string host_arch = (_SLIT_EQ(processor_architecture.str, processor_architecture.len, "x86") ? (_S("X86")) : (_S("X64"))); string target_arch = (!m64_target ? (_S("X86")) : (_S("X64"))); _result_v__builder__WindowsKit _t2 = v__builder__find_windows_kit_root(target_arch); if (_t2.is_error) { IError err = _t2.err; return (_result_v__builder__MsvcResult){ .is_error=true, .err=_v_error(_S("Unable to find windows sdk")), .data={E_STRUCT} }; } v__builder__WindowsKit wk = (*(v__builder__WindowsKit*)_t2.data); _result_v__builder__VsInstallation _t4 = v__builder__find_vs(vswhere_dir, host_arch, target_arch); if (_t4.is_error) { IError err = _t4.err; return (_result_v__builder__MsvcResult){ .is_error=true, .err=_v_error(_S("Unable to find visual studio")), .data={E_STRUCT} }; } v__builder__VsInstallation vs = (*(v__builder__VsInstallation*)_t4.data); _result_v__builder__MsvcResult _t6 = {0}; _result_ok(&(v__builder__MsvcResult[]) { ((v__builder__MsvcResult){ .full_cl_exe_path = os__real_path(string__plus(string__plus(vs.exe_path, _const_os__path_separator), _S("cl.exe"))), .exe_path = vs.exe_path, .um_lib_path = wk.um_lib_path, .ucrt_lib_path = wk.ucrt_lib_path, .vs_lib_path = vs.lib_path, .um_include_path = wk.um_include_path, .ucrt_include_path = wk.ucrt_include_path, .vs_include_path = vs.include_path, .shared_include_path = wk.shared_include_path, .valid = true, }) }, (_result*)(&_t6), sizeof(v__builder__MsvcResult)); return _t6; } #else { _result_v__builder__MsvcResult _t7 = {0}; _result_ok(&(v__builder__MsvcResult[]) { ((v__builder__MsvcResult){.full_cl_exe_path = _S("/usr/bin/true"),.exe_path = (string){.str=(byteptr)"", .is_lit=1},.um_lib_path = (string){.str=(byteptr)"", .is_lit=1},.ucrt_lib_path = (string){.str=(byteptr)"", .is_lit=1},.vs_lib_path = (string){.str=(byteptr)"", .is_lit=1},.um_include_path = (string){.str=(byteptr)"", .is_lit=1},.ucrt_include_path = (string){.str=(byteptr)"", .is_lit=1},.vs_include_path = (string){.str=(byteptr)"", .is_lit=1},.shared_include_path = (string){.str=(byteptr)"", .is_lit=1},.valid = true,}) }, (_result*)(&_t7), sizeof(v__builder__MsvcResult)); return _t7; } #endif return (_result_v__builder__MsvcResult){0}; } void v__builder__Builder_cc_msvc(v__builder__Builder* v) { v__builder__MsvcResult r = v->cached_msvc; if (r.valid == false) { v__builder__verror(_S("cannot find MSVC on this OS")); VUNREACHABLE(); } string out_name_pdb = os__real_path(string__plus(v->out_name_c, _S(".pdb"))); string out_name_cmd_line = os__real_path(string__plus(v->out_name_c, _S(".rsp"))); string app_dir_out_name_c = string_all_before_last((string__plus(string__plus(string_all_before_last(v->pref->out_name, _S("\\")), _S("\\")), string_all_after_last(v->pref->out_name_c, _S("\\")))), _S(".")); string app_dir_out_name = (string_ends_with(v->pref->out_name, _S(".dll")) || string_ends_with(v->pref->out_name, _S(".exe")) ? (string_substr(v->pref->out_name, 0, (int)(v->pref->out_name.len - 4))) : (v->pref->out_name)); Array_string a = __new_array_with_default(0, 0, sizeof(string), 0); string env_cflags = os__getenv(_S("CFLAGS")); string all_cflags = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = env_cflags}}, {_S(" "), 0xfe10, {.d_s = v->pref->cflags}}, {_SLIT0, 0, { .d_c = 0 }}})); if (_SLIT_NE(all_cflags.str, all_cflags.len, " ")) { array_push((array*)&a, _MOV((string[]){ string_clone(all_cflags) })); } _PUSH_MANY(&a, (new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S("-w"), _S("/we4013"), _S("/volatile:ms"), _S("/F 16777216")}))), _t2, Array_string); if (v->pref->is_prod && !v->pref->no_prod_options) { array_push((array*)&a, _MOV((string[]){ _S("/O2") })); } if (v->pref->is_debug) { array_push((array*)&a, _MOV((string[]){ _S("/MDd") })); array_push((array*)&a, _MOV((string[]){ _S("/D_DEBUG") })); _PUSH_MANY(&a, (new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("/Zi"), str_intp(2, _MOV((StrIntpData[]){{_S("/Fd\""), 0xfe10, {.d_s = out_name_pdb}}, {_S("\""), 0, { .d_c = 0 }}}))}))), _t6, Array_string); } else { array_push((array*)&a, _MOV((string[]){ _S("/MD") })); array_push((array*)&a, _MOV((string[]){ _S("/DNDEBUG") })); if (!v->ccoptions.debug_mode) { array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ string_clone(out_name_pdb) })); array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ string__plus(app_dir_out_name, _S(".pdb")) })); } } if (v->pref->is_shared) { if (!string_ends_with(v->pref->out_name, _S(".dll"))) { v->pref->out_name = string__plus(v->pref->out_name, _S(".dll")); } array_push((array*)&a, _MOV((string[]){ _S("/LD") })); } else if (!string_ends_with(v->pref->out_name, _S(".exe"))) { v->pref->out_name = string__plus(v->pref->out_name, _S(".exe")); } v->pref->out_name = os__real_path(v->pref->out_name); if (v->pref->build_mode == v__pref__BuildMode__build_module) { array_push((array*)&a, _MOV((string[]){ _S("/c") })); } else if (v->pref->build_mode == v__pref__BuildMode__default_mode) { } if (v->pref->sanitize) { eprintln(_S("Sanitize not supported on msvc.")); } array_push((array*)&a, _MOV((string[]){ string__plus(string__plus(_S("\""), os__real_path(v->out_name_c)), _S("\"")) })); if (!v->ccoptions.debug_mode) { array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ os__real_path(v->out_name_c) })); } Array_string real_libs = new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S("kernel32.lib"), _S("user32.lib"), _S("advapi32.lib"), _S("ws2_32.lib")})); v__builder__MsvcStringFlags sflags = v__builder__msvc_string_flags(v__builder__Builder_get_os_cflags(v)); _PUSH_MANY(&real_libs, (sflags.real_libs), _t15, Array_string); Array_string inc_paths = sflags.inc_paths; Array_string lib_paths = sflags.lib_paths; Array_string defines = sflags.defines; Array_string other_flags = sflags.other_flags; _PUSH_MANY(&a, (v__builder__MsvcResult_include_paths(r)), _t16, Array_string); _PUSH_MANY(&a, (defines), _t17, Array_string); _PUSH_MANY(&a, (inc_paths), _t18, Array_string); _PUSH_MANY(&a, (other_flags), _t19, Array_string); array_push((array*)&a, _MOV((string[]){ Array_string_join(real_libs, _S(" ")) })); array_push((array*)&a, _MOV((string[]){ _S("/link") })); if (v->pref->is_shared) { string def_name = string__plus(app_dir_out_name, _S(".def")); array_push((array*)&a, _MOV((string[]){ string__plus(_S("/DEF:"), os__quoted_path(def_name)) })); if (!v->ccoptions.debug_mode) { array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ string_clone(def_name) })); array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ string__plus(app_dir_out_name_c, _S(".exp")) })); array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ string__plus(app_dir_out_name_c, _S(".lib")) })); } } array_push((array*)&a, _MOV((string[]){ _S("/nologo") })); array_push((array*)&a, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("/OUT:"), 0xfe10, {.d_s = os__quoted_path(v->pref->out_name)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); _PUSH_MANY(&a, (v__builder__MsvcResult_library_paths(r)), _t28, Array_string); if (!string_contains(all_cflags, _S("/DEBUG"))) { array_push((array*)&a, _MOV((string[]){ _S("/DEBUG:FULL") })); } if (v->pref->is_prod && !v->pref->no_prod_options) { array_push((array*)&a, _MOV((string[]){ _S("/INCREMENTAL:NO") })); array_push((array*)&a, _MOV((string[]){ _S("/OPT:REF") })); array_push((array*)&a, _MOV((string[]){ _S("/OPT:ICF") })); } _PUSH_MANY(&a, (lib_paths), _t33, Array_string); string env_ldflags = os__getenv(_S("LDFLAGS")); if ((env_ldflags).len != 0) { array_push((array*)&a, _MOV((string[]){ string_clone(env_ldflags) })); } if ((v->pref->ldflags).len != 0) { array_push((array*)&a, _MOV((string[]){ string_trim_space(v->pref->ldflags) })); } v__builder__Builder_dump_c_options(v, a); string args = string__plus(_S("\357\273\277"), Array_string_join(a, _S(" "))); _result_void _t36 = os__write_file(out_name_cmd_line, args); if (_t36.is_error) { IError err = _t36.err; v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_S("Unable to write response file to \""), 0xfe10, {.d_s = out_name_cmd_line}}, {_S("\""), 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } ; if (!v->ccoptions.debug_mode) { array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ string_clone(out_name_cmd_line) })); array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ string__plus(app_dir_out_name_c, _S(".obj")) })); array_push((array*)&v->pref->cleanup_files, _MOV((string[]){ string__plus(app_dir_out_name, _S(".ilk")) })); } string cmd = str_intp(3, _MOV((StrIntpData[]){{_S("\""), 0xfe10, {.d_s = r.full_cl_exe_path}}, {_S("\" \"@"), 0xfe10, {.d_s = out_name_cmd_line}}, {_S("\""), 0, { .d_c = 0 }}})); v__builder__Builder_show_cc(v, cmd, out_name_cmd_line, args); if (!string__eq(os__user_os(), _S("windows")) && !string_ends_with(v->pref->out_name, _S(".c"))) { v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_S("cannot build with msvc on "), 0xfe10, {.d_s = os__user_os()}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } v__util__timing_start(_S("C msvc")); os__Result res = os__execute(cmd); if (res.exit_code != 0) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("================== "), 0xfe10, {.d_s = _const_v__builder__c_compilation_error_title}}, {_S(" (from msvc): =============="), 0, { .d_c = 0 }}}))); eprintln(res.output); v__builder__verror(_S("msvc error")); VUNREACHABLE(); } v__util__timing_measure(_S("C msvc")); if (v->pref->show_c_output) { v__builder__Builder_show_c_compiler_output(v, r.full_cl_exe_path, res); } else { v__builder__Builder_post_process_c_compiler_output(v, r.full_cl_exe_path, res); } } VV_LOC void v__builder__Builder_build_thirdparty_obj_file_with_msvc(v__builder__Builder* v, string _mod, string path, Array_v__cflag__CFlag moduleflags) { v__builder__MsvcResult msvc = v->cached_msvc; if (msvc.valid == false) { v__builder__verror(_S("cannot find MSVC on this OS")); VUNREACHABLE(); } string path_without_o_postfix = string_substr(path, 0, (int)(path.len - 2)); string obj_path = str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = path_without_o_postfix}}, {_S(".obj"), 0, { .d_c = 0 }}})); obj_path = os__real_path(obj_path); if (os__exists(obj_path)) { return; } println(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = obj_path}}, {_S(" not found, building it (with msvc)..."), 0, { .d_c = 0 }}}))); flush_stdout(); string cfile = (os__exists(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = path_without_o_postfix}}, {_S(".c"), 0, { .d_c = 0 }}}))) ? (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = path_without_o_postfix}}, {_S(".c"), 0, { .d_c = 0 }}}))) : (str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = path_without_o_postfix}}, {_S(".cpp"), 0, { .d_c = 0 }}})))); v__builder__MsvcStringFlags flags = v__builder__msvc_string_flags(moduleflags); string inc_dirs = Array_string_join(flags.inc_paths, _S(" ")); string defines = Array_string_join(flags.defines, _S(" ")); Array_string oargs = __new_array_with_default(0, 0, sizeof(string), 0); string env_cflags = os__getenv(_S("CFLAGS")); string all_cflags = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = env_cflags}}, {_S(" "), 0xfe10, {.d_s = v->pref->cflags}}, {_SLIT0, 0, { .d_c = 0 }}})); if (_SLIT_NE(all_cflags.str, all_cflags.len, " ")) { array_push((array*)&oargs, _MOV((string[]){ string_clone(all_cflags) })); } array_push((array*)&oargs, _MOV((string[]){ _S("/nologo") })); array_push((array*)&oargs, _MOV((string[]){ _S("/volatile:ms") })); if (v->pref->is_prod) { if (!v->pref->no_prod_options) { array_push((array*)&oargs, _MOV((string[]){ _S("/O2") })); array_push((array*)&oargs, _MOV((string[]){ _S("/MD") })); array_push((array*)&oargs, _MOV((string[]){ _S("/DNDEBUG") })); } } else { array_push((array*)&oargs, _MOV((string[]){ _S("/MDd") })); array_push((array*)&oargs, _MOV((string[]){ _S("/D_DEBUG") })); } array_push((array*)&oargs, _MOV((string[]){ string_clone(defines) })); _PUSH_MANY(&oargs, (v__builder__MsvcResult_include_paths(msvc)), _t10, Array_string); array_push((array*)&oargs, _MOV((string[]){ string_clone(inc_dirs) })); array_push((array*)&oargs, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("/c \""), 0xfe10, {.d_s = cfile}}, {_S("\""), 0, { .d_c = 0 }}})) })); array_push((array*)&oargs, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("/Fo\""), 0xfe10, {.d_s = obj_path}}, {_S("\""), 0, { .d_c = 0 }}})) })); string env_ldflags = os__getenv(_S("LDFLAGS")); string all_ldflags = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = env_ldflags}}, {_S(" "), 0xfe10, {.d_s = v->pref->ldflags}}, {_SLIT0, 0, { .d_c = 0 }}})); if ((all_ldflags).len != 0) { array_push((array*)&oargs, _MOV((string[]){ string_clone(all_ldflags) })); } v__builder__Builder_dump_c_options(v, oargs); string str_oargs = Array_string_join(oargs, _S(" ")); string cmd = str_intp(3, _MOV((StrIntpData[]){{_S("\""), 0xfe10, {.d_s = msvc.full_cl_exe_path}}, {_S("\" "), 0xfe10, {.d_s = str_oargs}}, {_SLIT0, 0, { .d_c = 0 }}})); #if defined(CUSTOM_DEFINE_trace_thirdparty_obj_files) { println(str_intp(2, _MOV((StrIntpData[]){{_S(">>> build_thirdparty_obj_file_with_msvc cmd: "), 0xfe10, {.d_s = cmd}}, {_SLIT0, 0, { .d_c = 0 }}}))); flush_stdout(); } #endif os__Result res = ((os__Result){.exit_code = 0,.output = (string){.str=(byteptr)"", .is_lit=1},}); int i = 0; for (i = 0; i < 5; i++) { res = os__execute(cmd); if (res.exit_code == 0) { break; } if (!(string_contains(res.output, _S("Permission denied")) || string_contains(res.output, _S("cannot open file")))) { break; } eprintln(_S("---------------------------------------------------------------------")); eprintln(str_intp(3, _MOV((StrIntpData[]){{_S(" msvc: failed to build a thirdparty object, try: "), 0xfe07, {.d_i32 = i}}, {_S("/"), 0xfe07, {.d_i32 = _const_v__builder__thirdparty_obj_build_max_retries}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(" cmd: "), 0xfe10, {.d_s = cmd}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(_S(" output:")); eprintln(res.output); eprintln(_S("---------------------------------------------------------------------")); time__sleep(_const_v__builder__thirdparty_obj_build_retry_delay); } if (res.exit_code != 0) { v__builder__verror(str_intp(4, _MOV((StrIntpData[]){{_S("msvc: failed to build a thirdparty object after "), 0xfe07, {.d_i32 = i}}, {_S("/"), 0xfe07, {.d_i32 = _const_v__builder__thirdparty_obj_build_max_retries}}, {_S(" retries, cmd: "), 0xfe10, {.d_s = cmd}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); } println(res.output); flush_stdout(); } v__builder__MsvcStringFlags v__builder__msvc_string_flags(Array_v__cflag__CFlag cflags) { Array_string real_libs = __new_array_with_default(0, 0, sizeof(string), 0); Array_string inc_paths = __new_array_with_default(0, 0, sizeof(string), 0); Array_string lib_paths = __new_array_with_default(0, 0, sizeof(string), 0); Array_string defines = __new_array_with_default(0, 0, sizeof(string), 0); Array_string other_flags = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t1 = 0; _t1 < cflags.len; ++_t1) { v__cflag__CFlag flag = ((v__cflag__CFlag*)cflags.data)[_t1]; if (fast_string_eq(flag.name, _S("-l"))) { if (string_ends_with(flag.value, _S(".dll"))) { v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_S("MSVC cannot link against a dll (`#flag -l "), 0xfe10, {.d_s = flag.value}}, {_S("`)"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); } string lib_lib = string__plus(flag.value, _S(".lib")); array_push((array*)&real_libs, _MOV((string[]){ string_clone(lib_lib) })); } else if (fast_string_eq(flag.name, _S("-I"))) { _option_string _t4 = v__cflag__CFlag_format(&flag); if (_t4.state != 0) { IError err = _t4.err; continue; } array_push((array*)&inc_paths, _MOV((string[]){ (*(string*)_t4.data) })); } else if (fast_string_eq(flag.name, _S("-D"))) { array_push((array*)&defines, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("/D"), 0xfe10, {.d_s = flag.value}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else if (fast_string_eq(flag.name, _S("-L"))) { array_push((array*)&lib_paths, _MOV((string[]){ string_clone(flag.value) })); array_push((array*)&lib_paths, _MOV((string[]){ string__plus(string__plus(flag.value, _S("/")), _S("msvc")) })); } else if (string_ends_with(flag.value, _S(".o"))) { array_push((array*)&other_flags, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("\""), 0xfe10, {.d_s = flag.value}}, {_S("bj\""), 0, { .d_c = 0 }}})) })); } else if (string_starts_with(flag.value, _S("-D"))) { array_push((array*)&defines, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("/D"), 0xfe10, {.d_s = string_substr(flag.value, 2, 2147483647)}}, {_SLIT0, 0, { .d_c = 0 }}})) })); } else { array_push((array*)&other_flags, _MOV((string[]){ string_clone(flag.value) })); } } Array_string lpaths = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t11 = 0; _t11 < lib_paths.len; ++_t11) { string l = ((string*)lib_paths.data)[_t11]; array_push((array*)&lpaths, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("/LIBPATH:\""), 0xfe10, {.d_s = os__real_path(l)}}, {_S("\""), 0, { .d_c = 0 }}})) })); } return ((v__builder__MsvcStringFlags){.real_libs = real_libs,.inc_paths = inc_paths,.lib_paths = lpaths,.defines = defines,.other_flags = other_flags,}); } VV_LOC Array_string v__builder__MsvcResult_include_paths(v__builder__MsvcResult r) { Array_string res = __new_array_with_default(0, 4, sizeof(string), 0); if ((r.ucrt_include_path).len != 0) { array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-I \""), 0xfe10, {.d_s = r.ucrt_include_path}}, {_S("\""), 0, { .d_c = 0 }}})) })); } if ((r.vs_include_path).len != 0) { array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-I \""), 0xfe10, {.d_s = r.vs_include_path}}, {_S("\""), 0, { .d_c = 0 }}})) })); } if ((r.um_include_path).len != 0) { array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-I \""), 0xfe10, {.d_s = r.um_include_path}}, {_S("\""), 0, { .d_c = 0 }}})) })); } if ((r.shared_include_path).len != 0) { array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("-I \""), 0xfe10, {.d_s = r.shared_include_path}}, {_S("\""), 0, { .d_c = 0 }}})) })); } return res; } VV_LOC Array_string v__builder__MsvcResult_library_paths(v__builder__MsvcResult r) { Array_string res = __new_array_with_default(0, 3, sizeof(string), 0); if ((r.ucrt_lib_path).len != 0) { array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("/LIBPATH:\""), 0xfe10, {.d_s = r.ucrt_lib_path}}, {_S("\""), 0, { .d_c = 0 }}})) })); } if ((r.um_lib_path).len != 0) { array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("/LIBPATH:\""), 0xfe10, {.d_s = r.um_lib_path}}, {_S("\""), 0, { .d_c = 0 }}})) })); } if ((r.vs_lib_path).len != 0) { array_push((array*)&res, _MOV((string[]){ str_intp(2, _MOV((StrIntpData[]){{_S("/LIBPATH:\""), 0xfe10, {.d_s = r.vs_lib_path}}, {_S("\""), 0, { .d_c = 0 }}})) })); } return res; } void v__builder__Builder_rebuild_modules(v__builder__Builder* b) { if (!b->pref->use_cache || b->pref->build_mode == v__pref__BuildMode__build_module) { return; } Array_string _t1 = {0}; Array_v__ast__File_ptr _t1_orig = b->parsed_files; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__File* it = ((v__ast__File**) _t1_orig.data)[_t3]; string _t2 = it->path; array_push((array*)&_t1, &_t2); } Array_string all_files =_t1; #if defined(CUSTOM_DEFINE_trace_invalidations) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> rebuild_modules all_files: "), 0xfe10, {.d_s = Array_string_str(all_files)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif Array_string invalidations = v__builder__Builder_find_invalidated_modules_by_files(b, all_files); #if defined(CUSTOM_DEFINE_trace_invalidations) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> rebuild_modules invalidations: "), 0xfe10, {.d_s = Array_string_str(invalidations)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif if (invalidations.len > 0) { string vexe = v__pref__vexe_path(); for (int _t6 = 0; _t6 < invalidations.len; ++_t6) { string imp = ((string*)invalidations.data)[_t6]; v__builder__Builder_v_build_module(b, vexe, imp); } } } Array_string v__builder__Builder_find_invalidated_modules_by_files(v__builder__Builder* b, Array_string all_files) { v__util__timing_start(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _S("Builder.find_invalidated_modules_by_files")}}, {_S(" source_hashing"), 0, { .d_c = 0 }}}))); Map_string_string new_hashes = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_string old_hashes = new_map(sizeof(string), sizeof(string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; strings__Builder sb_new_hashes = strings__new_builder(1024); v__vcache__CacheManager cm = v__vcache__new_cache_manager(all_files); _result_string _t1 = v__vcache__CacheManager_load(&cm, _S(".hashes"), _S("all_files")); if (_t1.is_error) { IError err = _t1.err; *(string*) _t1.data = _S(" "); } string sold_hashes = (*(string*)_t1.data); Array_string sold_hashes_lines = string_split(sold_hashes, _S("\n")); for (int _t2 = 0; _t2 < sold_hashes_lines.len; ++_t2) { string line = ((string*)sold_hashes_lines.data)[_t2]; if (line.len == 0) { continue; } Array_string x = string_split(line, _S(" ")); string chash = (*(string*)array_get(x, 0)); string cpath = (*(string*)array_get(x, 1)); map_set(&old_hashes, &(string[]){cpath}, &(string[]) { chash }); } for (int _t3 = 0; _t3 < all_files.len; ++_t3) { string cpath = ((string*)all_files.data)[_t3]; _result_string _t4 = v__util__read_file(cpath); if (_t4.is_error) { IError err = _t4.err; *(string*) _t4.data = _S(""); } string ccontent = (*(string*)_t4.data); string chash = u64_hex_full(hash__sum64_string(ccontent, 7U)); map_set(&new_hashes, &(string[]){cpath}, &(string[]) { chash }); strings__Builder_write_string(&sb_new_hashes, chash); strings__Builder_write_u8(&sb_new_hashes, ' '); strings__Builder_write_string(&sb_new_hashes, cpath); strings__Builder_write_u8(&sb_new_hashes, '\n'); } string snew_hashes = strings__Builder_str(&sb_new_hashes); _result_string _t5 = v__vcache__CacheManager_save(&cm, _S(".hashes"), _S("all_files"), snew_hashes); (void)_t5; ; v__util__timing_measure(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _S("Builder.find_invalidated_modules_by_files")}}, {_S(" source_hashing"), 0, { .d_c = 0 }}}))); Array_string invalidations = __new_array_with_default(0, 0, sizeof(string), 0); if (!Map_string_string_map_eq(new_hashes, old_hashes)) { v__util__timing_start(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _S("Builder.find_invalidated_modules_by_files")}}, {_S(" rebuilding"), 0, { .d_c = 0 }}}))); #if defined(CUSTOM_DEFINE_trace_invalidations) { Map_string_Array_string _t7 = b->mod_invalidates_paths; int _t9 = _t7.key_values.len; for (int _t8 = 0; _t8 < _t9; ++_t8 ) { int _t10 = _t7.key_values.len - _t9; _t9 = _t7.key_values.len; if (_t10 < 0) { _t8 = -1; continue; } if (!DenseArray_has_index(&_t7.key_values, _t8)) {continue;} string k = *(string*)DenseArray_key(&_t7.key_values, _t8); k = string_clone(k); Array_string v = (*(Array_string*)DenseArray_value(&_t7.key_values, _t8)); Map_string_bool m = new_map(sizeof(string), sizeof(bool), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Array_string _t11 = (*(Array_string*)map_get(ADDR(map, b->mod_invalidates_mods), &(string[]){k}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })); for (int _t12 = 0; _t12 < _t11.len; ++_t12) { string mm = ((string*)_t11.data)[_t12]; map_set(&m, &(string[]){mm}, &(bool[]) { true }); } eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("> module `"), 0xfe10, {.d_s = k}}, {_S("` invalidates: "), 0xfe10, {.d_s = Array_string_str(map_keys(&m))}}, {_SLIT0, 0, { .d_c = 0 }}}))); for (int _t13 = 0; _t13 < v.len; ++_t13) { string fpath = ((string*)v.data)[_t13]; eprintln(str_intp(2, _MOV((StrIntpData[]){{_S(" "), 0xfe10, {.d_s = fpath}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } } #endif Map_string_int invalidated_paths = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; Map_string_int invalidated_mod_paths = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; int _t15 = new_hashes.key_values.len; for (int _t14 = 0; _t14 < _t15; ++_t14 ) { int _t16 = new_hashes.key_values.len - _t15; _t15 = new_hashes.key_values.len; if (_t16 < 0) { _t14 = -1; continue; } if (!DenseArray_has_index(&new_hashes.key_values, _t14)) {continue;} string npath = *(string*)DenseArray_key(&new_hashes.key_values, _t14); npath = string_clone(npath); string nhash = (*(string*)DenseArray_value(&new_hashes.key_values, _t14)); if (!_IN_MAP(ADDR(string, npath), ADDR(map, old_hashes))) { (*(int*)map_get_and_set((map*)&invalidated_paths, &(string[]){npath}, &(int[]){ 0 }))++; continue; } if (!string__eq((*(string*)map_get(ADDR(map, old_hashes), &(string[]){npath}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })), nhash)) { (*(int*)map_get_and_set((map*)&invalidated_paths, &(string[]){npath}, &(int[]){ 0 }))++; continue; } } int _t18 = old_hashes.key_values.len; for (int _t17 = 0; _t17 < _t18; ++_t17 ) { int _t19 = old_hashes.key_values.len - _t18; _t18 = old_hashes.key_values.len; if (_t19 < 0) { _t17 = -1; continue; } if (!DenseArray_has_index(&old_hashes.key_values, _t17)) {continue;} string opath = *(string*)DenseArray_key(&old_hashes.key_values, _t17); opath = string_clone(opath); string ohash = (*(string*)DenseArray_value(&old_hashes.key_values, _t17)); if (!_IN_MAP(ADDR(string, opath), ADDR(map, new_hashes))) { (*(int*)map_get_and_set((map*)&invalidated_paths, &(string[]){opath}, &(int[]){ 0 }))++; continue; } if (!string__eq((*(string*)map_get(ADDR(map, new_hashes), &(string[]){opath}, &(string[]){ (string){.str=(byteptr)"", .is_lit=1} })), ohash)) { (*(int*)map_get_and_set((map*)&invalidated_paths, &(string[]){opath}, &(int[]){ 0 }))++; continue; } } #if defined(CUSTOM_DEFINE_trace_invalidations) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("invalidated_paths: "), 0xfe10, {.d_s = Map_string_int_str(invalidated_paths)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif bool rebuild_everything = false; for (int cycle = 0; true; cycle++) { #if defined(CUSTOM_DEFINE_trace_invalidations) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("> cycle: "), 0xfe07, {.d_i32 = cycle}}, {_S(" | invalidated_paths: "), 0xfe10, {.d_s = Map_string_int_str(invalidated_paths)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif Map_string_int new_invalidated_paths = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; int _t23 = invalidated_paths.key_values.len; for (int _t22 = 0; _t22 < _t23; ++_t22 ) { int _t24 = invalidated_paths.key_values.len - _t23; _t23 = invalidated_paths.key_values.len; if (_t24 < 0) { _t22 = -1; continue; } if (!DenseArray_has_index(&invalidated_paths.key_values, _t22)) {continue;} string npath = *(string*)DenseArray_key(&invalidated_paths.key_values, _t22); npath = string_clone(npath); Array_string invalidated_mods = (*(Array_string*)map_get(ADDR(map, b->path_invalidates_mods), &(string[]){npath}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })); if (Array_string_arr_eq(invalidated_mods, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("main")})))) { continue; } if ((Array_string_contains(invalidated_mods, _S("builtin")))) { rebuild_everything = true; break; } for (int _t25 = 0; _t25 < invalidated_mods.len; ++_t25) { string imod = ((string*)invalidated_mods.data)[_t25]; if (_SLIT_EQ(imod.str, imod.len, "main")) { continue; } Array_string _t26 = (*(Array_string*)map_get(ADDR(map, b->mod_invalidates_paths), &(string[]){imod}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })); for (int _t27 = 0; _t27 < _t26.len; ++_t27) { string np = ((string*)_t26.data)[_t27]; (*(int*)map_get_and_set((map*)&new_invalidated_paths, &(string[]){np}, &(int[]){ 0 }))++; } } #if defined(CUSTOM_DEFINE_trace_invalidations) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("> npath -> invalidated_mods | "), 0xfe10, {.d_s = npath}}, {_S(" -> "), 0xfe10, {.d_s = Array_string_str(invalidated_mods)}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif string mpath = os__dir(npath); (*(int*)map_get_and_set((map*)&invalidated_mod_paths, &(string[]){mpath}, &(int[]){ 0 }))++; } if (rebuild_everything) { break; } if (new_invalidated_paths.len == 0) { break; } invalidated_paths = map_clone(&new_invalidated_paths); } if (rebuild_everything) { invalidated_mod_paths = new_map(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string) ; int _t30 = new_hashes.key_values.len; for (int _t29 = 0; _t29 < _t30; ++_t29 ) { int _t31 = new_hashes.key_values.len - _t30; _t30 = new_hashes.key_values.len; if (_t31 < 0) { _t29 = -1; continue; } if (!DenseArray_has_index(&new_hashes.key_values, _t29)) {continue;} string npath = *(string*)DenseArray_key(&new_hashes.key_values, _t29); npath = string_clone(npath); string mpath = os__dir(npath); Array_string pimods = (*(Array_string*)map_get(ADDR(map, b->path_invalidates_mods), &(string[]){npath}, &(Array_string[]){ __new_array(0, 0, sizeof(string)) })); if (Array_string_arr_eq(pimods, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("main")})))) { continue; } (*(int*)map_get_and_set((map*)&invalidated_mod_paths, &(string[]){mpath}, &(int[]){ 0 }))++; } } #if defined(CUSTOM_DEFINE_trace_invalidations) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("invalidated_mod_paths: "), 0xfe10, {.d_s = Map_string_int_str(invalidated_mod_paths)}}, {_SLIT0, 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("rebuild_everything: "), 0xfe10, {.d_s = rebuild_everything ? _S("true") : _S("false")}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif if (invalidated_mod_paths.len > 0) { Array_string impaths = map_keys(&invalidated_mod_paths); for (int _t33 = 0; _t33 < impaths.len; ++_t33) { string imp = ((string*)impaths.data)[_t33]; array_push((array*)&invalidations, _MOV((string[]){ string_clone(imp) })); } } v__util__timing_measure(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = _S("Builder.find_invalidated_modules_by_files")}}, {_S(" rebuilding"), 0, { .d_c = 0 }}}))); } return invalidations; } VV_LOC void v__builder__Builder_v_build_module(v__builder__Builder* b, string vexe, string imp_path) { bool v__builder__Builder_v_build_module_defer_0 = false; string pwd; pwd = os__getwd(); v__builder__Builder_v_build_module_defer_0 = true; string vroot = os__dir(vexe); _result_void _t1 = os__chdir(vroot); (void)_t1; ; string boptions = Array_string_join(b->pref->build_options, _S(" ")); string rebuild_cmd = str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = os__quoted_path(vexe)}}, {_S(" "), 0xfe10, {.d_s = boptions}}, {_S(" build-module "), 0xfe10, {.d_s = os__quoted_path(imp_path)}}, {_SLIT0, 0, { .d_c = 0 }}})); ; #if defined(CUSTOM_DEFINE_trace_v_build_module) { eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("> Builder.v_build_module: "), 0xfe10, {.d_s = rebuild_cmd}}, {_SLIT0, 0, { .d_c = 0 }}}))); } #endif os__system(rebuild_cmd); // Defer begin if (v__builder__Builder_v_build_module_defer_0) { _result_void _t3 = os__chdir(pwd); (void)_t3; ; } // Defer end } VV_LOC string v__builder__Builder_rebuild_cached_module(v__builder__Builder* b, string vexe, string imp_path) { _result_string _t1 = v__vcache__CacheManager_mod_exists(&b->pref->cache_manager, imp_path, _S(".o"), imp_path); if (_t1.is_error) { IError err = _t1.err; if (b->pref->is_verbose) { println(str_intp(3, _MOV((StrIntpData[]){{_S("Cached "), 0xfe10, {.d_s = imp_path}}, {_S(" .o file not found... Building .o file for "), 0xfe10, {.d_s = imp_path}}, {_SLIT0, 0, { .d_c = 0 }}}))); } v__builder__Builder_v_build_module(b, vexe, imp_path); _result_string _t2 = v__vcache__CacheManager_mod_exists(&b->pref->cache_manager, imp_path, _S(".o"), imp_path); if (_t2.is_error) { IError err = _t2.err; _v_panic(str_intp(3, _MOV((StrIntpData[]){{_S("could not rebuild cache module for "), 0xfe10, {.d_s = imp_path}}, {_S(", error: "), 0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}}))); VUNREACHABLE(); ; } string rebuilt_o = (*(string*)_t2.data); return rebuilt_o; } string res = (*(string*)_t1.data); return res; } VV_LOC void v__builder__Builder_handle_usecache(v__builder__Builder* b, string vexe) { if (!b->pref->use_cache || b->pref->build_mode == v__pref__BuildMode__build_module) { return; } Array_string libs = __new_array_with_default(0, 0, sizeof(string), 0); Array_string built_modules = __new_array_with_default(0, 0, sizeof(string), 0); string builtin_obj_path = v__builder__Builder_rebuild_cached_module(b, vexe, _S("vlib/builtin")); array_push((array*)&libs, _MOV((string[]){ string_clone(builtin_obj_path) })); for (int _t2 = 0; _t2 < b->parsed_files.len; ++_t2) { v__ast__File* ast_file = ((v__ast__File**)b->parsed_files.data)[_t2]; if (b->pref->is_test && !fast_string_eq(ast_file->mod.name, _S("main"))) { _result_string _t3 = v__builder__Builder_find_module_path(b, ast_file->mod.name, ast_file->path); if (_t3.is_error) { IError err = _t3.err; v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_S("cannot import module \""), 0xfe10, {.d_s = ast_file->mod.name}}, {_S("\" (not found)"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); break; } string imp_path = (*(string*)_t3.data); string obj_path = v__builder__Builder_rebuild_cached_module(b, vexe, imp_path); array_push((array*)&libs, _MOV((string[]){ string_clone(obj_path) })); array_push((array*)&built_modules, _MOV((string[]){ string_clone(ast_file->mod.name) })); } for (int _t6 = 0; _t6 < ast_file->imports.len; ++_t6) { v__ast__Import imp_stmt = ((v__ast__Import*)ast_file->imports.data)[_t6]; string imp = imp_stmt.mod; if (v__util__module_is_builtin(imp)) { continue; } if ((Array_string_contains(built_modules, imp))) { continue; } if (v__util__should_bundle_module(imp)) { continue; } if (_SLIT_EQ(imp.str, imp.len, "help")) { continue; } _result_string _t7 = v__builder__Builder_find_module_path(b, imp, ast_file->path); if (_t7.is_error) { IError err = _t7.err; v__builder__verror(str_intp(2, _MOV((StrIntpData[]){{_S("cannot import module \""), 0xfe10, {.d_s = imp}}, {_S("\" (not found)"), 0, { .d_c = 0 }}}))); VUNREACHABLE(); break; } string imp_path = (*(string*)_t7.data); string obj_path = v__builder__Builder_rebuild_cached_module(b, vexe, imp_path); array_push((array*)&libs, _MOV((string[]){ string_clone(obj_path) })); array_push((array*)&built_modules, _MOV((string[]){ string_clone(imp) })); } } _PUSH_MANY(&b->ccoptions.post_args, (libs), _t10, Array_string); } bool v__builder__Builder_should_rebuild(v__builder__Builder* b) { string exe_name = b->pref->out_name; #if defined(_WIN32) { exe_name = string__plus(exe_name, _S(".exe")); } #endif if (!os__is_file(exe_name)) { return true; } if (!b->pref->is_crun) { return true; } Array_string v_program_files = __new_array_with_default(0, 0, sizeof(string), 0); bool is_file = os__is_file(b->pref->path); bool is_dir = os__is_dir(b->pref->path); if (is_file) { array_push((array*)&v_program_files, _MOV((string[]){ string_clone(b->pref->path) })); } else if (is_dir) { _PUSH_MANY(&v_program_files, (v__builder__Builder_v_files_from_dir(b, b->pref->path)), _t5, Array_string); } if (v_program_files.len > 0) { qsort(v_program_files.data, v_program_files.len, v_program_files.element_size, (voidptr)compare_10151352214168403551_string); } ; b->crun_cache_keys = v_program_files; array_push((array*)&b->crun_cache_keys, _MOV((string[]){ string_clone(exe_name) })); i64 exe_stamp = os__file_last_mod_unix(exe_name); i64 source_stamp = v__builder__most_recent_timestamp(v_program_files); if (exe_stamp <= source_stamp) { return true; } v__vcache__CacheManager cm = v__vcache__new_cache_manager(b->crun_cache_keys); _result_string _t8 = v__vcache__CacheManager_load(&cm, _S(".build_options"), _S(".crun")); if (_t8.is_error) { IError err = _t8.err; return true; } string sbuild_options = (*(string*)_t8.data); if (!string__eq(sbuild_options, Array_string_join(b->pref->build_options, _S("\n")))) { return true; } _result_string _t11 = v__vcache__CacheManager_load(&cm, _S(".dependencies"), _S(".crun")); if (_t11.is_error) { IError err = _t11.err; return true; } string sdependencies = (*(string*)_t11.data); Array_string dependencies = string_split(sdependencies, _S("\n")); i64 dependencies_stamp = v__builder__most_recent_timestamp(dependencies); if (dependencies_stamp < exe_stamp) { return false; } return true; } VV_LOC i64 v__builder__most_recent_timestamp(Array_string files) { i64 res = ((i64)(0)); for (int _t1 = 0; _t1 < files.len; ++_t1) { string f = ((string*)files.data)[_t1]; i64 f_stamp = os__file_last_mod_unix(f); if (res <= f_stamp) { res = f_stamp; } } return res; } void v__builder__Builder_rebuild(v__builder__Builder* b, void (*backend_cb)(v__builder__Builder* b)) { time__StopWatch sw = time__new_stopwatch(((time__StopWatchOptions){.auto_start = true,})); backend_cb(b); if (b->pref->is_crun) { v__vcache__CacheManager cm = v__vcache__new_cache_manager(b->crun_cache_keys); Array_string _t1 = {0}; Array_v__ast__File_ptr _t1_orig = b->parsed_files; int _t1_len = _t1_orig.len; _t1 = __new_array(0, _t1_len, sizeof(string)); for (int _t3 = 0; _t3 < _t1_len; ++_t3) { v__ast__File* it = ((v__ast__File**) _t1_orig.data)[_t3]; string _t2 = it->path; array_push((array*)&_t1, &_t2); } Array_string dependency_files =_t1; _result_string _t4 = v__vcache__CacheManager_save(&cm, _S(".dependencies"), _S(".crun"), Array_string_join(dependency_files, _S("\n"))); (void)_t4; ; _result_string _t5 = v__vcache__CacheManager_save(&cm, _S(".build_options"), _S(".crun"), Array_string_join(b->pref->build_options, _S("\n"))); (void)_t5; ; } v__util__Timers* timers = v__util__get_timers(); v__util__Timers_show_remaining(timers); if (b->pref->is_stats) { i64 compilation_time_micros = (i64)(1 + time__Duration_microseconds(time__StopWatch_elapsed(sw))); string scompilation_time_ms = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xc062d, {.d_f64 = (f64)(((f64)(compilation_time_micros)) / ((f64)(1000.0)))}}, {_SLIT0, 0, { .d_c = 0 }}}))); int all_v_source_lines = 0; int all_v_source_bytes = 0; int all_v_source_tokens = 0; for (int _t6 = 0; _t6 < b->parsed_files.len; ++_t6) { v__ast__File* pf = ((v__ast__File**)b->parsed_files.data)[_t6]; all_v_source_lines += pf->nr_lines; all_v_source_bytes += pf->nr_bytes; all_v_source_tokens += pf->nr_tokens; } string sall_v_source_lines = int_str(all_v_source_lines); string sall_v_source_bytes = int_str(all_v_source_bytes); string sall_v_source_tokens = int_str(all_v_source_tokens); string sall_v_types = int_str(b->table->type_symbols.len); string sall_v_modules = int_str(b->table->modules.len); string sall_v_files = int_str(b->parsed_files.len); sall_v_source_lines = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0x14fe30, {.d_s = sall_v_source_lines}}, {_SLIT0, 0, { .d_c = 0 }}}))); sall_v_source_bytes = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0x14fe30, {.d_s = sall_v_source_bytes}}, {_SLIT0, 0, { .d_c = 0 }}}))); sall_v_source_tokens = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0x14fe30, {.d_s = sall_v_source_tokens}}, {_SLIT0, 0, { .d_c = 0 }}}))); sall_v_types = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xafe30, {.d_s = sall_v_types}}, {_SLIT0, 0, { .d_c = 0 }}}))); sall_v_modules = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xafe30, {.d_s = sall_v_modules}}, {_SLIT0, 0, { .d_c = 0 }}}))); sall_v_files = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xafe30, {.d_s = sall_v_files}}, {_SLIT0, 0, { .d_c = 0 }}}))); println(str_intp(7, _MOV((StrIntpData[]){{_S(" V source code size: "), 0xfe10, {.d_s = sall_v_source_lines}}, {_S(" lines, "), 0xfe10, {.d_s = sall_v_source_tokens}}, {_S(" tokens, "), 0xfe10, {.d_s = sall_v_source_bytes}}, {_S(" bytes, "), 0xfe10, {.d_s = sall_v_types}}, {_S(" types, "), 0xfe10, {.d_s = sall_v_modules}}, {_S(" modules, "), 0xfe10, {.d_s = sall_v_files}}, {_S(" files"), 0, { .d_c = 0 }}}))); string slines = int_str(b->stats_lines); string sbytes = int_str(b->stats_bytes); slines = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0x14fe30, {.d_s = slines}}, {_SLIT0, 0, { .d_c = 0 }}}))); sbytes = v__util__bold(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0x14fe30, {.d_s = sbytes}}, {_SLIT0, 0, { .d_c = 0 }}}))); println(str_intp(3, _MOV((StrIntpData[]){{_S("generated target code size: "), 0xfe10, {.d_s = slines}}, {_S(" lines, "), 0xfe10, {.d_s = sbytes}}, {_S(" bytes"), 0, { .d_c = 0 }}}))); int vlines_per_second = ((int)((f64)((f64)(((f64)(1000000.0)) * ((f64)(all_v_source_lines))) / ((f64)(compilation_time_micros))))); string svlines_per_second = v__util__bold(int_str(vlines_per_second)); int used_cgen_threads = (b->pref->no_parallel ? (1) : (runtime__nr_jobs())); println(str_intp(4, _MOV((StrIntpData[]){{_S("compilation took: "), 0xfe10, {.d_s = scompilation_time_ms}}, {_S(" ms, compilation speed: "), 0xfe10, {.d_s = svlines_per_second}}, {_S(" vlines/s, cgen threads: "), 0xfe07, {.d_i32 = used_cgen_threads}}, {_SLIT0, 0, { .d_c = 0 }}}))); } } string v__builder__Builder_get_vtmp_filename(v__builder__Builder* b, string base_file_name, string postfix) { string vtmp = os__vtmp_dir(); string uniq = _S(""); if (!b->pref->reuse_tmpc) { uniq = str_intp(2, _MOV((StrIntpData[]){{_S("."), 0xfe10, {.d_s = rand__ulid()}}, {_SLIT0, 0, { .d_c = 0 }}})); } string fname = string__plus(os__file_name(os__real_path(base_file_name)), str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = uniq}}, {_SLIT0, 0xfe10, {.d_s = postfix}}, {_SLIT0, 0, { .d_c = 0 }}}))); return os__real_path(os__join_path(vtmp, new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){fname})))); } void v__builder__cbuilder__compile_c(v__builder__Builder* b) { if (b->pref->is_verbose) { println(_S("all .v files before:")); } #if defined(_WIN32) { _result_void _t2 = v__builder__Builder_find_win_cc(b); if (_t2.is_error) { IError err = _t2.err; v__builder__verror(_S("\n==================\nError: no C compiler detected.\n\nYou can find instructions on how to install one in the V wiki:\nhttps://github.com/vlang/v/wiki/Installing-a-C-compiler-on-Windows\n\nIf you think you have one installed, make sure it is in your PATH.\nIf you do have one in your PATH, please raise an issue on GitHub:\nhttps://github.com/vlang/v/issues/new/choose\n\nYou can also use `v doctor`, to see what V knows about your current environment.\n\nYou can also seek #help on Discord: https://discord.gg/vlang\n")); VUNREACHABLE(); ; } ; } #endif Array_string files = v__builder__Builder_get_builtin_files(*b); _PUSH_MANY(&files, (v__builder__Builder_get_user_files(b)), _t3, Array_string); v__builder__Builder_set_module_lookup_paths(b); if (b->pref->is_verbose) { println(_S("all .v files:")); println(Array_string_str(files)); } string out_name_c = v__builder__Builder_get_vtmp_filename(b, b->pref->out_name, _S(".tmp.c")); if (b->pref->is_shared) { out_name_c = v__builder__Builder_get_vtmp_filename(b, b->pref->out_name, _S(".tmp.so.c")); } v__builder__cbuilder__build_c(b, files, out_name_c); if (!b->pref->parallel_cc) { v__builder__Builder_cc(b); } } void v__builder__cbuilder__build_c(v__builder__Builder* b, Array_string v_files, string out_file) { b->out_name_c = out_file; b->pref->out_name_c = os__real_path(out_file); v__builder__Builder_info(b, str_intp(2, _MOV((StrIntpData[]){{_S("build_c("), 0xfe10, {.d_s = out_file}}, {_S(")"), 0, { .d_c = 0 }}}))); strings__Builder output2 = v__builder__cbuilder__gen_c(b, v_files); if (b->pref->is_vlines) { output2 = v__gen__c__fix_reset_dbg_line(output2, out_file); } _result_void _t1 = os__write_file_array(out_file, output2); if (_t1.is_error) { IError err = _t1.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; if (b->pref->is_stats) { int _t2 = 0; strings__Builder _t2_orig = output2; int _t2_len = _t2_orig.len; for (int _t3 = 0; _t3 < _t2_len; ++_t3) { u8 it = ((u8*) _t2_orig.data)[_t3]; if (it == '\n') { ++_t2; } } b->stats_lines = (int)(_t2 + 1); b->stats_bytes = output2.len; } } strings__Builder v__builder__cbuilder__gen_c(v__builder__Builder* b, Array_string v_files) { _result_void _t1 = v__builder__Builder_front_and_middle_stages(b, v_files); if (_t1.is_error) { IError err = _t1.err; if (IError_name_table[err._typ]._method_code(err._object) > 7000) { return __new_array_with_default(0, 0, sizeof(u8), 0); } v__builder__verror(IError_name_table[err._typ]._method_msg(err._object)); VUNREACHABLE(); ; } ; v__util__timing_start(_S("C GEN")); v__gen__c__GenOutput *result = HEAP(v__gen__c__GenOutput, (v__gen__c__gen(b->parsed_files, b->table, b->pref))); v__util__timing_measure(_S("C GEN")); if (b->pref->parallel_cc) { v__builder__Builder_cc(b); v__util__timing_start(_S("Parallel C compilation")); _result_void _t3 = v__builder__cbuilder__parallel_cc(b, (*(result))); if (_t3.is_error) { IError err = _t3.err; v__builder__verror(IError_name_table[err._typ]._method_msg(err._object)); VUNREACHABLE(); ; } ; v__util__timing_measure(_S("Parallel C compilation")); } return (*(result)).res_builder; } VV_LOC _result_void v__builder__cbuilder__parallel_cc(v__builder__Builder* b, v__gen__c__GenOutput _v_toheap_result) { v__gen__c__GenOutput* result = HEAP(v__gen__c__GenOutput, _v_toheap_result); bool v__builder__cbuilder__parallel_cc_defer_0 = false; time__StopWatch sw_total; string tmp_dir = os__vtmp_dir(); sw_total = time__new_stopwatch(((time__StopWatchOptions){.auto_start = true,})); v__builder__cbuilder__parallel_cc_defer_0 = true; int c_files = int_max(1, _const_v__util__nr_jobs); eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("> c_files: "), 0xfe07, {.d_i32 = c_files}}, {_S(" | util.nr_jobs: "), 0xfe07, {.d_i32 = _const_v__util__nr_jobs}}, {_SLIT0, 0, { .d_c = 0 }}}))); _result_void _t1 = os__write_file(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_dir}}, {_S("/out.h"), 0, { .d_c = 0 }}})), (*(result)).header); if (_t1.is_error) { IError err = _t1.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; string out0 = string__plus(_S("//out0\n"), string_substr((*(result)).out_str, 0, (*(int*)array_get((*(result)).out_fn_start_pos, 0)))); _result_void _t2 = os__write_file(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_dir}}, {_S("/out_0.c"), 0, { .d_c = 0 }}})), string__plus(string__plus(string__plus(_S("#include \"out.h\"\n"), out0), _S("\n//X:\n")), (*(result)).out0_str)); if (_t2.is_error) { IError err = _t2.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; _result_void _t3 = os__write_file(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_dir}}, {_S("/out_x.c"), 0, { .d_c = 0 }}})), string__plus(string__plus(string__plus(_S("#include \"out.h\"\n\n"), (*(result)).extern_str), _S("\n")), string_substr((*(result)).out_str, (*(int*)array_last((*(result)).out_fn_start_pos)), 2147483647))); if (_t3.is_error) { IError err = _t3.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; int prev_fn_pos = 0; Array_os__File out_files = __new_array_with_default(c_files, 0, sizeof(os__File), (voidptr)&(os__File[]){(os__File){.cfile = 0,.fd = 0,.is_opened = 0,}}[0]); Array_string fnames = __new_array_with_default(0, 0, sizeof(string), 0); for (int i = 0; i < c_files; ++i) { string fname = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_dir}}, {_S("/out_"), 0xfe07, {.d_i32 = (int_literal)(i + 1)}}, {_S(".c"), 0, { .d_c = 0 }}})); array_push((array*)&fnames, _MOV((string[]){ string_clone(fname) })); _result_os__File _t5 = os__create(fname); if (_t5.is_error) { IError err = _t5.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } array_set(&out_files, i, &(os__File[]) { (*(os__File*)_t5.data) }); _result_int _t6 = os__File_writeln(&(*(os__File*)array_get(out_files, i)), _S("#include \"out.h\"\n")); if (_t6.is_error) { IError err = _t6.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; _result_int _t7 = os__File_writeln(&(*(os__File*)array_get(out_files, i)), (*(result)).extern_str); if (_t7.is_error) { IError err = _t7.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; } for (int i = 0; i < (*(result)).out_fn_start_pos.len; ++i) { int fn_pos = ((int*)(*(result)).out_fn_start_pos.data)[i]; if (prev_fn_pos >= (*(result)).out_str.len || fn_pos >= (*(result)).out_str.len || prev_fn_pos > fn_pos) { eprintln(str_intp(5, _MOV((StrIntpData[]){{_S("> EXITING i="), 0xfe07, {.d_i32 = i}}, {_S(" out of "), 0xfe07, {.d_i32 = (*(result)).out_fn_start_pos.len}}, {_S(" prev_pos="), 0xfe07, {.d_i32 = prev_fn_pos}}, {_S(" fn_pos="), 0xfe07, {.d_i32 = fn_pos}}, {_SLIT0, 0, { .d_c = 0 }}}))); break; } if (i == 0) { prev_fn_pos = fn_pos; continue; } string fn_text = string_substr((*(result)).out_str, prev_fn_pos, fn_pos); _result_int _t8 = os__File_writeln(&(*(os__File*)array_get(out_files, (int)(i % c_files))), fn_text); if (_t8.is_error) { IError err = _t8.err; _v_panic(IError_str(err)); VUNREACHABLE(); ; } ; prev_fn_pos = fn_pos; } for (int i = 0; i < c_files; ++i) { os__File_close(&(*(os__File*)array_get(out_files, i))); } string cc_path = _const_v__builder__cbuilder__cc_compiler; bool _t9 = false; Array_string _t9_orig = b->pref->build_options; int _t9_len = _t9_orig.len; for (int _t10 = 0; _t10 < _t9_len; ++_t10) { string it = ((string*) _t9_orig.data)[_t10]; if (string_starts_with(it, _S("-cc "))) { _t9 = true; break; } } bool explicit_cc_flag_passed =_t9; if (explicit_cc_flag_passed) { cc_path = b->pref->ccompiler; } string cc = os__quoted_path(cc_path); Array_string compile_args = v__builder__Builder_get_compile_args(b); Array_string linker_args = v__builder__Builder_get_linker_args(b); if (!explicit_cc_flag_passed) { Array_string _t11 = {0}; Array_string _t11_orig = compile_args; int _t11_len = _t11_orig.len; _t11 = __new_array(0, _t11_len, sizeof(string)); for (int _t12 = 0; _t12 < _t11_len; ++_t12) { string it = ((string*) _t11_orig.data)[_t12]; if (_SLIT_NE(it.str, it.len, "-bt25")) { array_push((array*)&_t11, &it); } } compile_args =_t11; Array_string _t13 = {0}; Array_string _t13_orig = linker_args; int _t13_len = _t13_orig.len; _t13 = __new_array(0, _t13_len, sizeof(string)); for (int _t14 = 0; _t14 < _t13_len; ++_t14) { string it = ((string*) _t13_orig.data)[_t14]; if (_SLIT_NE(it.str, it.len, "-bt25")) { array_push((array*)&_t13, &it); } } linker_args =_t13; } string scompile_args = Array_string_join(compile_args, _S(" ")); string slinker_args = Array_string_join(linker_args, _S(" ")); Array_string _t15 = {0}; Array_string _t15_orig = compile_args; int _t15_len = _t15_orig.len; _t15 = __new_array(0, _t15_len, sizeof(string)); for (int _t16 = 0; _t16 < _t15_len; ++_t16) { string it = ((string*) _t15_orig.data)[_t16]; if (_SLIT_NE(it.str, it.len, "-x objective-c")) { array_push((array*)&_t15, &it); } } string scompile_args_for_linker = Array_string_join(_t15, _S(" ")); Array_string o_postfixes = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("0"), _S("x")})); Array_string cmds = __new_array_with_default(0, 0, sizeof(string), 0); for (int i = 0; i < c_files; ++i) { array_push((array*)&o_postfixes, _MOV((string[]){ int_literal_str(((int_literal)(i + 1))) })); } for (int _t18 = 0; _t18 < o_postfixes.len; ++_t18) { string postfix = ((string*)o_postfixes.data)[_t18]; array_push((array*)&cmds, _MOV((string[]){ str_intp(9, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = cc}}, {_S(" "), 0xfe10, {.d_s = _const_v__builder__cbuilder__cc_cflags}}, {_S(" "), 0xfe10, {.d_s = _const_v__builder__cbuilder__cc_cflags_opt}}, {_S(" "), 0xfe10, {.d_s = scompile_args}}, {_S(" -w -o "), 0xfe10, {.d_s = tmp_dir}}, {_S("/out_"), 0xfe10, {.d_s = postfix}}, {_S(".o -c "), 0xfe10, {.d_s = tmp_dir}}, {_S("/out_"), 0xfe10, {.d_s = postfix}}, {_S(".c"), 0, { .d_c = 0 }}})) })); } int failed = 0; time__StopWatch sw = time__new_stopwatch(((time__StopWatchOptions){.auto_start = true,})); sync__pool__PoolProcessor* pp = sync__pool__new_pool_processor(((sync__pool__PoolProcessorConfig){.maxjobs = 0,.callback = (voidptr)v__builder__cbuilder__build_parallel_o_cb,})); sync__pool__PoolProcessor_set_max_jobs(pp, _const_v__util__nr_jobs); sync__pool__PoolProcessor_work_on_items_T_string(pp, cmds); Array_os__Result _t20 = sync__pool__PoolProcessor_get_results_T_os__Result(pp); for (int _t21 = 0; _t21 < _t20.len; ++_t21) { os__Result x = ((os__Result*)_t20.data)[_t21]; failed += (x.exit_code == 0 ? (0) : (1)); } v__builder__cbuilder__eprint_time(sw, str_intp(4, _MOV((StrIntpData[]){{_S("C compilation on "), 0xfe07, {.d_i32 = _const_v__util__nr_jobs}}, {_S(" thread(s), processing "), 0xfe07, {.d_i32 = cmds.len}}, {_S(" commands, failed: "), 0xfe07, {.d_i32 = failed}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (failed > 0) { _result_void _t22 = (_result_void){ .is_error=true, .err=error_with_code(_S("failed parallel C compilation"), failed), .data={E_STRUCT} }; // Defer begin if (v__builder__cbuilder__parallel_cc_defer_0) { v__builder__cbuilder__eprint_time(sw_total, _S("parallel_cc")); } // Defer end return _t22; } Array_string ofiles = __new_array_with_default(0, 0, sizeof(string), 0); for (int _t23 = 0; _t23 < fnames.len; ++_t23) { string f = ((string*)fnames.data)[_t23]; string fo = string_replace(f, _S(".c"), _S(".o")); array_push((array*)&ofiles, _MOV((string[]){ os__quoted_path(fo) })); } string obj_files = Array_string_join(ofiles, _S(" ")); Array_string alink = new_array_from_c_array(9, 9, sizeof(string), _MOV((string[9]){ string_clone(cc), string_clone(scompile_args_for_linker), _S("-o"), os__quoted_path(b->pref->out_name), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_dir}}, {_S("/out_0.o"), 0, { .d_c = 0 }}}))), string_clone(obj_files), os__quoted_path(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = tmp_dir}}, {_S("/out_x.o"), 0, { .d_c = 0 }}}))), string_clone(slinker_args), string_clone(_const_v__builder__cbuilder__cc_ldflags)})); string link_cmd = Array_string_join(alink, _S(" ")); time__StopWatch sw_link = time__new_stopwatch(((time__StopWatchOptions){.auto_start = true,})); os__Result link_res = os__execute(link_cmd); v__builder__cbuilder__eprint_result_time(sw_link, _S("link_cmd"), link_cmd, link_res); if (link_res.exit_code != 0) { _result_void _t25 = (_result_void){ .is_error=true, .err=error_with_code(_S("failed to link after parallel C compilation"), 1), .data={E_STRUCT} }; // Defer begin if (v__builder__cbuilder__parallel_cc_defer_0) { v__builder__cbuilder__eprint_time(sw_total, _S("parallel_cc")); } // Defer end return _t25; } // Defer begin if (v__builder__cbuilder__parallel_cc_defer_0) { v__builder__cbuilder__eprint_time(sw_total, _S("parallel_cc")); } // Defer end return (_result_void){0}; } VV_LOC os__Result* v__builder__cbuilder__build_parallel_o_cb(sync__pool__PoolProcessor* p, int idx, int _wid) { string cmd = sync__pool__PoolProcessor_get_item_T_string(p, idx); time__StopWatch sw = time__new_stopwatch(((time__StopWatchOptions){.auto_start = true,})); os__Result res = os__execute(cmd); v__builder__cbuilder__eprint_result_time(sw, _S("cc_cmd"), cmd, res); return ((os__Result*)memdup(&(os__Result){.exit_code = (res).exit_code,.output = (res).output,}, sizeof(os__Result))); } VV_LOC void v__builder__cbuilder__eprint_result_time(time__StopWatch sw, string label, string cmd, os__Result res) { v__builder__cbuilder__eprint_time(sw, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = label}}, {_S(": `"), 0xfe10, {.d_s = cmd}}, {_S("` => "), 0xfe07, {.d_i32 = res.exit_code}}, {_SLIT0, 0, { .d_c = 0 }}}))); if (res.exit_code != 0) { eprintln(res.output); } } VV_LOC void v__builder__cbuilder__eprint_time(time__StopWatch sw, string label) { eprintln(str_intp(3, _MOV((StrIntpData[]){{_S("> "), 0xafe29, {.d_i64 = time__Duration_milliseconds(time__StopWatch_elapsed(sw))}}, {_S(" ms, "), 0xfe10, {.d_s = label}}, {_SLIT0, 0, { .d_c = 0 }}}))); } VV_LOC v__util__Timers* main__timers_pointer(v__util__Timers* p) { static v__util__Timers* ptimers = ((v__util__Timers*)(((void*)0))); if (p != ((void*)0)) { ptimers = p; } return ptimers; } VV_LOC void main__main(void) { unbuffer_stdout(); bool timers_should_print = false; #if defined(CUSTOM_DEFINE_time_v) { timers_should_print = true; } #endif if ((Array_string_contains(_const_os__args, _S("-show-timings")))) { timers_should_print = true; } v__util__Timers* timers = main__timers_pointer(v__util__new_timers(((v__util__TimerParams){.should_print = timers_should_print,.label = _S("main"),}))); v__util__Timers_start(timers, _S("v start")); v__util__Timers_show(timers, _S("v start")); v__util__Timers_start(timers, _S("TOTAL")); _result_void _t2 = at_exit((voidptr) anon_fn_6a0ddf9f315b536f__1865); if (_t2.is_error) { panic_result_not_set(IError_name_table[_t2.err._typ]._method_msg(_t2.err._object)); } ; v__util__Timers_start(timers, _S("v parsing CLI args")); Array_string args = array_slice(_const_os__args, 1, 2147483647); if (args.len == 0 || (fast_string_eq((*(string*)array_get(args, 0)), _S("-")) || fast_string_eq((*(string*)array_get(args, 0)), _S("repl")))) { if (args.len == 0) { if (os__is_atty(0) == 0) { Array_string args_and_flags = array_clone_static_to_depth(array_slice(v__util__join_env_vflags_and_os_args(), 1, 2147483647), 0); _PUSH_MANY(&args_and_flags, (new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("run"), _S("-")}))), _t3, Array_string); v__pref__parse_args_and_show_errors(_const_main__external_tools, args_and_flags, true); } } v__util__launch_tool(false, _S("vrepl"), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); return; } Array_string args_and_flags = array_slice(v__util__join_env_vflags_and_os_args(), 1, 2147483647); multi_return_ref_v__pref__Preferences_string mr_2476 = v__pref__parse_args_and_show_errors(_const_main__external_tools, args_and_flags, true); v__pref__Preferences* prefs = mr_2476.arg0; string command = mr_2476.arg1; if (prefs->use_cache && string__eq(os__user_os(), _S("windows"))) { eprintln(_S("-usecache is currently disabled on windows")); _v_exit(1); VUNREACHABLE(); } v__util__Timers_show(timers, _S("v parsing CLI args")); main__setup_vbuild_env_vars(prefs); if ((Array_string_contains(_const_main__external_tools, command))) { v__util__launch_tool(prefs->is_verbose, string__plus(_S("v"), command), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); return; } if (_SLIT_EQ(command.str, command.len, "run") || _SLIT_EQ(command.str, command.len, "crun") || _SLIT_EQ(command.str, command.len, "build") || _SLIT_EQ(command.str, command.len, "build-module")) { main__rebuild(prefs); return; } else if (_SLIT_EQ(command.str, command.len, "help")) { main__invoke_help_and_exit(args); } else if (_SLIT_EQ(command.str, command.len, "version")) { println(v__util__version__full_v_version(prefs->is_verbose)); return; } else if (_SLIT_EQ(command.str, command.len, "new") || _SLIT_EQ(command.str, command.len, "init")) { v__util__launch_tool(prefs->is_verbose, _S("vcreate"), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); return; } else if (_SLIT_EQ(command.str, command.len, "install") || _SLIT_EQ(command.str, command.len, "list") || _SLIT_EQ(command.str, command.len, "outdated") || _SLIT_EQ(command.str, command.len, "remove") || _SLIT_EQ(command.str, command.len, "search") || _SLIT_EQ(command.str, command.len, "show") || _SLIT_EQ(command.str, command.len, "update") || _SLIT_EQ(command.str, command.len, "upgrade")) { v__util__launch_tool(prefs->is_verbose, _S("vpm"), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); return; } else if (_SLIT_EQ(command.str, command.len, "vlib-docs")) { v__util__launch_tool(prefs->is_verbose, _S("vdoc"), new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("doc"), _S("vlib")}))); VUNREACHABLE(); } else if (_SLIT_EQ(command.str, command.len, "interpret")) { v__util__launch_tool(prefs->is_verbose, _S("builders/interpret_builder"), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); } else if (_SLIT_EQ(command.str, command.len, "get")) { eprintln(_S("V Error: Use `v install` to install modules from vpm.vlang.io")); _v_exit(1); VUNREACHABLE(); } else if (_SLIT_EQ(command.str, command.len, "translate")) { v__util__launch_tool(prefs->is_verbose, _S("translate"), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); } else { if (string_ends_with(command, _S(".v")) || os__exists(command)) { main__rebuild(prefs); return; } } if (prefs->is_help) { main__invoke_help_and_exit(args); } Array_string other_commands = new_array_from_c_array(19, 19, sizeof(string), _MOV((string[19]){ _S("run"), _S("crun"), _S("build"), _S("build-module"), _S("help"), _S("version"), _S("new"), _S("init"), _S("install"), _S("list"), _S("outdated"), _S("remove"), _S("search"), _S("show"), _S("update"), _S("upgrade"), _S("vlib-docs"), _S("interpret"), _S("translate")})); Array_string all_commands = __new_array_with_default(0, 0, sizeof(string), 0); _PUSH_MANY(&all_commands, (_const_main__external_tools), _t4, Array_string); _PUSH_MANY(&all_commands, (other_commands), _t5, Array_string); if (all_commands.len > 0) { qsort(all_commands.data, all_commands.len, all_commands.element_size, (voidptr)compare_7642010017538462575_string); } ; eprintln(v__util__Suggestion_say(v__util__new_suggestion(command, all_commands, ((v__util__SuggestionParams){.similarity_threshold = 0.2,.similarity_fn = strings__dice_coefficient,})), str_intp(2, _MOV((StrIntpData[]){{_S("v: unknown command `"), 0xfe10, {.d_s = command}}, {_S("`"), 0, { .d_c = 0 }}})))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("Run "), 0xfe10, {.d_s = term__highlight_command(_S("v help"))}}, {_S(" for usage."), 0, { .d_c = 0 }}}))); _v_exit(1); VUNREACHABLE(); } VV_LOC void main__invoke_help_and_exit(Array_string remaining) { switch (remaining.len) { case 0: case 1: { v__help__print_and_exit(_S("default"), ((v__help__ExitOptions){.exit_code = 0,})); VUNREACHABLE(); break; } case 2: { v__help__print_and_exit((*(string*)array_get(remaining, 1)), ((v__help__ExitOptions){.exit_code = 0,})); VUNREACHABLE(); break; } default: { { break; } } } eprintln(str_intp(2, _MOV((StrIntpData[]){{_SLIT0, 0xfe10, {.d_s = term__highlight_command(_S("v help"))}}, {_S(": provide only one help topic."), 0, { .d_c = 0 }}}))); eprintln(str_intp(2, _MOV((StrIntpData[]){{_S("For usage information, use "), 0xfe10, {.d_s = term__highlight_command(_S("v help"))}}, {_S("."), 0, { .d_c = 0 }}}))); _v_exit(1); VUNREACHABLE(); } VV_LOC void main__rebuild(v__pref__Preferences* prefs) { switch (prefs->backend) { case v__pref__Backend__c: { #if defined(CUSTOM_DEFINE_no_bootstrapv) { v__util__launch_tool(prefs->is_verbose, _S("builders/c_builder"), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); } #endif v__builder__compile(_S("build"), prefs, (voidptr)v__builder__cbuilder__compile_c); break; } case v__pref__Backend__js_node: case v__pref__Backend__js_freestanding: case v__pref__Backend__js_browser: { v__util__launch_tool(prefs->is_verbose, _S("builders/js_builder"), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); break; } case v__pref__Backend__native: { v__util__launch_tool(prefs->is_verbose, _S("builders/native_builder"), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); break; } case v__pref__Backend__interpret: { v__util__launch_tool(prefs->is_verbose, _S("builders/interpret_builder"), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); break; } case v__pref__Backend__golang: { println(_S("using Go WIP backend...")); v__util__launch_tool(prefs->is_verbose, _S("builders/golang_builder"), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); break; } case v__pref__Backend__wasm: { v__util__launch_tool(prefs->is_verbose, _S("builders/wasm_builder"), array_slice(_const_os__args, 1, 2147483647)); VUNREACHABLE(); break; } } } VV_LOC void main__setup_vbuild_env_vars(v__pref__Preferences* prefs) { Array_string facts = __new_array_with_default(0, 10, sizeof(string), 0); array_push((array*)&facts, _MOV((string[]){ v__pref__OS_lower(prefs->os) })); array_push((array*)&facts, _MOV((string[]){ v__pref__CompilerType_str(prefs->ccompiler_type) })); array_push((array*)&facts, _MOV((string[]){ v__pref__Arch_str(prefs->arch) })); if (prefs->is_prod) { array_push((array*)&facts, _MOV((string[]){ _S("prod") })); } string github_job = os__getenv(_S("GITHUB_JOB")); if ((github_job).len != 0) { array_push((array*)&facts, _MOV((string[]){ string_clone(github_job) })); } v__pref__set_build_flags_and_defines(facts, prefs->compile_defines_all); string_free(&github_job); Array_string_free(&facts); } void _vinit(int ___argc, voidptr ___argv) { #if __STDC_HOSTED__ == 1 signal(11, v_segmentation_fault_handler); #endif as_cast_type_indexes = new_array_from_c_array(109, 109, sizeof(VCastTypeIndexName), _MOV((VCastTypeIndexName[109]){ (VCastTypeIndexName){.tindex = 0, .tname = _S("unknown")} , (VCastTypeIndexName){.tindex = 335, .tname = _S("v.ast.NodeError")} , (VCastTypeIndexName){.tindex = 336, .tname = _S("v.ast.AnonFn")} , (VCastTypeIndexName){.tindex = 337, .tname = _S("v.ast.ArrayDecompose")} , (VCastTypeIndexName){.tindex = 338, .tname = _S("v.ast.ArrayInit")} , (VCastTypeIndexName){.tindex = 339, .tname = _S("v.ast.AsCast")} , (VCastTypeIndexName){.tindex = 340, .tname = _S("v.ast.Assoc")} , (VCastTypeIndexName){.tindex = 341, .tname = _S("v.ast.AtExpr")} , (VCastTypeIndexName){.tindex = 342, .tname = _S("v.ast.BoolLiteral")} , (VCastTypeIndexName){.tindex = 343, .tname = _S("v.ast.CTempVar")} , (VCastTypeIndexName){.tindex = 344, .tname = _S("v.ast.CallExpr")} , (VCastTypeIndexName){.tindex = 345, .tname = _S("v.ast.CastExpr")} , (VCastTypeIndexName){.tindex = 346, .tname = _S("v.ast.ChanInit")} , (VCastTypeIndexName){.tindex = 347, .tname = _S("v.ast.CharLiteral")} , (VCastTypeIndexName){.tindex = 348, .tname = _S("v.ast.Comment")} , (VCastTypeIndexName){.tindex = 349, .tname = _S("v.ast.ComptimeCall")} , (VCastTypeIndexName){.tindex = 350, .tname = _S("v.ast.ComptimeSelector")} , (VCastTypeIndexName){.tindex = 351, .tname = _S("v.ast.ComptimeType")} , (VCastTypeIndexName){.tindex = 352, .tname = _S("v.ast.ConcatExpr")} , (VCastTypeIndexName){.tindex = 353, .tname = _S("v.ast.DumpExpr")} , (VCastTypeIndexName){.tindex = 354, .tname = _S("v.ast.EmptyExpr")} , (VCastTypeIndexName){.tindex = 355, .tname = _S("v.ast.EnumVal")} , (VCastTypeIndexName){.tindex = 356, .tname = _S("v.ast.FloatLiteral")} , (VCastTypeIndexName){.tindex = 357, .tname = _S("v.ast.GoExpr")} , (VCastTypeIndexName){.tindex = 358, .tname = _S("v.ast.Ident")} , (VCastTypeIndexName){.tindex = 359, .tname = _S("v.ast.IfExpr")} , (VCastTypeIndexName){.tindex = 360, .tname = _S("v.ast.IfGuardExpr")} , (VCastTypeIndexName){.tindex = 361, .tname = _S("v.ast.IndexExpr")} , (VCastTypeIndexName){.tindex = 362, .tname = _S("v.ast.InfixExpr")} , (VCastTypeIndexName){.tindex = 363, .tname = _S("v.ast.IntegerLiteral")} , (VCastTypeIndexName){.tindex = 364, .tname = _S("v.ast.IsRefType")} , (VCastTypeIndexName){.tindex = 365, .tname = _S("v.ast.LambdaExpr")} , (VCastTypeIndexName){.tindex = 366, .tname = _S("v.ast.Likely")} , (VCastTypeIndexName){.tindex = 367, .tname = _S("v.ast.LockExpr")} , (VCastTypeIndexName){.tindex = 368, .tname = _S("v.ast.MapInit")} , (VCastTypeIndexName){.tindex = 369, .tname = _S("v.ast.MatchExpr")} , (VCastTypeIndexName){.tindex = 370, .tname = _S("v.ast.Nil")} , (VCastTypeIndexName){.tindex = 371, .tname = _S("v.ast.None")} , (VCastTypeIndexName){.tindex = 372, .tname = _S("v.ast.OffsetOf")} , (VCastTypeIndexName){.tindex = 373, .tname = _S("v.ast.OrExpr")} , (VCastTypeIndexName){.tindex = 374, .tname = _S("v.ast.ParExpr")} , (VCastTypeIndexName){.tindex = 375, .tname = _S("v.ast.PostfixExpr")} , (VCastTypeIndexName){.tindex = 376, .tname = _S("v.ast.PrefixExpr")} , (VCastTypeIndexName){.tindex = 377, .tname = _S("v.ast.RangeExpr")} , (VCastTypeIndexName){.tindex = 378, .tname = _S("v.ast.SelectExpr")} , (VCastTypeIndexName){.tindex = 379, .tname = _S("v.ast.SelectorExpr")} , (VCastTypeIndexName){.tindex = 380, .tname = _S("v.ast.SizeOf")} , (VCastTypeIndexName){.tindex = 381, .tname = _S("v.ast.SpawnExpr")} , (VCastTypeIndexName){.tindex = 382, .tname = _S("v.ast.SqlExpr")} , (VCastTypeIndexName){.tindex = 383, .tname = _S("v.ast.StringInterLiteral")} , (VCastTypeIndexName){.tindex = 384, .tname = _S("v.ast.StringLiteral")} , (VCastTypeIndexName){.tindex = 385, .tname = _S("v.ast.StructInit")} , (VCastTypeIndexName){.tindex = 386, .tname = _S("v.ast.TypeNode")} , (VCastTypeIndexName){.tindex = 387, .tname = _S("v.ast.TypeOf")} , (VCastTypeIndexName){.tindex = 388, .tname = _S("v.ast.UnsafeExpr")} , (VCastTypeIndexName){.tindex = 557, .tname = _S("v.ast.UnknownTypeInfo")} , (VCastTypeIndexName){.tindex = 537, .tname = _S("v.ast.Aggregate")} , (VCastTypeIndexName){.tindex = 539, .tname = _S("v.ast.Alias")} , (VCastTypeIndexName){.tindex = 513, .tname = _S("v.ast.Array")} , (VCastTypeIndexName){.tindex = 549, .tname = _S("v.ast.ArrayFixed")} , (VCastTypeIndexName){.tindex = 550, .tname = _S("v.ast.Chan")} , (VCastTypeIndexName){.tindex = 548, .tname = _S("v.ast.Enum")} , (VCastTypeIndexName){.tindex = 553, .tname = _S("v.ast.FnType")} , (VCastTypeIndexName){.tindex = 555, .tname = _S("v.ast.GenericInst")} , (VCastTypeIndexName){.tindex = 542, .tname = _S("v.ast.Interface")} , (VCastTypeIndexName){.tindex = 514, .tname = _S("v.ast.Map")} , (VCastTypeIndexName){.tindex = 552, .tname = _S("v.ast.MultiReturn")} , (VCastTypeIndexName){.tindex = 518, .tname = _S("v.ast.Struct")} , (VCastTypeIndexName){.tindex = 544, .tname = _S("v.ast.SumType")} , (VCastTypeIndexName){.tindex = 551, .tname = _S("v.ast.Thread")} , (VCastTypeIndexName){.tindex = 418, .tname = _S("v.ast.EmptyScopeObject")} , (VCastTypeIndexName){.tindex = 419, .tname = _S("v.ast.AsmRegister")} , (VCastTypeIndexName){.tindex = 420, .tname = _S("v.ast.ConstField")} , (VCastTypeIndexName){.tindex = 421, .tname = _S("v.ast.GlobalField")} , (VCastTypeIndexName){.tindex = 422, .tname = _S("v.ast.Var")} , (VCastTypeIndexName){.tindex = 390, .tname = _S("v.ast.AsmStmt")} , (VCastTypeIndexName){.tindex = 391, .tname = _S("v.ast.AssertStmt")} , (VCastTypeIndexName){.tindex = 392, .tname = _S("v.ast.AssignStmt")} , (VCastTypeIndexName){.tindex = 393, .tname = _S("v.ast.Block")} , (VCastTypeIndexName){.tindex = 394, .tname = _S("v.ast.BranchStmt")} , (VCastTypeIndexName){.tindex = 395, .tname = _S("v.ast.ComptimeFor")} , (VCastTypeIndexName){.tindex = 396, .tname = _S("v.ast.ConstDecl")} , (VCastTypeIndexName){.tindex = 397, .tname = _S("v.ast.DebuggerStmt")} , (VCastTypeIndexName){.tindex = 398, .tname = _S("v.ast.DeferStmt")} , (VCastTypeIndexName){.tindex = 399, .tname = _S("v.ast.EmptyStmt")} , (VCastTypeIndexName){.tindex = 400, .tname = _S("v.ast.EnumDecl")} , (VCastTypeIndexName){.tindex = 401, .tname = _S("v.ast.ExprStmt")} , (VCastTypeIndexName){.tindex = 237, .tname = _S("v.ast.FnDecl")} , (VCastTypeIndexName){.tindex = 402, .tname = _S("v.ast.ForCStmt")} , (VCastTypeIndexName){.tindex = 403, .tname = _S("v.ast.ForInStmt")} , (VCastTypeIndexName){.tindex = 404, .tname = _S("v.ast.ForStmt")} , (VCastTypeIndexName){.tindex = 405, .tname = _S("v.ast.GlobalDecl")} , (VCastTypeIndexName){.tindex = 406, .tname = _S("v.ast.GotoLabel")} , (VCastTypeIndexName){.tindex = 407, .tname = _S("v.ast.GotoStmt")} , (VCastTypeIndexName){.tindex = 408, .tname = _S("v.ast.HashStmt")} , (VCastTypeIndexName){.tindex = 409, .tname = _S("v.ast.Import")} , (VCastTypeIndexName){.tindex = 410, .tname = _S("v.ast.InterfaceDecl")} , (VCastTypeIndexName){.tindex = 411, .tname = _S("v.ast.Module")} , (VCastTypeIndexName){.tindex = 412, .tname = _S("v.ast.Return")} , (VCastTypeIndexName){.tindex = 413, .tname = _S("v.ast.SemicolonStmt")} , (VCastTypeIndexName){.tindex = 414, .tname = _S("v.ast.SqlStmt")} , (VCastTypeIndexName){.tindex = 415, .tname = _S("v.ast.StructDecl")} , (VCastTypeIndexName){.tindex = 334, .tname = _S("v.ast.TypeDecl")} , (VCastTypeIndexName){.tindex = 476, .tname = _S("v.ast.IdentFn")} , (VCastTypeIndexName){.tindex = 477, .tname = _S("v.ast.IdentVar")} , (VCastTypeIndexName){.tindex = 496, .tname = _S("v.ast.AsmAddressing")} , (VCastTypeIndexName){.tindex = 497, .tname = _S("v.ast.AsmAlias")} , (VCastTypeIndexName){.tindex = 498, .tname = _S("v.ast.AsmDisp")} , (VCastTypeIndexName){.tindex = 21, .tname = _S("string")} })); builtin_init(); // Initializations of consts for module builtin.closure g_closure = ((builtin__closure__Closure){.ClosureMutex = ((builtin__closure__ClosureMutex){E_STRUCT}),.closure_ptr = 0,.closure_get_data = ((void*)0),.closure_cap = 0,.v_page_size = ((int)(0x4000)),}); // global 3 { { Array_u8 _t1; #if defined(__V_amd64) _t1 = new_array_from_c_array(15, 15, sizeof(u8), _MOV((u8[15]){ ((u8)(0xF3)), 0x44, 0x0F, 0x7E, 0x3D, 0xF7, 0xBF, 0xFF, 0xFF, 0xFF, 0x25, 0xF9, 0xBF, 0xFF, 0xFF})); ; #elif defined(__V_x86) _t1 = new_array_from_c_array(16, 16, sizeof(u8), _MOV((u8[16]){ ((u8)(0xe8)), 0x00, 0x00, 0x00, 0x00, 0x59, 0x66, 0x0F, 0x6E, 0xF9, 0xff, 0xA1, 0xff, 0xbf, 0xff, 0xff})); ; #elif defined(__V_arm64) _t1 = new_array_from_c_array(12, 12, sizeof(u8), _MOV((u8[12]){ ((u8)(0x11)), 0x00, 0xFE, 0x5C, 0x30, 0x00, 0xFE, 0x58, 0x00, 0x02, 0x1F, 0xD6})); ; #elif defined(__V_arm32) _t1 = new_array_from_c_array(20, 20, sizeof(u8), _MOV((u8[20]){ ((u8)(0x04)), 0xC0, 0x4F, 0xE2, 0x01, 0xC9, 0x4C, 0xE2, 0x90, 0xCA, 0x07, 0xEE, 0x00, 0xC0, 0x9C, 0xE5, 0x1C, 0xFF, 0x2F, 0xE1})); ; #elif defined(__V_rv64) _t1 = new_array_from_c_array(16, 16, sizeof(u8), _MOV((u8[16]){ ((u8)(0x97)), 0xCF, 0xFF, 0xFF, 0x03, 0xBF, 0x8F, 0x00, 0x07, 0xB3, 0x0F, 0x00, 0x67, 0x00, 0x0F, 0x00})); ; #elif defined(true) _t1 = new_array_from_c_array(16, 16, sizeof(u8), _MOV((u8[16]){ ((u8)(0x97)), 0xCF, 0xFF, 0xFF, 0x03, 0xAF, 0x4F, 0x00, 0x07, 0xAB, 0x0F, 0x00, 0x67, 0x00, 0x0F, 0x00})); ; #elif defined(__V_s390x) _t1 = new_array_from_c_array(18, 18, sizeof(u8), _MOV((u8[18]){ ((u8)(0xC0)), 0x70, 0xFF, 0xFF, 0xE0, 0x00, 0x68, 0xF0, 0x70, 0x00, 0xE3, 0x70, 0x70, 0x08, 0x00, 0x04, 0x07, 0xF7})); ; #elif defined(__V_ppc64le) _t1 = new_array_from_c_array(36, 36, sizeof(u8), _MOV((u8[36]){ ((u8)(0xa6)), 0x02, 0x08, 0x7c, 0x05, 0x00, 0x00, 0x48, 0xa6, 0x02, 0xc8, 0x7d, 0xf8, 0xbf, 0xce, 0x39, 0x00, 0x00, 0xce, 0xc9, 0x08, 0x00, 0xce, 0xe9, 0xa6, 0x03, 0x08, 0x7c, 0xa6, 0x03, 0xc9, 0x7d, 0x20, 0x04, 0x80, 0x4e})); ; #elif defined(__V_loongarch64) _t1 = new_array_from_c_array(16, 16, sizeof(u8), _MOV((u8[16]){ ((u8)(0x92)), 0xFF, 0xFF, 0x1D, 0x48, 0x02, 0x80, 0x2B, 0x51, 0x22, 0xC0, 0x28, 0x20, 0x02, 0x00, 0x4C})); ; #else _t1 = __new_array_with_default(0, 0, sizeof(u8), 0); ; #endif _const_builtin__closure__closure_thunk = _t1; } } { { Array_u8 _t2; #if defined(__V_amd64) _t2 = new_array_from_c_array(6, 6, sizeof(u8), _MOV((u8[6]){((u8)(0x66)), 0x4C, 0x0F, 0x7E, 0xF8, 0xC3})); ; #elif defined(__V_x86) _t2 = new_array_from_c_array(11, 11, sizeof(u8), _MOV((u8[11]){ ((u8)(0x66)), 0x0F, 0x7E, 0xF8, 0x8B, 0x80, 0xFB, 0xBF, 0xFF, 0xFF, 0xc3})); ; #elif defined(__V_arm64) _t2 = new_array_from_c_array(8, 8, sizeof(u8), _MOV((u8[8]){((u8)(0x20)), 0x02, 0x66, 0x9E, 0xC0, 0x03, 0x5F, 0xD6})); ; #elif defined(__V_arm32) _t2 = new_array_from_c_array(12, 12, sizeof(u8), _MOV((u8[12]){ ((u8)(0x90)), 0x0A, 0x17, 0xEE, 0x04, 0x00, 0x10, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1})); ; #elif defined(__V_rv64) _t2 = new_array_from_c_array(8, 8, sizeof(u8), _MOV((u8[8]){((u8)(0x53)), 0x05, 0x03, 0xE2, 0x67, 0x80, 0x00, 0x00})); ; #elif defined(true) _t2 = new_array_from_c_array(8, 8, sizeof(u8), _MOV((u8[8]){((u8)(0x53)), 0x05, 0x0B, 0xE0, 0x67, 0x80, 0x00, 0x00})); ; #elif defined(__V_s390x) _t2 = new_array_from_c_array(6, 6, sizeof(u8), _MOV((u8[6]){((u8)(0xB3)), 0xCD, 0x00, 0x2F, 0x07, 0xFE})); ; #elif defined(__V_ppc64le) _t2 = new_array_from_c_array(8, 8, sizeof(u8), _MOV((u8[8]){((u8)(0x66)), 0x00, 0xc3, 0x7d, 0x20, 0x00, 0x80, 0x4e})); ; #elif defined(__V_loongarch64) _t2 = new_array_from_c_array(8, 8, sizeof(u8), _MOV((u8[8]){((u8)(0x04)), 0xB9, 0x14, 0x01, 0x20, 0x00, 0x00, 0x4C})); ; #else _t2 = __new_array_with_default(0, 0, sizeof(u8), 0); ; #endif _const_builtin__closure__closure_get_data_bytes = _t2; } } { { _const_builtin__closure__closure_size_1 = ((u32)(2 * ((u32)(sizeof(voidptr)))) > ((u32)(_const_builtin__closure__closure_thunk.len)) ? ((u32)(2 * ((u32)(sizeof(voidptr))))) : ((u32)((u32)(((u32)(_const_builtin__closure__closure_thunk.len)) + ((u32)(sizeof(voidptr)))) - 1U))); } } _const_builtin__closure__closure_size = ((int)((_const_builtin__closure__closure_size_1 & ~((u32)(((u32)(sizeof(voidptr))) - 1U))))); // Initializations of consts for module strconv _const_strconv__digit_pairs = _S("00102030405060708090011121314151617181910212223242526272829203132333435363738393041424344454647484940515253545556575859506162636465666768696071727374757677787970818283848586878889809192939495969798999"); _const_strconv__base_digits = _S("0123456789abcdefghijklmnopqrstuvwxyz"); // Initializations of consts for module builtin _const_digit_pairs = _S("00102030405060708090011121314151617181910212223242526272829203132333435363738393041424344454647484940515253545556575859506162636465666768696071727374757677787970818283848586878889809192939495969798999"); _const_si_s_code = _S("0xfe10"); _const_si_g32_code = _S("0xfe0e"); _const_si_g64_code = _S("0xfe0f"); g_live_reload_info = *(voidptr*)&((voidptr[]){0}[0]); // global 5 _const_min_i64 = ((i64)((int_literal)(-9223372036854775807 - 1))); _const_max_i64 = ((i64)(9223372036854775807)); _const_none__ = I_None___to_Interface_IError(((None__*)memdup(&(None__){.Error = ((Error){E_STRUCT}),}, sizeof(None__)))); // Initializations of consts for module time _const_time__months_string = _S("JanFebMarAprMayJunJulAugSepOctNovDec"); _const_time__nanosecond = ((time__Duration)(1)); _const_time__infinite = ((((i64)(9223372036854775807)))); _const_time__microsecond = ((1000 * _const_time__nanosecond)); _const_time__millisecond = ((1000 * _const_time__microsecond)); _const_time__second = ((1000 * _const_time__millisecond)); _const_time__minute = ((60 * _const_time__second)); _const_time__hour = ((60 * _const_time__minute)); // Initializations of consts for module v.token _const_v__token__orm_custom_operators = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("like"), _S("ilike")})); { _const_v__token__assign_tokens = new_array_from_c_array(15, 15, sizeof(v__token__Kind), _MOV((v__token__Kind[15]){ v__token__Kind__assign, v__token__Kind__decl_assign, v__token__Kind__plus_assign, v__token__Kind__minus_assign, v__token__Kind__mult_assign, v__token__Kind__div_assign, v__token__Kind__xor_assign, v__token__Kind__mod_assign, v__token__Kind__or_assign, v__token__Kind__and_assign, v__token__Kind__right_shift_assign, v__token__Kind__left_shift_assign, v__token__Kind__unsigned_right_shift_assign, v__token__Kind__boolean_and_assign, v__token__Kind__boolean_or_assign})); } { _const_v__token__valid_at_tokens = new_array_from_c_array(21, 21, sizeof(string), _MOV((string[21]){ _S("@VROOT"), _S("@VMODROOT"), _S("@VEXEROOT"), _S("@FN"), _S("@METHOD"), _S("@MOD"), _S("@STRUCT"), _S("@VEXE"), _S("@FILE"), _S("@DIR"), _S("@LINE"), _S("@COLUMN"), _S("@VHASH"), _S("@VCURRENTHASH"), _S("@VMOD_FILE"), _S("@VMODHASH"), _S("@FILE_LINE"), _S("@LOCATION"), _S("@BUILD_DATE"), _S("@BUILD_TIME"), _S("@BUILD_TIMESTAMP")})); } _const_v__token__token_str = v__token__build_token_str(); _const_v__token__precedences = v__token__build_precedences(); _const_v__token__keywords = v__token__build_keys(); _const_v__token__scanner_matcher = v__token__new_keywords_matcher_trie_T_v__token__Kind(_const_v__token__keywords); // Initializations of consts for module flag _const_flag__space = _S(" "); _const_flag__underline = _S("-----------------------------------------------"); // Initializations of consts for module os _const_os__fslash_str = _S("/"); _const_os__dot_dot = _S(".."); _const_os__empty_str = _S(""); _const_os__dot_str = _S("."); _const_os__path_separator = _S("/"); _const_os__path_delimiter = _S(":"); _const_os__wd_at_startup = os__getwd(); _const_os__executable_suffixes = new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("")})); _const_os__args = arguments(); // Initializations of consts for module term can_show_color_on_stdout_cache = (_option_bool){ .state=2, .err=_const_none__, .data={E_STRUCT} }; // global 3 can_show_color_on_stderr_cache = (_option_bool){ .state=2, .err=_const_none__, .data={E_STRUCT} }; // global 3 // Initializations of consts for module v.help _const_v__help__cli_topics = new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_S("new"), _S("init"), _S("repeat")})); // Initializations of consts for module v.util.version _const_v__util__version__v_version = _S("0.4.11"); // Initializations of consts for module v.vmod _const_v__vmod__mod_file_stop_paths = new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S(".git"), _S(".hg"), _S(".svn"), _S(".v.mod.stop")})); _const_v__vmod__private_file_cacher = v__vmod__new_mod_file_cacher(); // Initializations of consts for module v.cflag _const_v__cflag__fexisting_literal = _S("$first_existing"); _const_v__cflag__wexisting_literal = _S("$when_first_existing"); // Initializations of consts for module v.pkgconfig _const_v__pkgconfig__version = _S("0.3.4"); { _const_v__pkgconfig__default_paths = new_array_from_c_array(18, 18, sizeof(string), _MOV((string[18]){ _S("/usr/local/lib/x86_64-linux-gnu/pkgconfig"), _S("/usr/local/lib64/pkgconfig"), _S("/usr/local/lib/pkgconfig"), _S("/usr/local/share/pkgconfig"), _S("/usr/lib/x86_64-linux-gnu/pkgconfig"), _S("/usr/lib/aarch64-linux-gnu/pkgconfig"), _S("/usr/lib64/pkgconfig"), _S("/usr/lib/pkgconfig"), _S("/usr/share/pkgconfig"), _S("/opt/homebrew/lib/pkgconfig"), _S("/opt/homebrew/share/pkgconfig"), _S("/opt/homebrew/Library/Homebrew/os/mac/pkgconfig/11"), _S("/opt/local/lib/pkgconfig"), _S("/usr/local/libdata/pkgconfig"), _S("/usr/libdata/pkgconfig"), _S("/usr/lib/i386-linux-gnu/pkgconfig"), _S("/data/data/com.termux/files/usr/lib/pkgconfig"), _S("/usr/pkg/lib/pkgconfig")})); } // Initializations of consts for module rand _const_rand__ulid_encoding = _S("0123456789ABCDEFGHJKMNPQRSTVWXYZ"); default_rng = *(rand__PRNG**)&((rand__PRNG*[]){0}[0]); // global 5 // Calling fn init() for module rand rand__init(); // Initializations of consts for module v.pref _const_v__pref__supported_test_runners = new_array_from_c_array(5, 5, sizeof(string), _MOV((string[5]){_S("normal"), _S("simple"), _S("tap"), _S("dump"), _S("teamcity")})); _const_v__pref__default_module_path = os__vmodules_dir(); // Initializations of consts for module v.util _const_v__util__d_sig = _S("$d('"); _const_v__util__double_escape = _S("\\\\"); _const_v__util__map_prefix = _S("map[string]"); _const_v__util__verror_paths_absolute = string__eq(os__getenv(_S("VERROR_PATHS")), _S("absolute")); lines_cache = ((v__util__LinesCache*)memdup(&(v__util__LinesCache){.lines = new_map(sizeof(string), sizeof(Array_string), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string),}, sizeof(v__util__LinesCache))); // global 3 _const_v__util__invalid_escapes = string_bytes(_S("({$`.")); memcpy(&_const_v__util__name_char_table, v__util__get_name_char_table().ret_arr, sizeof(Array_fixed_bool_256)); memcpy(&_const_v__util__func_char_table, v__util__get_func_char_table().ret_arr, sizeof(Array_fixed_bool_256)); memcpy(&_const_v__util__non_whitespace_table, v__util__get_non_white_space_table().ret_arr, sizeof(Array_fixed_bool_256)); g_timers = v__util__new_timers(((v__util__TimerParams){.should_print = false,.label = _S("g_timers"),})); // global 3 _const_v__util__builtin_module_parts = new_array_from_c_array(7, 7, sizeof(string), _MOV((string[7]){_S("math.bits"), _S("strconv"), _S("dlmalloc"), _S("strconv.ftoa"), _S("strings"), _S("builtin"), _S("builtin.closure")})); { { _const_v__util__external_module_dependencies_for_tool = new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 1, sizeof(string), sizeof(Array_string), _MOV((string[1]){ _S("vdoc"), }), _MOV((Array_string[1]){ new_array_from_c_array(1, 1, sizeof(string), _MOV((string[1]){_S("markdown")})), }) ) ; } } _const_v__util__nr_jobs = runtime__nr_jobs(); _const_v__util__emanager = v__util__new_error_manager(); _const_v__util__normalised_workdir = string__plus(string_replace(_const_os__wd_at_startup, _S("\\"), _S("/")), _S("/")); _const_v__util__stable_build_time = v__util__get_build_time(); // Initializations of consts for module v.ast _const_v__ast__result_name = _S("_result"); _const_v__ast__option_name = _S("_option"); _const_v__ast__int_type_name = _S("int"); { _const_v__ast__global_reserved_type_names = new_array_from_c_array(21, 21, sizeof(string), _MOV((string[21]){ _S("byte"), _S("bool"), _S("char"), _S("i8"), _S("i16"), _S("int"), _S("i64"), _S("u8"), _S("u16"), _S("u32"), _S("u64"), _S("f32"), _S("f64"), _S("map"), _S("string"), _S("rune"), _S("usize"), _S("isize"), _S("voidptr"), _S("thread"), _S("array")})); } _const_v__ast__empty_expr = v__ast__EmptyExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__EmptyExpr, (((v__ast__EmptyExpr)(0))))); _const_v__ast__empty_stmt = v__ast__EmptyStmt_to_sumtype_v__ast__Stmt(ADDR(v__ast__EmptyStmt, (((v__ast__EmptyStmt){.pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}),})))); _const_v__ast__empty_scope_object = v__ast__EmptyScopeObject_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__EmptyScopeObject, (((v__ast__EmptyScopeObject){.name = _S("empty_scope_object"),.typ = 0,})))); _const_v__ast__empty_comptime_const_value = v__ast__EmptyExpr_to_sumtype_v__ast__ComptTimeConstValue(ADDR(v__ast__EmptyExpr, (((v__ast__EmptyExpr)(0))))); { { _const_v__ast__x86_no_number_register_list = new_map_init(&map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop, 4, sizeof(int), sizeof(Array_string), _MOV((int[4]){ 8, 16, 32, 64, }), _MOV((Array_string[4]){ new_array_from_c_array(12, 12, sizeof(string), _MOV((string[12]){ _S("al"), _S("ah"), _S("bl"), _S("bh"), _S("cl"), _S("ch"), _S("dl"), _S("dh"), _S("bpl"), _S("sil"), _S("dil"), _S("spl")})), new_array_from_c_array(22, 22, sizeof(string), _MOV((string[22]){ _S("ax"), _S("bx"), _S("cx"), _S("dx"), _S("bp"), _S("si"), _S("di"), _S("sp"), _S("cs"), _S("ss"), _S("ds"), _S("es"), _S("fs"), _S("gs"), _S("flags"), _S("ip"), _S("gdtr"), _S("idtr"), _S("tr"), _S("ldtr"), _S("fp_ds"), _S("fp_opc")})), new_array_from_c_array(11, 11, sizeof(string), _MOV((string[11]){ _S("eax"), _S("ebx"), _S("ecx"), _S("edx"), _S("ebp"), _S("esi"), _S("edi"), _S("esp"), _S("eflags"), _S("eip"), _S("mxcsr")})), new_array_from_c_array(10, 10, sizeof(string), _MOV((string[10]){ _S("rax"), _S("rbx"), _S("rcx"), _S("rdx"), _S("rbp"), _S("rsi"), _S("rdi"), _S("rsp"), _S("rflags"), _S("rip")})), }) ) ; } } { { _const_v__ast__x86_with_number_register_list = new_map_init(&map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop, 8, sizeof(int), sizeof(Map_string_int), _MOV((int[8]){ 8, 16, 32, 64, 80, 128, 256, 512, }), _MOV((Map_string_int[8]){ new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 1, sizeof(string), sizeof(int), _MOV((string[1]){ _S("r#b"), }), _MOV((int[1]){ 16, }) ) , new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 1, sizeof(string), sizeof(int), _MOV((string[1]){ _S("r#w"), }), _MOV((int[1]){ 16, }) ) , new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 1, sizeof(string), sizeof(int), _MOV((string[1]){ _S("r#d"), }), _MOV((int[1]){ 16, }) ) , new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 4, sizeof(string), sizeof(int), _MOV((string[4]){ _S("r#"), _S("mm#"), _S("cr#"), _S("dr#"), }), _MOV((int[4]){ 16, 16, 16, 16, }) ) , new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 1, sizeof(string), sizeof(int), _MOV((string[1]){ _S("st#"), }), _MOV((int[1]){ 16, }) ) , new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 1, sizeof(string), sizeof(int), _MOV((string[1]){ _S("xmm#"), }), _MOV((int[1]){ 32, }) ) , new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 1, sizeof(string), sizeof(int), _MOV((string[1]){ _S("ymm#"), }), _MOV((int[1]){ 32, }) ) , new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 1, sizeof(string), sizeof(int), _MOV((string[1]){ _S("zmm#"), }), _MOV((int[1]){ 32, }) ) , }) ) ; } } _const_v__ast__arm_no_number_register_list = new_array_from_c_array(5, 5, sizeof(string), _MOV((string[5]){_S("fp"), _S("ip"), _S("sp"), _S("lr"), _S("pc")})); { { _const_v__ast__arm_with_number_register_list = new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 1, sizeof(string), sizeof(int), _MOV((string[1]){ _S("r#"), }), _MOV((int[1]){ 16, }) ) ; } } _const_v__ast__riscv_no_number_register_list = new_array_from_c_array(5, 5, sizeof(string), _MOV((string[5]){_S("zero"), _S("ra"), _S("sp"), _S("gp"), _S("tp")})); { { _const_v__ast__riscv_with_number_register_list = new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 4, sizeof(string), sizeof(int), _MOV((string[4]){ _S("x#"), _S("t#"), _S("s#"), _S("a#"), }), _MOV((int[4]){ 32, 3, 12, 8, }) ) ; } } _const_v__ast__s390x_no_number_register_list = __new_array_with_default(0, 0, sizeof(string), 0); { { _const_v__ast__s390x_with_number_register_list = new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 3, sizeof(string), sizeof(int), _MOV((string[3]){ _S("f#"), _S("r#"), _S("v#"), }), _MOV((int[3]){ 16, 16, 32, }) ) ; } } _const_v__ast__ppc64le_no_number_register_list = __new_array_with_default(0, 0, sizeof(string), 0); { { _const_v__ast__ppc64le_with_number_register_list = new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 2, sizeof(string), sizeof(int), _MOV((string[2]){ _S("f#"), _S("r#"), }), _MOV((int[2]){ 32, 32, }) ) ; } } _const_v__ast__loongarch64_no_number_register_list = __new_array_with_default(0, 0, sizeof(string), 0); { { _const_v__ast__loongarch64_with_number_register_list = new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, 2, sizeof(string), sizeof(int), _MOV((string[2]){ _S("f#"), _S("r#"), }), _MOV((int[2]){ 32, 32, }) ) ; } } { _const_v__ast__valid_comptime_if_os = new_array_from_c_array(22, 22, sizeof(string), _MOV((string[22]){ _S("windows"), _S("ios"), _S("macos"), _S("mach"), _S("darwin"), _S("hpux"), _S("gnu"), _S("qnx"), _S("linux"), _S("freebsd"), _S("openbsd"), _S("netbsd"), _S("bsd"), _S("dragonfly"), _S("android"), _S("termux"), _S("solaris"), _S("haiku"), _S("serenity"), _S("vinix"), _S("plan9"), _S("wasm32_emscripten")})); } _const_v__ast__valid_comptime_if_compilers = new_array_from_c_array(6, 6, sizeof(string), _MOV((string[6]){_S("gcc"), _S("tinyc"), _S("clang"), _S("mingw"), _S("msvc"), _S("cplusplus")})); { _const_v__ast__valid_comptime_if_platforms = new_array_from_c_array(10, 10, sizeof(string), _MOV((string[10]){ _S("amd64"), _S("i386"), _S("aarch64"), _S("arm64"), _S("arm32"), _S("rv64"), _S("rv32"), _S("s390x"), _S("ppc64le"), _S("loongarch64")})); } _const_v__ast__valid_comptime_if_cpu_features = new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S("x64"), _S("x32"), _S("little_endian"), _S("big_endian")})); { _const_v__ast__valid_comptime_if_other = new_array_from_c_array(21, 21, sizeof(string), _MOV((string[21]){ _S("apk"), _S("js"), _S("debug"), _S("prod"), _S("test"), _S("glibc"), _S("prealloc"), _S("no_bounds_checking"), _S("freestanding"), _S("threads"), _S("js_node"), _S("js_browser"), _S("js_freestanding"), _S("interpreter"), _S("es5"), _S("profile"), _S("wasm32"), _S("wasm32_wasi"), _S("fast_math"), _S("native"), _S("autofree")})); } _const_v__ast__valid_comptime_compression_types = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("none"), _S("zlib")})); _const_v__ast__native_builtins = new_array_from_c_array(7, 7, sizeof(string), _MOV((string[7]){_S("assert"), _S("print"), _S("eprint"), _S("println"), _S("eprintln"), _S("exit"), _S("C.syscall")})); _const_v__ast__fn_type_escape_seq = new_array_from_c_array(6, 6, sizeof(string), _MOV((string[6]){_S(" "), _S(""), _S("("), _S("_"), _S(")"), _S("")})); _const_v__ast__map_cname_escape_seq = new_array_from_c_array(6, 6, sizeof(string), _MOV((string[6]){_S("["), _S("_T_"), _S(", "), _S("_"), _S("]"), _S("")})); global_table = ((v__ast__Table*)(((void*)0))); // global 3 { _const_v__ast__builtin_type_names = new_array_from_c_array(31, 31, sizeof(string), _MOV((string[31]){ _S("void"), _S("voidptr"), _S("byteptr"), _S("charptr"), _S("i8"), _S("i16"), _S("int"), _S("i64"), _S("isize"), _S("u8"), _S("u16"), _S("u32"), _S("u64"), _S("usize"), _S("f32"), _S("f64"), _S("char"), _S("bool"), _S("none"), _S("string"), _S("rune"), _S("array"), _S("map"), _S("chan"), _S("any"), _S("float_literal"), _S("int_literal"), _S("thread"), _S("Error"), _S("nil"), _S("i32")})); } _const_v__ast__builtins = new_array_from_c_array(8, 8, sizeof(string), _MOV((string[8]){_S("string"), _S("array"), _S("DenseArray"), _S("map"), _S("Error"), _S("IError"), string_clone(_const_v__ast__option_name), string_clone(_const_v__ast__result_name)})); _const_v__ast__valid_comptime_not_user_defined = v__ast__all_valid_comptime_idents(); { { _const_v__ast__invalid_type_symbol = ((v__ast__TypeSymbol*)memdup(&(v__ast__TypeSymbol){.parent_idx = _const_v__ast__invalid_type_idx, .info = (v__ast__TypeInfo){._v__ast__UnknownTypeInfo=HEAP(v__ast__UnknownTypeInfo, ((v__ast__UnknownTypeInfo){E_STRUCT})),._typ=557}, .kind = v__ast__Kind__placeholder, .name = _S("InvalidType"), .cname = _S("InvalidType"), .rname = (string){.str=(byteptr)"", .is_lit=1}, .methods = __new_array(0, 0, sizeof(v__ast__Fn)), .generic_types = __new_array(0, 0, sizeof(v__ast__Type)), .mod = _S("builtin"), .is_pub = 0, .is_builtin = false, .language = v__ast__Language__v, .idx = _const_v__ast__invalid_type_idx, .size = -1, .align = -1, }, sizeof(v__ast__TypeSymbol))); } } _const_v__ast__builtin_type_names_matcher = v__token__new_keywords_matcher_from_array_trie(_const_v__ast__builtin_type_names); { _const_v__ast__integer_type_idxs = new_array_from_c_array(13, 13, sizeof(int), _MOV((int[13]){ _const_v__ast__i8_type_idx, _const_v__ast__i16_type_idx, _const_v__ast__int_type_idx, _const_v__ast__i64_type_idx, _const_v__ast__u8_type_idx, _const_v__ast__u16_type_idx, _const_v__ast__u32_type_idx, _const_v__ast__u64_type_idx, _const_v__ast__isize_type_idx, _const_v__ast__usize_type_idx, _const_v__ast__int_literal_type_idx, _const_v__ast__rune_type_idx, _const_v__ast__i32_type_idx})); } _const_v__ast__signed_integer_type_idxs = new_array_from_c_array(7, 7, sizeof(int), _MOV((int[7]){_const_v__ast__char_type_idx, _const_v__ast__i8_type_idx, _const_v__ast__i16_type_idx, _const_v__ast__int_type_idx, _const_v__ast__i64_type_idx, _const_v__ast__i32_type_idx, _const_v__ast__isize_type_idx})); _const_v__ast__unsigned_integer_type_idxs = new_array_from_c_array(5, 5, sizeof(int), _MOV((int[5]){_const_v__ast__u8_type_idx, _const_v__ast__u16_type_idx, _const_v__ast__u32_type_idx, _const_v__ast__u64_type_idx, _const_v__ast__usize_type_idx})); _const_v__ast__int_promoted_type_idxs = new_array_from_c_array(5, 5, sizeof(int), _MOV((int[5]){_const_v__ast__char_type_idx, _const_v__ast__i8_type_idx, _const_v__ast__i16_type_idx, _const_v__ast__u8_type_idx, _const_v__ast__u16_type_idx})); _const_v__ast__float_type_idxs = new_array_from_c_array(3, 3, sizeof(int), _MOV((int[3]){_const_v__ast__f32_type_idx, _const_v__ast__f64_type_idx, _const_v__ast__float_literal_type_idx})); { _const_v__ast__number_type_idxs = new_array_from_c_array(17, 17, sizeof(int), _MOV((int[17]){ _const_v__ast__i8_type_idx, _const_v__ast__i16_type_idx, _const_v__ast__int_type_idx, _const_v__ast__i32_type_idx, _const_v__ast__i64_type_idx, _const_v__ast__u8_type_idx, _const_v__ast__char_type_idx, _const_v__ast__u16_type_idx, _const_v__ast__u32_type_idx, _const_v__ast__u64_type_idx, _const_v__ast__isize_type_idx, _const_v__ast__usize_type_idx, _const_v__ast__f32_type_idx, _const_v__ast__f64_type_idx, _const_v__ast__int_literal_type_idx, _const_v__ast__float_literal_type_idx, _const_v__ast__rune_type_idx})); } _const_v__ast__pointer_type_idxs = new_array_from_c_array(4, 4, sizeof(int), _MOV((int[4]){_const_v__ast__voidptr_type_idx, _const_v__ast__byteptr_type_idx, _const_v__ast__charptr_type_idx, _const_v__ast__nil_type_idx})); _const_v__ast__invalid_type = v__ast__idx_to_type(_const_v__ast__invalid_type_idx); _const_v__ast__no_type = v__ast__idx_to_type(_const_v__ast__no_type_idx); _const_v__ast__void_type = v__ast__new_type(_const_v__ast__void_type_idx); _const_v__ast__ovoid_type = v__ast__Type_set_flag(v__ast__new_type(_const_v__ast__void_type_idx), v__ast__TypeFlag__option); _const_v__ast__rvoid_type = v__ast__Type_set_flag(v__ast__new_type(_const_v__ast__void_type_idx), v__ast__TypeFlag__result); _const_v__ast__voidptr_type = v__ast__new_type(_const_v__ast__voidptr_type_idx); _const_v__ast__byteptr_type = v__ast__new_type(_const_v__ast__byteptr_type_idx); _const_v__ast__charptr_type = v__ast__new_type(_const_v__ast__charptr_type_idx); _const_v__ast__i8_type = v__ast__new_type(_const_v__ast__i8_type_idx); _const_v__ast__i16_type = v__ast__new_type(_const_v__ast__i16_type_idx); _const_v__ast__i32_type = v__ast__new_type(_const_v__ast__i32_type_idx); _const_v__ast__int_type = v__ast__new_type(_const_v__ast__int_type_idx); _const_v__ast__i64_type = v__ast__new_type(_const_v__ast__i64_type_idx); _const_v__ast__isize_type = v__ast__new_type(_const_v__ast__isize_type_idx); _const_v__ast__u8_type = v__ast__new_type(_const_v__ast__u8_type_idx); _const_v__ast__u16_type = v__ast__new_type(_const_v__ast__u16_type_idx); _const_v__ast__u32_type = v__ast__new_type(_const_v__ast__u32_type_idx); _const_v__ast__u64_type = v__ast__new_type(_const_v__ast__u64_type_idx); _const_v__ast__usize_type = v__ast__new_type(_const_v__ast__usize_type_idx); _const_v__ast__f32_type = v__ast__new_type(_const_v__ast__f32_type_idx); _const_v__ast__f64_type = v__ast__new_type(_const_v__ast__f64_type_idx); _const_v__ast__char_type = v__ast__new_type(_const_v__ast__char_type_idx); _const_v__ast__bool_type = v__ast__new_type(_const_v__ast__bool_type_idx); _const_v__ast__none_type = v__ast__new_type(_const_v__ast__none_type_idx); _const_v__ast__string_type = v__ast__new_type(_const_v__ast__string_type_idx); _const_v__ast__rune_type = v__ast__new_type(_const_v__ast__rune_type_idx); _const_v__ast__array_type = v__ast__new_type(_const_v__ast__array_type_idx); _const_v__ast__map_type = v__ast__new_type(_const_v__ast__map_type_idx); _const_v__ast__chan_type = v__ast__new_type(_const_v__ast__chan_type_idx); _const_v__ast__any_type = v__ast__new_type(_const_v__ast__any_type_idx); _const_v__ast__float_literal_type = v__ast__new_type(_const_v__ast__float_literal_type_idx); _const_v__ast__int_literal_type = v__ast__new_type(_const_v__ast__int_literal_type_idx); _const_v__ast__thread_type = v__ast__new_type(_const_v__ast__thread_type_idx); _const_v__ast__error_type = v__ast__new_type(_const_v__ast__error_type_idx); _const_v__ast__nil_type = v__ast__new_type(_const_v__ast__nil_type_idx); _const_v__ast__charptr_types = v__ast__new_charptr_types(); _const_v__ast__byteptr_types = v__ast__new_byteptr_types(); _const_v__ast__voidptr_types = v__ast__new_voidptr_types(); _const_v__ast__cptr_types = v__ast__merge_types(new_array_from_c_array(3, 3, sizeof(Array_v__ast__Type), _MOV((Array_v__ast__Type[3]){_const_v__ast__voidptr_types, _const_v__ast__byteptr_types, _const_v__ast__charptr_types}))); // Initializations of consts for module v.scanner _const_v__scanner__internally_generated_v_code = _S("internally_generated_v_code"); // Initializations of consts for module v.checker _const_v__checker__unicode_lit_overflow_message = _S("unicode character exceeds max allowed value of 0x10ffff, consider using a unicode literal (\\u####)"); { _const_v__checker__array_builtin_methods = new_array_from_c_array(22, 22, sizeof(string), _MOV((string[22]){ _S("filter"), _S("clone"), _S("repeat"), _S("reverse"), _S("map"), _S("slice"), _S("sort"), _S("sort_with_compare"), _S("sorted"), _S("sorted_with_compare"), _S("contains"), _S("index"), _S("wait"), _S("any"), _S("all"), _S("first"), _S("last"), _S("pop"), _S("delete"), _S("insert"), _S("prepend"), _S("count")})); } { _const_v__checker__fixed_array_builtin_methods = new_array_from_c_array(13, 13, sizeof(string), _MOV((string[13]){ _S("contains"), _S("index"), _S("any"), _S("all"), _S("wait"), _S("map"), _S("sort"), _S("sorted"), _S("sort_with_compare"), _S("sorted_with_compare"), _S("reverse"), _S("reverse_in_place"), _S("count")})); } { _const_v__checker__reserved_type_names = new_array_from_c_array(19, 19, sizeof(string), _MOV((string[19]){ _S("bool"), _S("char"), _S("i8"), _S("i16"), _S("int"), _S("i64"), _S("u8"), _S("u16"), _S("u32"), _S("u64"), _S("f32"), _S("f64"), _S("map"), _S("string"), _S("rune"), _S("usize"), _S("isize"), _S("voidptr"), _S("thread")})); } _const_v__checker__print_everything_fns = new_array_from_c_array(5, 5, sizeof(string), _MOV((string[5]){_S("println"), _S("print"), _S("eprintln"), _S("eprint"), _S("panic")})); { { _const_v__checker__iencoding_map = new_map_init(&map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop, 4, sizeof(rune), sizeof(v__checker__LoHiLimit), _MOV((rune[4]){ 'B', 'O', '_', 'X', }), _MOV((v__checker__LoHiLimit[4]){ ((v__checker__LoHiLimit){.lower = _S("1000000000000000000000000000000000000000000000000000000000000000"),.higher = _S("1111111111111111111111111111111111111111111111111111111111111111"),}), ((v__checker__LoHiLimit){.lower = _S("1000000000000000000000"),.higher = _S("1777777777777777777777"),}), ((v__checker__LoHiLimit){.lower = _S("9223372036854775808"),.higher = _S("18446744073709551615"),}), ((v__checker__LoHiLimit){.lower = _S("8000000000000000"),.higher = _S("FFFFFFFFFFFFFFFF"),}), }) ) ; } } _const_v__checker__array_builtin_methods_chk = v__token__new_keywords_matcher_from_array_trie(_const_v__checker__array_builtin_methods); _const_v__checker__fixed_array_builtin_methods_chk = v__token__new_keywords_matcher_from_array_trie(_const_v__checker__fixed_array_builtin_methods); _const_v__checker__reserved_type_names_chk = v__token__new_keywords_matcher_from_array_trie(_const_v__checker__reserved_type_names); _const_v__checker__err_ref_uninitialized = _v_error(_S("arrays of references need to be initialized right away")); _const_v__checker__err_interface_uninitialized = _v_error(_S("arrays of interfaces need to be initialized right away")); _const_v__checker__err_sumtype_uninitialized = _v_error(_S("arrays of sumtypes need to be initialized right away")); // Initializations of consts for module v.parser _const_v__parser__error_msg = _S("only `$tmpl()`, `$env()`, `$embed_file()`, `$pkgconfig()`, `$vweb.html()`, `$compile_error()`, `$compile_warn()`, `$d()` and `$res()` comptime functions are supported right now"); _const_v__parser__tmpl_str_end = _S("')\n"); { _const_v__parser__allowed_lock_prefix_ins = new_array_from_c_array(19, 19, sizeof(string), _MOV((string[19]){ _S("add"), _S("adc"), _S("and"), _S("btc"), _S("btr"), _S("bts"), _S("cmpxchg"), _S("cmpxchg8b"), _S("cmpxchg16b"), _S("dec"), _S("inc"), _S("neg"), _S("not"), _S("or"), _S("sbb"), _S("sub"), _S("xor"), _S("xadd"), _S("xchg")})); } _const_v__parser__valid_tokens_inside_types = new_array_from_c_array(7, 7, sizeof(v__token__Kind), _MOV((v__token__Kind[7]){v__token__Kind__lsbr, v__token__Kind__rsbr, v__token__Kind__name, v__token__Kind__dot, v__token__Kind__comma, v__token__Kind__key_fn, v__token__Kind__lt})); codegen_files = __new_array_with_default(0, 0, sizeof(v__ast__File*), 0); // global 3 _const_v__parser__supported_comptime_calls = new_array_from_c_array(9, 9, sizeof(string), _MOV((string[9]){ _S("html"), _S("tmpl"), _S("env"), _S("embed_file"), _S("pkgconfig"), _S("compile_error"), _S("compile_warn"), _S("d"), _S("res")})); { _const_v__parser__comptime_types = new_array_from_c_array(16, 16, sizeof(string), _MOV((string[16]){ _S("map"), _S("array"), _S("array_dynamic"), _S("array_fixed"), _S("int"), _S("float"), _S("struct"), _S("interface"), _S("enum"), _S("sumtype"), _S("alias"), _S("function"), _S("option"), _S("string"), _S("pointer"), _S("voidptr")})); } _const_v__parser__normalised_working_folder = string_replace((string__plus(os__real_path(os__getwd()), _S("/"))), _S("\\"), _S("/")); // Initializations of consts for module v.gen.c _const_v__gen__c__si_s_code = _S("0xfe10"); _const_v__gen__c__result_name = _S("_result"); _const_v__gen__c__option_name = _S("_option"); _const_v__gen__c__c_commit_hash_default = _S("\n#ifndef V_COMMIT_HASH\n\011#define V_COMMIT_HASH \"@@@\"\n#endif\n"); _const_v__gen__c__c_concurrency_helpers = _S("\ntypedef struct __shared_map __shared_map;\nstruct __shared_map {\n\011sync__RwMutex mtx;\n\011map val;\n};\nstatic inline voidptr __dup_shared_map(voidptr src, int sz) {\n\011__shared_map* dest = memdup(src, sz);\n\011sync__RwMutex_init(&dest->mtx);\n\011return dest;\n}\ntypedef struct __shared_array __shared_array;\nstruct __shared_array {\n\011sync__RwMutex mtx;\n\011array val;\n};\nstatic inline voidptr __dup_shared_array(voidptr src, int sz) {\n\011__shared_array* dest = memdup(src, sz);\n\011sync__RwMutex_init(&dest->mtx);\n\011return dest;\n}\nstatic inline void __sort_ptr(uintptr_t a[], bool b[], int l) {\n\011for (int i=1; i0 && a[j-1] > ins) {\n\011\011\011a[j] = a[j-1];\n\011\011\011b[j] = b[j-1];\n\011\011\011j--;\n\011\011}\n\011\011a[j] = ins;\n\011\011b[j] = insb;\n\011}\n}\n"); _const_v__gen__c__c_headers = _S("//============================== HELPER C MACROS =============================*/\n// _SLIT0 is used as NULL string for literal arguments\n// `\"\" s` is used to enforce a string literal argument\n#define _SLIT0 (string){.str=(byteptr)(\"\"), .len=0, .is_lit=1}\n#define _S(s) ((string){.str=(byteptr)(\"\" s), .len=(sizeof(s)-1), .is_lit=1})\n#define _SLEN(s, n) ((string){.str=(byteptr)(\"\" s), .len=n, .is_lit=1})\n// optimized way to compare literal strings\n#define _SLIT_EQ(sptr, slen, lit) (slen == sizeof(\"\" lit)-1 && !vmemcmp(sptr, \"\" lit, slen))\n#define _SLIT_NE(sptr, slen, lit) (slen != sizeof(\"\" lit)-1 || vmemcmp(sptr, \"\" lit, slen))\n\n// take the address of an rvalue\n#define ADDR(type, expr) (&((type[]){expr}[0]))\n\n// copy something to the heap\n#define HEAP(type, expr) ((type*)memdup((void*)&((type[]){expr}[0]), sizeof(type)))\n#define HEAP_noscan(type, expr) ((type*)memdup_noscan((void*)&((type[]){expr}[0]), sizeof(type)))\n#define HEAP_align(type, expr, align) ((type*)memdup_align((void*)&((type[]){expr}[0]), sizeof(type), align))\n\n#define _PUSH_MANY(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array_push_many(arr, tmp.data, tmp.len);}\n#define _PUSH_MANY_noscan(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array_push_many_noscan(arr, tmp.data, tmp.len);}\n\n// unsigned/signed comparisons\nstatic inline bool _us32_gt(uint32_t a, int32_t b) { return a > INT32_MAX || (int32_t)a > b; }\nstatic inline bool _us32_ge(uint32_t a, int32_t b) { return a >= INT32_MAX || (int32_t)a >= b; }\nstatic inline bool _us32_eq(uint32_t a, int32_t b) { return a <= INT32_MAX && (int32_t)a == b; }\nstatic inline bool _us32_ne(uint32_t a, int32_t b) { return a > INT32_MAX || (int32_t)a != b; }\nstatic inline bool _us32_le(uint32_t a, int32_t b) { return a <= INT32_MAX && (int32_t)a <= b; }\nstatic inline bool _us32_lt(uint32_t a, int32_t b) { return a < INT32_MAX && (int32_t)a < b; }\nstatic inline bool _us64_gt(uint64_t a, int64_t b) { return a > INT64_MAX || (int64_t)a > b; }\nstatic inline bool _us64_ge(uint64_t a, int64_t b) { return a >= INT64_MAX || (int64_t)a >= b; }\nstatic inline bool _us64_eq(uint64_t a, int64_t b) { return a <= INT64_MAX && (int64_t)a == b; }\nstatic inline bool _us64_ne(uint64_t a, int64_t b) { return a > INT64_MAX || (int64_t)a != b; }\nstatic inline bool _us64_le(uint64_t a, int64_t b) { return a <= INT64_MAX && (int64_t)a <= b; }\nstatic inline bool _us64_lt(uint64_t a, int64_t b) { return a < INT64_MAX && (int64_t)a < b; }\n\n#define EMPTY_VARG_INITIALIZATION 0\n#define EMPTY_STRUCT_DECLARATION\n#define E_STRUCT\n// Due to a tcc bug, the length of an array needs to be specified, but GCC crashes if it is...\n#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[])\n#define TCCSKIP(x) x\n\n#define __NOINLINE __attribute__((noinline))\n#define __IRQHANDLER __attribute__((interrupt))\n\n#define __V_architecture 0\n#if defined(__x86_64__) || defined(_M_AMD64)\n\011#define __V_amd64 1\n\011#undef __V_architecture\n\011#define __V_architecture 1\n#endif\n\n#if defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64)\n\011#define __V_arm64 1\n\011#undef __V_architecture\n\011#define __V_architecture 2\n#endif\n\n#if defined(__arm__) || defined(_M_ARM)\n\011#define __V_arm32 1\n\011#undef __V_architecture\n\011#define __V_architecture 3\n#endif\n\n#if defined(__riscv) && __riscv_xlen == 64\n\011#define __V_rv64 1\n\011#undef __V_architecture\n\011#define __V_architecture 4\n#endif\n\n#if defined(__riscv) && __riscv_xlen == 32\n\011#define __V_rv32 1\n\011#undef __V_architecture\n\011#define __V_architecture 5\n#endif\n\n#if defined(__i386__) || defined(_M_IX86)\n\011#define __V_x86 1\n\011#undef __V_architecture\n\011#define __V_architecture 6\n#endif\n\n#if defined(__s390x__)\n\011#define __V_s390x 1\n\011#undef __V_architecture\n\011#define __V_architecture 7\n#endif\n\n#if defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)\n\011#define __V_ppc64le 1\n\011#undef __V_architecture\n\011#define __V_architecture 8\n#endif\n\n#if defined(__loongarch64)\n\011#define __V_loongarch64 1\n\011#undef __V_architecture\n\011#define __V_architecture 9\n#endif\n\n// Using just __GNUC__ for detecting gcc, is not reliable because other compilers define it too:\n#ifdef __GNUC__\n\011#define __V_GCC__\n#endif\n#ifdef __TINYC__\n\011#undef __V_GCC__\n#endif\n#ifdef __cplusplus\n\011#undef __V_GCC__\n#endif\n#ifdef __clang__\n\011#undef __V_GCC__\n#endif\n\n#ifdef _MSC_VER\n\011#undef __V_GCC__\n\011#undef EMPTY_STRUCT_DECLARATION\n\011#undef E_STRUCT\n\011#define EMPTY_STRUCT_DECLARATION unsigned char _dummy_pad\n\011#define E_STRUCT 0\n#endif\n\n#ifndef _WIN32\n\011#if defined __has_include\n\011\011#if __has_include ()\n\011\011\011#include \n\011\011#else\n\011\011\011// On linux: int backtrace(void **__array, int __size);\n\011\011\011// On BSD: size_t backtrace(void **, size_t);\n\011\011#endif\n\011#endif\n#endif\n\n#ifdef __TINYC__\n\011#define _Atomic volatile\n\011#undef EMPTY_STRUCT_DECLARATION\n\011#undef E_STRUCT\n\011#define EMPTY_STRUCT_DECLARATION unsigned char _dummy_pad\n\011#define E_STRUCT 0\n\011#undef EMPTY_ARRAY_OF_ELEMS\n\011#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[n])\n\011#undef __NOINLINE\n\011#undef __IRQHANDLER\n\011// tcc does not support inlining at all\n\011#define __NOINLINE\n\011#define __IRQHANDLER\n\011#undef TCCSKIP\n\011#define TCCSKIP(x)\n\011// #include \n\011int tcc_backtrace(const char *fmt, ...);\n#endif\n\n// Use __offsetof_ptr instead of __offset_of, when you *do* have a valid pointer, to avoid UB:\n#ifndef __offsetof_ptr\n\011#define __offsetof_ptr(ptr,PTYPE,FIELDNAME) ((size_t)((byte *)&((PTYPE *)ptr)->FIELDNAME - (byte *)ptr))\n#endif\n\n// for __offset_of\n#ifndef __offsetof\n#if defined(__TINYC__) || defined(_MSC_VER)\n\011#define __offsetof(PTYPE,FIELDNAME) ((size_t)(&((PTYPE *)0)->FIELDNAME))\n#else\n\011#define __offsetof(st, m) __builtin_offsetof(st, m)\n#endif\n#endif\n\n#define OPTION_CAST(x) (x)\n\n#if defined(_WIN32) || defined(__CYGWIN__)\n\011#define VV_EXP extern __declspec(dllexport)\n\011#define VV_LOC static\n#else\n\011// 4 < gcc < 5 is used by some older Ubuntu LTS and Centos versions,\n\011// and does not support __has_attribute(visibility) ...\n\011#ifndef __has_attribute\n\011\011#define __has_attribute(x) 0 // Compatibility with non-clang compilers.\n\011#endif\n\011#if (defined(__GNUC__) && (__GNUC__ >= 4)) || (defined(__clang__) && __has_attribute(visibility))\n\011\011#ifdef ARM\n\011\011\011#define VV_EXP extern __attribute__((externally_visible,visibility(\"default\")))\n\011\011#else\n\011\011\011#define VV_EXP extern __attribute__((visibility(\"default\")))\n\011\011#endif\n\011\011#if defined(__clang__) && (defined(_VUSECACHE) || defined(_VBUILDMODULE))\n\011\011\011#define VV_LOC static\n\011\011#else\n\011\011\011#define VV_LOC __attribute__ ((visibility (\"hidden\")))\n\011\011#endif\n\011#else\n\011\011#define VV_EXP extern\n\011\011#define VV_LOC static\n\011#endif\n#endif\n\n#ifdef __cplusplus\n\011#include \n\011#define _MOV std::move\n#else\n\011#define _MOV\n#endif\n\n// tcc does not support has_include properly yet, turn it off completely\n#if defined(__TINYC__) && defined(__has_include)\n#undef __has_include\n#endif\n\n\n#if !defined(VWEAK)\n\011#define VWEAK __attribute__((weak))\n\011#ifdef _MSC_VER\n\011\011#undef VWEAK\n\011\011#define VWEAK\n\011#endif\n\011#if defined(__MINGW32__) || defined(__MINGW64__)\n\011\011#undef VWEAK\n\011\011#define VWEAK\n\011#endif\n#endif\n\n#if !defined(VHIDDEN)\n\011#define VHIDDEN __attribute__((visibility(\"hidden\")))\n\011#ifdef _MSC_VER\n\011\011#undef VHIDDEN\n\011\011#define VHIDDEN\n\011#endif\n\011#if defined(__MINGW32__) || defined(__MINGW64__)\n\011\011#undef VHIDDEN\n\011\011#define VHIDDEN\n\011#endif\n#endif\n\n#if !defined(VNORETURN)\n\011#if defined(__TINYC__)\n\011\011#include \n\011\011#define VNORETURN noreturn\n\011#endif\n\011# if !defined(__TINYC__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L\n\011# define VNORETURN _Noreturn\n\011# elif !defined(VNORETURN) && defined(__GNUC__) && __GNUC__ >= 2\n\011# define VNORETURN __attribute__((noreturn))\n\011# endif\n\011#ifndef VNORETURN\n\011\011#define VNORETURN\n\011#endif\n#endif\n\n#if !defined(VUNREACHABLE)\n\011#if defined(__GNUC__) && !defined(__clang__)\n\011\011#define V_GCC_VERSION (__GNUC__ * 10000L + __GNUC_MINOR__ * 100L + __GNUC_PATCHLEVEL__)\n\011\011#if (V_GCC_VERSION >= 40500L) && !defined(__TINYC__)\n\011\011\011#define VUNREACHABLE() do { __builtin_unreachable(); } while (0)\n\011\011#endif\n\011#endif\n\011#if defined(__clang__) && defined(__has_builtin) && !defined(__TINYC__)\n\011\011#if __has_builtin(__builtin_unreachable)\n\011\011\011#define VUNREACHABLE() do { __builtin_unreachable(); } while (0)\n\011\011#endif\n\011#endif\n\011#ifndef VUNREACHABLE\n\011\011#define VUNREACHABLE() do { } while (0)\n\011#endif\n#endif\n\n//likely and unlikely macros\n#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)\n\011#define _likely_(x) __builtin_expect(x,1)\n\011#define _unlikely_(x) __builtin_expect(x,0)\n#else\n\011#define _likely_(x) (x)\n\011#define _unlikely_(x) (x)\n#endif\n\n\n// c_headers\ntypedef int (*qsort_callback_func)(const void*, const void*);\n#include // TODO: remove all these includes, define all function signatures and types manually\n#include \n#include \n\n#include // for va_list\n\n//================================== GLOBALS =================================*/\nint load_so(byteptr);\nvoid _vinit(int ___argc, voidptr ___argv);\nvoid _vcleanup(void);\n#ifdef _WIN32\n\011// workaround for windows, export _vinit_caller/_vcleanup_caller, let dl.open()/dl.close() call it\n\011// NOTE: This is hardcoded in vlib/dl/dl_windows.c.v!\n\011VV_EXP void _vinit_caller();\n\011VV_EXP void _vcleanup_caller();\n#endif\n#define sigaction_size sizeof(sigaction);\n#define _ARR_LEN(a) ( (sizeof(a)) / (sizeof(a[0])) )\n\nvoid v_free(voidptr ptr);\n\n#if INTPTR_MAX == INT32_MAX\n\011#define TARGET_IS_32BIT 1\n#elif INTPTR_MAX == INT64_MAX\n\011#define TARGET_IS_64BIT 1\n#else\n\011#error \"The environment is not 32 or 64-bit.\"\n#endif\n\n#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__)\n\011#define TARGET_ORDER_IS_BIG 1\n#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || defined(_M_AMD64) || defined(_M_ARM64) || defined(_M_X64) || defined(_M_IX86)\n\011#define TARGET_ORDER_IS_LITTLE 1\n#else\n\011#error \"Unknown architecture endianness\"\n#endif\n\n#ifndef _WIN32\n\011#include \n\011#include // tolower\n\011#include \n\011#include // sleep\n\011extern char **environ;\n#endif\n\n#if defined(__CYGWIN__) && !defined(_WIN32)\n\011#error Cygwin is not supported, please use MinGW or Visual Studio.\n#endif\n\n#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__vinix__) || defined(__serenity__) || defined(__sun) || defined(__plan9__)\n\011#include \n\011#include // os__wait uses wait on nix\n#endif\n\n#ifdef __OpenBSD__\n\011#include \n\011#include \n\011#include // os__wait uses wait on nix\n#endif\n\n#ifdef __FreeBSD__\n\011#include \n\011#include \n#endif\n\n#ifdef __NetBSD__\n\011#include // os__wait uses wait on nix\n#endif\n\n#ifdef _WIN32\n\011#define WINVER 0x0600\n\011#ifdef _WIN32_WINNT\n\011\011#undef _WIN32_WINNT\n\011#endif\n\011#define _WIN32_WINNT 0x0600\n\011#ifndef WIN32_FULL\n\011#define WIN32_LEAN_AND_MEAN\n\011#endif\n\011#ifndef _UNICODE\n\011#define _UNICODE\n\011#endif\n\011#ifndef UNICODE\n\011#define UNICODE\n\011#endif\n\011#include \n\n\011#include // _waccess\n\011#include // _wgetcwd\n\011#ifdef V_USE_SIGNAL_H\n\011#include // signal and SIGSEGV for segmentation fault handler\n\011#endif\n\n\011#ifdef _MSC_VER\n\011\011// On MSVC these are the same (as long as /volatile:ms is passed)\n\011\011#define _Atomic volatile\n\n\011\011// MSVC cannot parse some things properly\n\011\011#undef OPTION_CAST\n\011\011#define OPTION_CAST(x)\n\011\011#undef __NOINLINE\n\011\011#undef __IRQHANDLER\n\011\011#define __NOINLINE __declspec(noinline)\n\011\011#define __IRQHANDLER __declspec(naked)\n\n\011\011#include \n\011\011#pragma comment(lib, \"Dbghelp\")\n\011#endif\n#else\n\011#include \n\011#ifndef PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP\n\011\011// musl does not have that\n\011\011#define pthread_rwlockattr_setkind_np(a, b)\n\011#endif\n#endif\n\n// g_live_info is used by live.info()\nstatic void* g_live_info = NULL;\n\n#if defined(__MINGW32__) || defined(__MINGW64__) || (defined(_WIN32) && defined(__TINYC__))\n\011#undef PRId64\n\011#undef PRIi64\n\011#undef PRIo64\n\011#undef PRIu64\n\011#undef PRIx64\n\011#undef PRIX64\n\011#define PRId64 \"lld\"\n\011#define PRIi64 \"lli\"\n\011#define PRIo64 \"llo\"\n\011#define PRIu64 \"llu\"\n\011#define PRIx64 \"llx\"\n\011#define PRIX64 \"llX\"\n#endif\n\n#ifdef _VFREESTANDING\n#undef _VFREESTANDING\n#endif\n"); _const_v__gen__c__c_builtin_types = _S("\n//================================== builtin types ================================*/\n#if defined(__x86_64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || (defined(__riscv_xlen) && __riscv_xlen == 64) || defined(__s390x__) || (defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)) || defined(__loongarch64)\ntypedef int64_t vint_t;\n#else\ntypedef int32_t vint_t;\n#endif\ntypedef int64_t i64;\ntypedef int16_t i16;\ntypedef int8_t i8;\ntypedef uint64_t u64;\ntypedef uint32_t u32;\ntypedef uint8_t u8;\ntypedef uint16_t u16;\ntypedef u8 byte;\ntypedef int32_t i32;\ntypedef uint32_t rune;\ntypedef size_t usize;\ntypedef ptrdiff_t isize;\n#ifndef VNOFLOAT\ntypedef float f32;\ntypedef double f64;\n#else\ntypedef int32_t f32;\ntypedef int64_t f64;\n#endif\ntypedef int64_t int_literal;\n#ifndef VNOFLOAT\ntypedef double float_literal;\n#else\ntypedef int64_t float_literal;\n#endif\ntypedef unsigned char* byteptr;\ntypedef void* voidptr;\ntypedef char* charptr;\ntypedef u8 array_fixed_byte_300 [300];\n\ntypedef struct sync__Channel* chan;\n\n#ifndef CUSTOM_DEFINE_no_bool\n\011#ifndef __cplusplus\n\011\011#ifndef bool\n\011\011\011#ifdef CUSTOM_DEFINE_4bytebool\n\011\011\011\011typedef int bool;\n\011\011\011#else\n\011\011\011\011typedef u8 bool;\n\011\011\011#endif\n\011\011\011#define true 1\n\011\011\011#define false 0\n\011\011#endif\n\011#endif\n#endif\n"); _const_v__gen__c__c_mapfn_callback_types = _S("\ntypedef u64 (*MapHashFn)(voidptr);\ntypedef bool (*MapEqFn)(voidptr, voidptr);\ntypedef void (*MapCloneFn)(voidptr, voidptr);\ntypedef void (*MapFreeFn)(voidptr);\n"); _const_v__gen__c__c_bare_headers = _S("//============================== HELPER C MACROS =============================*/\n// _SLIT0 is used as NULL string for literal arguments\n// `\"\" s` is used to enforce a string literal argument\n#define _SLIT0 (string){.str=(byteptr)(\"\"), .len=0, .is_lit=1}\n#define _S(s) ((string){.str=(byteptr)(\"\" s), .len=(sizeof(s)-1), .is_lit=1})\n#define _SLEN(s, n) ((string){.str=(byteptr)(\"\" s), .len=n, .is_lit=1})\n// optimized way to compare literal strings\n#define _SLIT_EQ(sptr, slen, lit) (slen == sizeof(\"\" lit)-1 && !vmemcmp(sptr, \"\" lit, slen))\n#define _SLIT_NE(sptr, slen, lit) (slen != sizeof(\"\" lit)-1 || vmemcmp(sptr, \"\" lit, slen))\n\n// take the address of an rvalue\n#define ADDR(type, expr) (&((type[]){expr}[0]))\n\n// copy something to the heap\n#define HEAP(type, expr) ((type*)memdup((void*)&((type[]){expr}[0]), sizeof(type)))\n#define HEAP_noscan(type, expr) ((type*)memdup_noscan((void*)&((type[]){expr}[0]), sizeof(type)))\n#define HEAP_align(type, expr, align) ((type*)memdup_align((void*)&((type[]){expr}[0]), sizeof(type), align))\n\n#define _PUSH_MANY(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array_push_many(arr, tmp.data, tmp.len);}\n#define _PUSH_MANY_noscan(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array_push_many_noscan(arr, tmp.data, tmp.len);}\n\n// unsigned/signed comparisons\nstatic inline bool _us32_gt(uint32_t a, int32_t b) { return a > INT32_MAX || (int32_t)a > b; }\nstatic inline bool _us32_ge(uint32_t a, int32_t b) { return a >= INT32_MAX || (int32_t)a >= b; }\nstatic inline bool _us32_eq(uint32_t a, int32_t b) { return a <= INT32_MAX && (int32_t)a == b; }\nstatic inline bool _us32_ne(uint32_t a, int32_t b) { return a > INT32_MAX || (int32_t)a != b; }\nstatic inline bool _us32_le(uint32_t a, int32_t b) { return a <= INT32_MAX && (int32_t)a <= b; }\nstatic inline bool _us32_lt(uint32_t a, int32_t b) { return a < INT32_MAX && (int32_t)a < b; }\nstatic inline bool _us64_gt(uint64_t a, int64_t b) { return a > INT64_MAX || (int64_t)a > b; }\nstatic inline bool _us64_ge(uint64_t a, int64_t b) { return a >= INT64_MAX || (int64_t)a >= b; }\nstatic inline bool _us64_eq(uint64_t a, int64_t b) { return a <= INT64_MAX && (int64_t)a == b; }\nstatic inline bool _us64_ne(uint64_t a, int64_t b) { return a > INT64_MAX || (int64_t)a != b; }\nstatic inline bool _us64_le(uint64_t a, int64_t b) { return a <= INT64_MAX && (int64_t)a <= b; }\nstatic inline bool _us64_lt(uint64_t a, int64_t b) { return a < INT64_MAX && (int64_t)a < b; }\n\n#define EMPTY_VARG_INITIALIZATION 0\n#define EMPTY_STRUCT_DECLARATION\n#define E_STRUCT\n// Due to a tcc bug, the length of an array needs to be specified, but GCC crashes if it is...\n#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[])\n#define TCCSKIP(x) x\n\n#define __NOINLINE __attribute__((noinline))\n#define __IRQHANDLER __attribute__((interrupt))\n\n#define __V_architecture 0\n#if defined(__x86_64__) || defined(_M_AMD64)\n\011#define __V_amd64 1\n\011#undef __V_architecture\n\011#define __V_architecture 1\n#endif\n\n#if defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64)\n\011#define __V_arm64 1\n\011#undef __V_architecture\n\011#define __V_architecture 2\n#endif\n\n#if defined(__arm__) || defined(_M_ARM)\n\011#define __V_arm32 1\n\011#undef __V_architecture\n\011#define __V_architecture 3\n#endif\n\n#if defined(__riscv) && __riscv_xlen == 64\n\011#define __V_rv64 1\n\011#undef __V_architecture\n\011#define __V_architecture 4\n#endif\n\n#if defined(__riscv) && __riscv_xlen == 32\n\011#define __V_rv32 1\n\011#undef __V_architecture\n\011#define __V_architecture 5\n#endif\n\n#if defined(__i386__) || defined(_M_IX86)\n\011#define __V_x86 1\n\011#undef __V_architecture\n\011#define __V_architecture 6\n#endif\n\n#if defined(__s390x__)\n\011#define __V_s390x 1\n\011#undef __V_architecture\n\011#define __V_architecture 7\n#endif\n\n#if defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)\n\011#define __V_ppc64le 1\n\011#undef __V_architecture\n\011#define __V_architecture 8\n#endif\n\n#if defined(__loongarch64)\n\011#define __V_loongarch64 1\n\011#undef __V_architecture\n\011#define __V_architecture 9\n#endif\n\n// Using just __GNUC__ for detecting gcc, is not reliable because other compilers define it too:\n#ifdef __GNUC__\n\011#define __V_GCC__\n#endif\n#ifdef __TINYC__\n\011#undef __V_GCC__\n#endif\n#ifdef __cplusplus\n\011#undef __V_GCC__\n#endif\n#ifdef __clang__\n\011#undef __V_GCC__\n#endif\n\n#ifdef _MSC_VER\n\011#undef __V_GCC__\n\011#undef EMPTY_STRUCT_DECLARATION\n\011#undef E_STRUCT\n\011#define EMPTY_STRUCT_DECLARATION unsigned char _dummy_pad\n\011#define E_STRUCT 0\n#endif\n\n#ifndef _WIN32\n\011#if defined __has_include\n\011\011#if __has_include ()\n\011\011\011#include \n\011\011#else\n\011\011\011// On linux: int backtrace(void **__array, int __size);\n\011\011\011// On BSD: size_t backtrace(void **, size_t);\n\011\011#endif\n\011#endif\n#endif\n\n#ifdef __TINYC__\n\011#define _Atomic volatile\n\011#undef EMPTY_STRUCT_DECLARATION\n\011#undef E_STRUCT\n\011#define EMPTY_STRUCT_DECLARATION unsigned char _dummy_pad\n\011#define E_STRUCT 0\n\011#undef EMPTY_ARRAY_OF_ELEMS\n\011#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[n])\n\011#undef __NOINLINE\n\011#undef __IRQHANDLER\n\011// tcc does not support inlining at all\n\011#define __NOINLINE\n\011#define __IRQHANDLER\n\011#undef TCCSKIP\n\011#define TCCSKIP(x)\n\011// #include \n\011int tcc_backtrace(const char *fmt, ...);\n#endif\n\n// Use __offsetof_ptr instead of __offset_of, when you *do* have a valid pointer, to avoid UB:\n#ifndef __offsetof_ptr\n\011#define __offsetof_ptr(ptr,PTYPE,FIELDNAME) ((size_t)((byte *)&((PTYPE *)ptr)->FIELDNAME - (byte *)ptr))\n#endif\n\n// for __offset_of\n#ifndef __offsetof\n#if defined(__TINYC__) || defined(_MSC_VER)\n\011#define __offsetof(PTYPE,FIELDNAME) ((size_t)(&((PTYPE *)0)->FIELDNAME))\n#else\n\011#define __offsetof(st, m) __builtin_offsetof(st, m)\n#endif\n#endif\n\n#define OPTION_CAST(x) (x)\n\n#if defined(_WIN32) || defined(__CYGWIN__)\n\011#define VV_EXP extern __declspec(dllexport)\n\011#define VV_LOC static\n#else\n\011// 4 < gcc < 5 is used by some older Ubuntu LTS and Centos versions,\n\011// and does not support __has_attribute(visibility) ...\n\011#ifndef __has_attribute\n\011\011#define __has_attribute(x) 0 // Compatibility with non-clang compilers.\n\011#endif\n\011#if (defined(__GNUC__) && (__GNUC__ >= 4)) || (defined(__clang__) && __has_attribute(visibility))\n\011\011#ifdef ARM\n\011\011\011#define VV_EXP extern __attribute__((externally_visible,visibility(\"default\")))\n\011\011#else\n\011\011\011#define VV_EXP extern __attribute__((visibility(\"default\")))\n\011\011#endif\n\011\011#if defined(__clang__) && (defined(_VUSECACHE) || defined(_VBUILDMODULE))\n\011\011\011#define VV_LOC static\n\011\011#else\n\011\011\011#define VV_LOC __attribute__ ((visibility (\"hidden\")))\n\011\011#endif\n\011#else\n\011\011#define VV_EXP extern\n\011\011#define VV_LOC static\n\011#endif\n#endif\n\n#ifdef __cplusplus\n\011#include \n\011#define _MOV std::move\n#else\n\011#define _MOV\n#endif\n\n// tcc does not support has_include properly yet, turn it off completely\n#if defined(__TINYC__) && defined(__has_include)\n#undef __has_include\n#endif\n\n\n#if !defined(VWEAK)\n\011#define VWEAK __attribute__((weak))\n\011#ifdef _MSC_VER\n\011\011#undef VWEAK\n\011\011#define VWEAK\n\011#endif\n\011#if defined(__MINGW32__) || defined(__MINGW64__)\n\011\011#undef VWEAK\n\011\011#define VWEAK\n\011#endif\n#endif\n\n#if !defined(VHIDDEN)\n\011#define VHIDDEN __attribute__((visibility(\"hidden\")))\n\011#ifdef _MSC_VER\n\011\011#undef VHIDDEN\n\011\011#define VHIDDEN\n\011#endif\n\011#if defined(__MINGW32__) || defined(__MINGW64__)\n\011\011#undef VHIDDEN\n\011\011#define VHIDDEN\n\011#endif\n#endif\n\n#if !defined(VNORETURN)\n\011#if defined(__TINYC__)\n\011\011#include \n\011\011#define VNORETURN noreturn\n\011#endif\n\011# if !defined(__TINYC__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L\n\011# define VNORETURN _Noreturn\n\011# elif !defined(VNORETURN) && defined(__GNUC__) && __GNUC__ >= 2\n\011# define VNORETURN __attribute__((noreturn))\n\011# endif\n\011#ifndef VNORETURN\n\011\011#define VNORETURN\n\011#endif\n#endif\n\n#if !defined(VUNREACHABLE)\n\011#if defined(__GNUC__) && !defined(__clang__)\n\011\011#define V_GCC_VERSION (__GNUC__ * 10000L + __GNUC_MINOR__ * 100L + __GNUC_PATCHLEVEL__)\n\011\011#if (V_GCC_VERSION >= 40500L) && !defined(__TINYC__)\n\011\011\011#define VUNREACHABLE() do { __builtin_unreachable(); } while (0)\n\011\011#endif\n\011#endif\n\011#if defined(__clang__) && defined(__has_builtin) && !defined(__TINYC__)\n\011\011#if __has_builtin(__builtin_unreachable)\n\011\011\011#define VUNREACHABLE() do { __builtin_unreachable(); } while (0)\n\011\011#endif\n\011#endif\n\011#ifndef VUNREACHABLE\n\011\011#define VUNREACHABLE() do { } while (0)\n\011#endif\n#endif\n\n//likely and unlikely macros\n#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)\n\011#define _likely_(x) __builtin_expect(x,1)\n\011#define _unlikely_(x) __builtin_expect(x,0)\n#else\n\011#define _likely_(x) (x)\n\011#define _unlikely_(x) (x)\n#endif\n\n\n#define _VFREESTANDING\n\ntypedef long unsigned int size_t;\n\n// Memory allocation related headers\nvoid *malloc(size_t size);\nvoid *calloc(size_t nitems, size_t size);\nvoid *realloc(void *ptr, size_t size);\nvoid *memcpy(void *dest, void *src, size_t n);\nvoid *memset(void *s, int c, size_t n);\nvoid *memmove(void *dest, void *src, size_t n);\n\n// varargs implementation, TODO: works on tcc and gcc, but is very unportable and hacky\ntypedef __builtin_va_list va_list;\n#define va_start(a, b) __builtin_va_start(a, b)\n#define va_end(a) __builtin_va_end(a)\n#define va_arg(a, b) __builtin_va_arg(a, b)\n#define va_copy(a, b) __builtin_va_copy(a, b)\n\n//================================== GLOBALS =================================*/\nint load_so(byteptr);\nvoid _vinit(int ___argc, voidptr ___argv);\nvoid _vcleanup();\n#define sigaction_size sizeof(sigaction);\n#define _ARR_LEN(a) ( (sizeof(a)) / (sizeof(a[0])) )\n\nvoid v_free(voidptr ptr);\nvoidptr memdup(voidptr src, isize size);\n\n"); _const_v__gen__c__c_wyhash_headers = _S("\n// ============== wyhash ==============\n#ifndef wyhash_final_version_3\n#define wyhash_final_version_3\n\n#ifndef WYHASH_CONDOM\n// protections that produce different results:\n// 1: normal valid behavior\n// 2: extra protection against entropy loss (probability=2^-63), aka. \"blind multiplication\"\n#define WYHASH_CONDOM 1\n#endif\n\n#ifndef WYHASH_32BIT_MUM\n// 0: normal version, slow on 32 bit systems\n// 1: faster on 32 bit systems but produces different results, incompatible with wy2u0k function\n#define WYHASH_32BIT_MUM 0\n#endif\n\n// includes\n#include \n#if defined(_MSC_VER) && defined(_M_X64)\n\011#include \n\011#pragma intrinsic(_umul128)\n#endif\n\n// 128bit multiply function\nstatic inline uint64_t _wyrot(uint64_t x) { return (x>>32)|(x<<32); }\nstatic inline void _wymum(uint64_t *A, uint64_t *B){\n#if(WYHASH_32BIT_MUM)\n\011uint64_t hh=(*A>>32)*(*B>>32), hl=(*A>>32)*(uint32_t)*B, lh=(uint32_t)*A*(*B>>32), ll=(uint64_t)(uint32_t)*A*(uint32_t)*B;\n\011#if(WYHASH_CONDOM>1)\n\011*A^=_wyrot(hl)^hh; *B^=_wyrot(lh)^ll;\n\011#else\n\011*A=_wyrot(hl)^hh; *B=_wyrot(lh)^ll;\n\011#endif\n#elif defined(__SIZEOF_INT128__) && !defined(VWASM)\n\011__uint128_t r=*A; r*=*B;\n\011#if(WYHASH_CONDOM>1)\n\011*A^=(uint64_t)r; *B^=(uint64_t)(r>>64);\n\011#else\n\011*A=(uint64_t)r; *B=(uint64_t)(r>>64);\n\011#endif\n#elif defined(_MSC_VER) && defined(_M_X64)\n\011#if(WYHASH_CONDOM>1)\n\011uint64_t a, b;\n\011a=_umul128(*A,*B,&b);\n\011*A^=a; *B^=b;\n\011#else\n\011*A=_umul128(*A,*B,B);\n\011#endif\n#else\n\011uint64_t ha=*A>>32, hb=*B>>32, la=(uint32_t)*A, lb=(uint32_t)*B, hi, lo;\n\011uint64_t rh=ha*hb, rm0=ha*lb, rm1=hb*la, rl=la*lb, t=rl+(rm0<<32), c=t>32)+(rm1>>32)+c;\n\011#if(WYHASH_CONDOM>1)\n\011*A^=lo; *B^=hi;\n\011#else\n\011*A=lo; *B=hi;\n\011#endif\n#endif\n}\n\n// multiply and xor mix function, aka MUM\nstatic inline uint64_t _wymix(uint64_t A, uint64_t B){ _wymum(&A,&B); return A^B; }\n\n// endian macros\n#ifndef WYHASH_LITTLE_ENDIAN\n\011#ifdef TARGET_ORDER_IS_LITTLE\n\011\011#define WYHASH_LITTLE_ENDIAN 1\n\011#else\n\011\011#define WYHASH_LITTLE_ENDIAN 0\n\011#endif\n#endif\n\n// read functions\n#if (WYHASH_LITTLE_ENDIAN)\n\011static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return v;}\n\011static inline uint64_t _wyr4(const uint8_t *p) { uint32_t v; memcpy(&v, p, 4); return v;}\n#elif !defined(__TINYC__) && (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__))\n\011static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return __builtin_bswap64(v);}\n\011static inline uint64_t _wyr4(const uint8_t *p) { uint32_t v; memcpy(&v, p, 4); return __builtin_bswap32(v);}\n#elif defined(_MSC_VER)\n\011static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return _byteswap_uint64(v);}\n\011static inline uint64_t _wyr4(const uint8_t *p) { uint32_t v; memcpy(&v, p, 4); return _byteswap_ulong(v);}\n#else\n\011static inline uint64_t _wyr8(const uint8_t *p) {\n\011\011uint64_t v; memcpy(&v, p, 8);\n\011\011return (((v >> 56) & 0xff)| ((v >> 40) & 0xff00)| ((v >> 24) & 0xff0000)| ((v >> 8) & 0xff000000)| ((v << 8) & 0xff00000000)| ((v << 24) & 0xff0000000000)| ((v << 40) & 0xff000000000000)| ((v << 56) & 0xff00000000000000));\n\011}\n\011static inline uint64_t _wyr4(const uint8_t *p) {\n\011\011uint32_t v; memcpy(&v, p, 4);\n\011\011return (((v >> 24) & 0xff)| ((v >> 8) & 0xff00)| ((v << 8) & 0xff0000)| ((v << 24) & 0xff000000));\n\011}\n#endif\nstatic inline uint64_t _wyr3(const uint8_t *p, size_t k) { return (((uint64_t)p[0])<<16)|(((uint64_t)p[k>>1])<<8)|p[k-1];}\n// wyhash main function\nstatic inline uint64_t wyhash(const void *key, size_t len, uint64_t seed, const uint64_t *secret){\n\011const uint8_t *p=(const uint8_t *)key; seed^=*secret;\011uint64_t a, b;\n\011if (_likely_(len<=16)) {\n\011\011if (_likely_(len>=4)) { a=(_wyr4(p)<<32)|_wyr4(p+((len>>3)<<2)); b=(_wyr4(p+len-4)<<32)|_wyr4(p+len-4-((len>>3)<<2)); }\n\011\011else if (_likely_(len>0)) { a=_wyr3(p,len); b=0; }\n\011\011else a=b=0;\n\011} else {\n\011\011size_t i=len;\n\011\011if (_unlikely_(i>48)) {\n\011\011\011uint64_t see1=seed, see2=seed;\n\011\011\011do {\n\011\011\011\011seed=_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed);\n\011\011\011\011see1=_wymix(_wyr8(p+16)^secret[2],_wyr8(p+24)^see1);\n\011\011\011\011see2=_wymix(_wyr8(p+32)^secret[3],_wyr8(p+40)^see2);\n\011\011\011\011p+=48; i-=48;\n\011\011\011} while(_likely_(i>48));\n\011\011\011seed^=see1^see2;\n\011\011}\n\011\011while(_unlikely_(i>16)) { seed=_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed); i-=16; p+=16; }\n\011\011a=_wyr8(p+i-16); b=_wyr8(p+i-8);\n\011}\n\011return _wymix(secret[1]^len,_wymix(a^secret[1],b^seed));\n}\n// the default secret parameters\nstatic const uint64_t _wyp[4] = {0xa0761d6478bd642f, 0xe7037ed1a0b428db, 0x8ebc6af09c88c6e3, 0x589965cc75374cc3};\n\n// a useful 64bit-64bit mix function to produce deterministic pseudo random numbers that can pass BigCrush and PractRand\nstatic inline uint64_t wyhash64(uint64_t A, uint64_t B){ A^=0xa0761d6478bd642f; B^=0xe7037ed1a0b428db; _wymum(&A,&B); return _wymix(A^0xa0761d6478bd642f,B^0xe7037ed1a0b428db);}\n\n// the wyrand PRNG that pass BigCrush and PractRand\nstatic inline uint64_t wyrand(uint64_t *seed){ *seed+=0xa0761d6478bd642f; return _wymix(*seed,*seed^0xe7037ed1a0b428db);}\n\n#ifndef __vinix__\n// convert any 64 bit pseudo random numbers to uniform distribution [0,1). It can be combined with wyrand, wyhash64 or wyhash.\nstatic inline double wy2u01(uint64_t r){ const double _wynorm=1.0/(1ull<<52); return (r>>12)*_wynorm;}\n\n// convert any 64 bit pseudo random numbers to APPROXIMATE Gaussian distribution. It can be combined with wyrand, wyhash64 or wyhash.\nstatic inline double wy2gau(uint64_t r){ const double _wynorm=1.0/(1ull<<20); return ((r&0x1fffff)+((r>>21)&0x1fffff)+((r>>42)&0x1fffff))*_wynorm-3.0;}\n#endif\n\n#if(!WYHASH_32BIT_MUM)\n// fast range integer random number generation on [0,k) credit to Daniel Lemire. May not work when WYHASH_32BIT_MUM=1. It can be combined with wyrand, wyhash64 or wyhash.\nstatic inline uint64_t wy2u0k(uint64_t r, uint64_t k){ _wymum(&r,&k); return k; }\n#endif\n#endif\n\n#define _IN_MAP(val, m) map_exists(m, val)\n\n"); _const_v__gen__c__reset_dbg_line = _S("#line 999999999"); _const_v__gen__c__closure_ctx = _S("_V_closure_ctx"); _const_v__gen__c__posix_hotcode_definitions_1 = _S("\nvoid v_bind_live_symbols(void* live_lib){\n\011@LOAD_FNS@\n}\n"); _const_v__gen__c__windows_hotcode_definitions_1 = _S("\nvoid v_bind_live_symbols(void* live_lib){\n\011@LOAD_FNS@\n}\n"); _const_v__gen__c__cprefix = _S("v__reflection__"); _const_v__gen__c__unsupported_ctemp_assert_transform = I_v__gen__c__UnsupportedAssertCtempTransform_to_Interface_IError(((v__gen__c__UnsupportedAssertCtempTransform*)memdup(&(v__gen__c__UnsupportedAssertCtempTransform){.Error = ((Error){E_STRUCT}),}, sizeof(v__gen__c__UnsupportedAssertCtempTransform)))); { _const_v__gen__c__c_reserved = new_array_from_c_array(66, 66, sizeof(string), _MOV((string[66]){ _S("asm"), _S("array"), _S("auto"), _S("bool"), _S("break"), _S("calloc"), _S("case"), _S("char"), _S("class"), _S("complex"), _S("const"), _S("continue"), _S("default"), _S("delete"), _S("do"), _S("double"), _S("else"), _S("enum"), _S("error"), _S("exit"), _S("export"), _S("extern"), _S("false"), _S("float"), _S("for"), _S("free"), _S("goto"), _S("if"), _S("inline"), _S("int"), _S("link"), _S("long"), _S("malloc"), _S("namespace"), _S("new"), _S("nil"), _S("panic"), _S("register"), _S("restrict"), _S("return"), _S("short"), _S("signed"), _S("sizeof"), _S("static"), _S("string"), _S("struct"), _S("switch"), _S("typedef"), _S("typename"), _S("typeof"), _S("union"), _S("unix"), _S("unsigned"), _S("void"), _S("volatile"), _S("while"), _S("template"), _S("true"), _S("small"), _S("stdout"), _S("stdin"), _S("stderr"), _S("far"), _S("near"), _S("huge"), _S("requires")})); } _const_v__gen__c__cmp_str = new_array_from_c_array(6, 6, sizeof(string), _MOV((string[6]){_S("eq"), _S("ne"), _S("gt"), _S("lt"), _S("ge"), _S("le")})); _const_v__gen__c__cmp_rev = new_array_from_c_array(6, 6, sizeof(string), _MOV((string[6]){_S("eq"), _S("ne"), _S("lt"), _S("gt"), _S("le"), _S("ge")})); _const_v__gen__c__c_fn_name_escape_seq = new_array_from_c_array(4, 4, sizeof(string), _MOV((string[4]){_S("["), _S("_T_"), _S("]"), _S("")})); _const_v__gen__c__skip_struct_init = new_array_from_c_array(2, 2, sizeof(string), _MOV((string[2]){_S("struct stat"), _S("struct addrinfo")})); _const_v__gen__c__c_reserved_chk = v__token__new_keywords_matcher_from_array_trie(_const_v__gen__c__c_reserved); // Initializations of consts for module v.builder _const_v__builder__c_std = _S("c99"); _const_v__builder__c_std_gnu = _S("gnu99"); _const_v__builder__cpp_std = _S("c++17"); _const_v__builder__cpp_std_gnu = _S("gnu++17"); _const_v__builder__c_verror_message_marker = _S("VERROR_MESSAGE "); _const_v__builder__c_compilation_error_title = _S("C compilation error"); _const_v__builder__current_os = os__user_os(); _const_v__builder__hkey_local_machine = ((v__builder__RegKey)(0x80000002)); _const_v__builder__thirdparty_obj_build_retry_delay = 200 * _const_time__millisecond; // Initializations of consts for module v.builder.cbuilder { { _option_string _t1 = os__getenv_opt(_S("CC")); if (_t1.state != 0) { IError err = _t1.err; *(string*) _t1.data = _S("cc"); } _const_v__builder__cbuilder__cc_compiler = (*(string*)_t1.data); } } { { _option_string _t2 = os__getenv_opt(_S("LDFLAGS")); if (_t2.state != 0) { IError err = _t2.err; *(string*) _t2.data = _S(""); } _const_v__builder__cbuilder__cc_ldflags = (*(string*)_t2.data); } } { { _option_string _t3 = os__getenv_opt(_S("CFLAGS")); if (_t3.state != 0) { IError err = _t3.err; *(string*) _t3.data = _S(""); } _const_v__builder__cbuilder__cc_cflags = (*(string*)_t3.data); } } { { _option_string _t4 = os__getenv_opt(_S("CFLAGS_OPT")); if (_t4.state != 0) { IError err = _t4.err; *(string*) _t4.data = _S(""); } _const_v__builder__cbuilder__cc_cflags_opt = (*(string*)_t4.data); } } // Initializations of consts for module main { _const_main__external_tools = new_array_from_c_array(44, 44, sizeof(string), _MOV((string[44]){ _S("ast"), _S("bin2v"), _S("bug"), _S("build-examples"), _S("build-tools"), _S("build-vbinaries"), _S("bump"), _S("check-md"), _S("complete"), _S("compress"), _S("cover"), _S("diff"), _S("doc"), _S("doctor"), _S("download"), _S("fmt"), _S("gret"), _S("ls"), _S("missdoc"), _S("reduce"), _S("repl"), _S("repeat"), _S("retry"), _S("self"), _S("setup-freetype"), _S("shader"), _S("share"), _S("should-compile-all"), _S("symlink"), _S("scan"), _S("test"), _S("test-all"), _S("test-cleancode"), _S("test-fmt"), _S("test-parser"), _S("test-self"), _S("time"), _S("timeout"), _S("tracev"), _S("up"), _S("vet"), _S("wipe-cache"), _S("watch"), _S("where")})); } } void _vcleanup(void) { } int main(int ___argc, char** ___argv){ g_main_argc = ___argc; g_main_argv = ___argv; _vinit(___argc, (voidptr)___argv); main__main(); _vcleanup(); return 0; } // THE END.